Initial commit: VoIdeaAI - voice-first AI idea assistant
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
# 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
|
||||
→ <ErrorBoundary> catches (componentDidCatch)
|
||||
→ Logs to console.error
|
||||
→ Shows <ServerErrorPage /> (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`
|
||||
Reference in New Issue
Block a user