# VoIdea — Technical Architecture ## System Overview ``` ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Client │────▶│ Nginx │────▶│ FastAPI │────▶ PostgreSQL │ (PWA/Web)│ │ :80/443 │ │ :8020 │────▶ Redis └──────────┘ └──────────┘ └──────────┘ ┌──────────┐ │ Celery │ │ (AI/backup) └──────────┘ ``` ## Frontend (webui/) Architecture ### Layer Structure ``` pages/ ← Route-level components (1 page = 1 route) ├── LoginPage.tsx ├── IdeaEdit.tsx └── AdminPage.tsx components/ ← Shared UI ├── Layout.tsx ├── ErrorBoundary.tsx ├── SkipToContent.tsx ├── VoiceChat.tsx └── HelpFAB.tsx stores/ ← Zustand stores ├── auth.ts (migration target from AuthContext) ├── ideas.ts └── settings.ts api/ ← HTTP client ├── client.ts └── endpoints.ts constants/ ← i18n-ready strings └── strings.ts hooks/ ← Custom hooks ├── useVoiceCommands.ts └── useBroadcastChannel.ts types/ ← Shared TS types └── index.ts ``` ### Data Flow ``` User Action (click, voice) → Page component → Zustand store action (or react-hook-form submit) → api/client.ts (fetch with JWT) → FastAPI endpoint → Service layer → Database / AI ← Response ← JSON ← Store update (set state) ← React re-render (only subscribers) ← UI update ``` ### Auth Flow ``` Login/Register → POST /api/v1/auth/login ← { access_token, refresh_token } → setTokens() → localStorage → Zustand store: user = fetched /users/me → apiFetch() reads token from store (not localStorage) On page load: → isAuthenticated() checks localStorage → GET /users/me → 200: setUser(data) → 401: clearTokens(), redirect /login ``` ### Error Boundary Flow ``` Error in render → catches (componentDidCatch) → Logs to console.error → Shows (fallback UI) → User clicks "На главную" → navigate("/") ``` ## Backend Layer See `app/` directory structure. Key modules: - `app/api/v1/` — REST endpoints (auth, ideas, users, admin, agents, sync) - `app/services/` — Business logic - `app/models/` — SQLAlchemy ORM - `app/schemas/` — Pydantic request/response - `app/agents/` — 11 system agents (DocAgent, QATesterAgent, etc.) - `app/integrations/` — AI providers (YandexGPT, GigaChat), OAuth - `app/core/` — Config, security, DB, dependencies ## Design Tokens Source of truth: `docs/design-system/tokens.json` Generators: | Platform | Generator | Output | |----------|-----------|--------| | Web (CSS) | `generators/css_generator.py` | `app/design-tokens/css/theme.css` | | iOS (Swift) | `generators/swift_generator.py` | `app/design-tokens/swift/Colors.swift` | | Android (Kotlin) | `generators/kotlin_generator.py` | `app/design-tokens/kotlin/colors.xml` | ## Backups - Cron: daily at 03:00 (server time) - Retention: 7 days - Output: `/opt/voidea/backups/` - Tool: `tools/backup_db.py`