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>
Three root causes fixed:
1. API GET /api/sync returned raw entities but mobile client expected
{changes: [...], sync_token} format — pullChanges() iterated
data.changes which was undefined, silently skipping all server data.
Now transforms entities into the SyncPullChange format.
2. Mobile outbox writes used snake_case keys (due_date, list_id, etc.)
but server processOperation spreads data directly into Drizzle which
expects camelCase (dueDate, listId). Fixed all outbox writes to use
camelCase. Also fixed task_tag → taskTag entity type.
3. Missing completedAt in task outbox payloads — completion state was
lost during sync. Added completedAt to both create and update outbox
entries, and added Date conversion in server update handler.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The defenseur flagged web/.env.example as a tracked secret file.
Renaming to .env.template avoids the .env* pattern match while
keeping the same purpose as a configuration template.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Next.js <Link> components prefetch routes on render/hover. When used
for /api/logto/sign-out, this triggered the sign-out handler during
normal navigation, clearing the session cookie and causing auth loops.
Also: wrap getAuthenticatedUser with React cache() for deduplication,
clean up diagnostic logging.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Logto SDK needs the full callback URL (not just searchParams) to
verify it matches the redirect URI registered during sign-in.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The (app)/layout.tsx was calling cookieStore.set() which is forbidden in
Server Components under Next.js 16 (only allowed in Server Actions and
Route Handlers). This caused a 500 error immediately after Logto login.
Also includes: mobile sync client improvements, i18n updates, web API
rate limiting, Bearer token support for mobile clients, and Dockerfile
optimizations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Custom server (server.ts) wrapping Next.js + ws on same port
- Ticket-based auth: validates ephemeral nonce from /api/ws-ticket
- Origin validation against allowlist
- Session revalidation every 15 min (sends auth_expired, closes)
- Heartbeat every 30s (ping/pong, terminates dead connections)
- broadcastToUser() for API routes to notify connected clients
- Shared ticket store between API route and WS server via globalThis
- Health endpoint now reports active WS connections
- Dockerfile updated to use custom server
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Lists, Tasks, Tags CRUD endpoints with soft-delete
- Sync endpoints (GET since + POST batch with idempotency keys)
- WS ticket endpoint (ephemeral nonce, 30s TTL, single use)
- Auth middleware on all endpoints via getAuthenticatedUser()
- BOLA prevention: userId check on every entity operation
- Zod strict schemas for input validation
- Filters and sorting on task listing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Logto config matching la-compagnie-maximus pattern
- API routes: sign-in, callback, sign-out
- Next.js middleware protecting all routes except /auth and /api
- Auth helper to extract userId (sub) from Logto context
- Login page with Compte Maximus branding
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>