---
description: Structural reference for dashboard modules. Directory tree, naming conventions, module groups, where to put new code, and checklist. For invariants (principles, rules), see module-architecture-conventions.md.
paths:
  - "src/pages/dashboard/**"
---

# Module Architecture — Structure

Reference for organizing dashboard modules: how to name files, where to place code,
and how to set up new modules.

For the foundational rules (what is allowed/forbidden), see `module-architecture-conventions.md`.
For code patterns per file, see `module-architecture-files.md` and `module-architecture-hooks.md`.

---

## Location

```
src/pages/dashboard/{ModuleName}/
```

`{ModuleName}` in **PascalCase**. Example: `TimeOff`, `ServiceManagement`, `Goals`.

---

## Module structure

```
src/pages/dashboard/{ModuleName}/
│
├── index.tsx                  # (optional) Layout wrapper — providers, guards, helmet (uses <Outlet />)
├── README.md                  # Module documentation (REQUIRED)
│
├── routes.ts                  # Path factories + lazy loading per page
├── services.ts                # API calls (src/config/api)
├── queries.ts                 # Query key factory for react-query
├── types.ts                   # Module types/interfaces (or types/ folder)
├── constants.ts               # Module constants
├── utils.ts                   # Module-exclusive utilities
│
├── contexts/                  # Module contexts (optional)
│   ├── ModuleContext.ts       # createContext + useModuleContext hook
│   └── ModuleProvider.tsx     # Provider component
│
├── hooks/                     # Module-specific hooks
│   ├── useGet{Entity}.ts      # 1 wrapper hook per GET service
│   ├── use{Action}Mutation.ts # 1 wrapper hook per write service
│   └── use{CustomLogic}.ts    # Business logic hooks
│
├── components/                # Shared components within the module
│   ├── ModuleCard.tsx
│   └── ModuleFilters.tsx
│
├── {PageName}/                # Each subfolder = a module page/view
│   ├── index.tsx              # Page entry point (export default required)
│   ├── components/
│   ├── hooks/                 # (optional)
│   ├── types.ts               # (optional)
│   └── utils.ts               # (optional)
│
└── {OtherPage}/
    ├── index.tsx
    └── components/
```

---

## Naming conventions

### Folders

- **PascalCase** for all folders: modules (`Goals/`), pages (`GoalDetail/`), components (`SurveyConfigForm/`)
- One folder = one module, page, or main component

### Files

- **`index.tsx`**: Entry point of each page or component folder. Import the folder, not the file directly.
  `import GoalDetail from './GoalDetail'` instead of `import GoalDetail from './GoalDetail/GoalDetail'`.
- **`types.ts`**: Types for that folder
- **`constants.ts`**: Static config, select options, i18n keys
- **`utils.ts`**: Pure helpers (no hooks, no React)
- **`hooks/`**: React hooks for the module or page
- **`schemas.ts`**: Zod validation schemas (lives inside the Form folder — see `forms.md`)

### Components

- One main component per folder with `index.tsx` as entry
- Subcomponents in `components/` subfolder
- If a component is used by **two or more distinct modules**, move it to `src/components/`

---

## Module groups (special case)

When several related modules are grouped under a common root folder (e.g. `Learning`
containing `Courses`, `Paths`, `Sessions`, `Settings`), the root folder is a
**namespace/container**, not a module itself.

**Container rules:**

- Does NOT have its own `services.ts`, `queries.ts`, or `hooks/`
- Each subfolder is an independent module following the full architecture
- May have a `routes.ts` that composes route configs from sub-modules

```
src/pages/dashboard/Learning/          # Namespace — groups related modules
├── routes.ts                          # Composes sub-module route configs
├── Courses/                           # Independent module (full architecture)
│   ├── index.tsx
│   ├── routes.ts
│   ├── services.ts
│   ├── queries.ts
│   ├── types.ts
│   ├── hooks/
│   └── {Page}/
├── Paths/                             # Independent module
│   └── ...
├── Sessions/                          # Independent module
│   └── ...
└── Settings/                          # Independent module
    └── ...
```

**How to distinguish a sub-module from a page:**

| If the folder has... | It is... |
|---|---|
| Its own `services.ts` and/or `queries.ts` | Sub-module → apply full architecture |
| Only components that use parent services | Page → `{PageName}/index.tsx` |

---

## Module contexts

When the module needs shared state across several of its pages via React Context,
use `contexts/` in the module root (optional — only when needed):

```
{ModuleName}/
└── contexts/
    ├── ModuleContext.ts    # createContext + useModuleContext hook
    └── ModuleProvider.tsx  # Provider component
```

If the context is specific to a single page, it can live inside that page: `{PageName}/contexts/`.

---

## Where to put new code

| Adding... | Location |
|---|---|
| New page/feature | `{ModuleName}/{NewPage}/index.tsx` + `components/` |
| New component for a page | `{PageName}/components/{ComponentName}/index.tsx` |
| New form | `{PageName}/forms/{FormName}/` (one folder per form) |
| Validation schema | `{PageName}/forms/{FormName}/schemas.ts` (next to the form) |
| Schema shared across forms | `{PageName}/forms/shared/schemas.ts` |
| Types for a single page | `{PageName}/types.ts` |
| Module types | Module root `types.ts` or `types/{domain}.ts` (no barrel) |
| Module API | Module root `services.ts` or `services/{domain}.ts` (no barrel) |
| Module constants | Module root `constants.ts` |
| Module hook | `hooks/use{Name}.ts` |
| Page hook | `{PageName}/hooks/use{Name}.ts` |
| Module context | `contexts/ModuleContext.ts` + `contexts/ModuleProvider.tsx` |
| Page context | `{PageName}/contexts/` |

---

## Checklist for new modules

- [ ] Folder at `src/pages/dashboard/{ModuleName}/`
- [ ] `index.tsx` — (optional) layout wrapper with `<Outlet />` for providers/guards (NOT a barrel)
- [ ] `README.md` using `templates/module-readme.md`
- [ ] `routes.ts` with path factories + lazy loading per page
- [ ] Route config exported from `routes.ts` and imported in `src/routes.tsx`
- [ ] `services.ts` with API calls (using `src/config/api`)
- [ ] `queries.ts` with query key factory
- [ ] `types.ts` with domain types
- [ ] `constants.ts` (if applicable)
- [ ] `contexts/` if there is shared state between pages (optional)
- [ ] `hooks/` with query/mutation hooks (1:1 with services)
- [ ] `components/` for shared module components
- [ ] Page subfolders with `index.tsx` and `export default`
- [ ] Schemas inside `{PageName}/forms/{FormName}/schemas.ts` (not at the module root)
- [ ] No internal barrels in `services/`, `types/`, or `hooks/`
- [ ] No imports from other modules (`src/pages/dashboard/OtherModule/`)
- [ ] Services use `import api from 'src/config/api'` (NOT `src/utils/axios`)
