Web Client — Enterprise Readiness Assessment¶
Status: Audit v0.1 (2026-05-09). Source documents: all docs in
./plus existing project documentation in../.
1. Executive Summary¶
Verdict¶
The Someli web client is a feature-rich, functional SPA whose operational maturity has not kept pace with its product surface. The product side is broad: ~150 backend endpoints exercised across content planning, AI generation, social-platform OAuth (5 providers), Stripe + Paddle billing, the Polotno-based design editor, branded onboarding flows, and 14+ dashboard surfaces (full feature inventory in ../19-feature-inventory.md). The architectural patterns are coherent and well-documented internally — 20 developer docs codify auth, routing, state, build, conventions. But the enforcement mechanisms that make a SaaS auditable to enterprise standards are largely absent: no automated tests, no error tracking, no CSP, no dependency-update pipeline, no type safety, no source-map upload, no documented branch protection, no preview deploys. The framework stack (Vue 2 / Nuxt 2 / Webpack 4) is end-of-life, capping the upper bound on every other improvement.
There is also one critical security finding (AWS access keys committed to git history since 2022-08-01) that requires remediation before any external due-diligence review can be passed cleanly.
For enterprise procurement and SOC 2 readiness, the gap is moderate-to-large — closeable in 6–12 months of focused investment, but not closeable on a one-quarter timeline.
For an acquisition or partnership context, the buyer should expect a "Phase 2" reasonable-cost migration to Vue 3 / Nuxt 3 as part of the post-acquisition roadmap, plus a Phase 0 security hygiene pass that is mandatory before deployment to any new enterprise customer.
Top 3 strengths¶
- Coherent architectural conventions despite the scale. Routing, state management, axios interceptor, post-status state machine, plan-filtering helper — these are documented patterns the team consistently follows. Adding new features is straightforward; the path is clear.
- Active engineering and recent shipping velocity. The git log shows weekly merges and fixes; the platform is live, functional, and serving customers. This is not a stalled codebase.
- Comprehensive backend integration. ~150 endpoints exercised, including AI generation, social-platform OAuth (5 providers), Stripe + Paddle billing, Polotno-based design editing. Few B2B SaaS frontends touch as many integrations at once.
Top 5 risks¶
| ID | Risk | Severity |
|---|---|---|
| WC-SEC-1 | AWS access keys committed to git history since 2022-08-01 | Critical |
| WC-SEC-5 | Vue 2 / Nuxt 2 / Webpack 4 — all EOL; no security patches | High |
| WC-AUTH-2 | Session token in browser-readable cookie; XSS = account takeover | High |
| WC-TEST-1 | Zero project-owned automated tests; regression risk unbounded | High |
| WC-OBS-1 | No client-side error tracking; bugs visible only via customer reports | High |
Top 5 recommendations (Phase 0a — this week)¶
- Rotate the leaked AWS access key, audit CloudTrail, rewrite git history, remove
plugins/aws_sdk.js, installgitleaksin CI. - Add Subresource Integrity to all CDN
<script>tags (14 external third-party scripts). - Enable Dependabot security-only auto-PRs in GitHub.
- Decide canonical CI/CD (GitHub Actions vs. Jenkins) and decommission the other.
- Add baseline security headers in nginx (CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy).
2. Methodology & Scope¶
Frameworks used¶
- CMMI 1–5 maturity model (per
WEB_CLIENT_AUDIT_GUIDE.md§6) - OWASP Top 10 (2021) for security findings
- WCAG 2.1 AA as the accessibility target (currently aspirational, not achieved)
- Core Web Vitals as the performance baseline (currently unmeasured)
Source documents¶
This assessment synthesises:
- The 13 deep-dive docs in
./*.md(architecture, routing, api consumption, auth, ui, accessibility, performance, security, testing, build, observability, i18n, SEO, dependencies) - The existing project developer documentation in
../*.md(auth, routing, state, polotno, build, conventions, troubleshooting, etc.) - The audit guide
../WEB_CLIENT_AUDIT_GUIDE.md - Direct inspection of source code at the SHA current as of 2026-05-09
What was audited / what was not¶
Audited:
- Source tree (pages/, components/, store/, middleware/, plugins/, helpers/, constants/, polotno-editor/)
- Configuration (nuxt.config.js, package.json × 2, Dockerfile, Jenkinsfile, GitHub Actions workflows, nginx.conf, .env, .editorconfig, .prettierrc)
- Build artifacts (dist/_nuxt/*.js chunk inventory, gzipped sizing of top 5 chunks)
- Git history of specific files (plugins/aws_sdk.js)
Not audited (deferred to verification or later passes):
- Production deployment (no curl against UAT/prod for headers, manifest, Lighthouse)
- yarn audit / npm audit output (run in environment-specific manner)
- Visual / behavioural QA in a browser
- Polotno editor internal code beyond the integration boundary
- Backend API contract (separate audit; cross-referenced where applicable)
3. Maturity Assessment¶
The 14 CMMI pillars per the audit guide. Levels: 1 Initial / 2 Repeatable / 3 Defined / 4 Quantitatively Managed / 5 Optimizing.
| # | Pillar | Current | 12-mo target | 24-mo target | Notes |
|---|---|---|---|---|---|
| 1 | Architecture & Modularity | 1 | 3 | 4 | Multiple 2K–10K LOC files; near-duplicate _accid vs legacy routes; no design system. Significant refactor needed. |
| 2 | API Contract & Versioning | 1 | 3 | 4 | No OpenAPI types, no Zod, 963 ad-hoc axios calls; backend has 728 endpoints (per audit guide context). |
| 3 | Data Architecture | 2 | 3 | 4 | Vuex api.js cache layer is well-documented; non-strict mode, inconsistent TTLs, no automatic invalidation on mutation. |
| 4 | Background Processing | 1 | 2 | 3 | Service worker exists but with minimal runtime caching. No Web Workers. |
| 5 | Security & Compliance | 1 | 3 | 4 | AWS-key leak, no CSP/HSTS, no SRI, token in browser-readable cookies, EOL stack, no Dependabot. |
| 6 | Observability | 1 | 3 | 4 | No error tracking, no RUM, no source-map upload, no correlation IDs. Microsoft Clarity for replays only. |
| 7 | Reliability & Resilience | 1 | 2 | 3 | No errorCaptured / global Vue error handler observed; no AbortController; no retries; silent error swallowing in api.js. |
| 8 | Scalability | 2 | 3 | 4 | Bundle ~5 MB raw / 1.4 MB gzipped on editor routes; no virtualisation for long lists. |
| 9 | Testing & Quality Gates | 1 | 2 | 3 | Zero project-owned tests. Manual review only. |
| 10 | CI/CD & Deployment | 2 | 3 | 4 | Two parallel pipelines (GH Actions + Jenkins); no preview deploys; rollback undocumented. |
| 11 | Infrastructure as Code | 2 | 3 | 4 | Dockerfile + nginx.conf + workflows are in code. EFS-mounted node_modules is unconventional. |
| 12 | Cost Visibility & FinOps | 1 | 2 | 2 | Not assessed. |
| 13 | Documentation & Knowledge Management | 3 | 4 | 4 | Highest-rated pillar. The repo has comprehensive developer docs in ../*.md (20 docs, including this audit). Raise via verification automation. |
| 14 | Team Practices & Governance | 2 | 3 | 4 | PR template exists but is minimal; no documented review checklist; commit conventions loosely followed. |
Per-pillar narrative¶
Architecture & Modularity — 1 → 3¶
architecture-overview.md documents the EOL framework, files >4,000 lines (5 of them), and the _accid vs legacy route duplication. Reaching Level 3 ("Defined, anyone on the team can do it") requires:
- Decomposing the top 10 oversized components/pages.
- Removing the legacy route tree.
- Establishing a design-system primitives layer.
Not reachable on a 6-month timeline; reachable on 12 months with focused refactor effort.
API Contract & Versioning — 1 → 3¶
api-consumption.md documents 963 ad-hoc axios call sites and no schema validation. Level 3 requires per-feature service modules + Zod (or generated types).
Security & Compliance — 1 → 3¶
security.md lists 14 findings. Level 3 requires:
- Phase 0a: AWS-key rotation + history rewrite.
- Phase 0: security headers, dep-update pipeline, sanitisation, httpOnly cookies, source-map handling.
- Phase 1: token-refresh, OAuth secret bundle audit, CSP tightening.
Achievable in 9–12 months; level 4 requires SOC 2-grade evidence which depends on backend coordination.
Testing & Quality Gates — 1 → 2¶
testing.md is unambiguous: no tests. Reaching Level 2 (Repeatable) requires only 3 E2E smoke tests + a CI gate — achievable in a week. Level 3 (Defined) requires unit-test coverage thresholds on the helper / store layer — 3 months.
Documentation & Knowledge Management — 3 → 4¶
This is the strongest pillar. Concretely, the repo has:
- 20 developer docs at
doc/01-…throughdoc/20-…, covering: local setup, architecture, auth & sessions, routing, state management, Polotno integration, build & deploy, integrations, conventions, troubleshooting, glossary, permissions & roles, post-lifecycle state machine, API endpoint catalog, onboarding flow, layouts, helpers, modal patterns, feature inventory, contributing. - A dev-doc index at
doc/README.mdwith a structured reading order (core onboarding 01–10; domain reference 11–20). - Documentation expectations formalised in
../20-contributing.md§ "Documentation expectations" — a table mapping load-bearing files (middleware/redirect.js,store/api.js, etc.) to the docs that must be updated in the same PR. - This audit subtree (
doc/web-client/) mirrors the audit guide structure.
What raises the rating above the typical "we have a README" level:
- The "if you change X, update Y" mapping converts documentation from a habit into an explicit reviewable PR requirement.
- The dev docs cite source (file:line) heavily, making them mechanically verifiable.
- The audit subtree's verify-markers.md is a live tracker for open questions — institutionalising the "we don't know yet, that's a finding" discipline.
What keeps it at 3 rather than 4:
- No automation enforces documentation freshness. No link-check, no doc-test, no CI step that reads the "if you change X, update Y" table and warns when the heuristic is violated.
- No re-audit cadence yet. The audit guide §12 recommends every-6-months; this audit (v0.1, 2026-05-09) is the first run.
- Pre-existing repo state was sparse: the original README.md is 19 bytes ("# someli-platform"). Most current docs were authored within a short timespan and have not yet been stress-tested by drift over multiple quarters.
Path to Level 4: add a CI step that link-checks doc/**.md and a per-PR check that flags edits to load-bearing files without corresponding doc edits. Then re-audit on a 6-month cadence and track drift count over time.
Team Practices & Governance — 2 → 3¶
Evidence base from ../20-contributing.md and observed git history:
| Practice | Status | Source |
|---|---|---|
| Branch naming convention | None enforced — observed mix of BNIFLOW, 14days_free_trial, fix/opt-upload-temp, Change-the-text-Story_87_-90_92_93 |
../20-contributing.md § Branches |
| Commit conventions | Conventional Commits loosely followed (feat: / fix: / refactor:) |
../20-contributing.md § Commit messages |
| PR template | Present but minimal: 2-section template with one self-review checkbox | pull_request_template.md; ../20-contributing.md § Pull requests |
| Required reviewers | Unverified — likely ad-hoc | [VERIFY-TPG-1] check GitHub branch protection rules |
Branch protection on main / uat_app / dev_app |
Unverified — convention is "don't push directly" but no enforcement evidence | [VERIFY-TPG-2] check GitHub branch protection settings |
| Stale branches | Dozens of long-lived feature branches (git branch -a shows 30+ remote branches) |
../20-contributing.md § Sharp edges |
Auto-deploy from dev_app push |
Yes — see Risk WC-16 | ../20-contributing.md § Sharp edges; Jenkinsfile; .github/workflows/dev_app.yml |
| Self-review required | Documented in PR template; not enforced | pull_request_template.md |
| Code-review checklist | None observed | The [document link] placeholder in the PR template suggests one was intended |
| Postmortems | None observed in the repo | (Not strictly a repo artifact — may live elsewhere) [VERIFY-TPG-3] |
| SonarQube/SonarCloud | sonar-project.properties present; gate / configuration unknown |
../20-contributing.md § What is not reviewed |
This evidence supports a current rating of 2 (Repeatable / Managed) — the team has practices that work for the team that has them, but they are not codified or enforced. To reach Level 3 (Defined):
- Add GitHub branch protection rules requiring PR review on
main,uat_app,dev_app. - Convert the PR template's
[document link]into a real self-review checklist (security, accessibility, performance, doc updates). - Document the release process (who promotes
dev_app→uat_app→main, on what cadence, with what hand-off). - Establish a stale-branch cleanup cadence (e.g., monthly).
- Surface Sonar's gate (or remove it if dead).
- Postmortem template and convention.
Phase 0a effort: enable branch protection (2 hours). Phase 0 effort: write the rest (1 week).
4. Findings (consolidated)¶
Findings are referenced by their per-doc IDs (e.g., WC-SEC-1 from security.md).
Critical¶
| ID | Finding | Source doc | Mitigation phase |
|---|---|---|---|
| WC-SEC-1 | Hardcoded AWS access keys in plugins/aws_sdk.js (committed since 2022-08-01) |
security.md |
Phase 0a — this week |
High¶
| ID | Finding | Source doc | Mitigation phase |
|---|---|---|---|
| WC-ARCH-1 | Multiple files >4K lines (one >10K) | architecture-overview.md |
Phase 0/1 |
| WC-ARCH-2 | Near-duplicate code in pages/ legacy vs pages/_accid/ (~30K LOC) |
architecture-overview.md |
Phase 1 |
| WC-API-1 | No central API client wrapper; 963 ad-hoc call sites | api-consumption.md |
Phase 1 |
| WC-API-2 | No response interceptor; no 401-retry/refresh path | api-consumption.md |
Phase 0 |
| WC-API-5 | Auth header is token (non-standard) — three formats coexist |
api-consumption.md |
Phase 1 |
| WC-API-8 | Three Authorization formats coexist |
api-consumption.md |
Phase 1 |
| WC-API-11 | Uncaught promise rejections not piped to error tracking | api-consumption.md |
Phase 0 |
| WC-AUTH-2 | Token in browser-readable cookies; XSS = account takeover | authentication-client.md |
Phase 0 |
| WC-AUTH-3 | PII in browser-readable cookies | authentication-client.md |
Phase 0 |
| WC-AUTH-4 | Frontend-trusted roleType in accountdetails cookie |
authentication-client.md |
Phase 0/1 |
| WC-RT-3 | localStorage.accountId sync gap (head.js unwired) |
routing-and-state.md |
Phase 0 |
| WC-ST-4 | No automatic cache invalidation after mutations | routing-and-state.md |
Phase 1 |
| WC-DEP-3 | Server-side stripe SDK in production deps |
dependencies-inventory.md |
Phase 0a (verify) |
| WC-DEP-7 | No automated dependency-update pipeline | dependencies-inventory.md |
Phase 0 |
| WC-SEC-2 | No CSP header | security.md |
Phase 0 |
| WC-SEC-3 | No SRI on CDN scripts | security.md |
Phase 0a |
| WC-SEC-4 | 9 v-html sites without sanitisation |
security.md |
Phase 0 |
| WC-SEC-5 | Vue 2 / Nuxt 2 / Webpack 4 EOL | security.md |
Phase 2 |
| WC-PERF-1 | 1.4 MB gzipped editor chunk | performance.md |
Phase 1 |
| WC-PERF-5 | Bootstrap loaded 3 times | performance.md |
Phase 0 |
| WC-PERF-9 | No measured Core Web Vitals; no RUM | performance.md |
Phase 0 |
| WC-A11Y-1 | No automated a11y tooling | accessibility.md |
Phase 0 |
| WC-A11Y-2 | ~50% of images lack alt | accessibility.md |
Phase 0/1 |
| WC-A11Y-3 | No route-change focus management | accessibility.md |
Phase 1 |
| WC-TEST-1 | Zero project-owned automated tests | testing.md |
Phase 0 |
| WC-OBS-1 | No client-side error tracking | observability.md |
Phase 0 |
| WC-OBS-2 | No RUM | observability.md |
Phase 0 |
| WC-UI-5 | 7 components >1500 lines | ui-component-library.md |
Phase 1 |
| WC-BD-3 | No preview-per-PR deployments | build-and-deploy.md |
Phase 0/1 |
Medium¶
(See per-doc tables; condensed list)
WC-ARCH-3, WC-ARCH-4, WC-ARCH-5, WC-API-3/4/6/7/9/10, WC-AUTH-1/5/6/7/8, WC-RT-1/2, WC-ST-1/2/3, WC-DEP-1/2/4/5/6, WC-SEC-6/7/8/12/13, WC-PERF-2/3/4/6/8/10/11/12/13, WC-A11Y (multiple verification items), WC-UI-1/2/3/4/6/7/8, WC-OBS-3/5/6/8, WC-BD-1/2/4/5/6/7, WC-I18N-1, WC-SEO-1/2/3/4/5/6/7.
Low¶
WC-A11Y-4, WC-AUTH-6, WC-UI-3, WC-OBS-4, WC-SEO-5/6/7.
5. Strategic Decisions¶
Framework / runtime¶
- Vue 2 / Nuxt 2 are EOL. Migration to Vue 3 / Nuxt 3 is a Phase 2 (months 9–18) effort. Estimate: 3–6 engineer-months depending on team size, given 159K LOC and 161 components.
- Alternative paths: a "rewrite in Next.js + React" or "rewrite in SvelteKit" should be evaluated for cost/benefit. Migration tools exist for Vue 2 → Vue 3 (Vue's official migration build), so the in-place upgrade is the default recommendation.
- Polotno editor is independent and remains React-based regardless. The Nuxt host migration does not affect it.
Bundling / build tool¶
- Webpack 4 is bundled with Nuxt 2; upgrading to webpack 5 requires upgrading to Nuxt 3 (which uses Vite or webpack 5 in different modes).
- Decision: tie webpack upgrade to the Nuxt 3 migration — don't try to upgrade webpack independently.
State management¶
- Vuex 3 is fine for now. Pinia is the modern Vue alternative; it integrates more cleanly with Vue 3 and TypeScript. Migrate during the Vue 3 migration, not as a separate step.
Component library¶
- Decision pending: keep bootstrap-vue + Bootstrap 5 (which has ongoing inconsistency cost — see
ui-component-library.md§ WC-UI-8) or migrate to a modern Vue 3 UI library (Vuetify 3, PrimeVue, Naive UI, shadcn-vue) during the Vue 3 work. The latter is more disruptive but pays dividends.
6. Roadmap¶
Phase 0a — This week (1–7 days)¶
| Item | Priority | Effort | Source finding |
|---|---|---|---|
| Rotate leaked AWS access key + audit CloudTrail | Critical | 1 day | WC-SEC-1 |
Remove plugins/aws_sdk.js and rewrite git history (BFG) |
Critical | 1 day | WC-SEC-1 |
Install gitleaks (or equivalent) in CI |
High | 0.5 day | WC-SEC-1 |
| Verify no OAuth client secrets in production bundle | High | 0.5 day | WC-SEC-8 |
| Add Subresource Integrity to all CDN scripts | High | 0.5 day | WC-SEC-3 |
| Decide canonical CI/CD (GH Actions or Jenkins); decommission the other | High | 1 day | WC-BD-2 |
Delete package-lock.json (yarn is the convention); add to .gitignore |
Medium | <1 hour | WC-DEP-1 |
Remove npm and install from polotno-editor/package.json |
Low–Medium | <1 hour | WC-DEP-5 |
Phase 0 — Stabilize (months 0–3)¶
| Theme | Items | Effort |
|---|---|---|
| Security baseline | CSP + HSTS + X-Frame + Referrer-Policy in nginx; httpOnly auth cookie (backend coord); sanitise 9 v-html sites; Dependabot; yarn audit triage |
3–4 weeks |
| Observability foundation | Sentry + source-map upload from CI; web-vitals RUM; X-Request-ID correlation header; sweep console.* |
2–3 weeks |
| Testing foundation | Vitest + Playwright; 3 E2E smoke tests; CI gate; Lighthouse-CI informational | 2 weeks |
| Quality gates | ESLint + jsx-a11y/vue-a11y plugin + lint script in CI; vue/no-v-html rule |
1 week |
| CDN / cache | Add Cache-Control: immutable for /_nuxt/; consolidate Bootstrap to one version |
1 week |
| Routing fix | Wire head.js middleware (or migrate its logic into redirect.js); fix localStorage.accountId sync |
1 week |
| API client refinement | Add response interceptor (Sentry forwarding); try/catch the JSON.parse(usedetail) in interceptor; document the canonical auth header |
1 week |
Phase 0 total estimate: 3 months with 1 senior frontend engineer at 80% allocation.
Phase 1 — Foundation (months 3–9)¶
| Theme | Items | Effort |
|---|---|---|
| API service layer | Extract per-feature API service modules; deprecate direct $axios use; introduce Zod schema validation at the service layer |
6–8 weeks |
| Token refresh | Backend offers refresh endpoint; frontend response-interceptor handles 401 transparently | 1–2 weeks |
| Component decomposition | Top 10 oversized components/pages decomposed; aim for nothing >800 lines | 6–8 weeks |
| Library consolidation | One emoji picker, one date picker, one toast lib (vue-toastification), one cookie lib, one sortable lib | 3–4 weeks |
| Image optimisation | @nuxtjs/image adoption; sweep <img> → optimised |
2 weeks |
| Dynamic-import modals | Top 5 largest modals dynamic-imported | 1 week |
| Form library | VeeValidate 3 adoption | 4 weeks |
| moment → date-fns | Sweep moment usage | 2 weeks |
aws-sdk v2 → v3 |
S3 module migration; remove v2 | 1 week |
| Accessibility sweep | Alt-text sweep; route-change focus management; skip-to-content link; reduced-motion guards | 4 weeks |
| Feature flags | Adopt Flagsmith or LaunchDarkly | 1 week |
| Coverage targets | 30% line coverage on helpers/, store/, top 20 components |
ongoing |
| Preview-per-PR | GitHub Actions deploys per-PR to preview slot | 1 week |
Phase 1 total estimate: 6 months with 2 frontend engineers.
Phase 2 — Modular Refactor (months 9–18)¶
| Theme | Items | Effort |
|---|---|---|
| Vue 2 → Vue 3 migration | Vue migration build; per-component opt-in; adopt Composition API where it helps | 3–6 months |
| Nuxt 2 → Nuxt 3 | New routing, new module system, new server runtime | tied to Vue 3 |
| Vuex 3 → Pinia | Per-module migration | tied to Vue 3 |
| TypeScript adoption | Per-file opt-in; aim to convert helpers/, store/, services/ first | parallel with Vue 3 |
| Visual regression testing | Chromatic or Percy on design-system primitives | 2 weeks setup |
| Cross-browser CI | Playwright multi-browser | 2 weeks |
| Dedicated marketing site | Move /, /plan, /privacy, etc. to a separate static site (Webflow, Framer, or Astro) |
1 month |
| Component library curation | Choose Vuetify 3 / PrimeVue / Naive UI; deprecate bootstrap-vue | tied to Vue 3 |
Phase 2 total estimate: 9 months with 2–3 frontend engineers.
Phase 3 — Selective Extraction (months 18+)¶
Trigger-driven, not roadmapped. Candidates:
- Extract the editor as a separately-deployable micro-frontend.
- Internationalisation rollout (if product strategy demands non-English markets).
- SOC 2 Type I formal audit, with backend.
- WCAG 2.1 AA formal certification.
7. Risk Register¶
| ID | Description | Likelihood | Impact | Mitigation phase | Owner |
|---|---|---|---|---|---|
| RISK-WC-01 | AWS credentials in git history; rotation-and-history-rewrite required | High (already happened) | Critical (data loss / breach) | Phase 0a | Eng + Security + AWS Ops |
| RISK-WC-02 | XSS via unsafe v-html (Chatbot prompt injection from AI backend) |
Medium | High (account takeover) | Phase 0 | Frontend |
| RISK-WC-03 | Vue 2 / Nuxt 2 EOL — ongoing CVE exposure | High over time | Medium → High over time | Phase 2 | Frontend |
| RISK-WC-04 | Production bug discovery delayed by missing error tracking | High (continuous) | Medium (customer trust) | Phase 0 | Frontend + Support |
| RISK-WC-05 | Regression risk from any change due to no automated tests | High (continuous) | Medium per regression | Phase 0 | Frontend + QA |
| RISK-WC-06 | Frontend-trusted role gating bypassable by cookie edit (backend assumed but unverified to enforce) | Low–Medium | High (privilege escalation) | Phase 0/1 + Backend | Backend (verify) |
| RISK-WC-07 | CDN third-party script compromise (no SRI) | Low | Critical (RCE in browser) | Phase 0a | Frontend |
| RISK-WC-08 | Migration to Vue 3 / Nuxt 3 will be costly and may slow feature delivery | High (during Phase 2) | Medium (opportunity cost) | Phase 2 with team-wide sign-off | Eng leadership |
| RISK-WC-09 | Dual lockfiles (yarn + npm) cause dependency drift | Low | Low–Medium | Phase 0a | Frontend |
| RISK-WC-10 | Two parallel CI/CD pipelines may conflict on dev_app push |
Low | Medium | Phase 0a | DevOps |
| RISK-WC-11 | Cross-user Polotno autosave leakage on shared devices. Polotno autosave is keyed by pathname + hash, not by user/account. Two users on the same machine editing different designs at the same path overwrite each other's autosave; one user opening a URL another user previously edited may load that user's draft from localStorage. (Source: existing dev doc ../10-troubleshooting.md § "Local autosave is loading old content from someone else's design".) |
Medium | Medium (data-leak / draft-loss) | Phase 1 (rekey by user/account) | Frontend |
| RISK-WC-12 | Account-switch stale-data window. Switching active account does not invalidate the store/api.js cache. For up to 5 minutes after switch, dashboards, settings, and lists may show data from the previous account. (Source: existing dev doc ../10-troubleshooting.md § "Account switch leaves stale data on the page", ../05-state-management.md.) |
Medium | Medium (cross-account data exposure) | Phase 0/1 | Frontend |
| RISK-WC-13 | Cookie-domain / HTTPS misconfiguration causes silent prod-only logout loops. With sameSite: 'none'; secure: true, any production environment that drops to HTTP, mismatches APP_URL vs serving domain, or has a cookie-domain mismatch (e.g., cookies set on app.someli.ai but the user is on www.someli.ai) breaks login silently. (Source: existing dev doc ../10-troubleshooting.md § "Site loads but immediately redirects to /#login".) |
Low–Medium (depends on infra change frequency) | High when triggered (full outage) | Phase 0 (add monitoring + runbook) | DevOps + Frontend |
| RISK-WC-14 | Browser-extension / ad-blocker breakage of payment SDKs. Stripe.js (https://js.stripe.com/v3/) and Paddle.js (https://cdn.paddle.com/paddle/v2/paddle.js) are loaded as global CDN scripts. Common ad-blockers and privacy extensions block these URLs. Checkout fails silently. Without error tracking (WC-OBS-1), the team learns about broken checkouts only via support tickets. (Source: ../10-troubleshooting.md § "Stripe / Paddle script not loading"; cross-ref observability.md § WC-OBS-1.) |
High (continuous, % of users) | High per user (lost revenue) | Phase 0 (load Stripe/Paddle on demand + detect+message users) | Frontend |
| RISK-WC-15 | EFS-mounted node_modules single point of failure. Production runtime depends on EFS-mounted node_modules arriving at boot; start.sh waits up to 60s, then fails. An EFS outage = container can't boot. (Source: ../10-troubleshooting.md § "nuxt: command not found after deploy"; ../07-build-and-deploy.md.) |
Low | High (full outage) | Phase 1 (bake node_modules into image) | DevOps |
| RISK-WC-16 | Auto-deploy from dev_app on push. Pushing to dev_app triggers immediate Jenkins deploy. Without branch protection rules (unverified — see CMMI pillar 14), any contributor with write access can ship to dev. (Source: ../20-contributing.md § "Sharp edges".) |
Low–Medium | Medium | Phase 0a (verify branch protection; document) | Eng leadership + DevOps |
Tags for the master TDD: all RISK-WC-* should be tagged [WC] when integrated into the master TDD's risk register. Items that combine with backend findings (RISK-WC-06, RISK-WC-04) should be tagged [ALL] for cross-component synthesis.
8. Standards Compliance¶
WCAG 2.1 AA¶
Status: Not assessed / not achieved. No automated tooling, no manual testing, ~50% of images lack alt, no route-change focus management, no skip-to-content link, no reduced-motion handling. Path to AA: Phase 1 effort across 4–6 weeks plus a final external audit.
OWASP Top 10 (2021)¶
| OWASP item | Web client status | Cross-ref |
|---|---|---|
| A01 Broken Access Control | At-risk: frontend-trusted roleType; backend assumed to enforce |
WC-AUTH-4 |
| A02 Cryptographic Failures | Active failure: AWS keys in git history | WC-SEC-1 |
| A03 Injection | At-risk: 9 v-html sites without sanitisation |
WC-SEC-4 |
| A04 Insecure Design | Token in JS-readable cookie; design choice, mitigatable | WC-AUTH-2 |
| A05 Security Misconfiguration | At-risk: no CSP/HSTS, __dangerouslyDisableSanitizers, maximum-scale=1 |
WC-SEC-2/7 |
| A06 Vulnerable & Outdated Components | At-risk: Vue 2 / Nuxt 2 / Webpack 4 EOL; no Dependabot | WC-SEC-5/6 |
| A07 Identification & Authentication Failures | At-risk: no token refresh, no MFA verification, three auth-header formats | WC-API-8, WC-AUTH-* |
| A08 Software & Data Integrity Failures | At-risk: no SRI on CDN scripts | WC-SEC-3 |
| A09 Logging & Monitoring Failures | Active failure: no error tracking, no RUM, no source-map upload | WC-OBS-1/2 |
| A10 SSRF | Not applicable to a frontend (server-side category) | — |
Core Web Vitals¶
Status: Unmeasured. No Lighthouse CI, no web-vitals library, no RUM. Phase 0 — establish baseline.
Targets (per Google "good" thresholds): - LCP ≤ 2.5s - INP ≤ 200ms - CLS ≤ 0.1
Likely current state for editor route, given the 1.4 MB gzipped chunk + 16 blocking CDN scripts: LCP ≥ 4s, INP unknown, CLS unknown.
9. Open Questions¶
The full [VERIFY-*] tracker is in ./verify-markers.md. Key items for engineering leadership:
- WC-SEC-1 follow-up: has the leaked AWS key been used unauthorisedly? Awaiting CloudTrail audit.
- WC-AUTH-1: backend support for httpOnly Set-Cookie?
- WC-AUTH-2: backend re-validation of
roleTypeper privileged endpoint? - WC-BD-2: GH Actions vs Jenkins — which is canonical?
- WC-OBS-1: budget approval for Sentry / equivalent?
- Vue 3 migration: green light for Phase 2, with what team allocation?
10. Hand-off to Master TDD¶
Per WEB_CLIENT_AUDIT_GUIDE.md §9, the integration steps for the master TDD author:
- Master § 1 Executive Summary — incorporate the verdict from §1 above with cross-component caveats
- Master § 3.2 Tech Stack per Component — pull from
architecture-overview.md§ At a Glance - Master § 4.1 Security cross-cutting — combine WC-SEC-1 (AWS-key leak) + backend findings; identify any combined exposure
- Master § 4.2 Observability cross-cutting — combine WC-OBS-1 (no FE error tracker) with backend logging story
- Master § 4.4 Identity end-to-end — combine
authentication-client.md+ backend's auth doc - Master § 5.2 Web Client summary — paste §1 above
- Master § 6 Risk Register — append all RISK-WC-* with
[WC]tags - Master § 7 Roadmap — append Phase 0a/0/1/2/3 items with
[WC]tags
The audit version is 0.1. Re-verification cadence: every 6 months or after any major refactor, whichever is sooner.