From c9c826247a9192c999592f0226061f868bd62a5a Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Fri, 15 May 2026 09:22:18 +0200 Subject: [PATCH] feat(04-01): add tasks migration and sqlc query source - CREATE TYPE task_status ENUM (todo, in_progress, in_review, done) - CREATE TABLE tasks with tablo_id FK, position, status columns - DROP order: table before type in Down migration (Pitfall 3) - sqlc queries: ListTasksByTablo, InsertTask, GetTaskByID, UpdateTask, DeleteTask, MaxPositionByTabloAndStatus - migration applied cleanly, sqlc generate produces TaskStatus type and Task struct --- backend/internal/db/queries/tasks.sql | 29 +++++++++++++++++++++++++++ backend/migrations/0004_tasks.sql | 25 +++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 backend/internal/db/queries/tasks.sql create mode 100644 backend/migrations/0004_tasks.sql diff --git a/backend/internal/db/queries/tasks.sql b/backend/internal/db/queries/tasks.sql new file mode 100644 index 0000000..3896568 --- /dev/null +++ b/backend/internal/db/queries/tasks.sql @@ -0,0 +1,29 @@ +-- name: ListTasksByTablo :many +SELECT id, tablo_id, title, description, status, position, created_at, updated_at +FROM tasks +WHERE tablo_id = $1 +ORDER BY status, position, created_at; + +-- name: InsertTask :one +INSERT INTO tasks (tablo_id, title, description, status, position) +VALUES ($1, $2, $3, $4, $5) +RETURNING id, tablo_id, title, description, status, position, created_at, updated_at; + +-- name: GetTaskByID :one +SELECT id, tablo_id, title, description, status, position, created_at, updated_at +FROM tasks +WHERE id = $1 AND tablo_id = $2; + +-- name: UpdateTask :one +UPDATE tasks +SET title = $2, description = $3, status = $4, position = $5, updated_at = now() +WHERE id = $1 +RETURNING id, tablo_id, title, description, status, position, created_at, updated_at; + +-- name: DeleteTask :exec +DELETE FROM tasks WHERE id = $1 AND tablo_id = $2; + +-- name: MaxPositionByTabloAndStatus :one +SELECT COALESCE(MAX(position), 0)::integer AS max_position +FROM tasks +WHERE tablo_id = $1 AND status = $2; diff --git a/backend/migrations/0004_tasks.sql b/backend/migrations/0004_tasks.sql new file mode 100644 index 0000000..c529608 --- /dev/null +++ b/backend/migrations/0004_tasks.sql @@ -0,0 +1,25 @@ +-- migrations/0004_tasks.sql +-- Phase 4: Tasks (Kanban) + +-- +goose Up + +-- ENUM declaration order must match visual left-to-right column order (Pitfall 6). +CREATE TYPE task_status AS ENUM ('todo', 'in_progress', 'in_review', 'done'); + +CREATE TABLE tasks ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + tablo_id uuid NOT NULL REFERENCES tablos(id) ON DELETE CASCADE, + title text NOT NULL, + description text, + status task_status NOT NULL DEFAULT 'todo', + position integer NOT NULL DEFAULT 100, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now() +); + +CREATE INDEX tasks_tablo_id_status_idx ON tasks(tablo_id, status, position); + +-- +goose Down +-- Table MUST be dropped before type (Pitfall 3 — type is still referenced by table column). +DROP TABLE IF EXISTS tasks; +DROP TYPE IF EXISTS task_status;