Routing model
The React SPA is a client-side router on Cloudflare Pages. There is no Next.js file-based router — the map is explicit TypeScript.
Related: Permissions · Domains · Features.
Source of truth
| File | Role |
|---|---|
apps/web/src/router/AppRoutes.tsx | Canonical route tree |
apps/web/src/router/config/routeConfig.ts | Permission / access per path |
apps/web/src/router/guards/PermissionGuard.tsx | Enforces access around page elements |
Access is permission-based, not “which folder the page file lives in.”
Path conventions
| Area | Paths |
|---|---|
| Auth | /login, register / verify flows as defined in AppRoutes |
| Account / me | Shared account surfaces under agreed /me or settings paths |
| Users | /users, /users/new, /users/:id, activities as nested routes |
| Maintenance | /maintenance, create / detail under the same shared prefix |
| Departments | /departments, detail |
| System | /system/monitor, /system/logs, /system/audit, /system/settings |
| Role dashboards | Role-unique home/dashboard routes (not used for shared CRUD) |
Do not prefix shared CRUD with /admin or /hod — that duplicates pages and fights the permission model.
How a route is wired
- Page component lives under
domains/shared/pages/...or a role folder AppRoutesmounts it at a pathgetRouteAccess(path)supplies the access config- Element is wrapped:
<PermissionGuard access={access}>{element}</PermissionGuard>
SPA hosting notes
- Pages serves the SPA; unknown paths fall through to
index.htmlfor client routing - API calls go to
api.cepatedge.com(or local Worker), not to the Pages origin - Auth cookies must cover app + API hosts — see Domains
Maintainer checklist
- [ ] Path added to
AppRoutes - [ ] Access entry in
routeConfig - [ ] Page placed under shared vs role per domains
- [ ] Nav / sidebar entries only if the user can actually open the route