# 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"; ```