Implements complete offline-first architecture with SQLite caching and MariaDB synchronization. Key features: - Local SQLite database for offline operation (data/quoteforge.db) - Connection settings with encrypted credentials - Component and pricelist caching with auto-sync - Sync API endpoints (/api/sync/status, /components, /pricelists, /all) - Real-time sync status indicator in UI with auto-refresh - Offline mode detection middleware - Migration tool for database initialization - Setup wizard for initial configuration New components: - internal/localdb: SQLite repository layer (components, pricelists, sync) - internal/services/sync: Synchronization service - internal/handlers/sync: Sync API handlers - internal/handlers/setup: Setup wizard handlers - internal/middleware/offline: Offline detection - cmd/migrate: Database migration tool UI improvements: - Setup page for database configuration - Sync status indicator with online/offline detection - Warning icons for pending synchronization - Auto-refresh every 30 seconds Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
108 lines
4.3 KiB
Markdown
108 lines
4.3 KiB
Markdown
# QuoteForge - Claude Code Instructions
|
|
|
|
## Overview
|
|
Корпоративный конфигуратор серверов и формирование КП. MariaDB (RFQ_LOG) + SQLite для оффлайн.
|
|
|
|
## Development Phases
|
|
|
|
### Phase 1: Pricelists in MariaDB ✅ DONE
|
|
### Phase 2: Local SQLite Database ✅ DONE
|
|
|
|
### Phase 2.5: Full Offline Mode 🔶 IN PROGRESS
|
|
Приложение должно полностью работать без MariaDB, синхронизация при восстановлении связи.
|
|
|
|
**Architecture:**
|
|
- Dual-source pattern: все операции идут через unified service layer
|
|
- Online: read/write MariaDB, async cache to SQLite
|
|
- Offline: read/write SQLite, queue changes for sync
|
|
|
|
**TODO:**
|
|
- ❌ Unified repository interface (online/offline transparent switching)
|
|
- ❌ Sync queue table (pending_changes: entity_type, entity_uuid, operation, payload, created_at)
|
|
- ❌ Background sync worker (push local changes when online)
|
|
- ❌ Conflict resolution (last-write-wins by updated_at, or manual)
|
|
- ❌ Initial data bootstrap (first sync downloads all needed data)
|
|
- ❌ Handlers use context.IsOffline to choose data source
|
|
- ❌ UI: pending changes counter, manual sync button, conflict alerts
|
|
|
|
**Sync flow:**
|
|
1. Online → Offline: continue work, changes saved locally with sync_status='pending'
|
|
2. Offline → Online: background worker pushes pending_changes, pulls updates
|
|
3. Conflict: if server version newer, mark as 'conflict' for manual resolution
|
|
|
|
### Phase 3: Projects and Specifications
|
|
- qt_projects, qt_specifications tables (MariaDB)
|
|
- Replace qt_configurations → Project/Specification hierarchy
|
|
- Fields: opty, customer_requirement, variant, qty, rev
|
|
- Local projects/specs with server sync
|
|
|
|
### Phase 4: Price Versioning
|
|
- Bind specifications to pricelist versions
|
|
- Price diff comparison
|
|
- Auto-cleanup expired pricelists (>1 year, usage_count=0)
|
|
|
|
## Tech Stack
|
|
Go 1.22+ | Gin | GORM | MariaDB 11 | SQLite (glebarez/sqlite) | htmx + Tailwind CDN | excelize
|
|
|
|
## Key Tables
|
|
|
|
### READ-ONLY (external systems)
|
|
- `lot` (lot_name PK, lot_description)
|
|
- `lot_log` (lot, supplier, date, price, quality, comments)
|
|
- `supplier` (supplier_name PK)
|
|
|
|
### MariaDB (qt_* prefix)
|
|
- `qt_lot_metadata` - component prices, methods, popularity
|
|
- `qt_categories` - category codes and names
|
|
- `qt_pricelists` - version snapshots (YYYY-MM-DD-NNN format)
|
|
- `qt_pricelist_items` - prices per pricelist
|
|
- `qt_projects` - uuid, opty, customer_requirement, name (Phase 3)
|
|
- `qt_specifications` - project_id, pricelist_id, variant, rev, qty, items JSON (Phase 3)
|
|
|
|
### SQLite (data/quoteforge.db)
|
|
- `connection_settings` - encrypted DB credentials
|
|
- `local_pricelists/items` - cached from server
|
|
- `local_components` - lot cache for offline search
|
|
- `local_configurations` - with sync_status (pending/synced/conflict)
|
|
- `local_projects/specifications` - Phase 3
|
|
- `pending_changes` - sync queue (entity_type, uuid, op, payload, created_at)
|
|
|
|
## Business Logic
|
|
|
|
**Part number parsing:** `CPU_AMD_9654` → category=`CPU`, model=`AMD_9654`
|
|
|
|
**Price methods:** manual | median | average | weighted_median
|
|
|
|
**Price freshness:** fresh (<30d, ≥3 quotes) | normal (<60d) | stale (<90d) | critical
|
|
|
|
**Pricelist version:** `YYYY-MM-DD-NNN` (e.g., `2024-01-31-001`)
|
|
|
|
## API Endpoints
|
|
|
|
| Group | Endpoints |
|
|
|-------|-----------|
|
|
| Setup | GET/POST /setup, POST /setup/test |
|
|
| Components | GET /api/components, /api/categories |
|
|
| Pricelists | CRUD /api/pricelists, GET /latest, POST /compare |
|
|
| Projects | CRUD /api/projects/:uuid (Phase 3) |
|
|
| Specs | CRUD /api/specs/:uuid, POST /upgrade, GET /diff (Phase 3) |
|
|
| Sync | GET /status, POST /components, /pricelists, /push, /pull, /resolve-conflict |
|
|
| Export | GET /api/specs/:uuid/export, /api/projects/:uuid/export |
|
|
|
|
## Commands
|
|
```bash
|
|
go run ./cmd/server # Dev server
|
|
go run ./cmd/cron -job=X # cleanup-pricelists | update-prices | update-popularity
|
|
CGO_ENABLED=0 go build -ldflags="-s -w" -o bin/quoteforge ./cmd/server
|
|
```
|
|
|
|
## Code Style
|
|
- gofmt, structured logging (slog), wrap errors with context
|
|
- snake_case files, PascalCase types
|
|
- RBAC disabled: DB username = user_id via `models.EnsureDBUser()`
|
|
|
|
## UI Guidelines
|
|
- htmx (hx-get/post/target/swap), Tailwind CDN
|
|
- Freshness colors: green (fresh) → yellow → orange → red (critical)
|
|
- Sync status + offline indicator in header
|