Skip to content

Enterprise Readiness Assessment

1. Executive summary

Verdict: The newest UI in the Someli platform, and the strongest signal of forward direction (Vite + React + TS + shadcn/ui + Tailwind, vs the Nuxt 2 / Vue 2 legacy of the customer and designer FEs). Codebase is small, modern, dependency-clean — a fundamentally healthy starting position. Weaknesses are uniformly maturity-level (no tests, no CI, no observability, no documented deploy story) rather than design-level. The biggest concrete risks are token-in-localStorage with no real revocation (inherited from the backend's auth design), and a third-party Lovable.dev script in production HTML without integrity verification.

Top 3 strengths: 1. Modern dependency tree, all current versions, no squatters — a notable contrast to the backends 2. shadcn/ui + Radix UI gives accessibility, keyboard handling, focus traps for free in most primitives 3. TypeScript — first FE in the platform with type-safety; sets a pattern future work can adopt

Top 5 risks: 1. Token in localStorage + no token expiry + no real revocation = long-lived credential exposure on any XSS 2. Third-party script (cdn.gpteng.co/gptengineer.js) in production HTML without SRI 3. No tests, no CI gating type errors → regressions ship freely 4. Role IDs configured via env vars → drift risk with backend 5. No observability, no error tracker → production bugs go unseen until users complain

Top 5 recommendations: 1. This week: remove/secure the Lovable.dev script; add noindex meta + robots.txt; strip console.log from production builds; fix hardcoded Apptype to use ENV.APP_TYPE 2. Phase 0: add CI (lint + tsc + build); add Sentry + web-vitals; add 401-handler in api.ts; add multi-tab storage listener 3. Phase 0: commit a Dockerfile or deploy workflow (currently absent) 4. Phase 1: add eslint-plugin-jsx-a11y; "skip to content" link; focus-on-route-change; document WCAG target 5. Phase 1: migrate token to httpOnly cookie (coordinated BE change in Someli-admin-api)

2. Methodology & scope

Audited via find, cat, grep, wc against the cloned someli-gh/admin_console_R/ directory. No build run (so projected bundle sizes are estimates from dependencies). No tests run (none exist).

3. Maturity assessment (CMMI 1–5)

Pillar Current 12-mo target Why
Architecture & Modularity 3 4 Clean Vite + React + TS layout; small component tree; healthy code style
API Contract & Versioning 1 2 No typed envelopes, no OpenAPI bindings; named methods are typed loosely
Data Architecture 2 3 React Query mounted but lightly used; localStorage for auth (XSS risk)
Background Processing n/a n/a n/a — FE
Security & Compliance 1 3 Token in localStorage; 3rd-party script without SRI; no CSP from repo; console.log of PII to prod
Observability 1 3 console-only; no Sentry / RUM / analytics
Reliability & Resilience 2 3 No error boundaries; no 401 handler; no multi-tab sync
Scalability 3 3 Small app; static bundle; not a concern at current scale
Testing & Quality Gates 1 3 Zero tests; no tsc --noEmit in CI; ESLint exists but no CI gate
CI/CD & Deployment 1 3 No CI workflow / Dockerfile / hosting config in repo
Infrastructure as Code 1 2 nothing
Cost Visibility & FinOps 2 2 Static hosting; negligible cost
Documentation & Knowledge Management 2 3 No in-repo README beyond Vite default; this audit covers the gap
Team Practices & Governance 2 3 No PR template, no code-owners; branch model implied not documented

4. Findings

Cross-references: see security.md, api-consumption.md, authentication-client.md, observability.md.

ID Severity Description Phase
F-1 MEDIUM Token in localStorage; XSS = long-lived takeover 1 (BE+FE coord)
F-2 LOW api.ts hardcodes Apptype = btoa("admin-console") instead of reading ENV.APP_TYPE 0a
F-3 MEDIUM cdn.gpteng.co/gptengineer.js in production HTML without SRI 0a
F-4 MEDIUM No CSP set from repo (depends on hosting layer) 0
F-5 LOW No SRI on the one external script 0a
F-6 LOW (dev) HMR overlay disabled 0
F-7 LOW lovable-tagger dev-plugin loaded (intentionally dev-only) n/a
F-8 LOW Vite fs.deny minimal; verify n/a
F-9 LOW No DOMPurify (only matters if dangerouslySetInnerHTML is added) n/a
F-10 LOW user_email in localStorage 0
F-11 MEDIUM No 401 → logout in api.ts 0
F-12 LOW Two coexisting toast libs (sonner + shadcn) 0a
F-13 LOW Three lockfiles in repo (npm + yarn + bun) 0a
F-14 LOW console.log of PII in production builds 0a
F-15 LOW Role IDs configured via env vars (drift risk with BE) 1
F-16 n/a No <meta noindex> or robots.txt 0a

5. Strategic decisions

  1. This is the platform's future FE stack. Future internal UIs should follow Vite + React + TS + shadcn/ui rather than Nuxt 2 + Vue 2. Don't extend the Nuxt repos for new product surface.

  2. shadcn/ui is the right choice for an internal tool — fast iteration, generated code is editable, Radix UI accessibility is solid. Don't replace.

  3. Authentication needs work, but the changes are coordinated with Someli-admin-api. Pursue the BE-side fixes (token expiry, DB-backed revocation, httpOnly cookie) first; the FE changes follow.

  4. CI/CD is the most-leveraged gap. One workflow file (~50 lines) closes the type-check / lint / build / deploy loop. Until then, every PR is hand-verified.

6. Roadmap

Phase 0a — This week

  • Remove or secure cdn.gpteng.co script (F-3)
  • Fix hardcoded Apptype (F-2)
  • Strip console.log in production via Vite esbuild.drop (F-14)
  • Add <meta name="robots" content="noindex, nofollow"> and public/robots.txt (F-16)
  • Pick one package manager; delete the other two lockfiles (F-13)
  • Decide sonner vs shadcn toast; remove the other (F-12)
  • Add SRI to any remaining external scripts (F-5)

Phase 0 — Stabilise (0-3 months)

  • GitHub Actions CI: npm cinpm run linttsc --noEmitnpm run build (F-CI gap)
  • Add 401 → logout in api.ts (F-11)
  • Add multi-tab storage listener for logout
  • Add Sentry + web-vitals
  • Add error boundary
  • Tighten CSP at hosting layer (F-4)
  • Commit vite.config.ts source-map config + Sentry upload step
  • Add Dockerfile / nginx.conf or formal hosting config
  • Document deploy runbook

Phase 1 — Foundation (3-9 months)

  • Add eslint-plugin-jsx-a11y; do a manual a11y pass
  • "Skip to content" link + focus-on-route-change
  • Add Vitest + msw + first 20 unit tests (auth, api client, key pages)
  • Add Playwright + 5 E2E happy-path specs
  • Migrate token to httpOnly cookie (coord with Someli-admin-api)
  • Pin role IDs as const enum (vs env vars) (F-15)
  • Standardise React Query adoption (vs raw fetch + useState)

Phase 2 — Modular refactor (9-18 months)

  • Route-based code splitting (if route count grows)
  • Storybook (if component count grows past ~75)
  • Bundle-size CI check
  • Set WCAG target + audit against it

Phase 3 — Selective extraction (18+ months)

  • Not currently relevant for an internal admin tool

7. Risk register

ID Risk Likelihood Impact Phase
R-1 XSS on admin.someli.ai → token theft → long-lived account compromise of admin staff Low High 0 / 1
R-2 Lovable.dev CDN compromise → arbitrary JS in admin staff browsers Low High 0a
R-3 Regression ships because no CI / no tests High Low/Medium 0
R-4 Admin staff member is offboarded but their stolen token remains valid because revocation is in-memory Medium Medium 1 (BE)
R-5 Production search engine indexing of admin URLs (gives recon to attackers) Low Low 0a
R-6 Backend role ID change without FE env var update → role-gating bug Low Medium 1
R-7 Three lockfile drift → different installs across team / CI / prod Medium Low 0a

8. Standards compliance

  • WCAG 2.1 AA: shadcn/Radix gets us most of the way; needs jsx-a11y lint + skip link + focus management
  • OWASP A02 / A05 / A06 / A07: see security.md
  • Core Web Vitals: not measured; projected to be fine at current bundle size

9. Open questions

See verify-markers.md.