Habit Tracker
Daily habits with composite-unique logs (one entry per habit per day).
What you get
- Habits with frequency (daily/weekly/monthly) and color
- Composite UNIQUE on (habit_id, date) — one log per habit per day
- Logs cascade-delete when their habit is deleted
- Strict owner-scoped access across all three tables
Schema
Copy and apply with PUT /v1/schema or set_schema via MCP. MoonDB auto-creates 3 tables: users, habits, logs.
{
"tables": {
"users": {
"auth_table": true,
"columns": {
"display_name": "string"
}
},
"habits": {
"columns": {
"name": "string required max_length 100",
"color": "string default #86efac",
"frequency": {
"type": "enum",
"values": [
"daily",
"weekly",
"monthly"
],
"default": "daily"
},
"active": "bool default true",
"user_id": "ref users required"
},
"owner_field": "user_id",
"access": {
"read": "owner",
"create": "auth",
"update": "owner",
"delete": "owner"
}
},
"logs": {
"columns": {
"habit_id": "ref habits required cascade",
"date": "date required",
"note": "text",
"user_id": "ref users required"
},
"owner_field": "user_id",
"unique": [
[
"habit_id",
"date"
]
],
"access": {
"read": "owner",
"create": "auth",
"update": "owner",
"delete": "owner"
}
}
}
}
Auto-generated endpoints
The moment the schema applies, this REST surface is live (replace {project_id} with the id returned by POST /v1/projects):
GET /api/users list/filter/sort/paginate
GET /api/users/{id} read one
POST /api/users create
PATCH /api/users/{id} partial update
DELETE /api/users/{id} delete
POST /api/users/bulk atomic bulk insert
POST /auth/signup (from this auth_table)
POST /auth/login (from this auth_table)
GET /auth/me Bearer {token}
GET /api/habits list/filter/sort/paginate
GET /api/habits/{id} read one
POST /api/habits create
PATCH /api/habits/{id} partial update
DELETE /api/habits/{id} delete
POST /api/habits/bulk atomic bulk insert
GET /api/logs list/filter/sort/paginate
GET /api/logs/{id} read one
POST /api/logs create
PATCH /api/logs/{id} partial update
DELETE /api/logs/{id} delete
POST /api/logs/bulk atomic bulk insert
Plus auto-generated /v1/openapi.json (OpenAPI 3.0.3) and /v1/llm-context (machine-readable agent reference) for any client generator or coding agent.
Apply via REST
# 1. create the project
curl -X POST https://api.moondb.ai/v1/projects \
-H "X-API-Key: mk_..." \
-H "Content-Type: application/json" \
-d '{"name":"habit-tracker"}'
# 2. apply the template schema
curl -X PUT https://api.moondb.ai/p/{project_id}/v1/schema \
-H "X-Admin-Key: sk_..." \
-H "Content-Type: application/json" \
-d @habit-tracker.schema.json
Apply via MCP
If your agent has the MoonDB MCP server installed (see install), one tool call applies the template:
# call set_schema via MCP (Cursor, Claude Code, Windsurf)
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": { "name": "set_schema", "arguments": {
"project_id": "...",
"schema": {
"tables": {
"users": {
"auth_table": true,
"columns": {
"display_name": "string"
}
},
"habits": {
"columns": {
"name": "string required max_length 100",
"color": "string default #86efac",
"frequency": {
"type": "enum",
"values": [
"daily",
"weekly",
"monthly"
],
"default": "daily"
},
"active": "bool default true",
"user_id": "ref users required"
},
"owner_field": "user_id",
"access": {
"read": "owner",
"create": "auth",
"update": "owner",
"delete": "owner"
}
},
"logs": {
"columns": {
"habit_id": "ref habits required cascade",
"date": "date required",
"note": "text",
"user_id": "ref users required"
},
"owner_field": "user_id",
"unique": [
[
"habit_id",
"date"
]
],
"access": {
"read": "owner",
"create": "auth",
"update": "owner",
"delete": "owner"
}
}
}
}
} } }
Prompt your agent
Or just paste this one-liner into Cursor / Claude Code / Lovable after the MoonDB prompt is in .cursorrules / CLAUDE.md:
Apply the MoonDB "Habit Tracker" template — users, habits (with frequency + color), logs with composite unique (habit_id, date), all owner-scoped.
Extending the template
Send the full updated schema (with your additions) to PUT /v1/schema — MoonDB diffs against the current version and auto-migrates. Destructive changes (dropping columns, narrowing enums, renaming) require "confirm_destructive": true in the body. Read more about schema updates →
Ship this in 30 seconds
Sign up free, create a project, paste the schema. The API is live before your kettle boils.
Get an API key