From 32fd9c1b2e75faaa851419aeaf2e1c13cd6d753c Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Wed, 15 Apr 2026 09:06:42 +0200 Subject: [PATCH] docs: add expo tasks & etapes feature design spec Co-Authored-By: Claude Opus 4.6 (1M context) --- .../2026-04-15-expo-tasks-etapes-design.md | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-15-expo-tasks-etapes-design.md diff --git a/docs/superpowers/specs/2026-04-15-expo-tasks-etapes-design.md b/docs/superpowers/specs/2026-04-15-expo-tasks-etapes-design.md new file mode 100644 index 0000000..91cf002 --- /dev/null +++ b/docs/superpowers/specs/2026-04-15-expo-tasks-etapes-design.md @@ -0,0 +1,158 @@ +# Expo App: Tasks & Etapes Feature Design + +**Date:** 2026-04-15 +**Scope:** Add task and etape (stage) management to the Expo mobile app, reusing the existing Supabase backend. + +## Context + +The web app (`apps/main`) has a full kanban-based task system with etapes (parent tasks/stages). The Expo app (`xtablo-expo/`) currently has no task management. This spec brings task and etape CRUD to mobile with a mobile-native UX. + +### Key Backend Facts + +- **No REST API for tasks** — the web app queries Supabase directly via PostgREST. The mobile app will do the same. +- **Etapes are tasks with `is_parent: true`** — not a separate table. Child tasks link via `parent_task_id`. +- **View:** `tasks_with_assignee` joins assignee profile info (name, avatar). +- **RLS** handles authorization — no manual user filtering needed. +- **Task statuses:** `todo`, `in_progress`, `in_review`, `done`. + +## Navigation & Entry Point + +### Tablo Detail Screen + +New screen: `app/(app)/tablo/[id].tsx` + +Accessed by tapping a tablo in the existing tablos list. Contains: +- Header: tablo name, color indicator, status badge +- Task list as primary content (described below) + +This screen becomes the natural place to add more sections later (files, members, settings). + +**Route update:** The tablos list screen (`app/(app)/(tabs)/tablos.tsx`) navigates to this new screen on tablo tap, instead of the current behavior. + +## Task List UI + +The task list is organized as **collapsible sections by etape**: + +### Section Structure +- Each **etape** renders as a section header: etape title, task count badge, collapse/expand chevron +- A **"Sans Étape"** section at the bottom for tasks with no `parent_task_id` +- Sections are ordered by etape `position` (ascending) + +### Within Each Section +- Tasks grouped by status with small color-coded status sub-headers (Todo, In Progress, In Review, Done) +- Tasks ordered by `position` within each status group + +### Task Row +Each task row displays: +- Status color dot (blue=todo, yellow=in_progress, purple=in_review, green=done) +- Title (single line, truncated) +- Assignee avatar (small circle, or empty circle placeholder if unassigned) +- Due date badge (gray normally, red if overdue) + +### Interactions +- **Tap section header** → collapse/expand the section +- **Tap task row** → navigate to task detail screen +- **Swipe left on task** → reveal delete action with confirmation +- **Pull-to-refresh** → refetch tasks and etapes +- **Floating "+" button** (bottom-right) → navigate to task creation screen + +## Task Detail Screen + +New screen: `app/(app)/task/[id].tsx` + +Used for both creating and editing tasks. Routes: +- **Edit:** `/task/{taskId}?tabloId={tabloId}` — `id` param is the task UUID +- **Create:** `/task/new?tabloId={tabloId}` — `id` param is the literal string `"new"` + +### Form Fields + +| Field | Input Type | Required | Notes | +|-------|-----------|----------|-------| +| Title | Text input | Yes | Single line | +| Description | Multiline text input | No | Expandable | +| Status | Horizontal segmented control | Yes | 4 options, color-coded. Defaults to "todo" on create. | +| Assignee | Bottom sheet picker | No | Lists tablo members with avatars. "Unassigned" option at top. | +| Etape | Bottom sheet picker | No | Lists etapes for the tablo. "Sans Étape" option at top. | +| Due date | Native date picker | No | iOS DateTimePicker / Android date dialog. Format: YYYY-MM-DD. | + +### Behavior +- **Create mode:** Status defaults to "todo". Etape and assignee default to null. "Save" button creates the task via `useCreateTask()`. +- **Edit mode:** All fields pre-populated from existing task data. "Save" button updates via `useUpdateTask()`. +- **Delete:** Red "Delete" button at the bottom of the edit screen. Confirmation dialog before deletion via `useDeleteTask()`. +- **No auto-save** — explicit save button to avoid accidental edits on mobile. + +## Etape Management + +Managed directly from the tablo detail screen — no separate screen. + +### Interactions +- **Long-press etape section header** → action menu with "Edit" and "Delete" +- **"+" button** next to the etape headers area → create new etape +- **Edit** → bottom sheet with: title input, description input, due date picker +- **Delete** → confirmation dialog. Child tasks become orphaned (move to "Sans Étape" section). + +### No Reorder on Mobile +Etapes display in `position` order from the database. Manual drag-to-reorder is not implemented on mobile — users can reorder from the web app. + +## Tablo Members (Read-Only) + +A read-only members fetch to support the task assignee picker: + +- Hook: `useTabloMembers(tabloId)` +- Query: Supabase query for tablo members with name, avatar, role +- Used only within the assignee picker bottom sheet +- No invite/manage/remove functionality + +## New Files + +### Screens + +| File | Purpose | +|------|---------| +| `app/(app)/tablo/[id].tsx` | Tablo detail screen with task list | +| `app/(app)/tablo/_layout.tsx` | Layout for tablo routes | +| `app/(app)/task/[id].tsx` | Task detail/create/edit screen | +| `app/(app)/task/_layout.tsx` | Layout for task routes | + +### Components + +| File | Purpose | +|------|---------| +| `components/TaskList.tsx` | Full task list with etape sections | +| `components/TaskRow.tsx` | Single task row in the list | +| `components/EtapeSection.tsx` | Collapsible etape section header | +| `components/EtapeSheet.tsx` | Bottom sheet for etape create/edit | +| `components/AssigneePicker.tsx` | Bottom sheet for assignee selection | +| `components/EtapePicker.tsx` | Bottom sheet for etape selection | +| `components/StatusControl.tsx` | Horizontal segmented status selector | + +### Hooks + +| Hook | Query Key | Purpose | +|------|-----------|---------| +| `useTasksByTablo(tabloId)` | `["tasks", "tablo", tabloId]` | Fetch tasks for a tablo (from `tasks_with_assignee` view, `is_parent: false`) | +| `useCreateTask()` | mutation | Insert into `tasks` table | +| `useUpdateTask()` | mutation | Update task fields | +| `useDeleteTask()` | mutation | Hard delete task | +| `useTabloEtapes(tabloId)` | `["tablo-etapes", tabloId]` | Fetch etapes (`is_parent: true`) for a tablo | +| `useCreateEtape()` | mutation | Insert parent task | +| `useUpdateEtape()` | mutation | Update etape fields | +| `useDeleteEtape()` | mutation | Hard delete etape | +| `useTabloMembers(tabloId)` | `["tablo-members", tabloId]` | Fetch members for assignee picker | + +### Cache Invalidation + +Mutations invalidate: +- Task mutations → `["tasks", "tablo", tabloId]` +- Etape mutations → `["tablo-etapes", tabloId]` and `["tasks", "tablo", tabloId]` + +## Out of Scope + +- Drag-and-drop reordering (tasks or etapes) +- Kanban board view +- Batch position updates +- File management on tablo detail +- Member management (invite/remove) +- Tablo settings editing +- Subscription/upgrade gating (freemium checks) +- Push notifications for task assignments