Modules (Frontend)
Overview
Frontend feature modules live in resources/js/modules/. Each module encapsulates a complete feature with its own components, store, services, API layer, and types — following the stores→services→api pattern.
Folder Structure
modules/landing/
├── setup/ # Feature: Setup wizard
│ └── form/
│ ├── Index.svelte # Entry point — minimal, pure composition
│ ├── api/ # API fetch functions
│ ├── parts/ # Sub-components (atomic design)
│ ├── services/ # Business logic
│ ├── stores/ # State management
│ │ └── entry/ # Store groups with barrel index.ts
│ ├── types/ # TypeScript interfaces
│ └── __tests__/ # Vitest tests
├── schools/ # Feature: School profiles
├── recruitment/ # Feature: Career portal
├── articles/ # Feature: News & articles
└── commons/ # Shared UI patterns
├── dropdown/ # Reusable dropdowns
├── language-switch/ # Language switcher
└── chatbot/ # Chatbot widgetThe stores→services→api Pattern
Every data flow follows this strict chain:
Component (Svelte)
↓ subscribe() + call action
Store (state management)
↓ delegate business logic
Service (orchestration)
↓ HTTP calls
API (fetch)
↓ network
Backend (Laravel)Layer Responsibilities
| Layer | Responsibility | Example |
|---|---|---|
| Component | Render UI, call store actions, subscribe to state | Index.svelte |
| Store | Manage StateContainer<TData>, expose getters/actions | super-user-form.stores.ts |
| Service | Orchestrate API calls, transform data | otp.services.ts |
| API | Pure HTTP fetch, typed responses | otp.api.ts |
Rules
- Never skip layers — component calls store, not service/API directly
- Store calls service, not API directly
- Service calls API, not fetch directly (SSE is the only exception)
Store Pattern
Every store uses StateContainer<TData> from @/types/state:
typescript
interface StateContainer<TData> {
meta: StateMeta; // loading, initialized, updatedAt, errorAt
data: TData; // domain data
errors: StateErrors; // validation errors
}Store File Naming
<action>-<module>.stores.tsExamples: fetch-bulletin.stores.ts, super-user-form.stores.ts, otp-form.stores.ts
Store Groups
Related stores are grouped in subdirectories with barrel index.ts:
stores/super-user-entry/
├── super-user-form.stores.ts
├── super-user-form-validation.stores.ts
└── index.ts // re-exports allCreating a New Module
bash
mkdir resources/js/modules/landing/{feature}/
mkdir resources/js/modules/landing/{feature}/api
mkdir resources/js/modules/landing/{feature}/parts
mkdir resources/js/modules/landing/{feature}/services
mkdir resources/js/modules/landing/{feature}/stores
mkdir resources/js/modules/landing/{feature}/types
mkdir resources/js/modules/landing/{feature}/__tests__Then create:
types/{module}.types.ts— Define data interfacesapi/{module}.api.ts— API fetch functionsservices/{module}.service.ts— Business logicstores/{module}.stores.ts— State management (StateContainer)parts/*.svelte— Sub-componentsIndex.svelte— Entry point
Key Files
| File | Purpose |
|---|---|
resources/js/lib/state.ts | StateContainer<TData> type definition |
resources/js/lib/i18n.svelte.ts | t() function for translations |
resources/js/modules/ | All feature modules |
resources/js/components/landing/ | Atomic design components |