Commit graph

79 commits

Author SHA1 Message Date
le king fu
f786947941 fix: resolve Logto auth crash on web — remove illegal cookie set in layout
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>
2026-04-08 13:12:59 -04:00
14c208be46 Merge pull request 'fix: force widget refresh after subtask toggle (#32)' (#33) from fix/simpl-liste-32-widget-subtask-toggle into master 2026-04-08 16:44:46 +00:00
le king fu
6328a8d0d3 fix: correct Logto session cookie prefix in middleware
Cookie is named `logto_<appId>` not `logto:<appId>`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 08:56:21 -04:00
8462aa9ef4 Merge pull request 'feat: add mobile sync client with outbox pattern (#40)' (#47) from issue-40-sync-mobile into master 2026-04-06 16:59:00 +00:00
b7a090df71 Merge pull request 'feat: implement web frontend with full task management UI (#39)' (#46) from issue-39-frontend-web into master 2026-04-06 16:58:35 +00:00
f4df9bbfd0 Merge pull request 'feat: setup Next.js web project with Drizzle + PostgreSQL schema (#35)' (#42) from issue-35-web-setup into master 2026-04-06 16:58:04 +00:00
d486be9227 Merge pull request 'feat: extract shared types, colors, priority and recurrence (#34)' (#41) from issue-34-shared-types into master 2026-04-06 16:57:29 +00:00
le king fu
c496d9586c feat: add mobile sync client with outbox pattern (#40)
- sync_outbox table in SQLite (migration 0004)
- Sync service: push/pull changes, fullSync, outbox cleanup
- Outbox writing in task/list/tag repositories after mutations
- Settings store: syncEnabled, lastSyncAt, userId
- Sync polling: on launch, every 2 min, on return from background
- Settings UI: Compte section with connect/sync/disconnect buttons
- i18n keys for sync strings (FR + EN)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:54:44 -04:00
le king fu
cb04adcc2e feat: implement web frontend with full task management UI (#39)
- Protected (app) layout with sidebar, header, theme toggle
- List detail page with tasks, filters, sorting
- Inline task editing (title, notes, priority, due date, recurrence)
- Subtask creation and nested display
- Dark mode (class-based, persisted to localStorage)
- WebSocket sync hook (connects via ticket auth, auto-refresh)
- Responsive sidebar (hamburger on mobile)
- French UI strings throughout
- Components: Sidebar, TaskList, TaskItem, TaskForm, FilterBar,
  ThemeToggle, Header, AppShell

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:40:11 -04:00
2f2a48f644 Merge pull request 'feat: add WebSocket server with ticket auth and heartbeat (#38)' (#45) from issue-38-websocket into issue-35-web-setup 2026-04-06 16:07:00 +00:00
le king fu
6d2e7449f3 feat: add WebSocket server with ticket auth and heartbeat (#38)
- 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>
2026-04-06 11:55:28 -04:00
46ead345b4 Merge pull request 'feat: implement REST API backend with full CRUD and sync (#37)' (#44) from issue-37-api-rest into issue-35-web-setup 2026-04-06 15:52:30 +00:00
le king fu
be9ba65337 feat: implement REST API backend with full CRUD and sync (#37)
- 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>
2026-04-06 11:47:53 -04:00
0369597eb6 Merge pull request 'feat: integrate Logto auth with middleware and login page (#36)' (#43) from issue-36-auth-logto into issue-35-web-setup 2026-04-06 15:38:45 +00:00
le king fu
42c39907cd feat: integrate Logto auth with middleware and login page (#36)
- 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>
2026-04-06 11:37:20 -04:00
le king fu
022fe53b92 feat: setup Next.js web project with Drizzle + PostgreSQL schema (#35)
- Init Next.js App Router with TypeScript, Tailwind, standalone output
- Drizzle ORM pg-core schema (sl_lists, sl_tasks, sl_tags, sl_task_tags)
- Database client, seed script, drizzle.config
- Health endpoint (/api/health) with DB latency check
- Dockerfile for Coolify deployment
- .env.example with DATABASE_URL and Logto config placeholders

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 11:03:34 -04:00
le king fu
91eef58186 fix: remove duplicate RecurrenceType definition in shared/types (#34)
Re-export from shared/recurrence instead of redefining.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 10:39:12 -04:00
le king fu
b277232462 feat: extract shared types, colors, priority and recurrence (#34)
Create src/shared/ with platform-agnostic types and helpers for
mobile/web code sharing. Add updatedAt to tags schema for sync.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 10:38:16 -04:00
escouade-bot
156e45496f fix: deduplicate WIDGET_NAMES and remove double-render in TOGGLE_SUBTASK (#32)
- Export WIDGET_NAMES from widgetSync.ts and import in widgetTaskHandler.ts
- Remove renderWithState call before forceWidgetRefresh to avoid double-render
- Use shared WIDGET_NAMES in widgetSync.ts refresh loop

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 04:01:01 -04:00
escouade-bot
645f778db5 fix: remove unnecessary forceWidgetRefresh from TOGGLE_COMPLETE and TOGGLE_EXPAND (#32)
Only TOGGLE_SUBTASK needs forceWidgetRefresh() because ListView caches
items. TOGGLE_COMPLETE and TOGGLE_EXPAND already work with renderWithState()
alone since they perform structural changes (remove item / toggle children).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 02:00:49 -04:00
escouade-bot
82b501e753 fix: force widget refresh via requestWidgetUpdate after click actions (#32)
The Android ListView caches its items, so visual-only changes (like
toggling a subtask checkbox) were not reflected without calling
requestWidgetUpdate() to invalidate the cache. Added forceWidgetRefresh()
helper that calls requestWidgetUpdate() for all 3 widget sizes after
TOGGLE_SUBTASK, TOGGLE_COMPLETE, and TOGGLE_EXPAND handlers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 00:01:14 -04:00
le king fu
7f8a0832d4 chore: bump version to 1.4.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 20:14:47 -04:00
244fbee405 Merge pull request 'fix: consolidate widget AsyncStorage and debounce expand (#29)' (#31) from issue-29-widget-expand-perf into master 2026-03-31 00:13:13 +00:00
9b1f7e79c9 Merge pull request 'feat: inline edit and delete for subtasks (#25)' (#30) from issue-25-edit-delete-subtasks into master 2026-03-31 00:13:04 +00:00
723f5d6501 Merge pull request 'fix: update vulnerable dependencies' (#28) from fix/simpl-liste-26-vulnerable-deps into master 2026-03-31 00:02:07 +00:00
le king fu
992c983026 chore: remove unused isWidgetTask function (#29)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 20:00:19 -04:00
le king fu
810bf2e939 fix: consolidate widget AsyncStorage keys and debounce expand (#29)
Merge widget:tasks, widget:isDark, and widget:expandedTaskIds into a
single widget:state key to reduce AsyncStorage I/O from 3 reads to 1.
Add 2s debounce on TOGGLE_EXPAND to prevent double-tap from collapsing
the subtask list. Legacy keys are migrated on first read.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 19:45:02 -04:00
le king fu
19706fa4a3 feat: add inline edit and delete for subtasks (#25)
Long-press a subtask to edit its title inline. Tap X to delete
with confirmation. Tap still toggles completion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 19:36:24 -04:00
escouade-bot
aa7ca20731 fix: use npm audit fix instead of broad overrides for vulnerable deps (#26)
Replace aggressive >=major overrides (picomatch>=4, brace-expansion>=2, etc.)
with npm audit fix which patches each dependency within its compatible semver
range: picomatch 2.3.2/3.0.2/4.0.4, brace-expansion 1.1.13/2.0.3/5.0.5,
undici 6.24.1, node-forge 1.4.0, tar 7.5.13, yaml 1.10.3/2.8.3.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 02:03:32 -04:00
escouade-bot
36e138ec55 fix: override vulnerable transitive dependencies with patched versions (#26)
Add npm overrides for picomatch, node-forge, tar, undici, brace-expansion,
and yaml to resolve 6 security vulnerabilities (4 high, 2 moderate).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 00:01:26 -04:00
le king fu
704ca9f693 fix: bump versionCode to 6 for APK upgrade compatibility
Previous preview build (v1.2.5) used versionCode 5 via production
autoIncrement, but app.json was still at 4. Android refuses to install
an APK with a lower versionCode than the currently installed one.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 21:10:29 -04:00
le king fu
72ace1db4a chore: bump version to 1.3.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:26:10 -04:00
3cecf9ba26 Merge pull request 'fix: show all tasks in widget (#23)' (#24) from fix/simpl-liste-23-widget-task-count into master 2026-03-13 00:25:21 +00:00
le king fu
9a8bb13e97 fix: cap widget task list at 30 items to prevent memory issues
Add safety limit of 30 rendered tasks in the widget to avoid Android
memory constraints. Also add cross-reference comment for the implicit
AsyncStorage coupling with useSettingsStore.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:20:47 -04:00
le king fu
2e13528c6b fix: default widget period to all tasks (#23)
Change default widgetPeriodWeeks from 2 to 0 (all tasks) so that the
issue is resolved out of the box without requiring the user to discover
the new setting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:10:45 -04:00
le king fu
f040ec7902 feat: add configurable widget display period setting (#23)
Instead of removing the time filter entirely, let users choose the
widget display period (1 week, 2 weeks, 4 weeks, or all tasks) from
Settings. Default remains 2 weeks for backward compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:04:35 -04:00
dde33acdf2 fix: show all tasks in widget without date or count limits
Remove the 2-week date filter from widget task query so tasks with
distant due dates are included. Remove the maxItems truncation from
the scrollable ListWidget so the displayed list matches the counter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:48:14 -04:00
b5e722c1f0 Merge pull request 'fix: save and back buttons not navigating away from task screen (#21)' (#22) from fix/simpl-liste-21-save-button-navigation into master 2026-03-10 01:26:05 +00:00
4c73a16302 fix: restore error handling and deduplicate goBack helper (#21)
- Replace `finally` with `catch` in [id].tsx handleSave so goBack is
  not called when updateTask/setTagsForTask fails
- Extract shared goBack helper into src/lib/navigation.ts
- Both [id].tsx and new.tsx now import goBack from the shared module

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 21:06:05 -04:00
2296126ba4 fix: use goBack helper with canGoBack fallback and reset saving state (#21)
Replace all router.back() calls with a goBack() helper that checks
router.canGoBack() first and falls back to router.replace('/') when
there is no screen to return to. In the task edit screen, change
catch to finally so the save button always resets its disabled state
even if updateTask/setTagsForTask throws.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 20:47:22 -04:00
d6a69d849b Merge pull request 'fix: restore add button in medium/large widget (#19)' (#20) from fix/simpl-liste-19-widget-add-button into master 2026-03-09 23:52:11 +00:00
594896a909 Restore add button in medium/large widget by moving it to header
The ListWidget (Android ListView) introduced for scrolling takes all
available vertical space, pushing the footer add button off-screen.
Move the + button into the header row where it remains always visible
regardless of the task list scroll state.

Related to #19

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 23:01:52 -04:00
8d34ae5267 chore: bump version to 1.2.5 (versionCode 4)
Includes widget scroll support, completed tasks sorting, and
esbuild vulnerability fix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:27:13 -04:00
0462b5a50b Merge pull request 'fix: sort completed main tasks to bottom of list (#15)' (#18) from fix/simpl-liste-15-sort-completed-tasks into master 2026-03-08 15:26:01 +00:00
2a7b70c65c Merge pull request 'fix: add scroll support in medium/large widgets (#11)' (#14) from fix/simpl-liste-11-widget-scroll into master 2026-03-08 15:25:16 +00:00
6c1bd043e6 Merge pull request 'fix: resolve esbuild vulnerability via npm override (#16)' (#17) from fix/simpl-liste-16-esbuild-vulnerability into master 2026-03-08 15:25:15 +00:00
2d9440b05c Sort completed main tasks to the bottom of the list
Add asc(tasks.completed) as the primary sort key in getOrderClauses()
so completed tasks always appear after active ones regardless of the
chosen sort mode (position, priority, dueDate, title, createdAt).

Also apply the same completed-first ordering to:
- getSubtasks() in tasks.ts
- noDateTasks query in widgetSync.ts
- subtasks query in widgetSync.ts

Ref: simpl-liste#15

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:04:32 -04:00
ce21337042 Add npm override to force esbuild ^0.25.0 across all dependencies
The transitive dependency chain drizzle-kit -> @esbuild-kit/esm-loader ->
@esbuild-kit/core-utils pulled in esbuild@0.18.20 which is vulnerable to
GHSA-67mh-4wv8-2f99. Adding an npm override forces all nested esbuild
instances to use ^0.25.0, resolving all 4 moderate audit findings.

Ref: simpl-liste#16

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:02:46 -04:00
le king fu
661ac0aa33 Add scrollable task list in medium/large widgets
Replace FlexWidget with ListWidget for the task list in medium and
large home screen widgets, enabling scroll when items exceed the
widget display area.

Fixes #11

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:56:13 -05:00
le king fu
fa037e9eef fix: increase touch targets for header buttons (#10)
Buttons (X, back, save, delete, export) had ~28px hit areas,
causing missed taps. Increased padding to p-2.5 + hitSlop for
~44px touch targets. Bump version to 1.2.4.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:22:54 -05:00