- Render competitor prices in Pricing tab (all three row branches)
- Add footer total accumulation for competitor column
- Deduplicate local_pricelist_items via migration + unique index
- Use ON CONFLICT DO NOTHING in SaveLocalPricelistItems to prevent duplicates on concurrent sync
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BOM paste: auto-detect columns by content (price, qty, PN, description);
handles $5,114.00 and European comma-decimal formats
- LOT input: HTML5 datalist rebuilt on each renderBOMTable from allComponents;
oninput updates data only (no re-render), onchange validates+resolves
- BOM persistence: PUT handler explicitly marshals VendorSpec to JSON string
(GORM Update does not reliably call driver.Valuer for custom types)
- BOM autosave after every resolveBOM() call
- Pricing tab: async renderPricingTab() calls /api/quote/price-levels for all
resolved LOTs directly — Estimate prices shown even before cart apply
- Unresolved PNs pushed to qt_vendor_partnumber_seen via POST
/api/sync/partnumber-seen (fire-and-forget from JS)
- sync.PushPartnumberSeen(): upsert with ON DUPLICATE KEY UPDATE last_seen_at
- partnumber_books: pull ALL books (not only is_active=1); re-pull items when
header exists but item count is 0; fallback for missing description column
- partnumber_books UI: collapsible snapshot section (collapsed by default),
pagination (10/page), sync button always visible in header
- vendorSpec handlers: use GetConfigurationByUUID + IsActive check (removed
original_username from WHERE — GetUsername returns "" without JWT)
- bible/09-vendor-spec.md: updated with all architectural decisions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Top nav: link to /partnumber-books
- Page: summary cards (active version, unique LOTs, total PN, primary PN)
+ searchable items table for active book
+ collapsible history of all snapshots
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Show supported column formats and auto-detection rules so users
know what to copy from Excel.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Features:
- Configuration versioning: immutable snapshots in local_configuration_versions
- Revisions UI: /configs/:uuid/revisions page to view version history
- Clone from version: ability to clone configuration from specific revision
- Project variant deletion: DELETE /api/projects/:uuid endpoint
- Updated CLAUDE.md with new architecture details and endpoints
Architecture updates:
- local_configuration_versions table for immutable snapshots
- Version tracking on each configuration save
- Rollback capability to previous versions
- Variant deletion with main variant protection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Root cause: Projects with duplicate (code, variant) pairs fail to sync
due to unique constraint on server. Example: multiple "OPS-1934" projects
with variant="Dell" where one already exists on server.
Fixes:
1. Sync service now detects duplicate (code, variant) on server and links
local project to existing server project instead of failing
2. Local repair checks for duplicate (code, variant) pairs and deduplicates
by appending UUID suffix to variant
3. Modal now scrollable with fixed header/footer (max-h-90vh)
This allows users to sync projects that were created offline with
conflicting codes/variants without losing data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements automatic repair mechanism for pending changes with sync errors:
- Projects: validates and fixes empty name/code fields
- Configurations: ensures project references exist or assigns system project
- Clears errors and resets attempts to give changes another sync chance
Backend:
- LocalDB.RepairPendingChanges() with smart validation logic
- POST /api/sync/repair endpoint
- Detailed repair results with remaining errors
Frontend:
- Auto-repair section in sync modal shown when errors exist
- "ИСПРАВИТЬ" button with clear explanation of actions
- Real-time feedback with result messages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Unified export filename format across both ExportCSV and ExportConfigCSV:
- Format: YYYY-MM-DD (project_name) config_name BOM.csv
- Use PriceUpdatedAt if available, otherwise CreatedAt
- Extract project name from ProjectUUID for ExportCSV via projectService
- Pass project_uuid from frontend to backend in export request
- Add projectUUID and projectName state variables to track project context
This ensures consistent naming whether exporting from form or project view,
and uses most recent price update timestamp in filename.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
After the recent refactor that removed CurrentPrice from local_components,
the configurator's autocomplete was filtering out all components because
it checked for the now-removed current_price field.
Instead, now load prices from the API when the user starts typing in a
component search field:
- Added ensurePricesLoaded() to fetch prices via /api/quote/price-levels
- Added componentPricesCache to store loaded prices
- Updated all 3 autocomplete modes (single, multi, section) to load prices
- Changed price checks from c.current_price to hasComponentPrice()
- Updated cart item creation to use cached prices
Components without prices are still filtered out as required, but the check
now uses API data rather than a removed database field.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Solve pagination issue where configs reference projects not in the
paginated list (default 10 items, but there could be 50+ projects).
Changes:
- Add GET /api/projects/all endpoint that returns ALL projects without
pagination as simple {uuid, name} objects
- Update frontend loadProjectsForConfigUI() to use /api/projects/all
instead of /api/projects?status=all
- Ensures all projects are available in projectNameByUUID for config
display, regardless of total project count
This fixes cases where project names don't display in /configs page
for configs that reference projects outside the paginated range.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Fix issue where frontend was ignoring server's Content-Disposition
header and using only config name + '.csv' for exported files.
Added getFilenameFromResponse() helper to extract proper filename
from Content-Disposition header and use it for downloaded files.
Applied to both:
- exportCSV() function
- exportCSVWithCustomPrice() function
Now files are downloaded with correct format:
YYYY-MM-DD (PROJECT-NAME) BOM.csv
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- 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>
- Fix nil pointer dereference in PricingHandler alert methods
- Add automatic MariaDB connection on startup if settings exist
- Update setupRouter to accept mariaDB as parameter
- Fix offline mode checks: use h.db instead of h.alertService
- Update setup handler to show restart required message
- Add warning status support in setup.html UI
This ensures that after saving connection settings, the application
works correctly in online mode after restart. All repositories are
properly initialized with MariaDB connection on startup.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>