- Remove unused stockMappingsCache variable (dead code after selectStockMappingRow removal)
- Move data-description from SVG to button element for reliable access
- Add disabled guard on bulk add/ignore buttons to prevent duplicate requests
- Return explicit error in UpsertIgnoreRule when rule already exists
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixed application freezing in offline mode by preventing unnecessary
reconnection attempts:
**Changes:**
1. **DSN timeouts** (localdb.go)
- Added timeout=3s, readTimeout=3s, writeTimeout=3s to MySQL DSN
- Reduces connection timeout from 75s to 3s when MariaDB unreachable
2. **Fast /api/db-status** (main.go)
- Check connection status before attempting GetDB()
- Avoid reconnection attempts on every status request
- Returns cached offline status instantly
3. **Optimized sync service** (sync/service.go)
- GetStatus() checks connection status before GetDB()
- NeedSync() skips server check if already offline
- Prevents repeated 3s timeouts on every sync info request
4. **Local pricelist fallback** (pricelist.go)
- GetLatest() returns local pricelists when server offline
- UI can now display pricelist version in offline mode
5. **Better UI error messages** (configs.html)
- 404 shows "Не загружен" instead of "Ошибка загрузки"
- Network errors show "Не доступен" in gray
- Distinguishes between missing data and real errors
**Performance:**
- Before: 75s timeout on every offline request
- After: <5ms response time in offline mode
- Cached error state prevents repeated connection attempts
**User Impact:**
- UI no longer freezes when loading pages offline
- Instant page loads and API responses
- Pricelist version displays correctly in offline mode
- Clear visual feedback for offline state
Fixes Phase 2.5 offline mode performance issues.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated sync-related code to use ConnectionManager instead of direct
database references:
- SyncService now creates repositories on-demand when connection available
- SyncHandler uses ConnectionManager for lazy DB access
- Added ComponentFilter and ListComponents to localdb for offline queries
- All sync operations check connection status before attempting MariaDB access
This completes the transition to offline-first architecture where all
database access goes through ConnectionManager.
Part of Phase 2.5: Full Offline Mode
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Introduced ConnectionManager to support offline-first architecture:
- New internal/db/connection.go with thread-safe connection management
- Lazy connection establishment (5s timeout, 10s cooldown)
- Automatic ping caching (30s interval) to avoid excessive checks
- Updated middleware/offline.go to use ConnectionManager.IsOnline()
- Updated sync/worker.go to use ConnectionManager instead of direct DB
This enables the application to start without MariaDB and gracefully
handle offline/online transitions.
Part of Phase 2.5: Full Offline Mode
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed two critical issues preventing offline-first operation:
1. **Instant startup** - Removed blocking GetDB() call during server
initialization. Server now starts in <10ms instead of 1+ minute.
- Changed setupRouter() to use lazy DB connection via ConnectionManager
- mariaDB connection is now nil on startup, established only when needed
- Fixes timeout issues when MariaDB is unreachable
2. **Offline mode nil pointer panics** - Added graceful degradation
when database is offline:
- ComponentService.GetCategories() returns DefaultCategories if repo is nil
- ComponentService.List/GetByLotName checks for nil repo
- PricelistService methods return empty/error responses in offline mode
- All methods properly handle nil repositories
**Before**: Server startup took 1min+ and crashed with nil pointer panic
when trying to load /configurator page offline.
**After**: Server starts instantly and serves pages in offline mode using
DefaultCategories and SQLite data.
Related to Phase 2.5: Full Offline Mode (local-first architecture)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Implement RefreshPrices for local-first mode
- Update prices from local_components.current_price cache
- Graceful degradation when component not found
- Add PriceUpdatedAt timestamp to LocalConfiguration model
- Support both authenticated and no-auth price refresh
- Fix sync duplicate entry bug
- pushConfigurationUpdate now ensures server_id exists before update
- Fetch from LocalConfiguration.ServerID or search on server if missing
- Update local config with server_id after finding
- Add application auto-restart after settings save
- Implement restartProcess() using syscall.Exec
- Setup handler signals restart via channel
- Setup page polls /health endpoint and redirects when ready
- Add "Back" button on setup page when settings exist
- Fix setup handler password handling
- Use PasswordEncrypted field consistently
- Support empty password by using saved value
- Improve sync status handling
- Add fallback for is_offline check in SyncStatusPartial
- Enhance background sync logging with prefixes
- Update CLAUDE.md documentation
- Mark Phase 2.5 tasks as complete
- Add UI Improvements section with future tasks
- Update SQLite tables documentation
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add price_updated_at field to qt_configurations table to track when prices were last updated
- Add RefreshPrices() method in configuration service to update all component prices with current values from database
- Add POST /api/configs/:uuid/refresh-prices API endpoint for price updates
- Add "Refresh Prices" button in configurator UI next to Save button
- Display last price update timestamp in human-readable format (e.g., "5 min ago", "2 hours ago")
- Create migration 004_add_price_updated_at.sql for database schema update
- Update CLAUDE.md documentation with new API endpoint and schema changes
- Add MIGRATION_PRICE_REFRESH.md with detailed migration instructions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Основные изменения:
1. CSV экспорт и веб-интерфейс:
- Компоненты теперь сортируются по иерархии категорий (display_order)
- Категории отображаются в правильном порядке: BB, CPU, MEM, GPU и т.д.
- Компоненты без категории отображаются в конце
2. Раздел PCI в конфигураторе:
- Разделен на секции: GPU/DPU, NIC/HCA, HBA
- Улучшена навигация и выбор компонентов
3. Сохранение "своей цены":
- Добавлено поле custom_price в модель Configuration
- Создана миграция 002_add_custom_price.sql
- "Своя цена" сохраняется при сохранении конфигурации
- При загрузке конфигурации восстанавливается сохраненная цена
4. Автосохранение:
- Конфигурация автоматически сохраняется через 1 секунду после изменений
- Debounce предотвращает избыточные запросы
- Автосохранение работает для всех изменений (компоненты, количество, цена)
5. Дополнительно:
- Добавлен cmd/importer для импорта метаданных из таблицы lot
- Создан скрипт apply_migration.sh для применения миграций
- Оптимизирована работа с категориями в ExportService
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Добавлено отображение последней полученной цены в окне настройки цены
- Добавлен функционал переименования конфигураций (PATCH /api/configs/:uuid/rename)
- Изменён формат имени файла при экспорте: "YYYY-MM-DD NAME SPEC.ext"
- Исправлена сортировка компонентов: перенесена на сервер для корректной работы с пагинацией
- Добавлен расчёт popularity_score на основе котировок из lot_log
- Исправлена потеря настроек (метод, период, коэффициент) при пересчёте цен
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tab-based configurator (Base, Storage, PCI, Power, Accessories, Other)
- Base tab: single-select with autocomplete for MB, CPU, MEM
- Other tabs: multi-select with autocomplete and quantity input
- Table view with LOT, Description, Price, Quantity, Total columns
- Add configuration list page with create modal (opportunity number)
- Remove Excel export functionality and excelize dependency
- Increase component list limit from 100 to 5000
- Add web templates (base, index, configs, login, admin_pricing)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Go module with Gin, GORM, JWT, excelize dependencies
- Configuration loading from YAML with all settings
- GORM models for users, categories, components, configurations, alerts
- Repository layer for all entities
- Services: auth (JWT), pricing (median/average/weighted), components,
quotes, configurations, export (CSV/XLSX), alerts
- Middleware: JWT auth, role-based access, CORS
- HTTP handlers for all API endpoints
- Main server with dependency injection and graceful shutdown
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>