Skip to content

Architecture & Technical Design

Last updated: July 17 2026 — Live access and route guidance now live in access-control.md and startupOS.md; this doc is the broader technical map, not the access source of truth.

Before making any money-/user-data change, consult .github/copilot-instructions.md §3 — the change-ripple matrix. It lists every surface (pages + endpoints) that reads the same data, so you don't accidentally ship a change that breaks a sibling feature (e.g. adding a new "share" path when sharing already exists via /api/share-links + SharedView.tsx).

Current live systems note: The unified Archetiq app runs on https://www.archetiq.com and https://demo.archetiq.com. For access policy, role names, and live gates, use access-control.md. For deployment, use deployment.md.

Stack

Layer Technology
Frontend React 19 + TypeScript (strict mode) + Vite 6
Styling Tailwind CSS 4
Animation motion/react 12
Icons lucide-react
Charts Chart.js 4 + react-chartjs-2, Recharts
Routing react-router-dom v7
Auth VPS JWT (issued by /api/auth/* endpoints; stored in localStorage)
Backend API Express.js on Hostinger VPS (port 5002, PM2, Node 20)
Database MongoDB (personality_db) on VPS
Payments Stripe Checkout → VPS webhook handler (/api/stripe/*)
AI Google Gemini (@google/genai) + Ollama (local LLM)
RAG MongoDB lexical retrieval + Ollama summarization
PDF Export html2canvas-pro + jsPDF

Note: Firebase has been completely removed. Auth is handled by the VPS (/api/auth/* endpoints issuing 30-day JWTs). All data is stored in MongoDB. The src/api/ folder holds the VPS HTTP client (client.ts), JWT auth helpers (auth.ts), a localStorage shim (config.ts), and the MongoDB data layer (db.ts).


AI & RAG Architecture

Ollama (VPS Docker)

Ollama runs as a Docker container on the VPS at 127.0.0.1:11434, exposed publicly via ollama.archetiq.com with Bearer token auth.

Installed models:

Model Size Purpose
gemma4:latest 9.6 GB Primary local LLM for summarization
qwen2.5-coder:1.5b-base 986 MB Code/analysis tasks
llama3.2:1b 1.3 GB Lightweight tasks

Ollama client: server/src/utils/ollamaClient.js - ollamaGenerate(prompt, timeoutMs) — generic text generation - summariseCareerPatterns(patterns) — compresses career transition patterns into market intelligence - ollamaIsAvailable() — health check

RAG Collections

Collection Purpose
archetiq_knowledge_chunks Platform knowledge corpus (Personality-Test)
startupos_framework_chunks NEW: StartupOS framework and module guides (for AI Mentor)
archetiq_user_memory User episodic memory (RAG-005 pending)
archetiq_team_memory Team episodic memory (RAG-006 pending)
archetiq_rag_shadow_log Shadow mode logs with TTL retention

Retrieval utility: server/src/utils/knowledge/retrieval.js - getKnowledgeChunks(moduleType, limit, options) — BM25 lexical retrieval - buildKnowledgeRetrievalSnippet(moduleType, limit, options) — builds context snippets for AI calls

RAG Implementation Status

Phase Status Description
Phase 1 ✅ Complete Knowledge corpus ingest + retrieval utility
Phase 2 ✅ Complete Shadow mode (parallel to Gemini, logging only)
Phase 3 🚧 In Progress Ollama primary + Gemini fallback rollout
Phase 4 ⬜ Pending User/team memory writes with PII sanitization

Career Insights Ollama Loop

The career insights system uses a 3-tier Ollama learning loop:

  1. Tier 1 (on-the-fly): Ollama summarization of career patterns on request
  2. Tier 2 (cache): Weekly aggregate stored in archetiq_user_memory
  3. Tier 3 (cron): careerInsightsCron.js runs Sundays 02:30 UTC to pre-compute aggregates

Infrastructure

Browser
  └─ HTTPS → archetiq.com (Nginx, Let's Encrypt SSL)
       ├─ /api/*    → proxy → Express :5002  (API + Stripe webhook)
       ├─ /health   → proxy → Express :5002
       └─ /*        → static files from /opt/personality-app/public/  (Vite dist)
  • VPS: Hostinger, IP 76.13.211.100
  • Static files: /opt/personality-app/public/ (Vite dist/ uploaded via SCP)
  • Backend app dir: /opt/personality-app/
  • Process manager: PM2 (personality-app, id 2)
  • MongoDB: mongodb://localhost:27017/personality_db
  • DEPRECATED: The startup.archetiq.com deployment, its directory (/opt/startup-playbook), and its database (startupplaybook) are now obsolete and will be removed post-migration.

Application Structure

src/
  pages/          — Full-page route components
    // ... existing pages
    startup/      — ARCH mission runtime (.tsx)
      ArchMissionPage.tsx
  components/     — Shared UI components
  store/          — NEW: Zustand stores for StartupOS features
    startupStore.ts
    sprintStore.ts
    aiMentorStore.ts
  data/           — Static JSON and data helpers
    startupArchMissionContract.ts — ARCH mission schema
  // ... other directories

server/src
  server.js       — Express entry point
  models/         — NEW: Mongoose schemas for all collections
    User.js
    Organisation.js
    Startup.js
    StartupJourney.js
    Sprint.js
    Cohort.js
    // ... other existing models
  middleware/     — auth.js, adminMiddleware, etc.
  routes/         — One file per resource
    // ... existing routes
    startups.js      — NEW
    sprints.js       — NEW
    cohorts.js       — NEW
    lecturer.js      — NEW
    decisionLab.js   — NEW
  utils/          — Utilities and business logic

API Design

All backend routes are prefixed /api/. Auth is validated via VPS-issued JWT in the Authorization: Bearer <token> header (authMiddleware in middleware/auth.js).

Key route groups:

Prefix Description
/api/auth Auth endpoints (no token required). POST /register (create account, returns JWT), POST /login (verify credentials, returns JWT), POST /forgot-password (sends SMTP reset email), POST /reset-password (sets new password via token), GET /me (own user doc, requires token)
/api/users User profiles. GET /me (own), PUT /me (own update — plan/payment fields excluded), GET /:uid (self or admin), PUT /:uid (admin — general field update), PUT /:uid/assign-coach (org admin)
/api/ai Gemini AI endpoints. POST /generate (structured JSON, 20/hr), POST /chat (multi-turn AiGuide, 30/hr per user), POST /draft-life-plan (Plan Assembly Engine — scopes: ikigai, vision-mission, pillars, all, field, capability-gap, one-pillar; builds context from user's Profile + Foundation + Life Wheel + Wellness + Money data + Life Path milestones from server/src/utils/careerPaths.json; rate-limited 10/hr per user shared with consistency/alignment checks). scope=one-pillar generates a single pillar goal object (~85% output token reduction vs scope=all). POST /check-ikigai-alignment — verifies coherence of all 4 Ikigai circles + Vision + Mission, returns { verdict, critique, suggestion? }. All endpoints use model gemini-2.5-flash.
/api/admin Admin-only atomic operations. POST /change-plan — atomically updates plan, planExpiresAt, coachAppStatus, and the coaches collection in one DB round-trip. All plan/payment state changes must go through this endpoint — never call /api/users/:uid directly for plan changes.
/api/responses Assessment responses
/api/coaches Coach profiles. GET supports ?email= and ?referralCode= filters — must be applied as DB filters, not ignored. POST supports { upsert: true } for create-or-reactivate by email (used internally by /api/admin/change-plan). See access-control.md §8 for the April 2026 filter bug.
/api/coach-tools Coach-only utility endpoints for org-selected coaches (orgRole === 'coach'). GET /manual streams the Archetiq demo PDF. POST /demo-reseed rebuilds demo org users, responses, and teams in a separate demo database (DEMO_MONGO_URI, fallback personality_demo_db).
/api/health Native health sync. POST /sync — writes workout/sleep/steps data from Capacitor Health API (mobile only). GET /summary — returns user's last 7 days of health metrics.
/api/organisations Orgs; POST /:id/activate-plan, POST /:id/deactivate-plan
/api/cohorts Coach cohorts (CRUD)
/api/teams Teams; POST /join, POST /leave, GET /:code/members
/api/stripe Checkout, webhook, verify-session; fires agent commission to agents-service (port 5003) after payment
/api/conversations Messaging. GET / — list user's conversations; POST / — create conversation (uses randomUUID() string _id); GET /:id/messages — paginated message list; POST /:id/messages — send message. Frontend polls conversations every 5 s and messages every 3 s.
/api/notifications User notifications. GET / — list unread/recent. PUT /mark-read — mark all read. DELETE / — delete all notifications for current user (used by "Clear all" button in Layout).
/api/share-links Report share tokens
/api/promo-codes Promo code lookup + redeem
/health Health check
/api/startups NEW: Startup CRUD and workspace progress tracking.
/api/startup-v2 Retired: legacy founder workspace route removed after ARCH cutover.
/api/startup-arch NEW: ARCH mission runtime, migration, coach, outputs, and telemetry.
/api/sprints NEW: Sprint and task management for startups.
/api/cohorts UPDATED: Now used for Institution cohort management.
/api/lecturer NEW: Endpoints for the Lecturer Dashboard.
/api/decision-lab NEW: Endpoints for the Decision Intelligence Lab.

Note: Compatibility comparison (RelationshipLensPage.tsx, /compare) is computed entirely client-side by src/services/compatibilityEngine.ts — there is no /api/compare server route.


User Journey (current, June 26 2026)

Navigation sections by plan:

Home     — Dashboard                                          (all users)
Discover — Assessment, My Report                              (all users)
Explore  — Book Guide, Mind & Body, Money Plan                (Explorer only)
Design   — Career Path (/life-simulator + CareerFitLab)        (Explorer only)
Master   — Growth Loop, Chemistry Check                        (Explorer only)
Organisation — Org Dashboard, Team Map, Team Intelligence      (Organisation plan only)

Journey gate chain (enforced in ProtectedRoute.tsx + journeyGates.ts):

requiresDiscovery     = discoveryCompleted
requiresFoundations   = discoveryCompleted AND financialPlan completed   ← Life Simulator
requiresPayment       = hasPaidAccess(profile)   [false for organisation plan]


Routing

All routes defined in App.tsx (current, June 26 2026):

Path Component Gate
/ LandingPage Public
/login, /register Login, Register Public
/verify-email VerifyEmailPage Public
/reset-password ResetPassword Public
/pricing Pricing Public
/about AboutPage Public
/terms, /privacy TermsOfService, PrivacyPolicy Public
/share/:token SharedView Public
/payment/success PaymentSuccess Public
/complete-profile CompleteProfile Auth
/dashboard Dashboard Auth
/questionnaire QuestionnairePage Auth
/report MyReportPage Auth
/archetype-reveal ArchetypeReveal Auth
/profile Profile Auth
/coach-portal CoachPortal Auth
/book BookPage requiresBook
/wellness-profile WellnessProfilePage requiresDiscovery + requiresPayment
/financial-plan FinancialPlanPage requiresDiscovery + requiresPayment
/life-simulator LifeSimulatorPage requiresFoundations + requiresPayment
/growth-loop GrowthLoopPage requiresDiscovery + requiresPayment
/chemistry ChemistryPage requiresChemistry (Explorer only)
/team TeamReport requiresOrganisation
/team-intelligence TeamIntelligencePage requiresOrganisation
/organisation OrganisationDashboardPage requiresOrganisation
/admin AdminDashboard Admin role only
/org-dashboard Redirect → /organisation Legacy
/health-dashboard Redirect → /wellness-profile?tab=health Legacy
/life-insights Redirect → /wellness-profile?tab=health Legacy
/relationship-lens Redirect → /chemistry?tab=personal Legacy
/people-blueprint Redirect → /chemistry?tab=work Legacy

requiresFoundations = Discovery completed + Money Plan completed (Life Simulator needs financialPlan data)

DELETED routes: /life-design, /life-design-legacy, /self-mastery, /compare, /corporate, /self-inquiry


Layout & Navigation

  • Layout.tsx renders the sidebar navigation and (on mobile) a top bar.
  • Navigation groups (in order): Home → Discover (01) → Explore (02 — Health, Financial Stability, Career Path) → Design (03 — Life Design, Growth Loop) → Master (04) → Account → Coaching → Organisation → Platform Admin.
  • “Explore” group appears after Discovery is completed. Contains Health, Financial Stability, and Career Path — Health and Financial Stability must both be completed before Life Design unlocks.
  • “Design” group is always visible (Life Design and Growth Loop items show lock icons until prerequisites are met).
  • Header hidden on desktop for authenticated inner pages — the top header bar is only shown on mobile/tablet to avoid double navigation chrome.
  • Collapsible sidebar on inner pages (Report, Wellness, LifeDesign, Financial): users can collapse the sidebar to gain horizontal space. Collapse state is toggled per-session.
  • Notification bell in the sidebar and top bar:
  • Unread count badge.
  • Clicking opens a fixed-position dropdown panel (avoids overflow/clipping issues).
  • "Mark all read" button marks every notification read server-side and clears the badge.
  • "Clear all" button calls DELETE /api/notifications to permanently remove all notifications for the user, then clears local state.
  • Notification links that reference a coach conversation include ?conv=<uuid> so Messages.tsx deep-links to the correct thread.

State Management

The application uses a hybrid state management approach: - UserProfileContext: A global context (src/contexts/UserProfileContext.tsx) polls GET /api/users/me every 30 seconds to provide a live-updating { user, profile } object. This is used for all authentication and access control logic. - Zustand: For features migrated from StartupOS, a store/ directory contains Zustand stores (startupStore, canvasStore, etc.) to manage complex client-side state for the founder journey. - Local State: Most individual components and pages manage their own UI state via useState / useEffect.

user is type AuthUser { uid: string; email: string } — not a Firebase User object. Auth state is restored from localStorage key personality_auth (written by client.ts:setStoredAuth) and kept live via a personality_auth_change CustomEvent listener. Previously Firebase onAuthStateChanged was used — replaced in April 2026.

Messages (Messages.tsx)

  • Polling-based real-time messaging between coach and client.
  • Conversations listed in a left panel; clicking one opens the thread.
  • Active conversation set from ?conv=<id> URL param on load; if no param is present, the first conversation is auto-selected.
  • Conversations polled every 5 seconds; messages polled every 3 seconds.
  • Conversation _id values are string UUIDs (generated via randomUUID() on the server), not MongoDB ObjectIds. All server-side findOne calls use a toDbId() helper that handles both formats for backward compatibility.

Scoring Engine (src/utils/scoring.ts)

Pure functions only — no side effects, no Firebase calls.

  • calculateResult(answers) — core scoring function. Do not modify without full regression testing.
  • smartOrderQuestions() — interleaves categories and alternates difficulty for engagement.
  • isAssessmentStable(answers, questions) — early-completion signal.

Services Layer

Service File Purpose
Insight Engine insightEngine.ts Generates 4 InsightPanel objects (self, direction, decision, evolution) from archetype + force data. Fully rule-based — no AI calls.
Career Insight Engine careerInsightEngine.ts Produces CareerEnhancement — personalised career context panels from profile fields.
Health Sync Service healthSyncService.ts Syncs native health data from Capacitor Health API on mobile. On web this is a no-op.
Wellness Engine wellnessEngine.ts Computes dosha scores and wellness profile recommendations from prakriti quiz answers.
Compatibility Engine compatibilityEngine.ts Computes CompatibilityResult from two archetype+force pairs.
Corporate Engine corporateEngine.ts computeCorporateGuide, computeTeamIntelligence, computePeerGroupIntelligence. Used by PeopleBlueprintPage, ChemistryPage, TeamIntelligencePage.
Payment Service paymentService.ts Thin wrapper around VPS API (POST /api/stripe/create-checkout-session).

DELETED services (do NOT recreate): ikigaiEngine.ts, selfInquiryService.ts, foundationDerivation.ts, selfMasteryData.ts, foundationSynthesisService.ts, visionGoalParser.ts, aiService.ts


Gamification Utility (src/utils/gamification.ts)

Pure functions — no Firebase calls, no side effects. Consumed by pages and UserProfileContext.

Export Purpose
XP_REWARDS Map of action key → XP value (e.g. ASSESSMENT_COMPLETE: 500)
BADGE_DEFINITIONS Map of badge ID → { label, icon, description } for all 9 badges
computeLevel(xp) Returns 'Stardust' \| 'Comet' \| 'Nova' \| 'Supernova' based on thresholds
levelProgress(xp) Returns 0–100 percentage within the current level band
nextLevelThreshold(xp) Returns { level, threshold } for the next level, or null at Supernova
computeStreak(habits, today?) Iterates habit completedDates backwards to compute consecutive-day count
computeNewBadges(profile, ctx?) Returns array of newly earned badge IDs not already in profile.badges
applyXp(profile, action) Returns updated { xp, level, badges } — does not write to DB
computeBackfill(profile) One-time retroactive calculation for existing users: derives XP + level + badges + streak from completed stages

Key Type Definitions (src/types/)

Type Purpose
SectionDetail { meaning, realLife, strength, growth } — used by all archetype section cards
InsightReport Four InsightPanel objects returned by insightEngine.ts
CareerEnhancement Personalised career context object from careerInsightEngine.ts
CareerDecisionAIResult Full career AI output including optional roleSuitability?: { verdict, score, suited[], gaps[], summary } (in src/types/careerDecision.ts)
CompatibilityResult Output from compatibilityEngine.ts: score, summary, strengths, challenges, dosList, dontsList, approachGuide, traitsToWatchOut, conflictFlashpoints

MongoDB Data Model

users collection — UserProfile

Key fields:

uid, name, email, role ('user' | 'admin')
discoveryCompleted
plan ('free' | 'explorer' | 'coach' | 'organisation'), planExpiresAt (ISO string | null), stripeCustomerId
orgId (null = individual), orgRole ('member' | 'admin' | 'coach'), assignedCoachId
emailVerified (boolean), emailVerificationToken (string | null)
coachAppStatus ('approved_pending_payment' | 'payment_received' | undefined)
referredBy (coachId), referralCode (coaches only), teamId
careerLabAnswers: { ikigai, lifeCtx, intentionChoice, pathChoices[], suggestedRoles[], chosenRole, wizardStep, ... }
careerFitResult: { bestRole, targetIndustry, roleSuitability?, next90Days, savedAt, ... }
careerCommitment: { plan, goals[], committedAt }
growthLoop: { habits, weeklyReflections, monthlyReviews, goalKanban: Record<goalId, GoalKanbanCard> }
shareToken (for public share link)
xp?, level?, badges?, streakCount?, lastStreakDate?```

**Plan access logic** (`src/utils/journeyGates.ts` — `hasPaidAccess`):

- `role === 'admin'` → always true
- `plan === 'coach'` → always true
- `plan === 'explorer'` with no `planExpiresAt` → true (admin-granted permanent access)
- `plan === 'explorer'` with future `planExpiresAt` → true (active paid or org subscription)
- All other cases → false

### `responses` collection — Assessment Response

One document per user (retakes overwrite). Key fields:

```text
uid, answers, archetype, secondaryArchetype, force, scores,
confidenceScore, energyOrientation, profileType, createdAt, assessmentHistory[]

createdAt is used by the 6-month retake cooldown enforced in DiscoveryPage.tsx.

coaches + coachApplications collections — Coaching

coaches/{id}:          name, email, title, bio, archetypes, modules, location, sessionType,
                       priceMin, priceMax, referralCode, status ('active' | 'inactive'), createdAt
coachApplications/{id}: name, email, archetype, message,
                       status ('pending' | 'approved_pending_payment' | 'payment_received' |
                               'approved' | 'rejected')
coachRequests/{id}:    userId, coachId, status ('pending'|'proposed'|'accepted'|
                       'awaiting_payment'|'payment_submitted'|'active'), proposal fields
commissions/{id}:      referralCode, coachId, clientUid, amount, createdAt
processedWebhooks/{sessionId}: processedAt (idempotency guard for Stripe events)

Coach application status lifecycle:

pending → approved_pending_payment → payment_received → approved
        ↘ rejected (at any stage)
  • approved_pending_payment — admin pre-approved; user's coachAppStatus set; payment gate shown in CoachPortal
  • payment_received — Stripe webhook confirmed payment; admin "Activate Coach" button appears
  • approved — admin activated; coaches doc created/reactivated; plan: 'coach' set on user; coachAppStatus cleared

organisations collection — Corporate & Institution Accounts

This collection now serves both corporate clients and the newly migrated university "Institutions". A new orgKind field is used to differentiate them.

_id, name, inviteCode, coachIds[],
plan ('explorer' | 'institution'), planExpiresAt,
seatLimit,
orgKind ('organisation' | 'institution'), // NEW
createdAt

startups collection (NEW)

Stores all data related to a founder's startup journey.

_id, owner (ref: User), name, tagline, industry,
members (ref: [User]),
progress: { persona: bool, ... }, // 27 boolean keys
evolutionStage, xp, badges

canvases collection (NEW)

Stores the data for each of the 26 canvases for a given startup.

_id, startup (ref: Startup),
type (enum: 26 canvas types),
data: Mixed

sprints collection (NEW)

Stores sprint planning data for a startup.

_id, startup (ref: Startup), name, status,
startDate, endDate,
tasks: [{ title, status, assignee, ... }]

cohorts collection (UPDATED)

Now used for managing university cohorts.

_id, institution (ref: Organisation),
name, joinCode,
lecturerIds (ref: [User]),
studentIds (ref: [User])

Assessment Retake Cooldown

Users are locked from retaking the assessment for 6 months after their first submission.

  • Check location: DiscoveryPage.tsx — useEffect on mount reads responses/{uid}.createdAt
  • Lock duration: SIX_MONTHS_MS = 6 * 30 * 24 * 60 * 60 * 1000
  • Locked UI: Shows the last assessment date, next unlock date, and a countdown in days
  • Manual admin override: Edit responses/{uid}.createdAt in MongoDB (via Admin > Users in AdminDashboard or direct MongoDB access) to any date 6+ months ago

Why 6 months: Personality archetypes are stable over months and years. Research shows meaningful shifts take at least 6 months of new life experience to register. Short re-tests mostly reflect mood, not real change.


Payment Flow (Stripe)

Explorer Plan (RM 59/year)

Client (Pricing.tsx)
  ↓ createCheckoutSession({ plan: 'explorer', userId, referralCode?, promoCodeId? })
VPS API: POST /api/stripe/create-checkout-session
  ↓ creates Stripe Checkout session (optionally applies coupon for discount codes)
  ↓ returns { url }
Browser → Stripe-hosted checkout page
  ↓ on success: redirects to /payment/success?session_id=...
Stripe Webhook (checkout.session.completed)
  → verifies signature, writes plan: 'explorer', planExpiresAt (+1 year) to users collection
  → increments usedCount + usedBy[] on promoCodes (if promo used)
  → records commission if referralCode present
Stripe Webhook (invoice.payment_succeeded, subscription_cycle)
  → extends planExpiresAt by 1 year
Stripe Webhook (customer.subscription.deleted)
  → sets plan: 'free', removes planExpiresAt

Coach Plan (RM 599 year 1 → RM 199/year renewal)

Coach plan uses a Stripe Subscription Schedule with two phases (RM 599 → RM 199). The webhook does not activate the portal directly — it requires admin review first.

CoachPortal (payment gate — only shown when coachAppStatus === 'approved_pending_payment')
  ↓ createCheckoutSession({ plan: 'coach', userId, ... })
VPS API: POST /api/stripe/create-checkout-session
  ↓ creates Stripe Checkout session at STRIPE_COACH_FIRST_PRICE_ID
  ↓ returns { url }
Browser → Stripe-hosted checkout
Stripe Webhook (checkout.session.completed)
  → sets coachAppStatus: 'payment_received' on users document
  → updates coachApplications document → status: 'payment_received'
  → creates SubscriptionSchedule (phase 1: RM 599, phase 2: RM 199 recurring)
  → does NOT set plan: 'coach' directly — admin must activate
Admin clicks "Activate Coach" in AdminDashboard → Coaches tab
  → creates coaches document, sets plan: 'coach', clears coachAppStatus
Stripe Webhook (customer.subscription.deleted)
  → sets plan: 'free', clears coachAppStatus, deactivates coaches document

PDF Export (MyReportPage.tsx)

Uses html2canvas-pro v2.0.2 + jsPDF v4.2.0. Each [data-pdf-section] element in the report renders as its own PDF page (image-based JPEG). Responsive Tailwind classes are inlined at capture time to ensure multi-column layouts render correctly regardless of viewport width.

html2canvas-pro v2 compatibility fix (May 2026): v2 added a Validator class that throws if canvas width/height ≤ 0 or > 32767. handleExportPDF passes { skipValidation: true } and clamps dimensions to Math.min(Math.max(dim, 1), 16383) to prevent both classes of error.


Data-Driven UI

No report or dashboard content is hardcoded. All text is pulled from:

  • src/data/framework.json — archetype sections, leadership profiles, learning profiles, financial data
  • src/data/questions.json — assessment questions
  • src/data/scoring.json — scoring weights
  • src/data/careerPaths.json — 3-path career data (acceleration / mastery / contribution)
  • src/data/powerMoves.json — per-archetype behavioural levers
  • src/data/actionPlans.json — growth action plans
  • src/data/manifestos.json — path manifestos
  • src/data/swotTemplates.json — SWOT prompts for Strategic Audit step