From c9a53578fd753abeedf17e0884579dfa44c20faf Mon Sep 17 00:00:00 2001 From: busya Date: Fri, 23 Jan 2026 14:56:05 +0300 Subject: [PATCH] tasks ready --- .kilocode/rules/specify-rules.md | 4 +- .../checklists/requirements.md | 42 ++++++++ .../contracts/ui-components.md | 50 +++++++++ specs/013-unify-frontend-css/data-model.md | 59 ++++++++++ specs/013-unify-frontend-css/plan.md | 70 ++++++++++++ specs/013-unify-frontend-css/quickstart.md | 63 +++++++++++ specs/013-unify-frontend-css/research.md | 51 +++++++++ specs/013-unify-frontend-css/spec.md | 102 ++++++++++++++++++ specs/013-unify-frontend-css/tasks.md | 69 ++++++++++++ 9 files changed, 509 insertions(+), 1 deletion(-) create mode 100644 specs/013-unify-frontend-css/checklists/requirements.md create mode 100644 specs/013-unify-frontend-css/contracts/ui-components.md create mode 100644 specs/013-unify-frontend-css/data-model.md create mode 100644 specs/013-unify-frontend-css/plan.md create mode 100644 specs/013-unify-frontend-css/quickstart.md create mode 100644 specs/013-unify-frontend-css/research.md create mode 100644 specs/013-unify-frontend-css/spec.md create mode 100644 specs/013-unify-frontend-css/tasks.md diff --git a/.kilocode/rules/specify-rules.md b/.kilocode/rules/specify-rules.md index 1cb51fb..2295440 100644 --- a/.kilocode/rules/specify-rules.md +++ b/.kilocode/rules/specify-rules.md @@ -25,6 +25,8 @@ Auto-generated from all feature plans. Last updated: 2025-12-19 - Filesystem (local git repo), SQLite (for GitServerConfig, Environment) (011-git-integration-dashboard) - Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, GitPython (or CLI git), Pydantic, SQLAlchemy, Superset API (011-git-integration-dashboard) - SQLite (for config/history), Filesystem (local Git repositories) (011-git-integration-dashboard) +- Node.js 18+ (Frontend Build), Svelte 5.x + SvelteKit, Tailwind CSS, `date-fns` (existing) (013-unify-frontend-css) +- LocalStorage (for language preference) (013-unify-frontend-css) - Python 3.9+ (Backend), Node.js 18+ (Frontend Build) (001-plugin-arch-svelte-ui) @@ -45,9 +47,9 @@ cd src; pytest; ruff check . Python 3.9+ (Backend), Node.js 18+ (Frontend Build): Follow standard conventions ## Recent Changes +- 013-unify-frontend-css: Added Node.js 18+ (Frontend Build), Svelte 5.x + SvelteKit, Tailwind CSS, `date-fns` (existing) - 011-git-integration-dashboard: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, GitPython (or CLI git), Pydantic, SQLAlchemy, Superset API - 011-git-integration-dashboard: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, GitPython (or CLI git), Pydantic, SQLAlchemy, Superset API -- 011-git-integration-dashboard: Added Python 3.9+, Node.js 18+ diff --git a/specs/013-unify-frontend-css/checklists/requirements.md b/specs/013-unify-frontend-css/checklists/requirements.md new file mode 100644 index 0000000..6ae5ec3 --- /dev/null +++ b/specs/013-unify-frontend-css/checklists/requirements.md @@ -0,0 +1,42 @@ +# Checklist: Frontend UI & i18n Requirements Quality + +**Purpose**: Validate the quality, clarity, and completeness of the requirements for the unified frontend CSS and localization feature. + +**Meta**: +- **Feature**: 013-unify-frontend-css +- **Created**: 2026-01-23 +- **Focus**: UX Consistency, Component Contracts, i18n Completeness + +## Requirement Completeness +- [ ] CHK001 Are all necessary UI components (Button, Input, Select, Card, PageHeader) explicitly identified for standardization? [Completeness, Spec §FR-002] +- [ ] CHK002 Are the supported languages (RU, EN) and default language (RU) explicitly defined? [Completeness, Spec §FR-008, §FR-009] +- [ ] CHK003 Is the persistence mechanism for language selection (LocalStorage) specified? [Completeness, Spec §FR-010] +- [ ] CHK004 Are the specific pages (Dashboard, Settings) targeted for migration identified? [Completeness, Spec §FR-005] + +## Requirement Clarity +- [ ] CHK005 Is the "consistent spacing" requirement quantified with specific values or a system (e.g., Tailwind scale)? [Clarity, Spec §FR-004] +- [ ] CHK006 Are the specific visual properties (color, padding, hover state) that must be consistent defined in the design system configuration? [Clarity, Spec §SC-001] +- [ ] CHK007 Is the behavior of "legacy components" clearly defined (refactor vs. approximate)? [Clarity, Spec Edge Cases] + +## Requirement Consistency +- [ ] CHK008 Do the component contracts in `contracts/ui-components.md` align with the visual requirements in the spec? [Consistency] +- [ ] CHK009 Is the decision to use Svelte stores for i18n consistent with the requirement for client-side persistence? [Consistency, Research §2] + +## Acceptance Criteria Quality +- [ ] CHK010 Can the "consistent visual experience" be objectively verified through the defined independent tests? [Measurability, Spec §User Story 1] +- [ ] CHK011 Is the "0 instances of arbitrary hardcoded color values" criterion measurable via static analysis or search? [Measurability, Spec §SC-003] +- [ ] CHK012 Is the language persistence requirement testable by reloading the page? [Measurability, Spec §SC-006] + +## Scenario Coverage +- [ ] CHK013 Are requirements defined for the scenario where a translation key is missing? [Coverage, Spec Edge Cases] +- [ ] CHK014 Are requirements defined for the initial load state (default language)? [Coverage, Spec §User Story 3] +- [ ] CHK015 Are requirements defined for switching languages while on a page with dynamic content? [Coverage, Gap] + +## Edge Case Coverage +- [ ] CHK016 Is the behavior defined for text that overflows when translated to a longer language (e.g., RU vs EN)? [Edge Case, Gap] +- [ ] CHK017 Is the behavior defined if LocalStorage is disabled or inaccessible? [Edge Case, Gap] +- [ ] CHK018 Are requirements defined for responsive behavior on mobile devices? [Edge Case, Spec §Edge Cases] + +## Non-Functional Requirements +- [ ] CHK019 Are there specific performance targets for language switching (e.g., "instant", "no layout shift")? [NFR, Research §Technical Context] +- [ ] CHK020 Are accessibility requirements (ARIA labels, keyboard nav) defined for the new components? [NFR, Gap] \ No newline at end of file diff --git a/specs/013-unify-frontend-css/contracts/ui-components.md b/specs/013-unify-frontend-css/contracts/ui-components.md new file mode 100644 index 0000000..7ebb98d --- /dev/null +++ b/specs/013-unify-frontend-css/contracts/ui-components.md @@ -0,0 +1,50 @@ +# UI Component Contracts + +This document defines the strict API contracts for the standardized UI components. + +## Button Component + +### Description +A standard interactive button element that triggers an action. + +### Props +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `variant` | `'primary' \| 'secondary' \| 'danger' \| 'ghost'` | `'primary'` | Visual style of the button. | +| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of the button. | +| `isLoading` | `boolean` | `false` | If true, shows a spinner and disables interaction. | +| `disabled` | `boolean` | `false` | If true, prevents interaction. | +| `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | HTML button type. | +| `onclick` | `(event: MouseEvent) => void` | `undefined` | Click handler. | +| `class` | `string` | `''` | Additional CSS classes (use sparingly). | + +### Slots +- `default`: The content of the button (text or icon). + +## Input Component + +### Description +A standard text input field with support for labels and error messages. + +### Props +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `label` | `string` | `undefined` | Text label displayed above the input. | +| `value` | `string` | `''` | The current value (bindable). | +| `placeholder` | `string` | `''` | Placeholder text. | +| `error` | `string` | `undefined` | Error message displayed below the input. | +| `disabled` | `boolean` | `false` | If true, prevents interaction. | +| `type` | `'text' \| 'password' \| 'email' \| 'number'` | `'text'` | HTML input type. | + +## Select Component + +### Description +A standard dropdown selection component. + +### Props +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `label` | `string` | `undefined` | Text label displayed above the select. | +| `value` | `string \| number` | `''` | The selected value (bindable). | +| `options` | `{ value: string \| number, label: string }[]` | `[]` | List of options to display. | +| `disabled` | `boolean` | `false` | If true, prevents interaction. | \ No newline at end of file diff --git a/specs/013-unify-frontend-css/data-model.md b/specs/013-unify-frontend-css/data-model.md new file mode 100644 index 0000000..c7f6c4c --- /dev/null +++ b/specs/013-unify-frontend-css/data-model.md @@ -0,0 +1,59 @@ +# Data Model: Frontend State & Components + +## 1. i18n State (Client-Side) + +The application state for internationalization is transient (in-memory) but initialized from and persisted to `localStorage`. + +### Entities + +#### `Locale` +- **Type**: String Enum +- **Values**: `"ru"`, `"en"` +- **Default**: `"ru"` +- **Persistence**: `localStorage.getItem("locale")` + +#### `TranslationDictionary` +- **Type**: JSON Object +- **Structure**: Nested key-value pairs where values are strings. +- **Example**: + ```json + { + "common": { + "save": "Сохранить", + "cancel": "Отмена" + }, + "dashboard": { + "title": "Панель управления" + } + } + ``` + +## 2. Component Props (Contracts) + +These define the "API" for the standardized UI components. + +### `Button` +- **variant**: `"primary" | "secondary" | "danger" | "ghost"` (default: "primary") +- **size**: `"sm" | "md" | "lg"` (default: "md") +- **isLoading**: `boolean` (default: false) +- **disabled**: `boolean` (default: false) +- **type**: `"button" | "submit" | "reset"` (default: "button") +- **onClick**: `() => void` (optional) + +### `Input` +- **label**: `string` (optional) +- **value**: `string` (two-way binding) +- **placeholder**: `string` (optional) +- **error**: `string` (optional) +- **disabled**: `boolean` (default: false) +- **type**: `"text" | "password" | "email" | "number"` (default: "text") + +### `Card` +- **title**: `string` (optional) +- **padding**: `"none" | "sm" | "md" | "lg"` (default: "md") + +### `Select` +- **options**: `Array<{ value: string | number, label: string }>` +- **value**: `string | number` (two-way binding) +- **label**: `string` (optional) +- **disabled**: `boolean` (default: false) \ No newline at end of file diff --git a/specs/013-unify-frontend-css/plan.md b/specs/013-unify-frontend-css/plan.md new file mode 100644 index 0000000..3b502c5 --- /dev/null +++ b/specs/013-unify-frontend-css/plan.md @@ -0,0 +1,70 @@ +# Implementation Plan: [FEATURE] + +**Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link] +**Input**: Feature specification from `/specs/[###-feature-name]/spec.md` + +**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/commands/plan.md` for the execution workflow. + +## Summary + +Unify frontend styling using a centralized Tailwind CSS configuration and a set of standardized Svelte wrapper components. Implement internationalization (i18n) with support for Russian (default) and English, persisting language preference in LocalStorage. + +## Technical Context + +**Language/Version**: Node.js 18+ (Frontend Build), Svelte 5.x +**Primary Dependencies**: SvelteKit, Tailwind CSS, `date-fns` (existing) +**Storage**: LocalStorage (for language preference) +**Testing**: Manual verification per User Scenarios (Visual Regression) +**Target Platform**: Web Browser (Responsive) +**Project Type**: Web application (Frontend) +**Performance Goals**: Instant language switching, zero layout shift +**Constraints**: Must support existing pages without breaking layout +**Scale/Scope**: ~10-15 core UI components, global CSS update + +## Constitution Check + +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* + +- **Semantic Protocol Compliance**: PASS. New Svelte components must follow the Component Header standard. +- **Causal Validity**: PASS. Design System (Tokens) and Component Contracts will be defined before implementation. +- **Immutability of Architecture**: PASS. No changes to backend architecture; strictly frontend presentation layer. +- **Design by Contract**: PASS. Components will define strict props/interfaces. +- **Everything is a Plugin**: N/A. UI components are not backend plugins, but will be modular. + +## Project Structure + +### Documentation (this feature) + +```text +specs/[###-feature]/ +├── plan.md # This file (/speckit.plan command output) +├── research.md # Phase 0 output (/speckit.plan command) +├── data-model.md # Phase 1 output (/speckit.plan command) +├── quickstart.md # Phase 1 output (/speckit.plan command) +├── contracts/ # Phase 1 output (/speckit.plan command) +└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan) +``` + +### Source Code (repository root) + +```text +frontend/ +├── src/ +│ ├── lib/ +│ │ ├── i18n/ # [NEW] Translation dictionaries and stores +│ │ └── ui/ # [NEW] Standardized Svelte components +│ ├── components/ # [EXISTING] To be refactored to use lib/ui +│ ├── routes/ # [EXISTING] Pages +│ └── app.css # [EXISTING] Global styles (Tailwind directives) +``` + +**Structure Decision**: Adopting a standard SvelteKit structure where reusable UI components and logic (i18n) reside in `src/lib`, accessible via `$lib` alias. Existing `components` directory will be gradually refactored or moved to `lib/ui` if generic enough. + +## Complexity Tracking + +> **Fill ONLY if Constitution Check has violations that must be justified** + +| Violation | Why Needed | Simpler Alternative Rejected Because | +|-----------|------------|-------------------------------------| +| [e.g., 4th project] | [current need] | [why 3 projects insufficient] | +| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | diff --git a/specs/013-unify-frontend-css/quickstart.md b/specs/013-unify-frontend-css/quickstart.md new file mode 100644 index 0000000..e717d4e --- /dev/null +++ b/specs/013-unify-frontend-css/quickstart.md @@ -0,0 +1,63 @@ +# Quickstart: Frontend Development + +## Prerequisites + +- Node.js 18+ +- npm + +## Setup + +1. Navigate to the frontend directory: + ```bash + cd frontend + ``` + +2. Install dependencies: + ```bash + npm install + ``` + +## Running the Development Server + +```bash +npm run dev +``` + +The application will be available at `http://localhost:5173`. + +## Using Standard UI Components + +Import components from `$lib/ui`: + +```svelte + + + + +``` + +## Using Internationalization + +Import the `t` store from `$lib/i18n`: + +```svelte + + +

{$t.dashboard.title}

+ +``` + +## Adding New Translations + +1. Open `frontend/src/lib/i18n/locales/ru.json` and add the new key-value pair. +2. Open `frontend/src/lib/i18n/locales/en.json` and add the corresponding English translation. + +## Adding New Components + +1. Create a new `.svelte` file in `frontend/src/lib/ui/`. +2. Define props and styles using Tailwind CSS. +3. Export the component in `frontend/src/lib/ui/index.ts`. \ No newline at end of file diff --git a/specs/013-unify-frontend-css/research.md b/specs/013-unify-frontend-css/research.md new file mode 100644 index 0000000..88e3681 --- /dev/null +++ b/specs/013-unify-frontend-css/research.md @@ -0,0 +1,51 @@ +# Research: Unify Frontend CSS & Localization + +## 1. Design System & Theming + +**Decision**: Use Tailwind CSS as the engine for the design system, but encapsulate usage within reusable Svelte components (`src/lib/ui/*`). + +**Rationale**: +- **Consistency**: Centralizing styles in components ensures that a "Button" always looks like a "Button" without copy-pasting utility classes. +- **Maintainability**: Tailwind configuration (`tailwind.config.js`) will hold the "Design Tokens" (colors, spacing), while components hold the "Structure". +- **Speed**: Tailwind is already integrated and allows for rapid development. + +**Alternatives Considered**: +- *Pure CSS/SCSS Modules*: Rejected because it requires more boilerplate and context switching between files. +- *Component Library (e.g., Skeleton, Flowbite)*: Rejected to maintain full control over the visual identity and avoid bloat, but we will use the "Headless UI" concept where we build our own accessible components. + +## 2. Internationalization (i18n) + +**Decision**: Implement a lightweight, store-based i18n solution using Svelte stores and JSON dictionaries. + +**Rationale**: +- **Simplicity**: For just two languages (RU, EN) and a moderate number of strings, a full-blown library like `svelte-i18n` or `i18next` adds unnecessary complexity and bundle size. +- **Control**: A custom store allows us to easily handle `localStorage` persistence and reactive updates across the app without fighting library-specific lifecycle issues. +- **Performance**: Direct object lookups are extremely fast. + +**Implementation Detail**: +- `src/lib/i18n/index.ts`: Exports a derived store `t` that reacts to the current `locale` store. +- `src/lib/i18n/locales/ru.json`: Default dictionary. +- `src/lib/i18n/locales/en.json`: English dictionary. + +**Alternatives Considered**: +- *svelte-i18n*: Good library, but overkill for current requirements. +- *Server-side i18n*: Rejected because the requirement specifies client-side persistence (LocalStorage) and immediate switching without page reloads. + +## 3. Component Architecture + +**Decision**: Create "Atomic" components in `src/lib/ui` that expose props for variants (e.g., `variant="primary" | "secondary"`). + +**Proposed Components**: +- `Button.svelte`: Handles variants, sizes, loading states. +- `Card.svelte`: Standard container with padding/shadow. +- `Input.svelte`: Standardized text input with label and error state. +- `Select.svelte`: Standardized dropdown. +- `PageHeader.svelte`: Unified title and actions area for pages. + +**Rationale**: These cover 80% of the UI inconsistency issues identified in the spec. + +## 4. Migration Strategy + +**Decision**: "Strangler Fig" pattern - create new components first, then incrementally replace usage in `src/routes` and existing `src/components`. + +**Rationale**: Allows the application to remain functional at all times. We can migrate one page or one section at a time. \ No newline at end of file diff --git a/specs/013-unify-frontend-css/spec.md b/specs/013-unify-frontend-css/spec.md new file mode 100644 index 0000000..8f29f2b --- /dev/null +++ b/specs/013-unify-frontend-css/spec.md @@ -0,0 +1,102 @@ +# Feature Specification: Unify Frontend CSS & Localization + +**Feature Branch**: `013-unify-frontend-css` +**Created**: 2026-01-23 +**Status**: Draft +**Input**: User description: "Я хочу унифицировать CSS для фронта. Добавь в спецификацию требование, что я хочу l18n для всех текстовых элементов. Плюс, должен быть переключатель языков. Для начала два языка - русский и английский, русский по умолчанию." + +## Clarifications + +### Session 2026-01-23 + +- Q: Should we refactor existing UI elements into reusable Svelte components or just apply standardized CSS utility classes? → A: Create thin wrapper Svelte components (e.g., `