Reorganize app workspaces and align Admin architecture
This commit is contained in:
+20
-20
@@ -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>
|
||||
);
|
||||
};
|
||||
```
|
||||
@@ -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).
|
||||
|
||||
@@ -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/`.
|
||||
+17
-15
@@ -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/`
|
||||
@@ -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` |
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user