Architecture
High-Level Architecture
Section titled “High-Level Architecture”Mindhyv follows a modular monolith architecture within a SvelteKit application. Each feature area is encapsulated in its own module under src/lib/modules/, with shared infrastructure in src/lib/.
src/├── routes/ # SvelteKit file-based routing│ ├── (app)/ # Authenticated app routes│ ├── (auth)/ # Authentication routes (public)│ ├── (goals)/ # Goal selection routes│ ├── (onboarding)/ # Onboarding flow│ ├── (public)/ # Public-facing pages│ └── api/ # API endpoints├── lib/│ ├── modules/ # Feature modules (self-contained)│ ├── components/ # Shared UI components│ ├── services/ # Shared services│ ├── stores/ # Shared state stores│ ├── types/ # Shared type definitions│ ├── schemas/ # Shared validation schemas│ ├── hooks/ # Svelte hooks│ ├── utils/ # Utility functions│ ├── data/ # Reference data (countries, languages, etc.)│ └── config.ts # App configurationModule Structure
Section titled “Module Structure”Each module in src/lib/modules/ follows a consistent internal structure:
modules/{module-name}/├── components/ # Svelte components specific to this module├── types/ # TypeScript interfaces and enums├── stores/ # Svelte 5 state managers (singletons)├── services/ # Business logic and Firebase operations├── schemas/ # Valibot validation schemas├── utils/ # Module-specific utilities└── index.ts # Public exportsDesign Patterns
Section titled “Design Patterns”Singleton Store Pattern
Section titled “Singleton Store Pattern”All state managers use a Singleton pattern with Svelte 5 runes:
class ManagerName { private static instance: ManagerName | null = null;
// Reactive state using Svelte 5 runes private _data = $derived(firekitDoc('collection/path')); public data = $derived(this._data?.data);
private constructor() {}
public static getInstance(): ManagerName { if (!ManagerName.instance) { ManagerName.instance = new ManagerName(); } return ManagerName.instance; }}
export const managerName = ManagerName.getInstance();Service Class Pattern
Section titled “Service Class Pattern”Services encapsulate Firebase operations and business logic:
export class ServiceName { private readonly basePath: string;
constructor(userId: string) { this.basePath = `users/${userId}`; }
async createItem(data: ItemType): Promise<void> { // Firestore operations via svelte-firekit }}Module Re-export Pattern
Section titled “Module Re-export Pattern”Each module exposes its public API through an index.ts barrel file:
import Component from "./components/component.svelte";export { Component };export { managerName } from "./stores/manager.svelte";export type { TypeName } from "./types/types";Route Groups
Section titled “Route Groups”SvelteKit route groups organize pages by authentication and layout requirements:
| Group | Path | Purpose | Auth Required |
|---|---|---|---|
(auth) | /sign-in, /sign-up, /forgot-password | Authentication pages | No |
(onboarding) | /onboarding | New user setup | Yes |
(goals) | /goals | Goal selection | Yes |
(app) | /dashboard, /hubs, /connect, etc. | Main application | Yes |
(public) | /public-profile/[id] | Public-facing pages | No |
api | /api/blogs, /api/stripe/* | Server API endpoints | Varies |
Data Flow
Section titled “Data Flow”User Action → Svelte Component → Store (Manager) → Service → Firebase (Firestore/Auth/Storage) ↓ Reactive UI Update ($derived)- Components dispatch actions to stores
- Stores hold reactive state via
$derivedfromfirekitDoc/firekitCollection - Services perform Firebase CRUD operations
- Firebase triggers real-time updates back to stores via svelte-firekit bindings
- Components reactively re-render via Svelte 5 runes
Authentication & Guard Flow
Section titled “Authentication & Guard Flow”Request → +layout.ts → AuthGuard → CustomGuard (registration approved?) ↓ CustomGuard (onboarding completed?) ↓ Route ComponentcheckRegistrationApproved()- Redirects to waiting-for-approve pagecheckOnboardingCompleted()- Redirects to onboarding page