Initial commit
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
# Infrastructure Layer
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Purpose](#purpose)
|
||||
- [Responsibilities](#responsibilities)
|
||||
- [Recommended Structure](#recommended-structure)
|
||||
- [Rules](#rules)
|
||||
- [Examples](#examples)
|
||||
|
||||
## Purpose
|
||||
|
||||
The `infrastructure/` layer contains app-wide technical adapters and integration helpers.
|
||||
|
||||
Use this layer for code that connects the frontend application to technical systems or shared runtime services, not for feature-specific business logic.
|
||||
|
||||
## Responsibilities
|
||||
|
||||
The `infrastructure/` layer is responsible for:
|
||||
|
||||
- HTTP clients and request/response interceptors
|
||||
- React Query shared helpers, response types, query key helpers, and error normalization
|
||||
- storage, browser, or runtime adapters
|
||||
- shared formatting/service adapters such as date or name formatting services
|
||||
- app-wide technical configuration wrappers
|
||||
|
||||
## Recommended Structure
|
||||
|
||||
```plaintext
|
||||
infrastructure/
|
||||
├── axios/
|
||||
│ ├── index.ts # configured axios client
|
||||
│ ├── interceptors.ts # request/response interceptors
|
||||
│ └── axios.d.ts # axios type augmentation
|
||||
│
|
||||
├── reactQuery/
|
||||
│ ├── index.ts
|
||||
│ ├── errors.ts # query error handling helpers
|
||||
│ ├── helpers.ts # query key and pagination helpers
|
||||
│ ├── queryParams.ts # table/query-param mapping helpers
|
||||
│ └── types.ts # shared API response/query types
|
||||
│
|
||||
├── IntlDate.ts # date formatting service adapter
|
||||
└── IntlName.ts # name formatting service adapter
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
1. Keep infrastructure feature-agnostic.
|
||||
|
||||
- No module-specific business rules
|
||||
- No page or component composition
|
||||
- No entity mapping that belongs in a module `data/mapper`
|
||||
|
||||
2. API modules should use infrastructure clients instead of creating their own clients.
|
||||
|
||||
```ts
|
||||
import { axiosClient } from "#infrastructure/axios";
|
||||
```
|
||||
|
||||
3. React Query helpers that are shared across modules belong here.
|
||||
|
||||
Examples: query key builders, list response types, pagination helpers, error extraction helpers.
|
||||
|
||||
4. UI layers must not call raw HTTP clients directly.
|
||||
|
||||
View and page code should call data-layer hooks. Direct `#infrastructure/axios` usage belongs in API/data modules, not in components.
|
||||
|
||||
5. Generic formatting adapters may be consumed by UI when they are not tied to a feature.
|
||||
|
||||
Examples: `IntlDate`, `IntlName`.
|
||||
|
||||
6. Prefer dependency injection for app-state coupling.
|
||||
|
||||
If an interceptor needs auth or query-client behavior, keep that coupling narrow and documented. Avoid importing random feature modules into infrastructure.
|
||||
|
||||
## Examples
|
||||
|
||||
API modules use the configured HTTP client:
|
||||
|
||||
```ts
|
||||
import { axiosClient } from "#infrastructure/axios";
|
||||
|
||||
export class UserAPI {
|
||||
getDetailed(id: number) {
|
||||
return axiosClient.get(`/users/${id}`).then((response) => response.data);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Data/query modules use shared query helpers:
|
||||
|
||||
```ts
|
||||
import {
|
||||
createKeyBuilder,
|
||||
getPaginationInfo,
|
||||
} from "#infrastructure/reactQuery";
|
||||
|
||||
export const usersCacheKey = createKeyBuilder("USERS", "LIST");
|
||||
```
|
||||
|
||||
UI can consume generic app-wide formatters:
|
||||
|
||||
```ts
|
||||
import { IntlDate } from "#infrastructure/IntlDate";
|
||||
```
|
||||
Reference in New Issue
Block a user