Files
QuoteForge/CLAUDE.md
Michael Chus 143d217397 Add Phase 2: Local SQLite database with sync functionality
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>
2026-02-01 11:00:32 +03:00

4.3 KiB

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

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