Reorganize app workspaces and align Admin architecture

This commit is contained in:
Igor Martyniuk
2026-07-17 13:46:21 +00:00
parent ba691d3a0c
commit 0ba01cd111
183 changed files with 3745 additions and 4354 deletions
+20 -20
View File
@@ -4,34 +4,34 @@ This is documentation home for the CRUX monorepo. Use it for system-level archit
## Monorepo Map
| Area | Source | Documentation |
| --------------- | --------------------------------------------------- | -------------------------------------------- |
| Backend API | `backend/` | Core module docs and backend-specific guides |
| Admin frontend | `apps/admin/` | [Admin app docs](./apps/admin/Readme.md) |
| Shared packages | `packages/` | [Packages index](./packages/Readme.md) |
| Devtools | `apps/admin/src/devtools/` | [Devtools docs](./devtools/Readme.md) |
| Core modules | `backend/app/base_modules/`, `apps/admin/src/core/` | [Core modules](#core-modules) |
| Future apps | `apps/*` | Add an app page under `docs/apps/` |
| Area | Source | Documentation |
| --------------- | -------------------------------------------------------- | -------------------------------------------- |
| Backend API | `apps/backend/` | Core module docs and backend-specific guides |
| Admin frontend | `apps/admin/` | [Admin app docs](./apps/admin/Readme.md) |
| Shared packages | `packages/` | [Packages index](./packages/Readme.md) |
| Devtools | `apps/admin/src/devtools/` | [Devtools docs](./devtools/Readme.md) |
| Core modules | `apps/backend/app/base_modules/`, `apps/admin/src/core/` | [Core modules](#core-modules) |
| Future apps | `apps/*` | Add an app page under `docs/apps/` |
## App Architecture
| Architecture | Scope | Documentation |
| -------------- | ------------------------------------------------- | --------------------------------------------------------------------------- |
| React frontend | Frontend apps and frontend modules under `apps/*` | [React frontend architecture](./apps-architecture/react-frontend/Readme.md) |
| Backend | AdonisJS backend apps and backend modules | [Backend architecture](./apps-architecture/backend/Readme.md) |
| Architecture | Scope | Documentation |
| -------------- | ------------------------------------------------- | ------------------------------------------------------------------ |
| React frontend | Frontend apps and frontend modules under `apps/*` | [React frontend architecture](./apps/admin/architecture/Readme.md) |
| Backend | AdonisJS backend apps and backend modules | [Backend architecture](./apps/backend/architecture/Readme.md) |
## Core Modules
Core modules are reusable admin panel areas that may have both backend and frontend implementations.
| Module | Backend | Frontend | Documentation |
| ---------------- | --------------------------------------- | -------------------------------------- | ----------------------------------------------------- |
| Access Control | Admin, Role, Permission base modules | `apps/admin/src/core/AccessControl/` | [Overview](./core-modules/access-control/Readme.md) |
| Account Settings | Admin profile endpoints | `apps/admin/src/core/AccountSettings/` | [Overview](./core-modules/account-settings/Readme.md) |
| Auth | `backend/app/base_modules/Auth/` | `apps/admin/src/core/Auth/` | [Overview](./core-modules/auth/Readme.md) |
| Fallback Screens | Frontend-only | `apps/admin/src/core/FallbackScreens/` | [Overview](./core-modules/fallback-screens/Readme.md) |
| File Manager | `backend/app/base_modules/FileManager/` | `apps/admin/src/core/FileManager/` | [Overview](./core-modules/file-manager/Readme.md) |
| Permission | Permission service and policies | `apps/admin/src/core/Permission/` | [Overview](./core-modules/permission/Readme.md) |
| Module | Backend | Frontend | Documentation |
| ---------------- | -------------------------------------------- | -------------------------------------- | ----------------------------------------------------- |
| Access Control | Admin, Role, Permission base modules | `apps/admin/src/core/AccessControl/` | [Overview](./core-modules/access-control/Readme.md) |
| Account Settings | Admin profile endpoints | `apps/admin/src/core/AccountSettings/` | [Overview](./core-modules/account-settings/Readme.md) |
| Auth | `apps/backend/app/base_modules/Auth/` | `apps/admin/src/core/Auth/` | [Overview](./core-modules/auth/Readme.md) |
| Fallback Screens | Frontend-only | `apps/admin/src/core/FallbackScreens/` | [Overview](./core-modules/fallback-screens/Readme.md) |
| File Manager | `apps/backend/app/base_modules/FileManager/` | `apps/admin/src/core/FileManager/` | [Overview](./core-modules/file-manager/Readme.md) |
| Permission | Permission service and policies | `apps/admin/src/core/Permission/` | [Overview](./core-modules/permission/Readme.md) |
Add a new page when the information has a stable owner. Keep temporary notes in issue trackers or task files until they are worth maintaining.
@@ -1,392 +0,0 @@
# CRUX React Frontend Architecture
This guide describes the recommended React frontend architecture for apps in the CRUX monorepo.
Its main goal is to make frontend development easier, more structured, and consistent across teams, so that every developer can write and understand each other's code quickly.
## Table of Contents
- [Base Concepts](#base-concepts)
- [Disclaimer](#disclaimer)
- [Core Principles](#core-principles)
- [Recommended Layering](#recommended-layering)
- [Architecture Scope](#architecture-scope)
- [Layer Dependency Rules](#layer-dependency-rules)
- [Entities Layer](#1-entities-layer)
- [Data Layer (Data Access Layer)](#2-data-layer-data-access-layer)
- [Purpose](#purpose)
- [Responsibilities](#responsibilities-2)
- [Rules and Guidelines](#rules-and-guidelines)
- [Infrastructure Layer](#infrastructure-layer)
- [Reference Data Layer](#reference-data-layer)
- [Providers Layer](#3-providers-layer)
- [Pages Layer](#4-pages-layer)
- [View Layer](#5-view-layer)
- [view/components/](#viewcomponents)
- [view/forms/](#viewforms)
- [view/widgets/](#viewwidgets)
- [Shared Layer](#6-shared-layer)
- [Responsibilities](#responsibilities-4)
- [Rules](#rules-2)
- [Full documentation](#full-documentation)
## Base Concepts
- **Purpose:** Provide a shared frontend foundation with predefined packages, utilities, and patterns for React apps and frontend modules in this monorepo.
- **Goals:**
- Reduce boilerplate code.
- Standardize folder structure, file naming, and coding practices in the company context.
- Assist in onboarding of new developers.
- **Included:**
- Preconfigured `React` + `TypeScript` setup.
- Common utilities and helper functions.
- Shared UI components, hooks, and state management helpers.
- Integrated i18n, form validation, and API utilities.
## Disclaimer
This architecture guide is intended as a **recommendation**, not a strict rulebook. **Feel free to adapt and modify it based on your team’s needs and project context**.
Key points to keep in mind:
1. **Maintainability comes first**.
The main goal of this structure is to help someone new to the project quickly understand where to make changes.
It’s about finding the right place to touch the code now, rather than strictly following a pattern for its own sake.
**Ultimately, the main goal is to make development easier for everyone**
2. **Naming debates are inevitable**.
Any architecture guide may spark discussions about file, folder, or function naming. Use this guide as a reference, but remember that practicality and clarity are more important than strict adherence.
3. **Flexibility is allowed**.
- You can adjust layers, module structure, or naming conventions if it improves readability or reduces complexity.
- New patterns or exceptions can be added as the project evolves.
In short: this guide exists to make the project easier to understand and maintain, not to create unnecessary friction. Use judgment and prioritize clarity over rigid consistency.
---
Цей посібник з архітектури є **рекомендацією**, а не суворим зводом правил. **Не соромтеся адаптувати та змінювати його відповідно до потреб вашої команди та контексту проєкту**.
Ключові моменти, які варто мати на увазі:
1. **Насамперед — зручність підтримки**.
Головна мета цієї структури — допомогти новому учаснику проєкту швидко зрозуміти, де вносити зміни.
Йдеться про те, щоб знайти правильне місце в коді просто зараз, а не сліпо дотримуватися патерну заради самого патерну.
**Зрештою, головна мета — зробити розробку простішою для всіх.**
2. **Дискусії щодо назв неминучі**.
Будь-який посібник з архітектури може спровокувати суперечки щодо назв файлів, папок або функцій. Використовуйте цей посібник як орієнтир, але пам'ятайте, що практичність і зрозумілість важливіші за суворе дотримання правил.
3. **Гнучкість допускається**.
- Ви можете коригувати шари, структуру модулів або угоди щодо найменування, якщо це покращує читабельність або зменшує складність.
- У міру розвитку проєкту можна додавати нові патерни або винятки.
Коротко: цей посібник існує для того, щоб проєкт був зрозумілішим і простішим у підтримці, а не для того, щоб створювати зайві труднощі. Керуйтеся здоровим глуздом і надавайте перевагу ясності, а не жорсткій послідовності.
## Core Principles
1. Blocks are composable and isolated
- Each block (component, form, widget) has a single responsibility.
- Higher-level blocks (widgets, pages) compose lower-level blocks.
2. Data vs. UI separation
- `data` handles API, state, and business data.
- `view` handles UI and interaction.
- No API logic in UI components — UI calls hooks from `data`.
3. Entities are global types/interfaces
- Placing them in `entities`.
- Any block (data hook, form, widget, page) can use these.
4. Shared
- shared/ = globally reusable components, hooks, utilities.
5. Infrastructure
- infrastructure/ = app-wide technical adapters such as HTTP clients, React Query, storage adapters, and formatting service wrappers.
6. Reference data
- refdata/ = app-wide API-backed lookup datasets shared by multiple modules.
## Recommended Layering
```plaintext
src/
├── data/ # API, react-query hooks, DTOs
├── entities/ # global types and interfaces
├── infrastructure/ # technical adapters: HTTP, query, storage, error handling
├── providers/ # global providers (router, query, session, i18n, theme)
├── refdata/ # API-backed common reference datasets
├── shared/ # reusable global components, hooks, libs, assets, styles
├── view/ # UI layer (blocks)
│ ├── components/ # Feature-level reusable components (ProductCard, LoginButton, VehicleSearchInput)
│ ├── forms/ # smart form components (ProductForm, UserForm)
│ └── widgets/ # composed smart, multi-entity components (DashboardStatsWidget, UserProfileWidget)
└── pages/ # route-level pages
```
## Architecture Scope
The layer structure can be used at three levels:
| Scope | Example | Meaning |
| --------------------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| App-level architecture | `apps/admin/src/app`, `apps/admin/src/shared` | Global app shell, providers, routing, layout, infrastructure, reusable app-wide building blocks. |
| Core module architecture | `apps/admin/src/core/FileManager` | Built-in product modules shipped with the admin template. Each large core module can own its own `data`, `entities`, `providers`, `pages`, `view`, and `shared`. |
| Project module architecture | `apps/admin/src/modules/*` | Generated or project-specific modules. Each module should follow the same layer rules inside its own folder when it becomes more than a simple page. |
For small modules, do not create empty layers only to match the template. Add a layer when the module has real ownership for that layer.
### Admin App Interpretation
`apps/admin` is a reusable admin panel template, not a simple single-purpose React app.
The app shell owns cross-cutting concerns:
- routing and route registration
- global providers
- layouts
- i18n setup
- shared UI
- technical infrastructure
- module registration
Admin app infrastructure that is shared by every module lives in `apps/admin/src/infrastructure`.
Examples include HTTP clients, React Query helpers, storage adapters, and error normalization.
Admin-wide API-backed reference datasets live in `apps/admin/src/refdata`.
Examples include country lists, common option datasets, and other reusable data that comes from the backend but is not owned by one feature module.
Each feature module owns its feature concerns:
- API calls and query hooks in module `data`
- module domain types in module `entities`
- module-local contexts and stores in module `providers`
- route-level screens in module `pages`
- module UI in module `view`
- module-only helpers in module `shared`
If a helper or component becomes useful across multiple modules, move it upward to `apps/admin/src/shared` or a package under `packages/`.
## Layer Dependency Rules
Each layer has defined set of layers it is allowed to import from.
Imports must only flow **downward** — a lower layer never knows about a higher one.
Violating this creates circular dependencies and couples layers that should be independent.
```mermaid
graph TD
pages["pages/"]
view["view/"]
data["data/"]
providers["providers/"]
infrastructure["infrastructure/"]
refdata["refdata/"]
entities["entities/"]
shared["shared/"]
pages --> view
pages --> data
pages --> refdata
pages --> providers
pages --> infrastructure
pages --> entities
pages --> shared
view --> data
view --> refdata
view --> infrastructure
view --> entities
view --> shared
refdata --> infrastructure
refdata --> shared
providers --> data
providers --> refdata
providers --> infrastructure
providers --> shared
data --> infrastructure
data --> entities
data --> shared
infrastructure --> shared
```
| Layer | Can import from |
| ----------------- | --------------------------------------------------------------------------- |
| `shared/` | nothing — zero app-layer dependencies |
| `entities/` | nothing — zero app-layer dependencies |
| `infrastructure/` | `shared/`, external packages, app runtime config |
| `refdata/` | `infrastructure/`, `shared/` |
| `data/` | `infrastructure/`, `entities/`, `shared/` |
| `providers/` | `infrastructure/`, `data/`, `refdata/`, `shared/` |
| `view/` | `data/`, `refdata/`, `entities/`, `shared/`, generic infrastructure helpers |
| `pages/` | all layers |
### Rules
1. **`shared/` has no imports** — it is infrastructure and UI primitives only. It must not reference any domain type or application layer. If a utility needs a domain type, it does not belong in `shared/`.
2. **`entities/` has no imports** — No logic, no React, no external libraries.
3. **`data/` never imports from `view/` or `pages/`** — data hooks and API functions are completely independent of the UI.
4. **`view/` never imports from `pages/`** — components, forms, and widgets do not depend on page-level composition.
5. **The boundary between `shared/ui/` and `view/components/` is enforced by this rule** — if a component needs to import from `entities/`, it cannot live in `shared/`.
6. **`infrastructure/` contains technical adapters, not feature logic** — HTTP clients, React Query, storage adapters, and formatting service wrappers live here.
7. **`refdata/` contains app-wide lookup data** — country lists, languages, currencies, and other shared backend datasets live here instead of inside one feature module.
### 1. **Entities** Layer
The `entities` layer contains global types and interfaces that define your domain models.
- Define entity types for your business objects: User, Product, Message
- Define enums or constants
- No Framework
- No API or hook logic
### 2. **Data** layer (Data Access Layer)
#### Purpose
The `data` layer is responsible for all interactions with external or internal data sources and state management hooks.
It is the only layer that knows how to fetch, mutate, and map data, while higher layers (`forms`, `widgets`, `pages`) just consume the hooks or data from this layer.
#### Responsibilities
- Handle API calls
- Provide React Query hooks or other state management hooks for data fetching/mutations
- Define DTOs (Data Transfer Objects)
- Provide DTO mappers (map raw API data to app entities or view models)
- Define types/interfaces specific to API responses
- Isolate side-effects like HTTP requests, error handling, or caching
#### Rules and Guidelines
1. Only data and state logic belongs here
- No UI, forms, or layout logic
2. Use React Query (or other state library) for fetching/mutations
- Expose hooks, not raw API functions, to the view layer
3. DTOs + Mappers
- Map API response to internal entities/ types
- Keep external API structure isolated from your app
- Mappers should be covered by unit tests because they define the data-layer contract between API DTOs and app entities
4. Types/Interfaces
- Define API-specific types
- Use entities/ for app-wide types
5. No direct imports from view/ or pages/
- data/ is completely independent
### Infrastructure Layer
The `infrastructure` layer contains app-wide technical adapters.
In the admin app, it lives in `apps/admin/src/infrastructure/`.
Examples:
- configured HTTP clients and interceptors
- React Query helpers, response types, and error normalization
- storage or browser adapters
- app-wide formatting service wrappers such as date and name formatters
This layer should stay feature-agnostic. Feature API modules should use infrastructure clients instead of creating their own clients.
### Reference Data Layer
The `refdata` layer contains app-wide reference datasets.
In the admin app, it lives in `apps/admin/src/refdata/`.
Examples:
- countries
- languages
- currencies
- time zones
- common option dictionaries
Use this layer for backend-backed lookup data shared by multiple modules. If the data belongs to one feature module, keep it in that module's `data/` layer.
### 3. **Providers** layer
The `providers` layer is responsible for global context, app-wide state, and services that need to be available throughout the React application.
It sets up everything that any component or page might need: routing, state management, internationalization, theme, notifications, etc.
### 4. **Pages** layer
- `pages` = the highest-level blocks
- Compose `widgets` + `forms` + `components` + `data` into full pages
- Only page-level layout, routing, and orchestration logic lives here
- Example: `UserPage` → uses `UserProfileWidget` + `UserActivityWidget`
### 5. **View** layer
1. **view/components/**
- “Dumb” components
- Pure UI, no business logic
- Example: `ProductCard`, `UserAvatar`
2. **view/forms/**
- Form components
- Encapsulate form state, validation, and submit logic
- Use hooks from `data/` for mutations/queries
- Example: `CreateProductForm` → uses `useCreateProduct()` from `data/hooks`
3. **view/widgets/**
- Composed components
- Combine `components` + `forms` + `shared/ui`
- Feature blocks that can be reused on multiple pages
- Example: `UserProfileWidget` → contains `UserAvatar`, `UserForm`, `UserStatsTable`
### 6. **Shared** layer
The `shared` layer contains global reusable building blocks for the frontend:
- Components, hooks, utilities, assets, styles
- Not tied to a specific feature or entity
- Can be used by `view`, `pages`, `widgets`, or `forms`
This is where common "Lego" blocks live.
#### Responsibilities
- Provide reusable UI components (`Button`, `Input`, `Modal`, `Card`)
- Provide reusable hooks (`useToggle`, `useDebounce`, `useLocalStorage`)
- Provide utility functions (`formatDate`, `errorHandler`, http helpers)
- Provide assets (icons, images, fonts)
- Provide global styles (CSS variables, global CSS, Tailwind overrides)
#### Rules
- Components here are dumb, reusable, feature-agnostic
- Hooks here are generic, not tied to a single entity or feature
- Assets can be imported anywhere
- Styles are global or utility-level, not component-specific
## Full documentation
- [Entities Layer](./layers/entities.md)
- [Data Layer](./layers/data.md)
- [Infrastructure Layer](./layers/infrastructure.md)
- [Reference Data Layer](./layers/refdata.md)
- [Providers Layer](./layers/providers.md)
- [View Layer](./layers/view.md)
- [Shared Layer](./layers/shared.md)
- [File & Folder Naming Convention](./naming.md)
@@ -1,96 +0,0 @@
# Providers Layer
## Table of Contents
- [Providers Layer](#providers-layer)
- [Purpose](#purpose)
- [Responsibilities](#responsibilities)
- [Recommended Structure](#recommended-structure)
- [App Provider Composition](#app-provider-composition)
- [Example: AppProviders](#example-appproviders)
## Purpose
The `providers` layer is responsible for **global application context and environment configuration**.
It acts as the **composition root of the application**, where all global React providers are initialized and combined.
Providers make global services available across the entire application, such as:
- routing
- data fetching clients
- theme configuration
- authentication/session context
- internationalization
- notifications
- global state management
Instead of importing these providers in many places, they are **composed once and applied at the application root**.
## Responsibilities
The `providers` layer is responsible for:
- initializing global React context providers
- configuring global services
- composing multiple providers into a single entry point
- exposing the provider tree to the application root
## Recommended Structure
```plaintext
providers/
|
| --- AppProviders.tsx # main provider composition
|
| --- QueryProvider.tsx # React Query setup
| --- RouterProvider.tsx # routing configuration
| --- ThemeProvider.tsx # theme context
| --- AuthProvider.tsx # authentication/session provider
| --- I18nProvider.tsx # internationalization provider
|
| --- index.ts # re-export providers (optional)
```
## App Provider Composition
Instead of wrapping the application with multiple providers manually, they are composed in a single root provider component.
This centralizes the provider tree and simplifies application initialization.
Example usage in the application entry point:
```tsx
import { AppProviders } from "@/providers/AppProviders";
ReactDOM.createRoot(document.getElementById("root")!).render(
<AppProviders>
<App />
</AppProviders>,
);
```
### Example: AppProviders
This component acts as the global application wrapper.
```tsx
import { ReactNode, FC, PropsWithChildren } from "react";
import { QueryProvider } from "./QueryProvider";
import { ThemeProvider } from "./ThemeProvider";
import { AuthProvider } from "./AuthProvider";
import { RouterProvider } from "./RouterProvider";
import { I18nProvider } from "./I18nProvider";
export const AppProviders: FC<PropsWithChildren> = ({ children }) => {
return (
<QueryProvider>
<I18nProvider>
<AuthProvider>
<ThemeProvider>
<RouterProvider>{children}</RouterProvider>
</ThemeProvider>
</AuthProvider>
</I18nProvider>
</QueryProvider>
);
};
```
+4 -74
View File
@@ -1,79 +1,9 @@
# Admin App Documentation
The admin app is a reusable React admin panel template. It includes the app shell, layouts, shared infrastructure, built-in core modules, development tools, and generated project modules.
Source root:
```txt
apps/admin/
```
Frontend architecture guide:
```txt
docs/apps-architecture/react-frontend/Readme.md
```
## Current Purpose
This page is a documentation stub. The admin app will be documented in more detail while its modules are migrated or aligned to the shared React frontend architecture.
For now, use this page to define ownership and the target documentation structure.
The admin app is a reusable React admin panel template.
It includes the app shell, layouts, shared infrastructure,
built-in core modules, development tools, and generated project modules.
## Architecture Direction
`apps/admin` follows the general React architecture described in [React Frontend Architecture](../../apps-architecture/react-frontend/Readme.md).
Because the admin app is a template and module host, the architecture applies at multiple levels:
1. App shell architecture under `apps/admin/src/app` and `apps/admin/src/shared`.
2. Core module architecture under `apps/admin/src/core/*`.
3. Generated or project module architecture under `apps/admin/src/modules/*`.
Large modules should be structured like small apps inside their own folder:
```txt
ModuleName/
config/
data/
entities/
providers/
pages/
shared/
view/
index.ts
```
Small modules may start with fewer folders. Add layers when the module actually owns API calls, entities, providers, pages, UI blocks, or module-only helpers.
## Source Areas
| Area | Path | Purpose |
| ----------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| App shell | `apps/admin/src/app/` | App routing, providers, layouts, i18n, styles, and global configuration. |
| Infrastructure | `apps/admin/src/infrastructure/` | HTTP, React Query helpers, storage adapters, and technical error handling shared by modules. |
| Reference data | `apps/admin/src/refdata/` | Common API-backed datasets and option lists that are not owned by a single feature module. |
| Core modules | `apps/admin/src/core/` | Built-in admin template modules such as File Manager, auth, account, permissions, dashboard, and admin management. |
| Generated modules | `apps/admin/src/modules/` | Project-specific or generated business modules. |
| Devtools | `apps/admin/src/devtools/` | Developer tools documented in the [Devtools guide](../../devtools/Readme.md). |
| Shared frontend | `apps/admin/src/shared/` | Admin-wide reusable UI, widgets, forms, editors, hooks, and pure utilities. |
## Module Documentation Plan
Each core module or generated module should eventually have documentation that covers:
1. Module purpose.
2. Source path.
3. Routes and pages.
4. Data layer API and query ownership.
5. Entities and DTO mapping.
6. Providers, stores, and local state ownership.
7. View widgets, forms, and reusable components.
8. Backend integration, if the module has backend routes.
9. Known migration gaps from the target architecture.
## Current Module Docs
| Module | Source | Docs |
| ------------ | ---------------------------------- | -------------------------------------------------------------------- |
| File Manager | `apps/admin/src/core/FileManager/` | [File Manager frontend](../../core-modules/file-manager/frontend.md) |
`apps/admin` follows the general React architecture described in [React Frontend Architecture](./architecture/Readme.md).
+126
View File
@@ -0,0 +1,126 @@
# CRUX React Admin Panel Architecture
## Table of Contents
- [Disclaimer](#disclaimer)
- [Core Principles](#core-principles)
- [Recommended Layering](#recommended-layering)
- [Architecture Scope](#architecture-scope)
- [Entities Layer](#1-entities-layer)
- [Data Layer (Data Access Layer)](#2-data-layer-data-access-layer)
- [Purpose](#purpose)
- [Responsibilities](#responsibilities-2)
- [Rules and Guidelines](#rules-and-guidelines)
- [Infrastructure Layer](#infrastructure-layer)
- [Reference Data Layer](#reference-data-layer)
- [App Layer](#3-app-layer)
- [Pages Layer](#4-pages-layer)
- [View Layer](#5-view-layer)
- [view/components/](#viewcomponents)
- [view/forms/](#viewforms)
- [view/widgets/](#viewwidgets)
- [Shared Layer](#6-shared-layer)
- [Responsibilities](#responsibilities-4)
- [Rules](#rules-2)
- [Full documentation](#full-documentation)
## Disclaimer
This architecture guide is intended as a **recommendation**, not a strict rulebook. **Feel free to adapt and modify it based on your team’s needs and project context**.
Key points to keep in mind:
1. **Maintainability comes first**.
The main goal of this structure is to help someone new to the project quickly understand where to make changes.
It’s about finding the right place to touch the code now, rather than strictly following a pattern for its own sake.
**Ultimately, the main goal is to make development easier for everyone**
2. **Naming debates are inevitable**.
Any architecture guide may spark discussions about file, folder, or function naming. Use this guide as a reference, but remember that practicality and clarity are more important than strict adherence.
3. **Flexibility is allowed**.
- You can adjust layers, module structure, or naming conventions if it improves readability or reduces complexity.
- New patterns or exceptions can be added as the project evolves.
In short: this guide exists to make the project easier to understand and maintain, not to create unnecessary friction. Use judgment and prioritize clarity over rigid consistency.
---
Цей посібник з архітектури є **рекомендацією**, а не суворим зводом правил. **Не соромтеся адаптувати та змінювати його відповідно до потреб вашої команди та контексту проєкту**.
Ключові моменти, які варто мати на увазі:
1. **Насамперед — зручність підтримки**.
Головна мета цієї структури — допомогти новому учаснику проєкту швидко зрозуміти, де вносити зміни.
Йдеться про те, щоб знайти правильне місце в коді просто зараз, а не сліпо дотримуватися патерну заради самого патерну.
**Зрештою, головна мета — зробити розробку простішою для всіх.**
2. **Дискусії щодо назв неминучі**.
Будь-який посібник з архітектури може спровокувати суперечки щодо назв файлів, папок або функцій. Використовуйте цей посібник як орієнтир, але пам'ятайте, що практичність і зрозумілість важливіші за суворе дотримання правил.
3. **Гнучкість допускається**.
- Ви можете коригувати шари, структуру модулів або угоди щодо найменування, якщо це покращує читабельність або зменшує складність.
- У міру розвитку проєкту можна додавати нові патерни або винятки.
Коротко: цей посібник існує для того, щоб проєкт був зрозумілішим і простішим у підтримці, а не для того, щоб створювати зайві труднощі. Керуйтеся здоровим глуздом і надавайте перевагу ясності, а не жорсткій послідовності.
## Core Principles
1. Blocks are composable and isolated
- Each block (component, form, widget) has a single responsibility.
- Higher-level blocks (widgets, pages) compose lower-level blocks.
2. Data vs. UI separation
- `data` handles API, state, and business data.
- `view` handles UI and interaction.
- No API logic in UI components — UI calls hooks from `data`.
3. Entities are global types/interfaces
- Placing them in `entities`.
- Any block (data hook, form, widget, page) can use these.
4. Shared
- shared/ = globally reusable components, hooks, utilities.
5. Infrastructure
- infrastructure/ = app-wide technical adapters such as HTTP clients, React Query, storage adapters, and formatting service wrappers.
6. Reference data
- refdata/ = app-wide API-backed lookup datasets shared by multiple modules.
## Recommended Layering
```plaintext
src/
├── app/ # composition root: providers, routing, config, i18n, layouts
├── infrastructure/ # technical adapters: HTTP, query, storage, error handling
├── refdata/ # API-backed common reference datasets
├── shared/ # reusable app-wide UI, hooks, utilities, and widgets
├── core/ # built-in product modules
├── modules/ # project-specific modules
└── devtools/ # development-only modules and tools
```
## Architecture Scope
The layer structure can be used at three levels:
| Scope | Example | Meaning |
| --------------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| App-level architecture | `apps/admin/src/app`, `apps/admin/src/shared` | Global app shell, providers, routing, layout, infrastructure, reusable app-wide building blocks. |
| Core module architecture | `apps/admin/src/core/FileManager` | Built-in product modules shipped with the admin template. Each large core module can own its own `data`, `entities`, `pages`, `view`, and `shared`, plus feature-scoped context when needed. |
| Project module architecture | `apps/admin/src/modules/*` | Generated or project-specific modules. Each module should follow the same layer rules inside its own folder when it becomes more than a simple page. |
For small modules, do not create empty layers only to match the template. Add a layer when the module has real ownership for that layer.
## Full documentation
- [Entities Layer](./layers/entities.md)
- [Data Layer](./layers/data.md)
- [App Layer](./layers/app.md)
- [Infrastructure Layer](./layers/infrastructure.md)
- [Reference Data Layer](./layers/refdata.md)
- [View Layer](./layers/view.md)
- [Shared Layer](./layers/shared.md)
- [File & Folder Naming Convention](./naming.md)
@@ -0,0 +1,83 @@
# App Layer
## Purpose
The `app` layer is the composition root of the Admin application. It owns the concerns
that exist once for the whole app and coordinates lower-level layers and feature
modules without containing feature business logic.
Global React providers belong inside `app/providers/`. They are an implementation
detail of the app layer, not a separate architectural layer.
## Responsibilities
- Compose global React providers in one root component.
- Configure application-wide settings and environment-derived values.
- Initialize internationalization and global styles.
- Define top-level routing and connect routes registered by modules.
- Provide application layouts, navigation, and menu composition.
- Register core, project, and development modules with the app shell.
## Current Structure
```plaintext
app/
├── config/ # global settings, environment values, and config types
├── css/ # global styles and app-level third-party overrides
├── i18n/ # languages, messages, and internationalization config
├── layouts/ # top-level Admin layout variants
├── providers/ # providers composed once for the entire application
│ ├── AppProviders.tsx
│ ├── I18nProvider.tsx
│ ├── QueryProvider.tsx
│ ├── SettingsProvider.tsx
│ └── ThemeProvider.tsx
├── routing/
│ ├── AppRouting.tsx
│ └── AppRoutingSetup.tsx
├── services/
│ └── modules/ # module registry, routes, menus, and messages
└── menu.tsx # app-level menu composition
```
The exact files may evolve, but their ownership should remain app-wide. A concern
used by only one feature belongs to that feature module instead.
## Global Providers
`app/providers/AppProviders.tsx` is the single provider composition point. The
current provider tree supplies:
- TanStack Query configuration and error handling
- authentication context from the Auth core module
- application settings
- shared tooltip and notification UI
- theme state
- internationalization and text direction
- React Router with the configured base URL
## Routing
`app/routing/` owns top-level route composition. It connects the application shell
to routes contributed by registered modules. Feature pages and route-specific logic
remain inside their owning modules.
## Configuration and Internationalization
- `app/config/` owns global settings, application metadata, and configuration types.
- `app/i18n/` owns supported languages, translated messages, and i18n configuration.
- Environment access should be centralized through app configuration instead of
being repeated throughout feature code.
## Layouts and Global CSS
`app/layouts/` contains the Admin shell variants. `app/css/` contains global styles,
layout styles, and app-wide overrides for third-party components. Feature-specific
styles should stay with the feature that owns them.
## Module Registration
`app/services/modules/` integrates modules into the application through their
routes, menus, and translated messages. It is integration code owned by the app
shell; module implementation details remain under `core/`, `modules/`, or
`devtools/`.
@@ -18,8 +18,6 @@
We follow **standard React community naming conventions**:
These conventions apply to frontend apps and to module folders inside those apps. For example, `apps/admin/src/core/FileManager` may use PascalCase because it is a product module folder, while its layer folders such as `data`, `entities`, `providers`, `pages`, `view`, and `shared` stay lowercase.
| Type | Convention | Example |
| ---------------------- | -------------------------------------------- | ------------------------------------- |
| Folders | lowercase (PascalCase for component folders) | `user/`, `shared/`, `CreateUserForm/` |
@@ -39,13 +37,13 @@ Component, form, and widget folders use **PascalCase** — matching the componen
```
src/
data/ # lowercase — layer folder
user/ # lowercase — entity folder
data/ # lowercase — layer folder
user/ # lowercase — entity folder
product/
view/ # lowercase — layer folder
view/ # lowercase — layer folder
components/
forms/
CreateUserForm/ # PascalCase — component folder
CreateUserForm/ # PascalCase — component folder
widgets/
UserProfileWidget/
shared/
@@ -147,17 +145,21 @@ data/
└── productMapper.ts
```
#### `providers/`
#### `app/`
```plaintext
providers/
├── AppProviders.tsx
├── QueryProvider.tsx
├── RouterProvider.tsx
├── ThemeProvider.tsx
├── AuthProvider.tsx
├── I18nProvider.tsx
└── index.ts
app/
├── config/
├── i18n/
├── layouts/
├── providers/
│ ├── AppProviders.tsx
│ ├── I18nProvider.tsx
│ ├── QueryProvider.tsx
│ ├── SettingsProvider.tsx
│ └── ThemeProvider.tsx
├── routing/
└── services/
```
#### `view/`
+7 -7
View File
@@ -9,10 +9,10 @@ The Access Control module manages admin accounts, roles, and permissions in the
| Frontend module | `apps/admin/src/core/AccessControl/` |
| Frontend routes | `apps/admin/src/core/AccessControl/config/routing.tsx` |
| Frontend translations | `apps/admin/src/core/AccessControl/config/translation/` |
| Backend admin module | `backend/app/base_modules/Admin/` |
| Backend role module | `backend/app/base_modules/Role/` |
| Backend permission module | `backend/app/base_modules/Permission/` |
| Permission loader | `backend/app/services/permission_service.ts` |
| Backend admin module | `apps/backend/app/base_modules/Admin/` |
| Backend role module | `apps/backend/app/base_modules/Role/` |
| Backend permission module | `apps/backend/app/base_modules/Permission/` |
| Permission loader | `apps/backend/app/services/permission_service.ts` |
## Documentation
@@ -46,8 +46,8 @@ The Access Control module manages admin accounts, roles, and permissions in the
| Add an admin field | `entities/AdminEntity.ts`, `data/api/dto.ts`, `data/mappers/AdminMapper.ts`, `view/forms/AdminForm/` |
| Change admin list columns | `view/widgets/AdminTable.tsx` |
| Change role form behavior | `view/forms/RoleForm/` |
| Add a new permission source | Backend module `config/permissions.ts` and `backend/app/services/permission_service.ts` |
| Add a new permission source | Backend module `config/permissions.ts` and `apps/backend/app/services/permission_service.ts` |
| Change cache invalidation | `data/queries/cache.ts` |
| Change translations | `config/translation/en.json` and `config/translation/uk.json` |
| Change backend admin API | `backend/app/base_modules/Admin/controller/admin_controller.ts` |
| Change backend role API | `backend/app/base_modules/Role/controller/role_controller.ts` |
| Change backend admin API | `apps/backend/app/base_modules/Admin/controller/admin_controller.ts` |
| Change backend role API | `apps/backend/app/base_modules/Role/controller/role_controller.ts` |
+14 -14
View File
@@ -3,9 +3,9 @@
Access Control frontend uses three backend base modules:
```txt
backend/app/base_modules/Admin/
backend/app/base_modules/Role/
backend/app/base_modules/Permission/
apps/backend/app/base_modules/Admin/
apps/backend/app/base_modules/Role/
apps/backend/app/base_modules/Permission/
```
## Routes
@@ -32,16 +32,16 @@ All routes use `middleware.auth()` except login routes owned by Auth.
Policies:
```txt
backend/app/base_modules/Admin/policy/admin_policy.ts
backend/app/base_modules/Role/policy/role_policy.ts
backend/app/base_modules/Permission/policy/permission_policy.ts
apps/backend/app/base_modules/Admin/policy/admin_policy.ts
apps/backend/app/base_modules/Role/policy/role_policy.ts
apps/backend/app/base_modules/Permission/policy/permission_policy.ts
```
Permission slugs are defined in:
```txt
backend/app/base_modules/Admin/config/permissions.ts
backend/app/base_modules/Role/config/permissions.ts
apps/backend/app/base_modules/Admin/config/permissions.ts
apps/backend/app/base_modules/Role/config/permissions.ts
```
Current AccessControl slugs:
@@ -62,7 +62,7 @@ role.delete
Available permissions are collected by:
```txt
backend/app/services/permission_service.ts
apps/backend/app/services/permission_service.ts
```
`getAllPermissions()` scans `app/base_modules/*/config/permissions.ts` and `app/modules/*/config/permissions.ts`. Add permissions to the owning backend module config; do not hard-code them in the frontend.
@@ -72,11 +72,11 @@ backend/app/services/permission_service.ts
Validators:
```txt
backend/app/base_modules/Admin/validators/admin_create_validator.ts
backend/app/base_modules/Admin/validators/admin_update_validator.ts
backend/app/base_modules/Admin/validators/admin_update_profile_validator.ts
backend/app/base_modules/Role/validator/role_create_validator.ts
backend/app/base_modules/Role/validator/role_update_validator.ts
apps/backend/app/base_modules/Admin/validators/admin_create_validator.ts
apps/backend/app/base_modules/Admin/validators/admin_update_validator.ts
apps/backend/app/base_modules/Admin/validators/admin_update_profile_validator.ts
apps/backend/app/base_modules/Role/validator/role_create_validator.ts
apps/backend/app/base_modules/Role/validator/role_update_validator.ts
```
Keep frontend form rules compatible with backend validators. Backend validation is authoritative.
+8 -8
View File
@@ -4,14 +4,14 @@ The Account Settings module provides the current admin user's profile settings s
## Source Map
| Area | Path |
| ------------------------- | ----------------------------------------------------------------------------- |
| Frontend module | `apps/admin/src/core/AccountSettings/` |
| Frontend routes | `apps/admin/src/core/AccountSettings/config/routing.tsx` |
| Frontend translations | `apps/admin/src/core/AccountSettings/config/translation/` |
| Auth provider dependency | `apps/admin/src/core/Auth/providers/AuthProvider/` |
| Backend profile endpoint | `backend/app/base_modules/Admin/controller/admin_controller.ts` |
| Backend profile validator | `backend/app/base_modules/Admin/validators/admin_update_profile_validator.ts` |
| Area | Path |
| ------------------------- | ---------------------------------------------------------------------------------- |
| Frontend module | `apps/admin/src/core/AccountSettings/` |
| Frontend routes | `apps/admin/src/core/AccountSettings/config/routing.tsx` |
| Frontend translations | `apps/admin/src/core/AccountSettings/config/translation/` |
| Auth provider dependency | `apps/admin/src/core/Auth/providers/AuthProvider/` |
| Backend profile endpoint | `apps/backend/app/base_modules/Admin/controller/admin_controller.ts` |
| Backend profile validator | `apps/backend/app/base_modules/Admin/validators/admin_update_profile_validator.ts` |
## Documentation
@@ -11,8 +11,8 @@ Account Settings does not have a separate backend base module. It uses the Admin
Source:
```txt
backend/app/base_modules/Admin/routes.ts
backend/app/base_modules/Admin/controller/admin_controller.ts
apps/backend/app/base_modules/Admin/routes.ts
apps/backend/app/base_modules/Admin/controller/admin_controller.ts
```
The route uses `middleware.auth()`.
@@ -35,7 +35,7 @@ PUT /admin/update-profile
Validator:
```txt
backend/app/base_modules/Admin/validators/admin_update_profile_validator.ts
apps/backend/app/base_modules/Admin/validators/admin_update_profile_validator.ts
```
Keep frontend validation compatible with this validator. Backend validation is authoritative.
+9 -9
View File
@@ -4,15 +4,15 @@ The Auth module owns admin authentication, current-user state, token persistence
## Source Map
| Area | Path |
| --------------------- | -------------------------------------------------- |
| Frontend module | `apps/admin/src/core/Auth/` |
| Frontend routes | `apps/admin/src/core/Auth/config/routing.tsx` |
| Frontend provider | `apps/admin/src/core/Auth/providers/AuthProvider/` |
| Frontend translations | `apps/admin/src/core/Auth/config/translation/` |
| Backend module | `backend/app/base_modules/Auth/` |
| Backend admin model | `backend/app/base_modules/Admin/model/admin.ts` |
| Auth config | `backend/config/auth.ts` |
| Area | Path |
| --------------------- | ---------------------------------------------------- |
| Frontend module | `apps/admin/src/core/Auth/` |
| Frontend routes | `apps/admin/src/core/Auth/config/routing.tsx` |
| Frontend provider | `apps/admin/src/core/Auth/providers/AuthProvider/` |
| Frontend translations | `apps/admin/src/core/Auth/config/translation/` |
| Backend module | `apps/backend/app/base_modules/Auth/` |
| Backend admin model | `apps/backend/app/base_modules/Admin/model/admin.ts` |
| Auth config | `apps/backend/config/auth.ts` |
## Documentation
+5 -5
View File
@@ -5,7 +5,7 @@ The backend Auth module exposes token-based admin authentication routes.
Source root:
```txt
backend/app/base_modules/Auth/
apps/backend/app/base_modules/Auth/
```
## Routes
@@ -19,7 +19,7 @@ backend/app/base_modules/Auth/
Route file:
```txt
backend/app/base_modules/Auth/routes.ts
apps/backend/app/base_modules/Auth/routes.ts
```
## Request Flow
@@ -51,7 +51,7 @@ GET /auth/user
Login validator:
```txt
backend/app/base_modules/Auth/validators/auth_login_validator.ts
apps/backend/app/base_modules/Auth/validators/auth_login_validator.ts
```
Current rules:
@@ -64,13 +64,13 @@ Current rules:
Auth config:
```txt
backend/config/auth.ts
apps/backend/config/auth.ts
```
The admin model is configured as the token user provider:
```txt
backend/app/base_modules/Admin/model/admin.ts
apps/backend/app/base_modules/Admin/model/admin.ts
```
## Response Contracts
+9 -9
View File
@@ -6,14 +6,14 @@ renaming, deleting, duplicating, and editing supported files.
## Source Map
| Area | Path |
| ---------------------- | ------------------------------------------------------------------------------------- |
| Backend module | `backend/app/base_modules/FileManager/` |
| Backend storage config | `backend/config/drive.ts` |
| Backend S3 adapter | `backend/app/base_modules/FileManager/services/storage_service/s3_storage_service.ts` |
| Frontend module | `apps/admin/src/core/FileManager/` |
| Frontend file assets | `apps/admin/public/media/files/` |
| Frontend routes | `apps/admin/src/core/FileManager/config/routing.tsx` |
| Area | Path |
| ---------------------- | ------------------------------------------------------------------------------------------ |
| Backend module | `apps/backend/app/base_modules/FileManager/` |
| Backend storage config | `apps/backend/config/drive.ts` |
| Backend S3 adapter | `apps/backend/app/base_modules/FileManager/services/storage_service/s3_storage_service.ts` |
| Frontend module | `apps/admin/src/core/FileManager/` |
| Frontend file assets | `apps/admin/public/media/files/` |
| Frontend routes | `apps/admin/src/core/FileManager/config/routing.tsx` |
## Documentation
@@ -92,7 +92,7 @@ The frontend maps DTOs into frontend entities and adds UI-oriented metadata such
| Change | Start Here |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Add or change an API route | `backend/app/base_modules/FileManager/routes.ts` and `controller/file_manager_controller.ts` |
| Add or change an API route | `apps/backend/app/base_modules/FileManager/routes.ts` and `controller/file_manager_controller.ts` |
| Change path validation or naming rules | `services/path_service.ts` |
| Change list filtering, sorting, or pagination | `services/entry_list_service.ts` and frontend query payloads |
| Add or change a storage backend | `services/storage_service/storage_service_interface.ts`, `create_storage_service.ts`, and [Backend storage docs](./backend.md#storage) |
+2 -2
View File
@@ -5,7 +5,7 @@ The backend module exposes authenticated file operations under `/file-manager`.
Source root:
```txt
backend/app/base_modules/FileManager/
apps/backend/app/base_modules/FileManager/
```
## Request Flow
@@ -252,7 +252,7 @@ DRIVE_DISK=s3
Adonis Drive config lives in:
```txt
backend/config/drive.ts
apps/backend/config/drive.ts
```
Configured disks:
+1 -1
View File
@@ -5,7 +5,7 @@ uploads, deletion, duplication, renaming, image editing tools, image map tools,
reusable file picker widgets.
This module follows the general
[React frontend architecture](../../apps-architecture/react-frontend/Readme.md) inside its own
[React frontend architecture](../../apps/admin/architecture/Readme.md) inside its own
module boundary.
Source root:
+2 -2
View File
@@ -10,8 +10,8 @@ The Permission module provides frontend permission checks and gates. It also cor
| Frontend gates | `apps/admin/src/core/Permission/view/gates/` |
| Frontend hook | `apps/admin/src/core/Permission/hooks/usePermissions.ts` |
| Frontend types | `apps/admin/src/core/Permission/entities/permission.ts` |
| Backend module | `backend/app/base_modules/Permission/` |
| Backend permission service | `backend/app/services/permission_service.ts` |
| Backend module | `apps/backend/app/base_modules/Permission/` |
| Backend permission service | `apps/backend/app/services/permission_service.ts` |
## Documentation
+8 -8
View File
@@ -5,7 +5,7 @@ The backend Permission module exposes available permission definitions. It is us
Source root:
```txt
backend/app/base_modules/Permission/
apps/backend/app/base_modules/Permission/
```
## Route
@@ -17,7 +17,7 @@ backend/app/base_modules/Permission/
Route file:
```txt
backend/app/base_modules/Permission/routes.ts
apps/backend/app/base_modules/Permission/routes.ts
```
## Request Flow
@@ -36,14 +36,14 @@ GET /permission
Permission discovery lives in:
```txt
backend/app/services/permission_service.ts
apps/backend/app/services/permission_service.ts
```
`getAllPermissions()` scans:
```txt
backend/app/base_modules/*/config/permissions.ts
backend/app/modules/*/config/permissions.ts
apps/backend/app/base_modules/*/config/permissions.ts
apps/backend/app/modules/*/config/permissions.ts
```
Each config exports permission items:
@@ -60,9 +60,9 @@ type PermissionItem = {
Core permission definitions currently include:
```txt
backend/app/base_modules/Admin/config/permissions.ts
backend/app/base_modules/Role/config/permissions.ts
backend/app/base_modules/FileManager/config/permissions.ts
apps/backend/app/base_modules/Admin/config/permissions.ts
apps/backend/app/base_modules/Role/config/permissions.ts
apps/backend/app/base_modules/FileManager/config/permissions.ts
```
When adding a feature that needs access control, add permission definitions to the owning backend module's `config/permissions.ts`.
+14 -14
View File
@@ -6,21 +6,21 @@ The generator is intended to produce a maintainable starting point. Generated au
## Source Ownership
| Part | Source |
| ------------------------------- | ---------------------------------------------- |
| Generator page and form | `apps/admin/src/devtools/` |
| Copied frontend module template | `apps/admin/src/modules/_template/` |
| Generator HTTP endpoints | `backend/start/routes.ts` |
| Generator controller | `backend/app/controllers/module_controller.ts` |
| Database inspection | `backend/app/services/database_inspector.ts` |
| Backend Handlebars templates | `backend/app/templates/backend/` |
| Frontend Handlebars templates | `backend/app/templates/frontend/` |
| Part | Source |
| ------------------------------- | --------------------------------------------------- |
| Generator page and form | `apps/admin/src/devtools/` |
| Copied frontend module template | `apps/admin/src/modules/_template/` |
| Generator HTTP endpoints | `apps/backend/start/routes.ts` |
| Generator controller | `apps/backend/app/controllers/module_controller.ts` |
| Database inspection | `apps/backend/app/services/database_inspector.ts` |
| Backend Handlebars templates | `apps/backend/app/templates/backend/` |
| Frontend Handlebars templates | `apps/backend/app/templates/frontend/` |
See [frontend.md](./frontend.md) for the UI, payload builders, and generated frontend architecture. See [backend.md](./backend.md) for endpoints, database inspection, templates, and generated backend files. If generated files are not loaded or the module is missing from the menu, use the [troubleshooting guide](./troubleshooting.md).
## Prerequisites
1. Run the backend from the `backend/` workspace. The controller resolves backend and frontend destinations relative to `process.cwd()`.
1. Run the backend from the `apps/backend/` workspace. The controller resolves backend and frontend destinations relative to `process.cwd()`.
2. Run the admin app with dev mode enabled so the devtools module is registered.
3. Authenticate in the admin app. All generator endpoints use authentication middleware.
4. Create and migrate the source database table before opening the generator. The form reads tables and columns from PostgreSQL `information_schema`.
@@ -45,12 +45,12 @@ The generator first copies the complete frontend template, then overwrites gener
## Generated Locations
```txt
backend/modules/<ModuleName>/
backend/tests/modules/<ModuleName>/
apps/backend/modules/<ModuleName>/
apps/backend/tests/modules/<ModuleName>/
apps/admin/src/modules/<name>/
```
Frontend modules are discovered automatically through their `config/module.ts` manifest. Backend module routes and API routes are loaded automatically from `backend/modules/` during application startup.
Frontend modules are discovered automatically through their `config/module.ts` manifest. Backend module routes and API routes are loaded automatically from `apps/backend/modules/` during application startup.
## Important Operational Behavior
@@ -75,4 +75,4 @@ After generating a module:
For restart, module-discovery, permission, and menu problems, see [Troubleshooting](./troubleshooting.md).
The generated frontend structure follows the [React frontend architecture](../../apps-architecture/react-frontend/Readme.md). Backend modules should be reviewed against the [backend architecture](../../apps-architecture/backend/Readme.md).
The generated frontend structure follows the [React frontend architecture](../../apps/admin/architecture/Readme.md). Backend modules should be reviewed against the [backend architecture](../../apps/backend/architecture/Readme.md).
+7 -7
View File
@@ -4,7 +4,7 @@ The backend generator exposes authenticated schema-inspection and generation end
## Endpoints
Routes are registered in `backend/start/routes.ts`.
Routes are registered in `apps/backend/start/routes.ts`.
| Method | Path | Controller method | Purpose |
| ------ | ---------------------------- | ----------------- | -------------------------------------------------- |
@@ -16,7 +16,7 @@ All three endpoints use `middleware.auth()`.
## Database Inspection
`backend/app/services/database_inspector.ts` reads PostgreSQL `information_schema`.
`apps/backend/app/services/database_inspector.ts` reads PostgreSQL `information_schema`.
- Table discovery is limited to the `public` schema.
- framework, authentication, access-control, migration, and PostgreSQL system tables are excluded.
@@ -45,7 +45,7 @@ Nullable database columns receive `| null` in generated model/entity types and o
For module name `<name>`, table `<table>`, and derived module class `<ModuleName>`, selected assets are written under:
```txt
backend/modules/<ModuleName>/
apps/backend/modules/<ModuleName>/
├── api/
│ ├── controllers/<entity>_api_controller.ts
│ ├── validators/<entity>_create_api_validator.ts
@@ -63,7 +63,7 @@ backend/modules/<ModuleName>/
Tests are written under:
```txt
backend/tests/modules/<ModuleName>/
apps/backend/tests/modules/<ModuleName>/
├── <entity>.spec.ts
└── <entity>.api.spec.ts
```
@@ -74,7 +74,7 @@ backend/tests/modules/<ModuleName>/
### Model
Renders `backend/app/templates/backend/model.hbs` with columns, inferred relationships, searchable fields, and optional password hashing.
Renders `apps/backend/app/templates/backend/model.hbs` with columns, inferred relationships, searchable fields, and optional password hashing.
### Controller and routes
@@ -86,7 +86,7 @@ Creates separate create and update Vine validators. Primary keys and timestamp/d
### Policy and permissions
Creates a Bouncer policy with view/create/update/delete checks, creates `config/permissions.ts`, and adds a lazy policy import to `backend/app/policies/main.ts` when missing.
Creates a Bouncer policy with view/create/update/delete checks, creates `config/permissions.ts`, and adds a lazy policy import to `apps/backend/app/policies/main.ts` when missing.
Permission slugs are derived from the module name, for example:
@@ -123,7 +123,7 @@ The controller registers Handlebars helpers for `eq`, `not`, `or`, and `and`. Ne
## Extending the Backend Generator
1. Add or update a Handlebars template under `backend/app/templates/`.
1. Add or update a Handlebars template under `apps/backend/app/templates/`.
2. Add an explicit destination path in the controller `paths` object.
3. Create its parent directory through the existing path initialization.
4. Render only when the corresponding asset is selected.
+1 -1
View File
@@ -132,6 +132,6 @@ When adding a new generated frontend artifact:
2. Add UI controls to `ModuleGeneratorForm`.
3. Add a focused builder under `data/builders/` if the artifact contains dynamic source.
4. Add the payload field to `GenerateModulePayload` and `buildGenerateModulePayload`.
5. Accept and write the field in `backend/app/controllers/module_controller.ts`.
5. Accept and write the field in `apps/backend/app/controllers/module_controller.ts`.
6. Add the static structure to `apps/admin/src/modules/_template/` when every module needs it.
7. Verify generation with and without the new asset selected.
@@ -20,7 +20,7 @@ Check for TypeScript errors, invalid generated imports, route-loading failures,
The restart is necessary because:
- the backend discovers generated route files under `backend/modules/` during startup;
- the backend discovers generated route files under `apps/backend/modules/` during startup;
- the admin app discovers `apps/admin/src/modules/**/config/module.ts` through Vite's module registry;
- adding an entirely new directory may not trigger the same reload behavior as editing an existing file.
@@ -33,7 +33,7 @@ If generation succeeded and both services restarted, a missing menu item usually
Check the generated backend permissions:
```txt
backend/modules/<ModuleName>/config/permissions.ts
apps/backend/modules/<ModuleName>/config/permissions.ts
```
Check the frontend permission constants:
@@ -112,7 +112,7 @@ npm run build:admin
Then verify:
1. `backend/modules/<ModuleName>/` exists and contains the selected backend assets.
1. `apps/backend/modules/<ModuleName>/` exists and contains the selected backend assets.
2. `apps/admin/src/modules/<name>/` exists and contains a valid module manifest.
3. Docker services or local development processes were restarted.
4. Backend and frontend permission slugs match.