style: Обновлены правила код стайла

This commit is contained in:
2026-05-08 08:21:34 +03:00
parent 7c0f597840
commit fec5ca78d0
32 changed files with 688 additions and 557 deletions

View File

@@ -19,7 +19,7 @@ https://petstore3.swagger.io/api/v3/openapi.json
Имена модуля:
```text
src/infrastructure/pet-store-api/
src/infra/pet-store-api/
petStoreApi
pet-store-api.generated.ts
```
@@ -31,7 +31,7 @@ pet-store-api.generated.ts
```json
{
"scripts": {
"codegen:pet-store-api": "npx @gromlab/api-codegen@latest -i https://petstore3.swagger.io/api/v3/openapi.json -o src/infrastructure/pet-store-api/generated -n pet-store-api.generated"
"codegen:pet-store-api": "npx @gromlab/api-codegen@latest -i https://petstore3.swagger.io/api/v3/openapi.json -o src/infra/pet-store-api/generated -n pet-store-api.generated"
}
}
```
@@ -53,7 +53,7 @@ npm run codegen:pet-store-api
Ожидаемый результат:
```text
src/infrastructure/pet-store-api/generated/
src/infra/pet-store-api/generated/
└── pet-store-api.generated.ts
```
@@ -77,7 +77,7 @@ petStoreApi.pet.getPetById(...)
Сгенерированный код не должен напрямую использоваться из приложения. Сначала создаётся настроенный инстанс клиента.
```ts
// src/infrastructure/pet-store-api/client.ts
// src/infra/pet-store-api/client.ts
import { Api, HttpClient } from './generated/pet-store-api.generated'
const httpClient = new HttpClient({
@@ -102,7 +102,7 @@ export const petStoreApi = new Api(httpClient)
Сгенерированный файл не правится руками. Если OpenAPI-спецификация неполная или генератор дал слишком общий тип (`object`, `unknown`, отсутствующее поле), расширения живут в `types/`.
```text
src/infrastructure/biocad-less-api/
src/infra/biocad-less-api/
├── generated/
│ └── biocad-less-api.generated.ts
├── types/
@@ -115,7 +115,7 @@ src/infrastructure/biocad-less-api/
Пример расширения generated-типа:
```ts
// src/infrastructure/biocad-less-api/types/term.ts
// src/infra/biocad-less-api/types/term.ts
import type { TermRecordItem } from '../generated/biocad-less-api.generated'
declare module '../generated/biocad-less-api.generated' {
@@ -149,7 +149,7 @@ export type TermRecordItemExtended = Omit<
```
```ts
// src/infrastructure/biocad-less-api/types/index.ts
// src/infra/biocad-less-api/types/index.ts
export type { TermRecordItemExtended } from './term'
```
@@ -158,18 +158,18 @@ export type { TermRecordItemExtended } from './term'
## Публичный API
```ts
// src/infrastructure/pet-store-api/index.ts
// src/infra/pet-store-api/index.ts
export { petStoreApi } from './client'
export type { Pet } from './generated/pet-store-api.generated'
export * from './hooks'
```
Наружу импортируют только из `infrastructure/pet-store-api`, не из `generated/`.
Наружу импортируют только из `infra/pet-store-api`, не из `generated/`.
Если у модуля есть расширенные типы, они тоже реэкспортируются через `index.ts`:
```ts
// src/infrastructure/biocad-less-api/index.ts
// src/infra/biocad-less-api/index.ts
export type { TermRecordItemExtended } from './types'
```

View File

@@ -1,7 +1,7 @@
---
title: GET-хуки REST-клиента
description: Прозрачные SWR-обёртки над GET-методами REST-клиента.
keywords: [rest, swr, get-хуки, client components, infrastructure]
keywords: [rest, swr, get-хуки, client components, infra]
---
# GET-хуки REST-клиента
@@ -13,7 +13,7 @@ GET-хуки REST-клиента — прозрачные SWR-обёртки н
GET-хуки принадлежат REST-клиенту конкретного сервиса и живут рядом с ним:
```text
src/infrastructure/
src/infra/
└── pet-store-api/
├── client.ts
├── generated/
@@ -41,7 +41,7 @@ src/infrastructure/
## Пример списка
```ts
// src/infrastructure/pet-store-api/hooks/use-get-pet-list.hook.ts
// src/infra/pet-store-api/hooks/use-get-pet-list.hook.ts
import useSWR from 'swr'
import type { SWRConfiguration } from 'swr'
import { petStoreApi } from '../client'
@@ -74,7 +74,7 @@ import { SWRConfig, unstable_serialize } from 'swr'
import {
getPetListKey,
petStoreApi,
} from 'infrastructure/pet-store-api'
} from 'infra/pet-store-api'
export default function PetsLayout({ children }: { children: ReactNode }) {
const petsPromise = petStoreApi.pet.findPetsByStatus({ status: 'available' })
@@ -102,7 +102,7 @@ const { data: pets } = useGetPetList('available')
## Пример detail-запроса
```ts
// src/infrastructure/pet-store-api/hooks/use-get-pet-detail.hook.ts
// src/infra/pet-store-api/hooks/use-get-pet-detail.hook.ts
import useSWR from 'swr'
import type { SWRConfiguration } from 'swr'
import { petStoreApi } from '../client'
@@ -141,23 +141,23 @@ const key = isReady ? getPetDetailKey(id) : null
## Экспорт
```ts
// src/infrastructure/pet-store-api/hooks/index.ts
// src/infra/pet-store-api/hooks/index.ts
export { getPetListKey, useGetPetList } from './use-get-pet-list.hook'
export type { PetStatus } from './use-get-pet-list.hook'
export { getPetDetailKey, useGetPetDetail } from './use-get-pet-detail.hook'
```
```ts
// src/infrastructure/pet-store-api/index.ts
// src/infra/pet-store-api/index.ts
export { petStoreApi } from './client'
export type { Pet } from './generated/pet-store-api.generated'
export * from './hooks'
```
## Где заканчивается infrastructure
## Где заканчивается infra
```ts
// Хорошо: infrastructure, прозрачный GET-хук
// Хорошо: infra, прозрачный GET-хук
const { data: pets } = useGetPetList('available')
```
@@ -184,7 +184,7 @@ const { data } = useSWR(
() => petStoreApi.pet.findPetsByStatus({ status }),
)
// Плохо — несколько GET внутри infrastructure-хука
// Плохо — несколько GET внутри infra-хука
export const usePetDashboard = () => {
const available = useGetPetList('available')
const sold = useGetPetList('sold')

View File

@@ -1,12 +1,12 @@
---
title: Создание клиента
description: Из чего состоит REST-клиент и какие части нужно подготовить перед использованием API.
keywords: [rest, клиент, infrastructure, методы, openapi, get-хуки, swr]
keywords: [rest, клиент, infra, методы, openapi, get-хуки, swr]
---
# Создание клиента
REST-клиент — это infrastructure-модуль, через который проект работает с внешним REST API.
REST-клиент — это infra-модуль, через который проект работает с внешним REST API.
На этом этапе нужно подготовить клиент сервиса: создать оболочку клиента, получить методы API и добавить GET-хуки для клиентских компонентов.
@@ -57,7 +57,7 @@ GET-хуки именуются с префиксом `useGet`: `useGetPetList`,
## Структура модуля
```text
src/infrastructure/{service-name}/
src/infra/{service-name}/
├── client.ts # самописная оболочка и инстанс клиента
├── generated/ или methods/ # методы API
├── hooks/ # GET-хуки REST-клиента

View File

@@ -1,7 +1,7 @@
---
title: Ручное создание
description: Создание REST-клиента вручную, когда OpenAPI нет или он неполный.
keywords: [rest, ручной клиент, fetch, methods, dto, errors, infrastructure]
keywords: [rest, ручной клиент, fetch, methods, dto, errors, infra]
---
# Ручное создание
@@ -13,7 +13,7 @@ keywords: [rest, ручной клиент, fetch, methods, dto, errors, infrast
## Что нужно создать
```text
src/infrastructure/
src/infra/
└── pet-project-api/
├── methods/
│ └── posts.ts
@@ -43,7 +43,7 @@ src/infrastructure/
DTO запросов и ответов живут в `types/`. `client.ts` не содержит DTO и доменные типы.
```ts
// src/infrastructure/pet-project-api/types/post.ts
// src/infra/pet-project-api/types/post.ts
export type PostDto = {
id: string
slug: string
@@ -57,14 +57,14 @@ export type PostListQueryDto = {
```
```ts
// src/infrastructure/pet-project-api/types/index.ts
// src/infra/pet-project-api/types/index.ts
export type { PostDto, PostListQueryDto } from './post'
```
Типы, которые нужны только базовому транспорту, можно держать отдельно:
```ts
// src/infrastructure/pet-project-api/types/client.ts
// src/infra/pet-project-api/types/client.ts
export type QueryParams = Record<string, string | number | boolean>
```
@@ -73,7 +73,7 @@ export type QueryParams = Record<string, string | number | boolean>
Ошибка API тоже относится к REST-модулю.
```ts
// src/infrastructure/pet-project-api/errors/pet-project-api.error.ts
// src/infra/pet-project-api/errors/pet-project-api.error.ts
export class PetProjectApiError extends Error {
constructor(
public readonly status: number,
@@ -90,7 +90,7 @@ export class PetProjectApiError extends Error {
`client.ts` содержит только транспортную оболочку и сборку инстанса. Прямой `fetch` живёт здесь, а не в компонентах и не в методах верхних слоёв.
```ts
// src/infrastructure/pet-project-api/client.ts
// src/infra/pet-project-api/client.ts
import { PetProjectApiError } from './errors/pet-project-api.error'
import type { QueryParams } from './types/client'
@@ -131,7 +131,7 @@ export class PetProjectApiClient {
Методы группируются по сущностям в `methods/`. Они не знают про React, SWR и UI.
```ts
// src/infrastructure/pet-project-api/methods/posts.ts
// src/infra/pet-project-api/methods/posts.ts
import type { PetProjectApiClient } from '../client'
import type { PostDto, PostListQueryDto } from '../types/post'
@@ -155,7 +155,7 @@ export function postsMethods(client: PetProjectApiClient) {
`index.ts` собирает именованный API-объект и открывает наружу только публичные части модуля.
```ts
// src/infrastructure/pet-project-api/index.ts
// src/infra/pet-project-api/index.ts
import { PetProjectApiClient } from './client'
import { postsMethods } from './methods/posts'
@@ -173,7 +173,7 @@ export type { PostDto, PostListQueryDto } from './types'
export * from './hooks'
```
Внешний код импортирует только из `infrastructure/pet-project-api`, не из внутренних файлов модуля.
Внешний код импортирует только из `infra/pet-project-api`, не из внутренних файлов модуля.
## Правила