Refactor project to transition from Rust backend to Node.js with Fastify; update Dockerfile and Docker configurations for new build process; enhance local development instructions in CONTRIBUTING.md; implement health checks in Docker Compose; update pnpm-lock.yaml with new dependencies for API and shared packages; revise README.md to reflect new stack and development setup.
Build, Test, and Push CFDM Docker Image / test (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / build-and-push (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / create-release (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / update-wiki (push) Has been cancelled

This commit is contained in:
Denozordec
2026-06-19 12:06:32 +07:00
parent 0a0a1a92f1
commit d11414666f
2065 changed files with 15782 additions and 16699 deletions
+16 -25
View File
@@ -1,46 +1,37 @@
---
description: Backend API — при изменениях, затрагивающих UI, строго следовать shadcn Components/Blocks
globs: backend/**/*
globs: apps/api/**/*,packages/shared/**/*
alwaysApply: false
---
# Backend API + shadcn/ui
Rust backend: `backend/src/` (Axum, sqlx). Frontend потребляет API через TanStack Query.
## Когда правило активно
Любое изменение в `backend/src/api/handlers/`, DTO, полей ответа, которые отображаются в UI.
Fastify backend: `apps/api/`. Контракты — `@cfdm/shared` (Zod). Frontend — TanStack Query.
## Обязательный порядок
1. **Backend** — handler, валидация, тесты API
2. **Схемы frontend** — `apps/web/src/lib/schemas.ts`, `apps/web/src/queries/index.ts`
3. **UI** — **только** [shadcn Components](https://ui.shadcn.com/docs/components) и [Blocks](https://ui.shadcn.com/blocks)
1. **Backend** — route, service, Vitest (`app.inject()`)
2. **Схемы** — `@cfdm/shared` (не дублировать в `apps/web/src/lib/schemas.ts`)
3. **UI** — shadcn MCP ([`shadcn-mcp.mdc`](shadcn-mcp.mdc))
## Запрещено на frontend при доработке API
- Новые raw `<table>` / `<select>` / кастомные badge-цвета
- Кастомный CSS для отображения новых полей
- Дублирование Zod schemas в `apps/web` — только re-export из `@cfdm/shared`
- Самописные формы без `Field` + RHF + Zod
## Рекомендуемые shadcn-паттерны для типовых API
## shadcn-паттерны
Перед выбором паттерна — **MCP** `search_items_in_registries` ([`shadcn-mcp.mdc`](shadcn-mcp.mdc)).
| API-данные | UI (из docs) |
|------------|--------------|
| Список сущностей | `Table` в `DataTableCard` или `data-table` block |
| Создание записи | `Card` + `FieldGroup` + RHF |
| Enum/фильтр | `Select` |
| Статус | `StatusBadge` → shadcn `Badge` variants |
| Ошибка мутации | `sonner` `toast.error` |
| Пустой список | `Empty` |
| Сводка/метрики | `Card` section-cards ([dashboard-01](https://ui.shadcn.com/blocks)) |
| API-данные | UI |
|------------|-----|
| Список | `Table` / `DataTableCard` |
| Создание | `Card` + `FieldGroup` + RHF |
| Статус | `Badge` variants |
| Ошибка | `sonner` `toast.error` |
## Согласованность
- Имена полей JSON — camelCase или snake_case как в существующем API; типы в Zod должны совпадать
- Новый endpoint → `queryOptions` factory в `apps/web/src/queries/`, не inline в route
- JSON поля — snake_case как в существующем API
- Новый endpoint → `queryOptions` в `apps/web/src/queries/`
Главное правило frontend: [`frontend-shadcn.mdc`](frontend-shadcn.mdc) · monorepo: [`frontend-monorepo.mdc`](frontend-monorepo.mdc) · обзор: [`shadcn-ui-production.mdc`](shadcn-ui-production.mdc)
MCP backend: [`backend-mcp.mdc`](backend-mcp.mdc) · Fastify: [`backend-fastify.mdc`](backend-fastify.mdc)
+26
View File
@@ -0,0 +1,26 @@
---
description: Drizzle ORM + SQLite — schema, migrations, queries
globs: packages/db/**/*,apps/api/src/services/**/*
alwaysApply: false
---
# Backend Drizzle
MCP Context7 (`drizzle-orm`, `drizzle-kit`) — [`backend-mcp.mdc`](backend-mcp.mdc).
## Schema
- `packages/db/src/schema/` — source of truth
- Migrations: `drizzle-kit generate` / `migrate`
- WAL + `foreign_keys` при открытии SQLite
- Индекс `idx_dns_records_domain_cf_id` на `(domain_id, cf_record_id)`
## Queries
- Batch queries (`inArray`, JOINs) — не N+1 loops
- UNIQUE violations → `CONFLICT` (409)
- Multi-step → `db.transaction()`
## SQLite
См. [`sqlite.mdc`](sqlite.mdc).
+43
View File
@@ -0,0 +1,43 @@
---
description: Fastify API — слои, плагины, контракт ошибок
globs: apps/api/**/*
alwaysApply: false
---
# Backend Fastify
Стек: **Node.js 22**, **Fastify 5**, `@fastify/*` plugins, `@cfdm/shared`, `@cfdm/db`.
MCP — [`backend-mcp.mdc`](backend-mcp.mdc).
## Слои
```
routes/ → services/ → @cfdm/db (repositories)
↘ lib/cf-client.ts
```
- Routes — тонкие Fastify plugins (`fastify-plugin`)
- **Запрещено:** SQL в routes, `fetch` к CF вне `cf-client`
## Плагины (официальные)
`@fastify/jwt`, `@fastify/cors`, `@fastify/sensible`, `@fastify/static`, `@fastify/helmet`, `@fastify/rate-limit`, `@fastify/type-provider-zod`, `fastify-plugin`
## Ошибки
Формат: `{ error: { code, message } }`
Коды: `NOT_FOUND`, `VALIDATION_ERROR`, `UNAUTHORIZED`, `FORBIDDEN`, `CONFLICT`, `CLOUDFLARE_ERROR`, `INTERNAL_ERROR`
## Правила
- Zod schemas только из `@cfdm/shared`
- `db.transaction()` для multi-step writes
- Операции >2s → async job (`sync_jobs` + `p-queue`)
- Env через Zod в `config.ts`; prod fail-fast на dev `JWT_SECRET`
- TypeScript strict; `function` для handlers/services
## API + UI
[`backend-api-ui.mdc`](backend-api-ui.mdc)
+28
View File
@@ -0,0 +1,28 @@
---
description: Обязательный порядок MCP перед backend-кодом (Fastify, Drizzle, Cloudflare API)
globs: apps/api/**/*,packages/db/**/*,packages/shared/**/*
alwaysApply: false
---
# Backend MCP — обязательно
Перед **любой** задачей в `apps/api`, `packages/db`, `packages/shared` — сначала MCP, не training data.
## Порядок
| Задача | MCP |
|--------|-----|
| Fastify plugins, routes, hooks | **Context7** `resolve-library-id` → `query-docs` (`fastify`, `@fastify/jwt`, `@fastify/type-provider-zod`) |
| Drizzle schema, queries, migrations | **Context7** (`drizzle-orm`, `drizzle-kit`, `better-sqlite3`) |
| Cloudflare DNS/Zones API | **`plugin-cloudflare-cloudflare-docs`** `search_cloudflare_documentation` |
| API + UI | `packages/shared` → **shadcn MCP** ([`shadcn-mcp.mdc`](shadcn-mcp.mdc)) |
| E2E / cutover | **cursor-ide-browser** |
| Неизвестный инструмент | **user-mcp-on-demand** `search_tools` |
## Запрещено
- Угадывать API Fastify/Drizzle/CF из памяти
- Самописные аналоги `@fastify/*` (CORS, static, JWT, rate-limit)
- Дублировать Zod schemas вне `@cfdm/shared`
Связанные: [`backend-fastify.mdc`](backend-fastify.mdc), [`backend-drizzle.mdc`](backend-drizzle.mdc), [`backend-testing.mdc`](backend-testing.mdc).
+26
View File
@@ -0,0 +1,26 @@
---
description: Backend Vitest + Fastify inject
globs: apps/api/**/*,packages/db/**/*,packages/shared/**/*
alwaysApply: false
---
# Backend Testing
Vitest + `app.inject()` (встроено в Fastify).
## Требования
- Каждый route plugin → минимум 1 integration test
- Sync/DNS → parity fixtures
- `:memory:` SQLite для unit; file DB для integration
- `beforeEach` — fresh schema migrate
## Паттерн
```ts
const app = await buildApp({ db: testDb })
const res = await app.inject({ method: 'GET', url: '/health' })
expect(res.statusCode).toBe(200)
```
См. [`vitest-best-practices.mdc`](vitest-best-practices.mdc).
+4 -3
View File
@@ -12,11 +12,12 @@ alwaysApply: false
```
apps/web/ # Vite SPA (routes, queries, domain components)
packages/ui/ # @cfdm/ui — shadcn primitives, utils, hooks, globals.css
apps/api/ # Fastify API + static SPA in prod
packages/ui/ # @cfdm/ui — shadcn primitives
packages/shared/ # @cfdm/shared — Zod schemas, parse-fqdn
packages/db/ # @cfdm/db — Drizzle schema, repositories
```
`backend/` — Rust, **вне** npm workspaces.
## Два components.json
| Файл | Назначение |
+4 -45
View File
@@ -1,52 +1,11 @@
---
description: General Rust rules for safe, idiomatic application and library development
description: "DEPRECATED — Rust backend удалён. См. backend-fastify.mdc"
globs: ["**/*.rs", "Cargo.toml", "Cargo.lock"]
alwaysApply: false
---
# Rust General Rules
# Rust General Rules (deprecated)
## Project Structure
Проект использует **TypeScript + Fastify** (`apps/api`). Это правило не применяется.
- Keep crates focused and name modules by domain responsibility.
- Put reusable library code in `src/lib.rs` and binary entry points in `src/main.rs` or `src/bin/`.
- Keep public APIs small and documented.
- Use feature flags deliberately and document non-default features.
- Commit `Cargo.lock` for applications; follow the project convention for libraries.
## Ownership and Types
- Prefer borrowing over cloning when ownership is not needed.
- Use owned values at API boundaries when the callee must store data.
- Model domain states with enums and structs instead of strings or booleans.
- Use `Option<T>` for absence and `Result<T, E>` for fallible operations.
- Avoid `unwrap()` and `expect()` outside tests, examples, and process-startup invariants.
## Error Handling
- Use `thiserror` or project-standard custom errors for libraries.
- Use `anyhow` or project-standard context-rich errors for applications.
- Add context when crossing IO, network, database, or parsing boundaries.
- Do not discard errors with `_` unless explicitly documented.
## Concurrency and Async
- Use `Send` and `Sync` boundaries intentionally.
- Prefer message passing or owned task inputs for async work.
- Do not hold blocking locks across `.await`.
- Use `tokio::task::spawn_blocking` or equivalent for blocking CPU or IO in async applications.
- Propagate cancellation through futures rather than hiding it in detached tasks.
## Testing and Quality
- Run `cargo fmt` and `cargo clippy` before delivery.
- Add unit tests for pure logic and integration tests for public behavior.
- Use property tests for parsers, serializers, and state machines when useful.
- Use benchmarks only after identifying a real performance question.
## Common Mistakes
- Do not fight the borrow checker by adding unnecessary `Arc<Mutex<_>>`.
- Do not expose internal module structure through public APIs by accident.
- Do not allocate in hot loops without measuring.
- Do not use unsafe code unless the invariant is documented and tested.
См. [`backend-fastify.mdc`](backend-fastify.mdc), [`backend-drizzle.mdc`](backend-drizzle.mdc).
+1 -1
View File
@@ -24,7 +24,7 @@ UI строится **исключительно** по [shadcn/ui](https://ui.s
## Backend → UI
При правках API с экранами: [`backend-api-ui.mdc`](backend-api-ui.mdc).
При правках API с экранами: [`backend-api-ui.mdc`](backend-api-ui.mdc). Backend: `apps/api` (Fastify + Drizzle).
## Язык