Skip to content

Taskbase API — Architecture

Overview

The taskbase API is a Go HTTP service under api/ in the skatzi/taskbase repo.

Entry point

api/cmd/server/main.go wires the application: connects to Postgres, runs migrations, registers all HTTP routes, and starts the server.

Package layout

Each resource (project, task) is a self-contained package under api/internal/:

api/internal/
  project/         # GET|POST /api/projects, GET|PUT|DELETE /api/projects/{id}
  task/            # GET|POST /api/projects/{id}/tasks, GET|PUT|DELETE /api/tasks/{id}
  taskgroup/       # GET /api/projects/{id}/groups — predefined kanban columns
  auth/            # OIDC JWT validation middleware (no-op when KEYCLOAK_ISSUER is unset)
  db/              # pgxpool connect + golang-migrate runner
  httputil/        # shared JSON helpers
  migrations/      # embedded *.sql files
  swagger/         # embedded OpenAPI spec + Swagger UI

Each domain package contains: | File | Purpose | |------|---------| | model.go | Struct definition | | store.go | Store interface | | store_memory.go | In-memory impl (unit tests, no DB) | | store_pg.go | PostgreSQL impl | | handler.go | HTTP handler + RegisterRoutes | | handler_test.go | Tests using MemoryStore |

Data model

  • Project: id, name, description, created_at, updated_at
  • Task: id, project_id (FK → projects), title, description, done, created_at, updated_at

A task belongs to exactly one project.

Configuration

Env var Default Purpose
DATABASE_URL postgres://taskbase:taskbase@localhost:5432/taskbase?sslmode=disable Postgres connection string
PORT 8080 HTTP listen port
KEYCLOAK_ISSUER (unset) OIDC issuer URL — auth is skipped entirely when absent. See Authentication.

Build

From the taskbase repo root:

make api-build   # produces api/bin/api
make api-test    # runs internal package tests (no DB required)
make api-vet

Adding a new resource

  1. Create api/internal/<resource>/ with model.go, store.go, store_memory.go, store_pg.go, handler.go, handler_test.go
  2. Write a migration in api/internal/migrations/
  3. Wire the handler in api/cmd/server/main.go
  4. Add a make <resource>-* target if needed