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
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:
@@ -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)
|
||||
|
||||
@@ -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).
|
||||
@@ -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)
|
||||
@@ -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).
|
||||
@@ -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).
|
||||
@@ -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
|
||||
|
||||
| Файл | Назначение |
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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).
|
||||
|
||||
## Язык
|
||||
|
||||
|
||||
Reference in New Issue
Block a user