Habit and task tracker app.
- Ruby 79.5%
- HTML 13.4%
- Dockerfile 3.7%
- JavaScript 1.6%
- CSS 1.2%
- Other 0.6%
| .github | ||
| .vscode | ||
| app | ||
| bin | ||
| config | ||
| db | ||
| lib | ||
| log | ||
| public | ||
| storage | ||
| test | ||
| tmp | ||
| vendor | ||
| .dockerignore | ||
| .gitattributes | ||
| .gitignore | ||
| .rubocop.yml | ||
| .ruby-version | ||
| config.ru | ||
| Dockerfile | ||
| Gemfile | ||
| Gemfile.lock | ||
| Rakefile | ||
| README.md | ||
🌿 Roots & Rhythm — Habit Tracker API
A personal habit tracker built to learn the GitLab tech stack: Rails · Grape · PostgreSQL (backend) + Vue (frontend, coming soon).
Tech Stack
| Layer | Technology | Why |
|---|---|---|
| Framework | Ruby on Rails 7.1 | Convention over configuration |
| API DSL | Grape | GitLab's API framework |
| Database | PostgreSQL | GitLab's primary data store |
| Auth | Grape + JWT (bcrypt) | Token-based, stateless REST auth |
| Frontend | Vue 3 (coming soon) | GitLab's frontend framework |
Getting Started
#0 Prerequisites
dnf group install development-tools
dnf install ruby-devel zlib-devel postgresql-server postgresql-devel libyaml-devel
rails update
gem install bundler -v 4.0.7
# 1. Install dependencies
bundle install
# 2. Set up the database
rails db:create db:migrate db:seed
# 3. Start the server
rails server
# API available at http://localhost:3000/api/v1
API Reference
Auth
| Method | Endpoint | Description | Auth? |
|---|---|---|---|
| POST | /api/v1/auth/register | Create account | No |
| POST | /api/v1/auth/login | Get JWT token | No |
Register:
POST /api/v1/auth/register
{ "email": "john@example.com", "name": "John", "password": "secret123" }
→ { "token": "eyJ...", "user": { "id": 1, "name": "John", "email": "..." } }
Login:
POST /api/v1/auth/login
{ "email": "john@example.com", "password": "secret123" }
→ { "token": "eyJ..." }
For all protected endpoints, pass the token as:
Authorization: Bearer eyJ...
Habits
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/habits | List all your habits |
| GET | /api/v1/habits/dashboard | Today's habits + streaks |
| POST | /api/v1/habits | Create a new habit |
| PUT | /api/v1/habits/:id | Update a habit |
| DELETE | /api/v1/habits/:id | Delete a habit |
Create a habit:
POST /api/v1/habits
{
"name": "Read the Bible",
"category": "faith", // faith | health | family | mind
"frequency": "daily" // daily | weekly | monthly
}
Dashboard response:
GET /api/v1/habits/dashboard
{
"date": "2026-02-28",
"habits": [
{
"id": 1,
"name": "Read the Bible",
"category": "faith",
"frequency": "daily",
"today_status": "done", // done | missed | pending
"streak": 12,
"note": null
}
],
"summary": { "total": 7, "done": 5, "missed": 0, "pending": 2 }
}
Habit Logs (check-ins)
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/habits/:id/logs | Log history for a habit |
| POST | /api/v1/habits/:id/logs | Mark done/missed for a date |
| GET | /api/v1/logs/range?from=&to= | All logs in a date range |
Mark a habit done (with a note):
POST /api/v1/habits/1/logs
{
"status": "done",
"logged_on": "2026-02-28",
"note": "Studied Philippians 4, notes on contentment and peace."
}
Project Structure
app/
api/
root_api.rb # Mounts all Grape APIs
v1/
auth_helper.rb # JWT encode/decode + authenticate! helper
auth_api.rb # POST /auth/register, /auth/login
habits_api.rb # CRUD + dashboard
habit_logs_api.rb # Check-ins (done/missed/skipped)
models/
user.rb # has_secure_password, streak calculation
habit.rb # categories, frequencies, validations
habit_log.rb # one log per habit per day
db/
schema.sql # Full PostgreSQL schema reference
Next Steps
- Rails migrations — translate
db/schema.sqlintodb/migrate/files - Seeds —
db/seeds.rbwith sample habits for development - Tests — RSpec request specs for each endpoint
- Vue frontend — Vue 3 + Pinia store + Axios hitting this API
- Swagger docs — add
grape-swaggerfor auto-generated API docs
Learning Resources
- Grape README — GitLab's actual API docs use this
- GitLab's API source — see how the pros do it
- JWT.io — debug your tokens here