Stack
Vue 3 (Composition API) + TypeScript + Vite + Tailwind CSS 3 + TanStack QueryDirectory Structure
Routing
Auth guard inrouter/index.ts: redirects to /login if no JWT in localStorage. Public routes marked with meta: { public: true }.
| Route | Component | Auth | Notes |
|---|---|---|---|
/login | LoginPage | No | Pre-filled demo creds |
/signup | SignupPage | No | 4-step wizard |
/forgot-password | ForgotPasswordPage | No | |
/reset-password | ResetPasswordPage | No | Token from query param |
/dashboard | DashboardPage | Yes | Default after login |
/athletes | AthletesPage | Yes | Expandable roster table |
/athletes/:id | AthleteProfilePage | Yes | Read-only analytics |
/athletes/:id/edit | AthleteDetailPage | Yes | Editable profile |
/agreements | AgreementsPage | Yes | Filterable deal list |
/agreements/upload | UploadWizardPage | Yes | Multi-file AI extraction |
/benchmarks | BenchmarksPage | Yes | Premium grid gated |
/budget | BudgetPage | Yes | Inline cap editing |
/reporting | ReportingPage | Yes | Verification queue |
/settings | SettingsPage | Yes | Admin only |
/pricing | PricingPage | Yes | Plan comparison |
/search | SearchResultsPage | Yes | Unified search |
State Management
Pinia (stores/auth.ts): user, token, isAuthenticated, isPremium, fullName, initials, login(), logout(), fetchProfile()
TanStack Query: All API data fetched via useQuery with computed query keys for reactivity. Mutations use useMutation with onSuccess cache invalidation.
Design System (Tailwind)
rounded-[10px] border-[1.5px] border-border. Labels are text-[10px] font-bold uppercase tracking-[0.07em].