---
phase: 09-etapes
plan: 04
type: execute
wave: 4
depends_on:
  - 09-03-PLAN.md
files_modified:
  - backend/internal/web/handlers_tasks.go
  - backend/templates/tasks.templ
  - backend/templates/etapes.templ
  - backend/internal/web/handlers_tasks_test.go
  - backend/internal/web/handlers_etapes_test.go
autonomous: false
requirements: [ETAPE-01, ETAPE-02, ETAPE-03, ETAPE-04, ETAPE-05, ETAPE-06]

must_haves:
  truths:
    - "D-08/D-09/D-10: drag/drop reorder preserves etape_id and remains status-scoped"
    - "D-01 through D-16: all context decisions are represented in source behavior or verified manual behavior"
    - "UI-SPEC: top strip, chips, active state, selector copy, and delete copy are visually present"
    - "Research Pitfall 2: every UpdateTask call preserves etape_id unless assignment is intentionally changing"
  artifacts:
    - path: "backend/internal/web/handlers_tasks.go"
      provides: "reorder paths that preserve etape assignment"
    - path: "backend/internal/web/handlers_tasks_test.go"
      provides: "filtered reorder and etape preservation regression tests"
---

<objective>
Vertical slice 4: harden the completed etape feature by proving drag/drop reorder still works with etape filters and assignments, then run final automated and browser verification. This closes the phase against all ETAPE requirements and the UI contract.
</objective>

<context>
@/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.planning/phases/09-etapes/09-CONTEXT.md
@/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.planning/phases/09-etapes/09-RESEARCH.md
@/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.planning/phases/09-etapes/09-UI-SPEC.md
@/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.planning/phases/09-etapes/09-VALIDATION.md
@/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.planning/phases/09-etapes/09-03-PLAN.md
</context>

<threat_model>
T-09-01 Cross-tablo assignment remains covered by prior tests and must not regress.
T-09-05 Data loss remains covered by delete-unassign test and browser verification.
T-09-06 Integrity regression: task reorder must never clear or change `etape_id` unless assignment form submitted that change.
</threat_model>

<tasks>

<task type="auto">
  <name>Task 1: Add reorder preservation regression tests</name>
  <files>
    - backend/internal/web/handlers_tasks_test.go
  </files>
  <read_first>
    - backend/internal/web/handlers_tasks_test.go
    - backend/internal/web/handlers_tasks.go
    - .planning/phases/09-etapes/09-RESEARCH.md
  </read_first>
  <action>
    Add failing regression tests:
    1. `TestTaskReorderPreservesEtapeAssignment` creates assigned task, posts single-task reorder to another status, and verifies `etape_id` remains unchanged.
    2. `TestFilteredTaskReorderPreservesHiddenTasks` creates tasks in the same status assigned to different etapes, submits reorder for only one visible filtered task, and verifies the hidden task still exists with its original `etape_id`.
    3. `TestTaskOrderPersistsWithEtapeFilter` verifies filtered board ordering remains stable after reload.
  </action>
  <verify>
    <automated>cd backend && go test ./internal/web -run 'TestTaskReorderPreservesEtapeAssignment|TestFilteredTaskReorderPreservesHiddenTasks|TestTaskOrderPersistsWithEtapeFilter' -count=1</automated>
  </verify>
  <acceptance_criteria>
    - `handlers_tasks_test.go` contains all three named regression tests.
    - Tests fail before implementation if reorder does not preserve `etape_id`.
  </acceptance_criteria>
</task>

<task type="auto">
  <name>Task 2: Preserve etape assignment through reorder and refresh counts</name>
  <files>
    - backend/internal/web/handlers_tasks.go
    - backend/templates/tasks.templ
    - backend/templates/etapes.templ
  </files>
  <read_first>
    - backend/internal/web/handlers_tasks.go
    - backend/templates/tasks.templ
    - backend/templates/etapes.templ
    - .planning/phases/09-etapes/09-RESEARCH.md
  </read_first>
  <action>
    Update every `UpdateTaskParams` call in `TaskReorderHandler` to pass the existing task's `etape_id`. Confirm the single-task path and array Sortable.js path both preserve assignment.
    Ensure reorder responses under an active etape filter return the filtered board or whole Tasks tab consistently enough that chip counts and active state remain correct after HTMX settles.
    Keep task position assignment status-scoped; do not add `(etape_id, status, position)` ordering semantics.
  </action>
  <verify>
    <automated>cd backend && just generate && go test ./internal/web -run 'TestTaskReorderPreservesEtapeAssignment|TestFilteredTaskReorderPreservesHiddenTasks|TestTaskOrderPersistsWithEtapeFilter|TestTaskReorderCrossColumn|TestTaskReorderSameColumn|TestTaskOrderPersists' -count=1</automated>
  </verify>
  <acceptance_criteria>
    - Every `UpdateTaskParams` call in `handlers_tasks.go` includes the current `EtapeID` or intentional parsed assignment value.
    - `TaskReorderHandler` does not parse or write assignment from drag/drop payload.
    - Reorder regression tests and existing reorder tests pass.
  </acceptance_criteria>
</task>

<task type="manual">
  <name>Task 3: Final automated and browser verification checkpoint</name>
  <files></files>
  <read_first>
    - .planning/phases/09-etapes/09-UI-SPEC.md
    - .planning/phases/09-etapes/09-VALIDATION.md
    - backend/internal/web/handlers_tasks_test.go
    - backend/internal/web/handlers_etapes_test.go
  </read_first>
  <action>
    Run full generated-code and backend verification, then perform browser verification:
    1. `cd backend && just generate`
    2. `cd backend && go test ./... -count=1`
    3. `git diff --check`
    4. Start `cd backend && just dev`.
    5. In a browser, open a tablo Tasks tab, create two etapes, create assigned and unassigned tasks, filter by an etape, filter by `Unassigned`, edit assignment from the task form, drag a filtered task across columns, delete an etape, and confirm affected tasks move to Unassigned rather than disappearing.
  </action>
  <verify>
    <automated>cd backend && just generate && go test ./... -count=1</automated>
    <manual>Browser confirms all ETAPE-01..06 success criteria and UI-SPEC interaction contract.</manual>
  </verify>
  <acceptance_criteria>
    - `cd backend && go test ./... -count=1` exits 0.
    - `git diff --check` exits 0.
    - Browser verification confirms top-strip chips, counts, filters, assignment selector, reorder, and delete-unassign behavior.
    - User approves the checkpoint before Phase 9 is marked complete.
  </acceptance_criteria>
</task>

</tasks>

<verification>
Run:
- `cd backend && just generate`
- `cd backend && go test ./... -count=1`
- `git diff --check`
- browser verification from Task 3
</verification>

<success_criteria>
- All ETAPE-01..06 requirements are complete.
- Existing kanban status and ordering behavior remains intact.
- UI-SPEC is satisfied in the first functional UI.
- Human verification checkpoint is approved.
</success_criteria>
