Remindr is a Go + PostgreSQL backend for user-owned tasks, tags, and reminder records. It exposes a versioned JSON API, stores all user data in PostgreSQL, and runs a lightweight reminder scheduler inside the API process.
The API supports:
- user registration and login with JWT authentication
- CRUD-style task management
- tag management with per-user unique tag names
- many-to-many task/tag relationships
- reminder CRUD, persistence, lifecycle state transitions, and background delivery processing
Current reminder note:
- authenticated reminder CRUD endpoints are available
- the reminder scheduler/worker runtime starts with the API process
- due reminders are claimed in batches, sent by workers, and marked
sentor retried - the default sender logs due reminders; plug in another
reminder.Senderfor email, SMS, push, webhooks, or any other transport - reminders are created explicitly through the reminder API; task creation does not automatically create reminders
- Go
1.26 - PostgreSQL
chirouter- JWT auth
- SQL migrations via
golang-migrate
- Docker Compose for local service orchestration
- Air for local live reload in the development container
maketargets for migration workflows- Postman or any HTTP client for API testing
cmd/apiHTTP server, handlers, middleware, route mountingcmd/utilsrequest parsing, validation helpers, error responses, paginationcmd/tokensJWT creation and verificationinternal/storepersistence layerinternal/dbdatabase connection setup and migrationsinternal/reminderreminder domain package, scheduler, workers, and sender interface
More detail:
The server expects these environment variables:
ADDRDB_ADDRDB_MAX_OPEN_CONNSDB_MAX_IDLE_CONNSDB_MAX_IDLE_TIMETOKEN_SECRET_KEY
Notes:
.envis loaded automatically byinternal/env/env.goTOKEN_SECRET_KEYmust be at least 32 characters for JWT signing
Before starting the app, create a .env file with the environment variables above and point DB_ADDR at a reachable PostgreSQL database.
The development container uses Air and exposes the API on localhost:8081.
docker compose up --buildThe container maps port 8081 on the host to 8080 in the app.
go run ./cmd/apiRun tests:
go test ./...Create a migration:
make migration add_some_changeApply migrations:
make migrate-upRollback migrations:
make migrate-down 1The migration files live in internal/db/migrations.
POST /v1/users/registercreates a userPOST /v1/users/loginreturns a JWT- authenticated routes require
Authorization: Bearer <token>
GET /v1/healthzPOST /v1/users/registerPOST /v1/users/login
POST /v1/tasks/GET /v1/tasks/GET /v1/tasks/{id}PATCH /v1/tasks/{id}DELETE /v1/tasks/{id}DELETE /v1/tasks/DELETE /v1/tasks/bulkPOST /v1/tasks/{id}/tags/{tag_id}PUT /v1/tasks/{id}/tagsGET /v1/tasks/tags
POST /v1/tags/GET /v1/tags/GET /v1/tags/{id}GET /v1/tags/{id}/tasksPATCH /v1/tags/{id}DELETE /v1/tags/{id}DELETE /v1/tags/{task_id}/{id}
POST /v1/reminders/GET /v1/reminders/task/{task_id}GET /v1/reminders/{id}PATCH /v1/reminders/{id}DELETE /v1/reminders/{id}
See docs/api.md for request and query details.
- API-first resource design with JWT-protected user-owned data
- user-scoped ownership rules for tasks, tags, task-tag relationships, and reminders
- soft-delete strategy for tasks and tags
- explicit reminder management instead of implicit task-side reminder creation
- database-backed integrity rules for uniqueness and ownership boundaries
- default reminder delivery logs due reminders instead of sending through a real external transport
- task status is currently independent from reminder status
- reminder service tuning is currently hard-coded in
cmd/api/main.gorather than exposed through environment variables