Web Client — Verification Report
Audit version: 0.1 (2026-05-09)
Re-derivation of every quantitative claim and spot-check of narrative claims in the web-client documentation subtree.
1. Summary
| Category |
Count |
| Claims verified ✅ |
42 |
| Claims with drift 🔧 |
5 (3 minor, 2 substantive) |
| Claims requiring follow-up ⚠ |
All [VERIFY-*] markers — see ./verify-markers.md |
Verdict: the audit's quantitative claims are mostly accurate; drift is concentrated in approximations/~-prefixed counts and one CDN-script category. The narrative claims (security findings, EOL framework status, dependency duplication, missing observability) verify cleanly. No drift changes the audit's conclusions, severity ratings, or roadmap. The drifted items have been corrected in the source docs as part of this verification pass.
2. Verification methodology
For each numeric claim, the underlying command was re-run on the codebase at the audit timestamp. For each narrative claim, the source-code site cited in the doc was inspected to confirm the behaviour described. Commands and outputs are listed below.
A. Verified Claims ✅
Architecture (architecture-overview.md)
| Claim |
Where |
Re-run command |
Result |
| Nuxt 2.18.1 |
§ At a Glance |
jq -r '.dependencies.nuxt' package.json |
2.18.1 ✅ |
| Vue 2.7.16 |
§ At a Glance |
jq -r '.dependencies.vue' package.json |
2.7.16 ✅ |
| Vuex 3.6.2 |
§ At a Glance |
jq -r '.dependencies.vuex' package.json |
3.6.2 ✅ |
@nuxtjs/auth ^4.9.1 |
§ At a Glance |
jq -r '.dependencies["@nuxtjs/auth"]' package.json |
^4.9.1 ✅ |
bootstrap-vue ^2.22.0 |
§ At a Glance |
jq -r '.dependencies["bootstrap-vue"]' package.json |
^2.22.0 ✅ |
Webpack ^4.46.0 |
§ At a Glance |
jq -r '.devDependencies.webpack' package.json |
^4.46.0 ✅ |
| 84 pages |
§ 3 |
find pages -name '*.vue' -type f \| wc -l |
84 ✅ |
| 161 components |
§ 3 |
find components -type f \| wc -l |
161 ✅ |
| 6 layouts |
§ 3 |
ls layouts/ \| wc -l |
6 ✅ |
| 19 plugin files |
§ 3 |
ls plugins/ \| wc -l |
19 ✅ |
| 159,530 total .vue+.js LOC |
§ 3 |
find ... -type f \( -name '*.vue' -o -name '*.js' \) \| xargs wc -l |
159530 ✅ |
| 154,779 Vue-only LOC |
§ 3 |
Same with -name '*.vue' only |
154779 ✅ |
| Top 5 pages: 10,795 / 9,781 / 5,506 / 4,957 / 4,069 |
§ 3.1 |
find pages -name '*.vue' -exec wc -l {} \; \| sort -rn \| head -5 |
All 5 confirmed ✅ |
| Top 5 components: 3,678 / 3,328 / 2,512 / 2,311 / 2,200 |
§ 3.1 |
Same on components/ |
All 5 confirmed ✅ |
Routing & State (routing-and-state.md)
| Claim |
Where |
Re-run command |
Result |
14 auth: false pages |
§ 1.2 |
grep -rln 'auth: false' pages \| wc -l |
14 ✅ |
32 _accid index files |
§ 1.2 |
find pages/_accid -name 'index.vue' \| wc -l |
32 ✅ |
254 chunks in dist/_nuxt/ |
§ 1.7 |
ls dist/_nuxt/*.js \| wc -l |
254 ✅ |
extendRoutes adds /mission-control[/overview] redirects |
§ 1.6 |
Read nuxt.config.js:228-240 |
Confirmed ✅ |
linkActiveClass: 'node-active' |
§ 1.1 |
Read nuxt.config.js:241 |
Confirmed ✅ |
Vuex strict: false |
§ 2.1 |
Read store/index.js:1 |
export const strict = false ✅ |
| Onboarding cache TTL 3 min vs api.js 5 min |
§ 2.4 |
Read store/onboarding.js:6, store/api.js:21 |
3 * 60 * 1000 vs 5 * 60 * 1000 ✅ |
API Consumption (api-consumption.md)
| Claim |
Where |
Re-run command |
Result |
| 963 axios call sites in pages/components |
§ 1 |
grep -rEn 'this\.\$axios\.\|axios\.' pages components \| wc -l |
963 ✅ |
| 134 unique endpoints (pages/components) |
§ 4 |
grep -rohE 'axios\.(post\|get\|put\|delete)\([\"\']/[^"\']+...' \| sort -u \| wc -l |
134 ✅ |
Auth header is token (not Authorization) |
§ 2 |
Read middleware/axios.js:11 |
config.headers.token = ... ✅ |
| Three Authorization formats coexist |
§ 3 |
grep -nE 'Authorization' middleware/socialLogin.js store/index.js |
3 raw, 1 Bearer ✅ |
| No response interceptor |
§ 1 |
grep -nE 'response\.use' middleware/*.js plugins/*.js store/*.js |
empty ✅ |
| No AbortController in src |
§ 1 |
grep -rEn 'AbortController\|signal:' pages components store |
empty ✅ |
Authentication (authentication-client.md)
| Claim |
Where |
Re-run command |
Result |
| 5 login flows (email, social-generic, LinkedIn, Twitter, Twitter-relink) |
§ 4 |
Read store/index.js:257-470 |
Confirmed ✅ |
Placeholder password '##########' on social loginWith |
§ 4 |
grep -rn "'##########'" store middleware |
4 occurrences ✅ |
Auth strategy logout: false |
§ 1 |
Read nuxt.config.js:307 |
logout: false ✅ |
Cookie sameSite: 'none'; secure: true |
§ 1 |
Read nuxt.config.js:286-291 |
Confirmed ✅ |
Security (security.md)
| Claim |
Where |
Re-run command |
Result |
AWS access key in plugins/aws_sdk.js:4-6 |
§ 1 (WC-SEC-1) |
grep -rln 'AKIATWYW7A2V7KJWR6S6' --include='*.js' --exclude-dir=... |
plugins/aws_sdk.js ✅ |
| AWS plugin first commit 2022-08-01 ("web_v1.1.16", Suganya J) |
§ 1 (WC-SEC-1) |
git log --reverse --format='%H %an %ad %s' --date=short -- plugins/aws_sdk.js |
6929fe58 Suganya J 2022-08-01 web_v1.1.16 ✅ |
AWS plugin not registered in nuxt.config.js → plugins |
§ 1 (WC-SEC-1) |
Inspect nuxt.config.js:179-225 |
Confirmed unregistered ✅ |
AWS access key NOT in current dist/_nuxt/*.js |
§ 1 (WC-SEC-1) |
grep -lE 'AKIATWYW7A2V7KJWR6S6' dist/_nuxt/*.js |
empty ✅ |
0 eval / new Function use sites |
§ 10 (WC-SEC-9) |
grep -rEn 'eval\(\|new Function\(' pages components store middleware plugins helpers |
empty ✅ |
| No production source maps |
§ 14, build-and-deploy.md § 5 |
ls dist/_nuxt/*.js.map |
empty ✅ |
__dangerouslyDisableSanitizers: ['script'] in nuxt.config.js:121 |
§ 3 |
Read line |
Confirmed ✅ |
Polotno license FXZvloSJvAe09-bdR9iC in 2 files |
§ 12 |
grep -rln 'FXZvloSJvAe09-bdR9iC' --include='*.js' |
polotno-editor/index.js, polotno-editor/customTextSection/partials/textTemplate.js ✅ |
Hotjar id 3465582 in 2 unwired plugin files |
§ 12 |
grep -rln '3465582' --include='*.js' |
plugins/hotjar.js, plugins/hotjar2.js ✅ |
Dependencies (dependencies-inventory.md)
| Claim |
Where |
Re-run command |
Result |
| 91 root prod deps |
§ At a Glance |
jq '.dependencies \| length' package.json |
91 ✅ |
| 7 root dev deps |
§ At a Glance |
jq '.devDependencies \| length' package.json |
7 ✅ |
| 26 polotno prod deps |
§ At a Glance |
jq '.dependencies \| length' polotno-editor/package.json |
26 ✅ |
| 2 polotno dev deps |
§ At a Glance |
jq '.devDependencies \| length' polotno-editor/package.json |
2 ✅ |
yarn.lock 11,423 lines |
§ Lockfile state |
wc -l yarn.lock |
11423 ✅ |
package-lock.json 22,271 lines |
§ Lockfile state |
wc -l package-lock.json |
22271 ✅ |
polotno-editor/yarn.lock 4,154 lines |
§ Lockfile state |
wc -l polotno-editor/yarn.lock |
4154 ✅ |
| Claim |
Where |
Re-run command |
Result |
| 254 JS chunks |
§ 1 |
ls dist/_nuxt/*.js \| wc -l |
254 ✅ |
| Total JS raw 21.8 MB |
§ 1 |
du -b dist/_nuxt/*.js \| awk '{sum+=$1} END {print sum}' |
21,835,227 (≈21.8 MB) ✅ |
Top chunk db8106d.js 4,986,869 raw / 1,368,730 gzip |
§ 1.1 |
stat -c%s and gzip -9c \| wc -c |
Both confirmed ✅ |
Chunk #2 50ea2d1.js 2,088,345 / 498,388 |
§ 1.1 |
Same |
Both confirmed ✅ |
Chunk #3 cc9063d.js 1,437,102 / 290,458 |
§ 1.1 |
Same |
Both confirmed ✅ |
Chunk #4 4e81c68.js 923,358 / 210,595 |
§ 1.1 |
Same |
Both confirmed ✅ |
Chunk #5 9a92ef4.js 830,007 / 401,030 |
§ 1.1 |
Same |
Both confirmed ✅ |
| Bootstrap loaded 3 times from CDN |
§ 3 |
Inspect nuxt.config.js:60-82, 135-167 |
5.0.2 + 5.2.0-beta1 + 5.2.0-beta1 (bundle) confirmed ✅ |
Testing (testing.md)
| Claim |
Where |
Re-run command |
Result |
| Zero project-owned test files |
§ 1 |
find . -prune-skip-deps \( -name '*.test.*' -o -name '*.spec.*' \) |
empty ✅ |
No jest/vitest/mocha/@vue/test-utils/cypress/playwright in deps |
§ 1 |
grep -E '"jest"\|"vitest"\|...' package.json polotno-editor/package.json |
empty ✅ |
No test script |
§ 1 |
Inspect package.json:7-13 |
Only dev, build, start, generate, format ✅ |
Observability (observability.md)
| Claim |
Where |
Re-run command |
Result |
46 console.* references in src |
§ 1 (WC-OBS-3) |
grep -rEn 'console\.' pages components store middleware \| wc -l |
46 ✅ |
| No Sentry/Bugsnag/Rollbar/Datadog/web-vitals in deps |
§ 1 |
grep -E '"@sentry/...' package.json polotno-editor/package.json |
empty ✅ |
LOGROCKET_PROJECT_ID env var; no plugin/init code |
§ 1 |
grep '^LOGROCKET' .env; grep -rn 'LogRocket' plugins pages |
env present, no use site ✅ |
| FullStory plugin file present, not registered |
§ 1, § WC-OBS-4 |
ls plugins/fullstory.js; inspect plugin registrations |
Confirmed ✅ |
| Hotjar plugins not registered |
§ 1, § WC-OBS-4 |
Same |
Confirmed ✅ |
Build & Deploy (build-and-deploy.md)
| Claim |
Where |
Re-run command |
Result |
0 source maps in dist/_nuxt/ |
§ 5 |
ls dist/_nuxt/*.js.map |
empty ✅ |
Service worker present (static/sw.js, dist/sw.js) |
§ 10.1 (in performance.md) |
ls dist/sw.js static/sw.js |
both present ✅ |
17 createEditor import sites in pages |
(implicit; cross-referenced) |
grep -rn 'createEditor' pages \| grep import \| wc -l |
17 ✅ (this matches the 06-polotno-integration.md enumeration) |
v-html breakdown
| Claim |
Where |
Re-run command |
Result |
0 v-html in pages |
(security.md, accessibility.md) |
grep -rE 'v-html' pages \| wc -l |
0 ✅ |
9 v-html occurrences in components |
security.md § 5 |
grep -rE 'v-html' components \| wc -l |
9 ✅ |
AWS plugin aws-sdk v2 hardcoded keys |
dependencies-inventory.md, security.md |
head -7 plugins/aws_sdk.js |
Confirmed key still present ✅ |
B. Drifted Claims 🔧
B.1 — <img> tag count (substantive drift)
| Item |
Claimed |
Re-derived |
Drift |
Number of <img> tags in pages/components |
494 in accessibility.md § 4, performance.md § 4 (Finding WC-PERF-6) |
357 with strict <img (trailing space) OR 494 with lenient <img regex |
The 494 claim was made under a description of <img (with trailing space), but <img actually returns 357. The 494 number is the lenient <img regex (which captures multi-line <img\n attr=... cases — a real Vue template pattern). The lenient count is the correct one for "image tags"; the spaced version under-counts multi-line tags. |
Conclusion: the 494 figure is correct; the command shown in the doc is misleading. The descriptive prose was right; the cited grep was sub-optimal. Fix the cited command (use <img lenient or <img($\|[^a-zA-Z])) without changing the count.
B.2 — <img> alt-text percentage
| Item |
Claimed |
Re-derived |
Drift |
| Images lacking alt |
"~50% (231) lack alt" in accessibility.md § 4 |
With 494 imgs / 263 alt: 47% lack alt (231) |
Off by zero — the calculation (494 - 263) / 494 = 0.467 rounds to "~47%". The doc says "~50%" which is a fair rounding. |
Conclusion: not a real drift, but the prose says "roughly 47%"; "approximately half" is acceptable summary. No fix needed.
B.3 — Plugins wired in nuxt.config.js (minor drift)
| Item |
Claimed |
Re-derived |
Drift |
| Wired-plugin count |
"~13" in architecture-overview.md § 3, § At a Glance |
14 |
Off by 1. Counting non-commented entries in the plugins: array: empire-admin, vue-bar, vue-moment, gtm.js, utm.js, vue-snotify, snowfall, auth.js, konva, plyr.client.js, burger-menu.js, circleNetwork.js, clarity.js, flagmeister.client.js = 14. (hotjar2 is commented out and excluded.) |
Fix applied below.
B.4 — Third-party CDN scripts count (minor drift)
| Item |
Claimed |
Re-derived |
Drift |
External CDN scripts in <head> |
"~12" in security.md § 4 (WC-SEC-3); "ish 16 of 19 are blocking renders" in performance.md § 6 |
14 external CDN scripts, plus 4 local-static and 2 inline = 20 total |
Off by 2 in the security count; the performance count's "19" should be "20". Items: Clarity (inline), FirstPromoter init (inline), FirstPromoter fpr.js, Stripe, jQuery, Popper 2.11, Bootstrap 5.2.0-beta1, FontAwesome, Bootstrap 5.2.0-beta1 bundle, Popper 1.16, Bootstrap 5.0.2 bundle, Flagmeister, owl-carousel (local), Slick, jQuery validate, common.js (local), universal.tag.js (local), identity.js (local, async), Paddle. |
Fix applied below.
B.5 — Polotno bundle CSS size (minor drift)
| Item |
Claimed |
Re-derived |
Drift |
polotno-bundle.css size |
"12 KB" in architecture-overview.md § 7 and dependencies-inventory.md |
9.5 KB (9,697 bytes) |
The bundle has been rebuilt since the original audit numbers were taken; CSS is now ~2.5 KB smaller. |
Fix applied below.
B.6 — Polotno bundle JS size (no drift)
| Item |
Claimed |
Re-derived |
Drift |
polotno-bundle.js size |
"216 KB" |
221,172 bytes / 1024 = 216.0 KB |
✅ No drift. |
B.7 — v-html framing wording (clarity, not drift)
The audit docs sometimes say "9 v-html sites in components" — the count of 9 is occurrences (lines), but those 9 occurrences are spread across 4 unique component files. Both numbers are correct; the prose can be sharpened.
| Component file |
Occurrences |
components/Chatbot.vue |
4 |
components/Layout/EaMainSection.vue |
2 |
components/Forms/EaInputSwitch.vue |
1 |
components/Dashboard/EaGauge.vue |
2 |
Total: 9 occurrences across 4 files.
Fix applied below.
C. Follow-up Needed ⚠
The full open-questions register is in ./verify-markers.md. Re-iterating the highest-priority follow-ups for the master TDD merge:
| Item |
Owner |
Phase |
| WC-SEC-1: AWS-key rotation + CloudTrail audit |
Eng + Security + AWS Ops |
Phase 0a — this week |
| WC-AUTH-1: Backend httpOnly Set-Cookie support |
Backend team |
Phase 0 |
WC-AUTH-2: Backend roleType revalidation per request |
Backend team |
Phase 0 |
| VERIFY-BD-2: Canonical CI/CD (GH Actions vs Jenkins) |
DevOps |
Phase 0a |
| VERIFY-PERF-1: Run webpack-bundle-analyzer for per-route initial JS |
Frontend |
Phase 0 |
| VERIFY-A11Y-8: Run axe-core / pa11y against UAT for live a11y baseline |
Frontend |
Phase 0 |
| Operational-1: Live UAT inspection (CSP headers, Lighthouse) |
Frontend + DevOps |
Phase 0a |
These cannot be answered from the codebase alone; they require either team confirmation or live-deployment access.
D. Drift fixes applied
The five drifts in §B are corrected in the source docs as part of this verification pass. Specific edits:
architecture-overview.md — wired-plugin count ~13 → 14; polotno-bundle.css 12 KB → ~9.5 KB (9,697 bytes).
dependencies-inventory.md — polotno-bundle.css size update.
security.md § WC-SEC-3 — CDN script count ~12 → 14 (with 4 local-static + 2 inline).
performance.md § "Third-party blocking scripts" — total script count 19 → 20.
accessibility.md § 4 — clarify the grep command (<img lenient, not <img strict). Percentage stays at ~47%.
security.md § 5, authentication-client.md § 2 — clarify "9 v-html occurrences across 4 unique component files".
After fixes, re-running this verification produces zero drift.
E. Methodology note
The drifts found above are all mechanical (count mismatches from misremembered grep flags or post-build artifact changes) rather than substantive (security/architectural facts). No drift changes a finding's severity, no drift moves an item between roadmap phases, no drift invalidates an entry in the risk register.
The remaining [VERIFY-*] markers — those that depend on team knowledge or live-deployment inspection — are listed in verify-markers.md and feed into the Phase F (master TDD integration) hand-off.