# 🏢 War Room Board _Generated from board.json — do not edit by hand. 34 tickets._ ## 🚦 Launch readiness: NOT LAUNCH-READY — LIVE SECURITY INCIDENT OPEN (34/100) > The core is architecturally sound (RBAC gated, scrypt-hashed passwords, derived stock, working Telegram bot, SPA built and served) but it is NOT launch-ready and is in fact carrying an active breach: default admin passwords (admin@2026 / chunhung@2026) still authenticate on the public URL, two secrets leaked in chat remain unrotated, there is no git, no backup, and no login rate-limit. Separately, the flagship 'measurement moat' currently runs on ~3 products of DEMO data (218 of 219 assignments are DEMO rows, 0 bot_tasks) and the app is unusable on mobile (sidebar hidden with no replacement nav) despite staff being phone-first. Fixing the P0 security + ops hygiene is days, not weeks; those gates must close before any external demo link or staff handoff. ## 🚨 P0 Blockers - LIVE BREACH: default admin passwords admin@2026 and chunhung@2026 still return an admin token on https://chunhung.agents.vn, with no login rate-limit — full account takeover is one guess away, right now. - LEAKED SECRETS UNROTATED: Telegram bot token and DeepSeek key were pasted in chat and are still live in server/.env (664 perms) — anyone with the bot token can hijack the work group's bot. - NO VERSION CONTROL: repo is not git-inited (verified 'fatal: not a git repository') — zero history, rollback, or CI; one bad edit to the live-served folder is unrecoverable. - NO BACKUP: the only datastore (server/data.db, 819KB uncheckpointed WAL vs 100KB main) has no backup job; disk loss or corruption = total, unrecoverable data loss. - NO PUBLIC-SURFACE HARDENING: no login rate-limit/lockout, no security headers/helmet, CORS origin:true reflects any origin — brute force and clickjacking are wide open on an internet-exposed app. - MOBILE UNUSABLE: at ≤720px the sidebar is display:none with no drawer/bottom-nav replacement, so phone-first staff get stuck on one view — role-based usability is moot until this is fixed. - REAL DATA NEVER LOADED: live DB has 3 products / 6 clips / 218 DEMO assignments / 0 bot_tasks; seed_real.py (196 SP / 344 posts) was never run against prod, so the measurement moat demos on fabricated trajectories. - NO NON-ADMIN DOGFOODING: both live users are role_id=1 admin; the stated #1 priority (non-technical staff each see only their role's work) has never existed or been tested with a real poster/ugc/qc account. ## 🧭 Critical path to launch 1. INCIDENT CONTAINMENT (hours): rotate default admin passwords to strong values via the running app, DELETE all sessions, and rotate the leaked Telegram + DeepSeek secrets at their providers; update server/.env (chmod 600) and pm2 restart kho-video --update-env. 2. VERSION CONTROL (hours): harden .gitignore, add server/.env.example, git init on main, dry-run add and eyeball for secrets, first commit, push PRIVATE remote, post-push secret scan of git log. 3. BACKUP + RESTORE DRILL (hours): ship server/scripts/backup.sh using sqlite3 .backup (WAL-safe), integrity_check + table assertions, tar .env alongside, keep 14, wire daily + weekly verify-restore cron; run one verified restore. 4. PUBLIC HARDENING (1-2 days): add @fastify/rate-limit (5/min on /api/login keyed on cf-connecting-ip) + per-username lockout, @fastify/helmet headers, tighten CORS to an allowlist; add must_change_pw force-reset flow + self-service change-password. 5. LOAD REAL DATA + SEPARATE DEMO (1 day): run seed_real.py against prod (196 SP / 344 posts), stand up an isolated read-only demo.db instance for external demos, and label DEMO data in the UI. 6. MOBILE + ROLE LANDING (2-4 days): ship drawer + bottom-nav for ≤720px, replace all 15 alert/prompt/confirm with shared Toast/Modal, add role-based landing + 'Việc của tôi', and add the identity layer (assignee_name/tg_username on users). 7. STAFF DOGFOOD + MOBILE SMOKE (1 day): create real least-privilege poster/ugc/qc accounts, walk the e2e stock+task flow on a real phone at 375px, fix what breaks. 8. OPS SURVIVAL (1 day): fix pm2 boot persistence (override.conf), consolidate to one named tunnel, add health monitoring/alerting, write the on-call + restore + onboarding runbook. 9. GO/NO-GO: run the launch-ready checklist against the internal 3-4 person team before handing it over; defer any multi-tenant/SaaS build until internal use is proven. ## ⚡ Sprint 0 (do first) - [ ] Rotate default passwords + leaked secrets and wipe all sessions — close the live breach TODAY (SEC-001, SEC-002). - [ ] git init + private remote as source of truth so all further work is safe and reversible (OPS-003). - [ ] Automated daily SQLite backup with one verified restore, before touching prod data further (OPS-004). - [ ] Login rate-limit + lockout + security headers + CORS lockdown + force-change-password flow (SEC-005, SEC-006). - [ ] Load real Sheet data into prod and stand up a labeled, isolated read-only demo instance (DATA-007, DATA-008). - [ ] Mobile navigation (drawer + bottom-nav) and replace alert/prompt/confirm with shared Toast/Modal so the phone-first staff flow works at all (UX-010, UX-011). - [ ] Role-based landing + 'Việc của tôi' + the user↔assignee identity layer so non-technical staff land on their work (UX-012, DATA-018). - [ ] Create real least-privilege staff accounts and dogfood the e2e flow on a real phone (SEC-016, QA-025). ## 📊 Summary | Priority | Count | | Status | Count | |---|---|---|---|---| | P0 | 13 | | backlog | 0 | | P1 | 16 | | todo | 0 | | P2 | 5 | | in_progress | 0 | | P3 | 0 | | review | 3 | | | | | done | 31 | ## CEO — Strategy & BizDev (4) | ID | P | Effort | Status | Title | Deps | |---|---|---|---|---|---| | SEC-001 | P0 | S | done | Rotate default admin passwords + wipe all sessions (LIVE INCIDENT) | SEC-006 | | SEC-016 | P0 | M | done | Create real least-privilege staff accounts + dogfood role first-run | SEC-006, DATA-018 | | QA-025 | P1 | M | done | Mobile e2e smoke of the staff flow on a real phone | UX-010, UX-012, DATA-007, SEC-016 | | CEO-028 | P1 | S | done | Define launch-ready checklist + go/no-go + multi-tenant gate | - | ## CTO — Engineering (8) | ID | P | Effort | Status | Title | Deps | |---|---|---|---|---|---| | SEC-002 | P0 | S | review | Rotate leaked Telegram bot token + DeepSeek key | - | | OPS-003 | P0 | S | done | git init + push private remote as source of truth | SEC-002 | | SEC-005 | P0 | M | done | Login rate-limit + brute-force lockout + security headers + CORS lockdown | - | | DATA-007 | P0 | M | review | Load real Sheet data into prod (196 SP / 344 posts) and retire demo from live | OPS-004 | | BE-019 | P1 | M | done | Harden session lifecycle: TTL, sweep, revoke-all, rotate on password change | SEC-006 | | BE-020 | P1 | M | done | Add DB indexes, foreign keys, and integrity guards | OPS-004 | | QA-024 | P1 | M | done | Put existing test harness in CI + e2e stock+task smoke | OPS-003 | | BE-026 | P2 | S | done | Make Telegram bot single-consumer safe and crash-resilient | - | ## COO — Ops, Legal & Finance (6) | ID | P | Effort | Status | Title | Deps | |---|---|---|---|---|---| | OPS-004 | P0 | M | done | Automated daily SQLite backup + WAL checkpoint + verified restore | - | | SEC-006 | P0 | M | done | Force-change-password flow + self-service change + password strength | - | | OPS-022 | P0 | S | done | Fix pm2 boot persistence so product survives reboot | - | | OPS-021 | P1 | S | done | Consolidate Cloudflare tunnels to one named tunnel | - | | OPS-023 | P1 | M | done | Health monitoring + alert on outage / crash-loop | - | | OPS-027 | P2 | M | done | Ops runbook + new-staff onboarding SOP (VN) | OPS-004, OPS-022 | ## CMO — Growth, Content & SEO (6) | ID | P | Effort | Status | Title | Deps | |---|---|---|---|---|---| | DATA-008 | P0 | M | done | Labeled, isolated read-only DEMO instance for external demos | SEC-001, SEC-005, OPS-021 | | CMO-029 | P1 | M | done | Public Vietnamese landing page with the measurement moat as hero | SEC-001, SEC-002, SEC-005, DATA-008 | | CMO-030 | P1 | S | done | ICP + positioning one-pager (VN) with objection handling | - | | CMO-031 | P1 | S | done | Honest anonymized case study from the one real deployment | DATA-007 | | CMO-032 | P1 | S | done | Entry pricing + near-term commercial model (private-instance vs multi-tenant) | CMO-030 | | CMO-033 | P2 | S | done | Community-launch plan for small VN affiliate/UGC teams (no paid SEO) | CMO-030 | ## CPO — Product & Design (10) | ID | P | Effort | Status | Title | Deps | |---|---|---|---|---|---| | UX-010 | P0 | M | done | Mobile navigation: drawer + bottom-nav so phones can navigate | - | | UX-011 | P0 | M | done | Replace 15 alert()/prompt()/confirm() with shared Toast + Modal/Confirm | - | | UX-012 | P0 | M | done | Role-based landing view + 'Việc của tôi hôm nay' | DATA-018 | | UX-013 | P1 | M | done | Empty states + skeleton loading + surfaced errors for all lists | - | | UX-014 | P1 | M | done | Mobile-safe touch targets + scrollable/collapsing tables | UX-010 | | UX-015 | P1 | M | done | Standardize FE role gating + split task/metrics permissions | UX-017 | | DATA-018 | P1 | M | done | Identity layer: link web users to assignee names + Telegram handles | - | | CPO-033 | P1 | M | done | Design-system refinement (European-modern) | - | | UX-017 | P2 | L | review | Split App.jsx monolith into components + shared UI tokens | OPS-003 | | UX-018 | P2 | S | done | Human-readable Vietnamese error copy | UX-011 |