docs: add expo tasks & etapes feature design spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4f31275c82
commit
32fd9c1b2e
1 changed files with 158 additions and 0 deletions
158
docs/superpowers/specs/2026-04-15-expo-tasks-etapes-design.md
Normal file
158
docs/superpowers/specs/2026-04-15-expo-tasks-etapes-design.md
Normal file
|
|
@ -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
|
||||
Loading…
Reference in a new issue