feat(monorepo): restructure web components and update configurations
CI / changes (push) Successful in 10s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 27s
CI / web (push) Successful in 38s
CI / go (push) Successful in 2m36s
CI / bird2 (push) Successful in 15s
CI / release (push) Failing after 3m7s

Refactored the project structure to support a monorepo setup, moving the web application to `apps/web/` and updating related configurations. Adjusted pre-commit hooks to use `pnpm` for linting and formatting. Updated CI workflows to reflect the new directory structure and dependencies. Removed legacy files and configurations from the previous `web/` directory, streamlining the project for better maintainability and clarity.
This commit is contained in:
Denozordec
2026-06-30 23:54:28 +07:00
parent db75126bea
commit a37c931ee7
377 changed files with 8537 additions and 1093 deletions
+75
View File
@@ -0,0 +1,75 @@
---
description: shadcn-svelte Monorepo — apps/web + packages/ui + packages/shared, CLI workflow
globs: apps/web/**/*,packages/ui/**/*,packages/shared/**/*
alwaysApply: false
---
# Frontend Monorepo (shadcn-svelte)
Структура по образцу vps-tracker, стек — **SvelteKit 2 + Svelte 5 + shadcn-svelte** (не React/ReUI).
## Layout
```
apps/web/ # SvelteKit (routes, queries, domain components)
packages/ui/ # @evobgp/ui — shadcn-svelte primitives (только CLI output)
packages/shared/ # @evobgp/shared — Zod contracts, API types
```
Go API в корне репозитория (`internal/`, `cmd/`) без изменений.
## Два components.json
| Файл | Назначение |
|------|------------|
| `apps/web/components.json` | App aliases; `ui` → `@evobgp/ui/components` |
| `packages/ui/components.json` | UI package aliases |
**Синхронизировать:** `style`, `iconLibrary`, `baseColor` в обоих файлах.
## CLI — только из apps/web
```powershell
cd apps/web
pnpm dlx shadcn-svelte@latest add button -y -o
pnpm dlx shadcn-svelte@latest add sidebar -y -o
pnpm dlx shadcn-svelte@latest add breadcrumb -y -o
```
Перед обновлением существующих компонентов: `pnpm dlx shadcn-svelte@latest add button --dry-run`
## Куда CLI кладёт файлы
| Команда | Куда |
|---------|------|
| `add button` | `packages/ui/src/components/button/` |
| `add sidebar` | `packages/ui/src/components/sidebar/` |
Если CLI кладёт в `apps/web/@evobgp/ui/` — перенести в `packages/ui/src/components/`.
## Импорты
```svelte
import { Button } from '@evobgp/ui/components/button/index.js';
import { cn } from '@evobgp/ui/lib/utils';
import '@evobgp/ui/styles/globals.css'; // только в routes/layout.css
import type { ModuleRow } from '@evobgp/shared/types/api.js';
import { moduleCreateSchema } from '@evobgp/shared/contracts/modules.js';
```
| Запрещено | Разрешено |
|-----------|-----------|
| `$lib/ui/core/*` | `@evobgp/ui/components/*` |
| `apps/web/src/lib/components/ui/` (legacy re-export) | `packages/ui/src/components/` |
| Ручное редактирование темы вне CLI | shadcn-svelte theming docs |
## globals.css
`packages/ui/src/styles/globals.css` с `@source` на `packages/ui` и `apps/web/src`.
## Проверка после правок
```powershell
pnpm --filter @evobgp/web check
pnpm --filter @evobgp/web lint
```
+65
View File
@@ -0,0 +1,65 @@
---
description: UI-паттерны apps/web — shared components, spacing, матрица (Svelte, без ReUI)
globs: apps/web/**/*
alwaysApply: false
---
# Frontend UI Patterns (Svelte)
Эталон UX: vps-tracker (`PageShell`, `QueryState`, `SectionCards`, `DataTableCard`). ReUI **не используется** — Data Table = shadcn-svelte + `AppDataTable` / `DataTableCard`.
## Иерархия
```
@evobgp/ui/components/* ← shadcn-svelte CLI (packages/ui)
apps/web/src/lib/components/ ← shared + domain + layout
page-shell.svelte
query-state.svelte
section-cards.svelte
data-table-card.svelte
status-badge.svelte
form-sheet.svelte
crud-list-page.svelte
list-filters-bar.svelte
patterns/ ← AppDataTable, FormField, ConfirmDialog, EmptyState
layout/app-shell.svelte
domain-*/ ← modules, network, operations…
```
## Матрица
| Элемент | Компонент | Primitive |
|---------|-----------|-----------|
| Page wrapper | `PageShell` | — |
| Page title | `PageHeader` (`ui/app/page-header`) | — |
| Stat metrics | `SectionCards` | `Card` |
| Data list | `DataTableCard` + `AppDataTable` | `Table` |
| Filters | `ListFiltersBar` | `Select`, `Badge` |
| Empty | `EmptyState` | — |
| Loading / Error | `QueryState` | `Skeleton`, `Alert` |
| Status | `StatusBadge` | `Badge` |
| Create/Edit form | `FormSheet` / Dialog | `Sheet`, `Field` |
| Delete confirm | `ConfirmDialog` | `AlertDialog` |
| Nav | `AppShell` | `Sidebar` |
| Breadcrumbs | `AppShell` header | `Breadcrumb` |
## Spacing
- `flex` + `gap-*`, не `space-y-*`
- Page: `gap-4 md:gap-6`, padding `p-4 md:p-6`
- Loading страницы → `Skeleton`, не page-level `Spinner`
- Max 1 primary CTA на экран
## Docs
- shadcn-svelte: https://shadcn-svelte.com/docs
- llms.txt: https://shadcn-svelte.com/llms.txt
- Data layer: `@tanstack/svelte-query` в `apps/web/src/lib/queries/`
## Overlay
| Сценарий | Компонент |
|----------|-----------|
| Create/edit | `Sheet` / `FormSheet` |
| Destructive | `ConfirmDialog` |
| Preview | `Dialog` |
+33 -104
View File
@@ -1,126 +1,55 @@
---
description: EvoBGP WebUI — shadcn-svelte, Svelte 5, слои ui/core|patterns|app
description: EvoBGP WebUI — shadcn-svelte monorepo, Svelte 5, @evobgp/ui
globs:
- web/**
- apps/web/**
- packages/ui/**
- packages/shared/**
alwaysApply: false
---
# Web UI — shadcn-svelte
# Web UI — shadcn-svelte (monorepo)
**Источник правды:** https://shadcn-svelte.com/docs (не React shadcn/ui, не Legacy Docs).
**Источник правды:** https://shadcn-svelte.com/docs
Общие правила Go/API: `.cursor/rules/engineering.mdc`. Локальная карта: `web/README.md`.
Monorepo: [`frontend-monorepo.mdc`](frontend-monorepo.mdc), паттерны: [`frontend-ui-patterns.mdc`](frontend-ui-patterns.mdc). Skill: [`.agents/skills/shadcn-svelte/SKILL.md`](.agents/skills/shadcn-svelte/SKILL.md).
## Слои UI
## Слои
| Слой | Путь | Назначение |
|------|------|------------|
| Примитивы | `src/lib/ui/core/` | shadcn-svelte (только CLI `add`) |
| Паттерны | `src/lib/ui/patterns/` | FormField, AppDataTable, ConfirmDialog, EmptyState |
| App chrome | `src/lib/ui/app/` | Layout, PageHeader, `notify` |
| Legacy | `src/lib/components/ui/` | Re-export; **не добавлять новые файлы** |
| Примитивы | `packages/ui/src/components/` | shadcn-svelte (только CLI) |
| Паттерны | `apps/web/src/lib/components/patterns/` | AppDataTable, FormField, ConfirmDialog |
| Shared UI | `apps/web/src/lib/components/` | PageShell, QueryState, SectionCards |
| App chrome | `apps/web/src/lib/ui/app/` | PageHeader, toast, nav |
| Контракты | `packages/shared/` | types + Zod |
Тема: `src/routes/layout.css`, `src/lib/ui/app/tokens.md`. CLI из `web/`: `npx shadcn-svelte@latest add <component> -y -o`.
Тема: `packages/ui/src/styles/globals.css` → импорт в `apps/web/src/routes/layout.css`.
---
CLI из `apps/web/`:
## Правила
**WEB-01** | MUST | Перед новым UI — проверить https://shadcn-svelte.com/docs/components; использовать компонент, не HTML+CSS с нуля.
*Rationale:* Open Code + единый дизайн.
*Проверка:* review; нет голых `<button class=…>`.
**WEB-02** | MUST | Отсутствующий примитив — `npx shadcn-svelte@latest add <component> -y -o` → `src/lib/ui/core/`.
*Rationale:* Distribution через CLI и `components.json`.
*Проверка:* файлы только в `ui/core`.
**WEB-03** | NEVER | Альтернативные UI-kit'ы (Material, Vuetify, DaisyUI-only без shadcn-примитива).
*Проверка:* `package.json` review.
**WEB-04** | MUST | Комозиция по docs: все sub-компоненты (`DialogHeader`, `TableRow`, `Field`, …).
*Проверка:* сверка со страницей компонента в docs.
**WEB-05** | MUST | Формы — Formsnap + `sveltekit-superforms`; UI в `ui/patterns/form`, не ad-hoc валидация на странице.
*Проверка:* https://shadcn-svelte.com/docs/components/form
**WEB-06** | MUST | Таблицы — Data Table + `@tanstack/table-core`; на страницах — `AppDataTable` из patterns.
*Проверка:* https://shadcn-svelte.com/docs/components/data-table
**WEB-07** | MUST | Toast — Sonner через `notify` из `ui/app/toast.js`.
*Проверка:* https://shadcn-svelte.com/docs/components/sonner
**WEB-08** | MUST | Иконки — `@lucide/svelte` (`components.json` → `iconLibrary: lucide`).
*Проверка:* imports.
**WEB-09** | MUST | Цвета — CSS-переменные `layout.css` и токены `tokens.md`; не hex/rgb на страницах.
*Проверка:* grep `#[0-9a-f]{3,6}` в `routes/`.
**WEB-10** | SHOULD | Кастомизация — правка `ui/core` (Open Code), не `!important` поверх API.
*Проверка:* review.
**WEB-11** | MUST | `routes/**` — композиция `ui/core` + `ui/patterns` + `ui/app`; не копировать целые примитивы shadcn в route.
*Проверка:* review.
**WEB-12** | NEVER | Примеры React shadcn/ui или Svelte 4 Legacy без адаптации под https://shadcn-svelte.com/docs/migration/svelte-5
*Проверка:* `npm run check`.
**WEB-13** | MUST | Реактивность — Svelte 5 runes (`$state`, `$derived`, `$effect`); не `export let` для локального state страниц.
*Проверка:* `npm run check`; Svelte MCP.
**WEB-14** | SHOULD | Нетривиальный UI — прочитать страницу компонента (props, a11y).
*Проверка:* PR description.
**WEB-15** | MUST | Сомнения — https://shadcn-svelte.com/llms.txt , Svelte MCP, `npm run check`.
*Проверка:* локально.
**WEB-19** | MUST | **После любого изменения `web/**`** — перед завершением задачи агент **обязан** выполнить в `web/`:
```powershell
npm run check
npm run lint
pnpm dlx shadcn-svelte@latest add <component> -y -o
```
Если `npm run lint` падает (Prettier) — **сначала** `npx prettier --write <изменённые файлы>` или `npx prettier --write .`, затем снова `npm run check` и `npm run lint`. Не сдавать PR/ответ, пока обе команды не exit 0.
*Rationale:* CI job `web` = `check` + `prettier --check`; `svelte-check` не ловит форматирование.
*Проверка:* CI job `web`; pre-commit hook `prettier-web`.
**WEB-16** | MUST | Подтверждение удаления — `ConfirmDialog` из patterns, не `window.confirm`.
*Проверка:* review.
## Правила (кратко)
**WEB-17** | MUST | Пустые списки — `EmptyState` из patterns.
*Проверка:* review.
- **WEB-01** Новый UI — сначала shadcn-svelte docs; не HTML+CSS с нуля
- **WEB-02** Примитивы только через CLI → `packages/ui`
- **WEB-05** Формы — Formsnap + superforms; `patterns/form/`
- **WEB-06** Таблицы — `AppDataTable` / `DataTableCard`
- **WEB-07** Toast — `notify` из `ui/app/toast.ts`
- **WEB-08** Иконки — `@lucide/svelte`
- **WEB-09** Цвета — CSS variables; не hex в routes
- **WEB-13** Svelte 5 runes
- **WEB-16** Удаление — `ConfirmDialog`
- **WEB-17** Пустые списки — `EmptyState`
- **WEB-19** После правок `apps/web/**`:
**WEB-18** | SHOULD | Повторяемая комбинация core (≥2 раза) — вынести в `ui/patterns/`.
*Проверка:* review.
---
## Documentation Sync (Web)
**DOC-SYNC-06** | MUST | UI — первично https://shadcn-svelte.com/docs; при конфликте с блогами/Stack Overflow побеждает официальная страница компонента.
**DOC-SYNC-07** | MUST | Перед `add` — сверить Installation/Theming с `web/components.json` и `src/routes/layout.css`.
Tailwind v4: https://shadcn-svelte.com/docs/migration/tailwind-v4
---
```powershell
pnpm --filter @evobgp/web check
pnpm --filter @evobgp/web lint
```
## Enforcement
**Обязательный финальный шаг агента при правках `web/**`:** `npm run check` **и** `npm run lint` (см. **WEB-19**). Только `check` недостаточно.
```powershell
cd web
npm run check
npm run lint
# при warn/fail lint:
npx prettier --write .
npm run check
npm run lint
```
**PR checklist `web/**`:**
- [ ] `npm run check` — exit 0
- [ ] `npm run lint` (prettier --check) — exit 0
- [ ] `ui/core` / `ui/patterns`, не дубли примитивов
- [ ] Новые примитивы через shadcn CLI
- [ ] Ссылка на docs компонента (если новый паттерн)
**CI:** job `web` — `npm run check` + `npm run lint`.
PR checklist: `check` + `lint` exit 0; примитивы в `@evobgp/ui`, не дубли в routes.