Split TaskItem into two independent states:
- `expanded` (chevron): toggles subtask visibility, only shown when
subtasks exist
- `detailOpen` (search icon + title click): opens detail panel with
notes, priority, edit/delete actions
The two actions are fully independent — expanding subtasks does not
open the detail view and vice versa.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Web: hide "Add subtask" button when depth >= 1 in TaskItem.
API: reject task creation if parentId points to a task that already
has a parentId (max depth validation).
Mobile: hide subtask section in task detail when viewing a subtask.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Web: add a RefreshCw button next to the list title in TaskList that
calls router.refresh() with a spin animation.
Mobile: add RefreshControl to DraggableFlatList on both inbox and
list detail screens, using the app's blue accent color.
Also deduplicate list insert values in sync/route.ts (review feedback).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Address review feedback:
1. Wrap inbox deduplication (select, reassign tasks, soft-delete) in a
db.transaction() for atomicity.
2. Revert seed.ts to use random UUID — a fixed ID shared across users
would cause PK conflicts. The sync endpoint handles deduplication.
3. Subtasks share the same listId as their parent, so the reassign
query already covers them (clarified in comment).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When mobile syncs its inbox (fixed ID) to the web, check if an inbox
already exists for the user. If so, reassign tasks and soft-delete the
old inbox to prevent duplicates. Also harmonize seed.ts to use the same
fixed inbox ID as mobile.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>