# Go Backend Tasks Multi-View Dashboard Design

**Date:** 2026-05-10

**Goal**

Replace the current simple `/tasks` CRUD page in `go-backend` with a richer owner-level tasks dashboard that aggregates tasks across every tablo owned by the signed-in user and renders three server-side views:

- `Tableau`
- `Liste`
- `Roadmap`

The page should use query params as the source of truth for view state and filtering, while keeping task creation, editing, and deletion inside the existing server-rendered and HTMX-friendly backend architecture.

**Context**

The current tasks vertical slice already exists in `go-backend`:

- owner-scoped task and etape persistence is implemented
- `/tasks` already supports create, edit, update, and delete
- the page is currently rendered as a simple grouped CRUD view

This work does not redesign the persistence model. It redesigns the `/tasks` page contract, its server-side view shaping, and the related create/edit flows so the route behaves like a personal cross-tablo dashboard.

**Scope**

- Work exclusively in `go-backend`
- Replace the current `/tasks` page with a server-rendered dashboard
- Aggregate tasks across all tablos owned by the current user
- Support three server-rendered views on the same route:
  - `kanban`
  - `list`
  - `roadmap`
- Support URL-driven state with query params
- Implement functional filtering for:
  - `tablo`
  - `assignee`
  - `status`
- Extend create and edit forms to include:
  - `tablo_id`
  - `parent_task_id`
  - `assignee_id`
  - `due_date`
  - `status`
  - `title`
  - `description`
- Constrain selectable etapes to the chosen tablo during create and edit
- Implement two roadmap sub-modes:
  - `week`
  - `month`

**Out Of Scope**

- Drag and drop
- Client-only tab switching
- Calendar view
- Reordering tasks or etapes
- Persisted synthetic "Sans étape" rows
- New JSON API endpoints
- Collaborator or RBAC expansion beyond owner-only access
- Comments, attachments, activity feeds, or task detail pages

**Architecture**

The feature should stay inside the current Go server-rendered stack:

- HTTP handlers in `go-backend/internal/web/handlers/`
- page and component rendering in `go-backend/internal/web/views/`
- task shaping and task-related helpers in `go-backend/internal/tasks/` or closely related view-model code
- existing repository methods reused or extended only as needed

The core architectural move is to split `/tasks` rendering into:

1. one shared page-state parser
2. one shared filtered task dataset
3. three pure view-specific shaping functions

Recommended shaping functions:

- `buildKanbanView(...)`
- `buildListView(...)`
- `buildRoadmapView(...)`

This keeps filtering and ownership logic centralized while isolating presentation-specific grouping rules.

**Route Contract**

The route remains `GET /tasks`, but the page state is now controlled by query params.

Supported query params:

- `view=kanban|list|roadmap`
- `roadmap_mode=week|month`
- `tablo=<tablo_id>` optional, repeatable
- `assignee=<user_id>` optional, repeatable
- `status=todo|in_progress|in_review|done` optional, repeatable

Default behavior:

- missing or invalid `view` falls back to `kanban`
- missing or invalid `roadmap_mode` falls back to `week`
- invalid filter values are ignored rather than breaking the page
- `roadmap_mode` is ignored when `view` is not `roadmap`

The page should remain shareable and refresh-safe:

- filter changes submit with `GET /tasks`
- tabs are links that preserve the current applicable filters
- roadmap mode toggles are links or GET forms that preserve filters

**Data Scope**

All three views consume the same owner-scoped task set:

- every active task across every tablo owned by the signed-in user
- every active etape required to label or group those tasks

This is intentionally not a single-tablo page. `/tasks` is a personal dashboard over the user’s full owned workload.

**Shared Page Shell**

The page shell should render:

- page title
- `Nouvelle tâche` action
- view tabs:
  - `Tableau`
  - `Liste`
  - `Roadmap`
- roadmap sub-mode toggle when `view=roadmap`
- filter controls for:
  - tablo
  - assignee
  - status

The shell also needs the option data required to render forms and filters:

- all owner tablos
- all relevant assignee options
- status options
- tablo-scoped etape options for create and edit forms

**Kanban View Design**

The kanban view is status-driven and cross-tablo.

Columns:

- `À faire`
- `En cours`
- `Vérification`
- `Terminé`

Each column contains task cards from all owned tablos matching that status.

Each card should show enough metadata to make a cross-tablo dashboard usable:

- title
- tablo name
- étape label, or `Sans étape`
- due date if present
- assignee if present

First pass interaction is explicit-action based:

- no drag and drop
- status changes happen through edit actions or other explicit server-backed controls

**List View Design**

The list view is grouped by status across all owned tablos.

Groups:

- `À faire`
- `En cours`
- `Vérification`
- `Terminé`

Inside each group, tasks are rendered as flat rows rather than nested by tablo or étape.

Each row should show:

- title
- tablo
- étape or `Sans étape`
- assignee if present
- due date if present
- status actions and edit/delete access as appropriate

This view is intentionally a personal workload list rather than a single-tablo breakdown.

**Roadmap View Design**

The roadmap view is grouped horizontally by étape lanes and bucketed by due date.

Lane rules:

- lanes represent `tablo + étape`
- the lane identity must include the tablo to avoid collisions between same-named etapes in different tablos
- tasks without a parent etape go into a synthetic per-tablo lane:
  - `Tablo name / Sans étape`

Bucket rules:

- tasks are grouped inside each lane by due date
- tasks without a due date go into a final `Sans date` bucket

Roadmap sub-modes:

- `week`
  - weekly buckets starting from today, May 10, 2026
- `month`
  - monthly buckets starting from the current month containing May 10, 2026

Past-due tasks:

- tasks with due dates before the current starting point should still remain visible
- they should be folded into the first visible bucket rather than disappearing into an unrendered past section

This preserves visibility without introducing a separate "past" axis in the first pass.

**Filter Behavior**

Filters must apply consistently across all three views.

Required filters:

- `tablo`
- `assignee`
- `status`

Behavior:

- filters are applied once to the shared task set before view-specific grouping
- switching between `kanban`, `list`, and `roadmap` preserves active filters where possible
- switching roadmap sub-modes preserves active filters

Invalid filters:

- unknown tablo IDs are dropped
- unknown assignee IDs are dropped
- unknown status values are dropped

The page should always normalize back to a valid state instead of failing.

**Create And Edit Flow**

Because `/tasks` is now cross-tablo, create and edit forms must include tablo selection.

Create form fields:

- `tablo_id`
- `title`
- `description`
- `status`
- `due_date`
- `assignee_id`
- `parent_task_id`

Edit form fields:

- `tablo_id`
- `title`
- `description`
- `status`
- `due_date`
- `assignee_id`
- `parent_task_id`

Tablo and étape coupling:

- once a tablo is chosen, selectable etapes must be limited to active etapes from that tablo only
- `Sans étape` remains a runtime concept, represented by `parent_task_id = null`

The chosen tablo and étape combination must be enforced on the server even if the browser submits an invalid combination.

**Validation Rules**

The dashboard should reuse the current task invariants and add page-specific validation.

Required server-side rules:

- `parent_task_id` must be null or point to an active etape
- `parent_task_id` must belong to the selected `tablo_id`
- a task cannot point to an etape from another tablo
- `assignee_id` must resolve to a valid selectable user
- invalid `view` and `roadmap_mode` values fall back to defaults

When editing a task:

- if the selected tablo changes, the selected parent etape must be revalidated against the new tablo
- if the current parent no longer belongs to the selected tablo, the mutation must be rejected

Delete behavior remains unchanged functionally:

- delete the task or etape
- re-render the page in the current normalized query state

**Rendering Strategy**

The page should keep the current server-driven model:

- full-page render for normal requests
- content fragment render for HTMX requests where appropriate
- create and edit forms can continue to use modal or inline fragment responses

The important change is not the transport mechanism. It is the introduction of explicit page-state modeling and isolated per-view presenters.

Recommended internal page-state model:

- selected `view`
- selected `roadmap_mode`
- selected tablo filters
- selected assignee filters
- selected status filters

Recommended shared view-model layers:

- page shell view model
- create/edit form view model
- `kanban` view model
- `list` view model
- `roadmap` view model

**Testing**

Testing should cover both state parsing and view grouping behavior.

Handler tests:

- default `/tasks` render
- `view=kanban`
- `view=list`
- `view=roadmap`
- `roadmap_mode=week`
- `roadmap_mode=month`
- filter combinations for:
  - tablo
  - assignee
  - status
- create flow with `tablo_id`
- edit flow with `tablo_id`
- invalid cross-tablo parent étape rejection

View-model tests where practical:

- kanban grouping by status across multiple tablos
- list grouping by status across multiple tablos
- roadmap lane identity uses `tablo + étape`
- synthetic `Sans étape` lanes are created per tablo
- `Sans date` bucket is rendered
- overdue tasks are placed in the first visible roadmap bucket

**Implementation Slices**

1. Extend `/tasks` query parsing and normalized page-state handling.
2. Build shared filter-option loading for tablos, assignees, and statuses.
3. Introduce a shared owner-level filtered task dataset.
4. Split rendering into `kanban`, `list`, and `roadmap` view-model builders.
5. Replace the current simple `/tasks` view with a page shell and mode-specific renderers.
6. Extend create and edit forms with `tablo_id` and tablo-scoped etape options.
7. Add tests for filtering, grouping, roadmap bucketing, and invalid parent validation.

**Recommendation**

Use one `/tasks` route with shared filtering and separate presenter functions for each mode.

This approach fits the current Go backend architecture best because it:

- keeps the URL as the source of truth
- avoids duplicated repository and filter logic
- keeps each view’s grouping logic isolated
- preserves server-rendered behavior without introducing a browser-side state machine
