Files
QuoteForge/CLAUDE.md
Mikhail Chusavitin f25477a25e add todo
2026-02-02 19:44:45 +03:00

7.6 KiB
Raw Blame History

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

Local-first architecture: приложение ВСЕГДА работает с SQLite, MariaDB только для синхронизации.

Принцип работы:

  • ВСЕ операции (CRUD) выполняются в SQLite
  • При создании конфигурации:
    1. Если online → проверить новые прайслисты на сервере → скачать если есть
    2. Далее работаем с local_pricelists (и online, и offline одинаково)
  • Background sync: push pending_changes → pull updates

DONE:

  • Sync queue table (pending_changes) - internal/localdb/models.go
  • Model converters: MariaDB ↔ SQLite - internal/localdb/converters.go
  • LocalConfigurationService: все CRUD через SQLite - internal/services/local_configuration.go
  • Pre-create pricelist check: SyncPricelistsIfNeeded() - internal/services/sync/service.go
  • Push pending changes: PushPendingChanges() - sync service + handlers
  • Sync API endpoints: /api/sync/push, /pending/count, /pending
  • Integrate LocalConfigurationService in main.go (replace ConfigurationService)
  • Add routes for new sync endpoints (/api/sync/push, /pending/count, /pending)
  • ConfigurationGetter interface for handler compatibility
  • Background sync worker: auto-sync every 5min (push + pull) - internal/services/sync/worker.go
  • UI: sync status indicator (pending badge + sync button + offline/online dot) - web/templates/partials/sync_status.html
  • RefreshPrices for local mode:
    • RefreshPrices() / RefreshPricesNoAuth() в local_configuration.go
    • Берёт цены из local_components.current_price
    • Graceful degradation при отсутствии компонента
    • Добавлено поле price_updated_at в LocalConfiguration (models.go:72)
    • Обновлены converters для PriceUpdatedAt
    • UI кнопка "Пересчитать цену" работает offline/online
  • Fixed sync bugs:
    • Duplicate entry error при update конфигураций (sync/service.go:334-365)
    • pushConfigurationUpdate теперь проверяет наличие server_id перед update
    • Если нет ID → получает из LocalConfiguration.ServerID или ищет на сервере
    • Fixed setup.go: settings.Passwordsettings.PasswordEncrypted

TODO:

  • Conflict resolution (Phase 4, last-write-wins default)

UI Improvements MOSTLY DONE

1. Sync UI + pricelist badge: DONE

  • sync_status.html: SVG иконки Online/Offline (кликабельные → открывают модал)
  • Кнопка sync → иконка circular arrows (только full sync)
  • Модальное окно "Статус системы" в base.html (info о БД, ошибки синхронизации)
  • configs.html: badge с версией активного прайслиста
  • Загрузка через /api/pricelists/latest при DOMContentLoaded
  • Удалён dropdown с Push changes (упрощение UI)

2. Прайслисты → вкладка в "Администратор цен": DONE

  • base.html: убрана ссылка "Прайслисты" из навигации
  • admin_pricing.html: добавлена вкладка "Прайслисты"
  • Логика перенесена из pricelists.html (table, create modal, CRUD)
  • Route /pricelists → редирект на /admin/pricing?tab=pricelists
  • Поддержка URL param ?tab=pricelists

3. Модал "Настройка цены" - кол-во котировок с учётом периода: TODO

  • Текущее: показывает только общее кол-во котировок
  • Новое: показывать N (всего: M) где N - за выбранный период, M - всего
  • admin_pricing.html: обновить #modal-quote-count
  • admin_pricing_handler.go: в /api/admin/pricing/preview возвращать quote_count_period + quote_count_total

4. Страница настроек: ОТЛОЖЕНО

  • Перенесено в Phase 3 (после основных UI улучшений)

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 (PasswordEncrypted field)
  • local_pricelists/items - cached from server
  • local_components - lot cache for offline search (with current_price)
  • local_configurations - UUID, items, price_updated_at, sync_status (pending/synced/conflict), server_id
  • local_projects/specifications - Phase 3
  • pending_changes - sync queue (entity_type, uuid, op, payload, created_at, attempts, last_error)

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)
Configs POST /:uuid/refresh-prices (обновить цены из local_components)
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