---
phase: 09-etapes
plan: 01
subsystem: tasks
tags: [go, htmx, templ, postgres, sqlc, etapes]
requires:
  - phase: 04-tasks
    provides: existing tablo task kanban and task create/update/reorder handlers
provides:
  - tablo-owned etapes schema and sqlc query surface
  - first Tasks tab etape strip with All, Unassigned, and etape filters
  - task creation with same-tablo etape assignment validation
affects: [09-etapes, tasks, tablos]
tech-stack:
  added: []
  patterns: [tablo-owned child rows, htmx fragment refresh, nullable assignment foreign key]
key-files:
  created:
    - backend/migrations/0007_etapes.sql
    - backend/internal/db/queries/etapes.sql
    - backend/internal/web/handlers_etapes.go
    - backend/templates/etapes.templ
    - backend/templates/etapes_forms.go
  modified:
    - backend/internal/db/queries/tasks.sql
    - backend/internal/web/handlers_tasks.go
    - backend/internal/web/handlers_files.go
    - backend/templates/tasks.templ
    - backend/templates/tablos.templ
key-decisions:
  - "Keep etape filtering as a tab-scoped query parameter instead of adding a separate page."
  - "Preserve task position as status-scoped; etape assignment does not influence task ordering."
  - "Validate submitted etape ids through GetEtapeByID with the current tablo id before task insert."
patterns-established:
  - "Etape tab refreshes use a full #tasks-tab fragment when chip counts and kanban contents both change."
  - "Task mutations preserve existing EtapeID when updating title, description, status, or position."
requirements-completed: []
completed: 2026-05-15
---

# Plan 09-01 Summary

**Tablo-owned etapes with a working Tasks tab chip filter and task create assignment path**

## Accomplishments

- Added `0007_etapes.sql` with no nested parent field and `tasks.etape_id ON DELETE SET NULL`.
- Added etape sqlc queries and extended task queries to read, insert, and preserve `etape_id`.
- Added protected etape create routes and a compact Tasks tab etape strip with `All`, `Unassigned`, and per-etape chips.
- Added etape filtering while preserving the existing four status columns.
- Extended task creation so submitted etape ids are validated against the current tablo before insert.

## Task Commits

1. **Task 1: Add RED coverage for first etape slice** - `a8a3e5f`
2. **Task 2: Implement create-filter-assigned-task slice** - `565bb88`

## Verification

- `cd backend && go test ./internal/web -run 'TestEtapeCreateRendersChipAndCount|TestTaskCreateAssignsEtape|TestEtapeFilterRendersExistingKanbanColumns' -count=1`
- `cd backend && go test ./internal/web -count=1`
- `cd backend && go test ./... -count=1`

## Deviations from Plan

None. The slice stayed within the planned schema, handlers, and template surface.

## Issues Encountered

Sqlc returned row-specific task types when `etape_id` was selected before timestamp columns. The task queries now select and return columns in the generated `Task` model order, keeping existing handler/template code on `sqlc.Task`.

## User Setup Required

None.

## Next Phase Readiness

Plan 09-02 can build directly on the etape query and fragment surface to add edit, delete, and reorder. Deleting etapes should rely on the migration-level `ON DELETE SET NULL` behavior already in place.

## Self-Check: PASSED
