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
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:
@@ -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
|
||||
```
|
||||
@@ -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
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user