Commit Graph

  • aa7387fca8 fix(docker): also copy /app/node_modules/.pnpm so workspace symlinks resolve master yiekheng 2026-05-10 22:33:46 +08:00
  • 7d3d34af7f fix(docker): copy workspace packages' node_modules into web runtime yiekheng 2026-05-10 22:31:14 +08:00
  • b47c0409ae fix(docker): pass placeholder DATABASE_URL/AUTH_SECRET during web build yiekheng 2026-05-10 22:23:49 +08:00
  • f08b2bcb13 fix(web): force-dynamic on /api/qr/[accountId] to unblock docker build yiekheng 2026-05-10 22:20:23 +08:00
  • 58b249097a security: untrack envs/ENV (leaked DB password + AUTH_SECRET) yiekheng 2026-05-10 22:14:44 +08:00
  • 6893ca6ba9 fix(web): lazy-parse env so docker build doesn't crash on missing DATABASE_URL yiekheng 2026-05-10 22:13:30 +08:00
  • 49f5c16b19 fix(docker): reuse node user instead of creating gid 1000 — unblocks publish yiekheng 2026-05-10 22:09:12 +08:00
  • 954d382b54 docs(env): refresh envs/.env.example for v1 + publish.sh yiekheng 2026-05-10 22:03:27 +08:00
  • 31cf845030 feat(scripts): real publish.sh — buildx push of bot + web images yiekheng 2026-05-10 22:02:13 +08:00
  • ea7d07b2c8 perf(db): composite index (account_id, name) + hide archived groups yiekheng 2026-05-10 21:57:17 +08:00
  • c906a9fa3a docs: refresh README + add docs/runbook.md for v1 sign-off yiekheng 2026-05-10 21:45:03 +08:00
  • 47d7c53fda feat(db): auto-guard against drizzle journal-skip regression yiekheng 2026-05-10 21:40:11 +08:00
  • 27318888bc fix(db): bump 0012/0013 journal timestamps so drizzle applies them yiekheng 2026-05-10 21:35:52 +08:00
  • b988d117a3 fix(db): restore whatsappGroups declaration that perf-notes comment ate yiekheng 2026-05-10 21:34:27 +08:00
  • d731390c9d fix(web): unpair soft-archives groups instead of DELETE — same FK abort yiekheng 2026-05-10 21:33:03 +08:00
  • 08f2c0fd27 fix(bot): group-sync soft-archives instead of DELETE — fixes FK abort yiekheng 2026-05-10 21:30:05 +08:00
  • 2fe8459d25 feat: duplicate-pair detection + logout-before-delete + ordering tests yiekheng 2026-05-10 21:26:58 +08:00
  • f566e4683a feat(web): sort accounts by created_at ascending (earliest first) yiekheng 2026-05-10 21:19:01 +08:00
  • 7df3ef9c31 fix(web): bump right-meta column cap a touch (max-w 34% / 9.5rem) yiekheng 2026-05-10 21:17:20 +08:00
  • 0fd581b365 fix(web): nudge right-meta column cap up (max-w 28% / 8rem) yiekheng 2026-05-10 21:17:00 +08:00
  • f4da1dd510 fix(web): halve right-meta column cap (max-w 20% / 5.5rem) yiekheng 2026-05-10 21:16:40 +08:00
  • 50b7e61037 fix(web): tighter cap on right-meta column (max-w 40% / 11rem) yiekheng 2026-05-10 21:15:18 +08:00
  • 89c7b1a84d fix(web): cap right-meta column on reminders list so name doesn't get starved yiekheng 2026-05-10 21:13:49 +08:00
  • 32f87e1a92 fix(web): truncate long recurrence description with ellipsis on detail card yiekheng 2026-05-10 21:12:02 +08:00
  • e32f633e02 fix(web): wrap long recurrence description on reminder detail card yiekheng 2026-05-10 21:11:09 +08:00
  • 429ae0827f fix(web): only ONE nav item highlighted at a time + drop redundant Close yiekheng 2026-05-10 21:08:40 +08:00
  • 496f882d9c feat: split user row into 2 lines + reserve operators.email column yiekheng 2026-05-10 21:04:15 +08:00
  • 3af0dc7ca7 feat(web): loosen user-row layout — more breathing room yiekheng 2026-05-10 21:00:08 +08:00
  • adaf087a5f feat(web): drop '· last admin' label from user row yiekheng 2026-05-10 20:44:41 +08:00
  • f69652d43b feat(web): AES-GCM cookies + per-username/global rate limit + origin check yiekheng 2026-05-10 20:41:49 +08:00
  • 6942745085 test(bot): cover the reschedule corner case in scheduleReminderFire yiekheng 2026-05-10 20:33:29 +08:00
  • 2e6fbfa7a5 fix(bot): reschedule was silently dropped under stately policy yiekheng 2026-05-10 20:27:52 +08:00
  • 991b7ae0ab fix(web): swallow click after a swipe so dragging a row does not navigate yiekheng 2026-05-10 19:54:31 +08:00
  • b293bbf142 fix(web): suppress native drag on SwipeableRow so anchors do not eat the swipe yiekheng 2026-05-10 19:52:11 +08:00
  • a789b61e1f fix(bot): triple-fire reminder bug — force pg-boss policy + close TOCTOU dedupe yiekheng 2026-05-10 19:43:41 +08:00
  • e800882d15 fix: 'Pause sending by' is off by default everywhere yiekheng 2026-05-10 19:30:09 +08:00
  • 5c48e0e85f fix(web): wire Refresh Groups button to syncGroupsAction with live SSE refresh yiekheng 2026-05-10 19:13:24 +08:00
  • 40d788302c test(bot): cover post-pair-restart re-warming sequence yiekheng 2026-05-10 19:10:46 +08:00
  • d0db248460 fix(bot): re-warm pairing flag on post-pair-restart close yiekheng 2026-05-10 19:09:08 +08:00
  • 7af7aa35d0 test(bot): cover the back→re-pair close-leak regression yiekheng 2026-05-10 19:06:39 +08:00
  • 68668ef2cd feat(web): footer reads 'Signed in as <username>' with italic name yiekheng 2026-05-10 19:04:39 +08:00
  • fe8e14b7a0 fix(bot): swallow leaked close from previous pairing attempt yiekheng 2026-05-10 19:02:10 +08:00
  • dbdb156a09 fix(web): drop redundant Close button from account dialogs yiekheng 2026-05-10 18:57:06 +08:00
  • 6759ca8131 fix(web): client-component delete/unpair cards on accounts/[id] yiekheng 2026-05-10 18:55:29 +08:00
  • 5d583d9194 fix(web): forgot-password dialog, settings tagline, account dialog triggers yiekheng 2026-05-10 18:50:28 +08:00
  • c493101b60 feat(web): password policy, sign-out, dashboard isolation, activity tweaks yiekheng 2026-05-10 18:46:29 +08:00
  • b92ead3a97 feat(web): add-user form + delete confirmation in user management yiekheng 2026-05-10 18:36:03 +08:00
  • 4ddf5c094e feat(web): admin nav entry + role-aware AppShell yiekheng 2026-05-10 18:30:58 +08:00
  • 797326e062 feat(web): collapse Skipped→Archived, Partial→Paused+Failed; full-width filter rows yiekheng 2026-05-10 18:26:34 +08:00
  • ebbbdbdfb8 fix(web): make session cookie secure flag conditional on production yiekheng 2026-05-10 18:19:59 +08:00
  • 7ab51335a4 fix(compose): pass AUTH_SECRET + OPERATOR_TOKEN_VERSION to web container yiekheng 2026-05-10 18:17:22 +08:00
  • 050292a282 feat(web): bare login header — only centred brand mark yiekheng 2026-05-10 18:14:03 +08:00
  • 1b7f553e24 fix(db): bump 0010/0011 journal timestamps so drizzle applies them yiekheng 2026-05-10 18:13:55 +08:00
  • b29d137c84 feat: production hardening — robots, allowedOrigins, container non-root, rate limits, CLI bootstrap yiekheng 2026-05-10 18:05:34 +08:00
  • 67091c294a feat(web): user-management surface (admin only) yiekheng 2026-05-10 18:01:09 +08:00
  • b77a9d106d feat(web): middleware gates non-allowlisted paths on session cookie yiekheng 2026-05-10 17:57:07 +08:00
  • 5b4787d10e fix(web): typed-routes + redirect-mock signatures in auth.ts yiekheng 2026-05-10 17:54:59 +08:00
  • 4f1056cdcd feat(web): /login page with username + password form yiekheng 2026-05-10 17:52:35 +08:00
  • cedd623466 feat(web): loginAction + logoutAction (with TDD) yiekheng 2026-05-10 17:50:41 +08:00
  • d236196476 feat(web): getCurrentUser / requireUser / requireAdmin helpers yiekheng 2026-05-10 17:46:16 +08:00
  • e1ba1da2de feat(web): safeRedirect helper for the login \?next= param yiekheng 2026-05-10 17:44:10 +08:00
  • 27b7a3df1f feat(web): edge-safe HMAC-signed session cookie yiekheng 2026-05-10 17:43:01 +08:00
  • 838e129f37 chore: add bcryptjs to web + db packages yiekheng 2026-05-10 17:41:06 +08:00
  • 46c0315559 refactor(db): drop operators.telegram_user_id (not used since v1.0) yiekheng 2026-05-10 17:39:46 +08:00
  • a37b36196d feat(db): add username + password_hash to operators yiekheng 2026-05-10 17:35:01 +08:00
  • 477e09f645 docs: implementation plan — auth + production hardening yiekheng 2026-05-10 17:19:20 +08:00
  • feffe419db docs: design spec — auth + production hardening for v1.1.x → v1.2.0 yiekheng 2026-05-10 17:09:46 +08:00
  • 4cb4015666 fix(bot): dedupe duplicate reminder.fire jobs (msg sent twice) v1.1.0 yiekheng 2026-05-10 16:41:11 +08:00
  • be3f28a1e6 refactor(web,bot,db): rename reminder status 'ended' → 'inactive' yiekheng 2026-05-10 16:32:53 +08:00
  • 2e1defaef6 feat(web): "Pause sending by" deadline is opt-in via a checkbox yiekheng 2026-05-10 16:25:44 +08:00
  • 309020fa5d feat(bot): sweep stale 'pending' runs on startup yiekheng 2026-05-10 16:05:18 +08:00
  • bb8d28a594 feat(web): paused-run banner + Activity Paused filter / Resume button yiekheng 2026-05-10 15:58:06 +08:00
  • 376bbe595b feat(web,bot): resumeReminderRunAction + cancelReminderRunAction yiekheng 2026-05-10 15:54:21 +08:00
  • 57786f9d09 feat(bot,web): window-end gate + paused/resume run lifecycle yiekheng 2026-05-10 15:48:52 +08:00
  • 670eaf493c feat(web): swipeable account rows, editable label, disabled-account guard v1.0.0 yiekheng 2026-05-10 15:42:10 +08:00
  • c166a09fdb fix(web): client bundle no longer pulls in node-only rrule code yiekheng 2026-05-10 15:33:47 +08:00
  • 1d0d06d648 feat(web): floating CTA on mobile so Add/New buttons aren't a wasted row yiekheng 2026-05-10 15:27:32 +08:00
  • 9b13223966 fix(web): tighten the page-header row — smaller buttons, less padding yiekheng 2026-05-10 15:25:08 +08:00
  • 7697ea5fcb feat(web): PageShell narrow variant for dense single-column tabs yiekheng 2026-05-10 15:23:06 +08:00
  • 3c3a3f57d3 refactor(web): extract EmptyState and reuse on every empty surface yiekheng 2026-05-10 15:21:51 +08:00
  • a5cb8cea46 refactor(web): extract PageShell and apply to every tab yiekheng 2026-05-10 15:19:17 +08:00
  • e38b9ac7b6 feat(web): RunEtaPill at the wizard review step yiekheng 2026-05-10 15:11:53 +08:00
  • e6521bd151 feat(web): run-eta helper + bigger pill-shaped add buttons yiekheng 2026-05-10 15:10:09 +08:00
  • bf49b80431 feat(web): pause-by-hour deadline + AM/PM dropdowns + dashboard tweaks yiekheng 2026-05-10 15:07:25 +08:00
  • f96eea8e93 fix(web): dashboard reminders card uses X/Y; hide /accounts duplicate H1 yiekheng 2026-05-10 14:53:47 +08:00
  • f50a1fc0a7 feat(web): create/update actions accept delivery window hours yiekheng 2026-05-10 14:52:05 +08:00
  • 7039d57a41 feat(db,shared): delivery window columns + windowEndAt helper yiekheng 2026-05-10 14:48:36 +08:00
  • c9a7e6f089 feat(bot): cross-account parallel + same-account serial fan-out yiekheng 2026-05-10 14:44:23 +08:00
  • 7da872eb5f feat(bot): MediaUploadCache for once-per-run media prepare yiekheng 2026-05-10 14:38:10 +08:00
  • bb58f5acf2 feat(bot): per-account token-bucket rate limiter yiekheng 2026-05-10 14:37:12 +08:00
  • 5913706ab9 feat(bot): PerKeyMutex for accountId-keyed serialisation yiekheng 2026-05-10 14:36:22 +08:00
  • c5339abe1a feat(bot): fan-out tuning env vars yiekheng 2026-05-10 14:35:26 +08:00
  • 082a70db06 docs: consolidate windowed-fanout spec/plan with ETA + paused/resume yiekheng 2026-05-10 14:33:51 +08:00
  • c4d4f1dda7 feat(web): extract reminder name to its own edit section yiekheng 2026-05-10 14:23:23 +08:00
  • d5b8c0beeb feat(reminders): name is required (was optional with auto-derive) yiekheng 2026-05-10 14:15:16 +08:00
  • 50187a86e1 docs: design spec — windowed, pacing-safe reminder fan-out yiekheng 2026-05-10 14:01:24 +08:00
  • 5d91b904f2 refactor(ui): hide page-title H1 on mobile (header already shows it) yiekheng 2026-05-10 13:45:01 +08:00
  • 68d3de5ee2 feat(reminders): user-supplied name; auto-derived as fallback yiekheng 2026-05-10 13:43:22 +08:00
  • 8f2ee5df9e feat(web): browser notifications for reminder + send-test events yiekheng 2026-05-10 13:30:40 +08:00
  • 29535d6bbc docs: refresh README for web-first state of the world (P3/T24) yiekheng 2026-05-10 13:23:04 +08:00