docs: детализация дизайна Фазы 1C (React SPA)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -233,3 +233,80 @@ check_runs(id uuid pk, domain_id uuid fk→domains, result jsonb /*сводка
|
|||||||
### Разбивка
|
### Разбивка
|
||||||
|
|
||||||
Реализуется **одним планом** `phase1b-persistence-api` (по решению — без под-планов).
|
Реализуется **одним планом** `phase1b-persistence-api` (по решению — без под-планов).
|
||||||
|
|
||||||
|
## Фаза 1C — детализация (React SPA)
|
||||||
|
|
||||||
|
Строится поверх готового REST API (Фаза 1B). Полный UI на весь API.
|
||||||
|
|
||||||
|
### Стек
|
||||||
|
|
||||||
|
- **Vite + React + TypeScript**, **react-router** (v6+), **TanStack Query v5** (server-state).
|
||||||
|
- **Tailwind CSS + shadcn/ui** (компоненты копируются в проект, `components.json`, alias `@`).
|
||||||
|
- Формы: **react-hook-form + zod**.
|
||||||
|
- Тесты: **Vitest + React Testing Library**.
|
||||||
|
- В dev — Vite `server.proxy` `/api` → `http://localhost:8080`. В prod — `vite build` → `dist/`
|
||||||
|
вшивается в Go-бинарь (`embed.FS`) и отдаётся тем же сервером (same-origin, CORS не нужен).
|
||||||
|
|
||||||
|
### Эстетическое направление
|
||||||
|
|
||||||
|
**Refined technical console.** Тёмная тема по умолчанию, плотная точная сетка, инженерный тон.
|
||||||
|
- Типографика: характерный UI-гротеск (НЕ Inter/Roboto/system) + **моноширинный** для DNS-записей,
|
||||||
|
зон и дифов (например IBM Plex Mono / JetBrains Mono). Пары: display для заголовков, mono для данных.
|
||||||
|
- Семантическое цветовое кодирование дифа: **add** (emerald), **update** (amber), **delete/prune**
|
||||||
|
(rose), **in-sync** (muted/slate), **read-only NS/SOA** (dimmed). Единая палитра через CSS-переменные.
|
||||||
|
- Атмосфера: тонкие текстуры/границы, аккуратные тени, без generic purple-on-white. Диф — центральный,
|
||||||
|
самый выразительный экран.
|
||||||
|
|
||||||
|
### Структура (`web/`)
|
||||||
|
|
||||||
|
```
|
||||||
|
web/
|
||||||
|
vite.config.ts — alias @, proxy /api → :8080, build outDir dist
|
||||||
|
components.json — shadcn
|
||||||
|
src/
|
||||||
|
main.tsx, App.tsx — QueryClientProvider + router
|
||||||
|
lib/ — utils, константа DEFAULT_PROJECT_ID = seed …0002
|
||||||
|
api/
|
||||||
|
client.ts — типизированная fetch-обёртка (base /api/v1/projects/{pid})
|
||||||
|
types.ts — зеркало Go DTO (Account, Template, Domain, Changeset, RecordView …)
|
||||||
|
hooks/ — TanStack Query: useAccounts/useTemplates/useDomains/useCheck/useApply/useImport
|
||||||
|
components/
|
||||||
|
ui/ — shadcn-компоненты
|
||||||
|
Layout.tsx, DiffView.tsx, RecordEditor.tsx
|
||||||
|
pages/
|
||||||
|
DomainsPage, DomainDiffPage, AccountsPage, TemplatesPage
|
||||||
|
```
|
||||||
|
|
||||||
|
### Экраны
|
||||||
|
|
||||||
|
- **Domains** — список доменов, импорт зон по учётке (`POST /domains/import`), привязка шаблона
|
||||||
|
(`PATCH /domains/{id}`), переход к дифу.
|
||||||
|
- **DomainDiff** (`/domains/:id`) — `GET .../check` → **DiffView**: секции Updates / Prunes / ReadOnly
|
||||||
|
+ счётчик in-sync. Кнопка **Apply**: чекбокс «применить удаления (prune)» — **по умолчанию выключен**,
|
||||||
|
требует явного подтверждения (визуально акцентированное предупреждение). `POST .../apply`.
|
||||||
|
- **Accounts** — CRUD учёток. Форма создания: поле API-ключа (secret, только на вход), **инструкция +
|
||||||
|
ссылка**, где получить ключ в панели Selectel. Секрет никогда не показывается обратно.
|
||||||
|
- **Templates** — CRUD шаблонов + **RecordEditor** (редактор набора записей `doc.records`: type/name/ttl/values,
|
||||||
|
включая SRV для почтового автодискавера).
|
||||||
|
|
||||||
|
### Мультитенантность
|
||||||
|
|
||||||
|
Фаза 1C — без логина: `DEFAULT_PROJECT_ID` (seed `…0002`) зашит в клиенте. Логин и переключение
|
||||||
|
проектов — Фаза 2 (тогда pid берётся из сессии).
|
||||||
|
|
||||||
|
### Подача в prod (Go)
|
||||||
|
|
||||||
|
- `internal/web/web.go` — `embed.FS` каталога `web/dist` + handler со **SPA-fallback** на `index.html`.
|
||||||
|
- `cmd/server` монтирует статику на `/`, API остаётся на `/api/v1` (роутинг chi: API-роуты имеют приоритет,
|
||||||
|
всё прочее → SPA).
|
||||||
|
|
||||||
|
### Тестирование 1C
|
||||||
|
|
||||||
|
- `api/client` — юниты на мок `fetch` (пути, сериализация, обработка ошибок).
|
||||||
|
- `DiffView` — рендер секций Updates/Prunes/ReadOnly, цветовое кодирование.
|
||||||
|
- Apply-guard — по умолчанию prune выключен; включается только явным действием.
|
||||||
|
- Go `internal/web` — статика отдаётся, `/api/*` не перехватывается, SPA-fallback на неизвестный путь.
|
||||||
|
|
||||||
|
### Разбивка
|
||||||
|
|
||||||
|
Один план `phase1c-react-spa`.
|
||||||
|
|||||||
Reference in New Issue
Block a user