Live integration status
Verified 10 Jun 2026 against the production app's own connection checks and sync endpoints. HubSpot access is strictly read-only.
Posture at a glance
Verified JWTs, enforced auth, sound RLS. Weak spot: public endpoints trust the public key.
Clean server boundary & data flow; heavy vendor coupling and an unsplit 822 KB bundle.
Governance layer absent; Italian worker-monitoring & AI face-photo exposures need counsel.
Not independently deployable: no CI, no health check, beta build server, Lovable-locked.
Prioritized findings
| Sev | Area | Finding | Fixed in |
|---|---|---|---|
| Critical | Security | Public sync endpoints authenticate with the public anon key — anyone could trigger metered HubSpot/Slack work. No rate limiting. | Phase 0→2 |
| Critical | Secrets | Live Supabase anon key committed to git; .env not ignored — a footgun for the first real secret added. | Phase 0 |
| High | Ops | Not independently deployable — build, OAuth, error reporting & data plane all behind proprietary vendor packages. | Phase 1–2 |
| High | Ops | Beta build server in the production path; two lockfiles resolving the same packages from different registries. | Phase 1 |
| High | Legal | Employee performance monitoring (leaderboards, streaks) with no Italian Art. 4 works-council agreement or worker notice. | Phase 4 |
| High | Legal | Employee face photos sent to US AI image models with no consent, DPIA or processing agreement. | Phase 2/4 |
| High | Legal | No data-processing agreements or record-of-processing for any third-party processor; no software licence. | Phase 4 |
| Medium | Ops | Scheduled jobs not reproducible & hard-coded to the vendor host; no CI, no health check, no external error/log sink. | Phase 0–2 |
| Medium | Architecture | Integration logic duplicated across five files; a 530-line “god hook”; several 600–1,200-line components. | Phase 2–3 |
| Medium | Hardening | No security headers; open self-signup; uncontrolled free-text fields; no data-retention policy. | Phase 0,3–4 |
| Low | Quality | Thin test coverage (4 files / 23k LOC, none on server logic); lint broken on Windows clones. | Phase 1,3 |
Full evidence with file/line references lives in docs/AUDIT_AND_ROADMAP.md in the repository. No personal data is reproduced here.
Productionization roadmap
Phase 0 — Quick winsShipped
Cron-secret scaffolding, secrets hygiene, security headers, health route, rebrand, signup restriction.
Phase 1 — De-couple the buildNext
Explicit Vite/Nitro config (Cloudflare preset), stable build server, single lockfile, secrets on Cloudflare, verified preview deploy.
Phase 2 — Replace vendor runtime
Direct HubSpot & Slack APIs, native Supabase Google OAuth, Sentry, rewired scheduled jobs — then retire the public-key cron trust.
Phase 3 — Hardening & quality
Rate limiting, code-splitting, de-duplication, single-tenant config extracted, real test coverage, CI/CD & monitoring.
Phase 4 — Legal & governance
Records of processing, processor agreements, DPIA, Italian worker-monitoring notice, retention & erasure, licence. (With counsel.)
Phase 5 — Decommission the builder
Remove all vendor packages, make this repo canonical, move the domain, rotate keys.
Shipped in this engagement (Phase 0)
- ✓Dedicated
CRON_SECRETwith constant-time comparison; public anon key retired at cutover. - ✓FX refresh endpoint made
POST-only (no browser-triggerable side effects). - ✓Secured-cron migration authored — Vault-held secret, all jobs reproducible.
- ✓
.envuntracked & ignored; keys-only.env.exampletemplate added. - ✓Security headers (CSP, HSTS, anti-clickjacking) on every response.
- ✓Unauthenticated
/api/healthliveness route for monitoring. - ✓Rebranded from the builder's defaults to fonio; self-signup limited to fonio work emails.
Verified by a clean local production build, a passing TypeScript typecheck, and lint-clean changed files. Changes are staged in the repo and reach production at the Phase 1 cutover — the live app is never broken mid-flight.