Commit Graph
100 Commits
Author SHA1 Message Date
Mikhail Chusavitin 7e1e2ac18d Fix storage sync and configurator category visibility 2026-04-15 18:40:34 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 aea6bf91ab fix: abbreviate GPU architecture suffixes in article token
Ampere, Hopper, Blackwell now produce AMP/HOP/BWL suffixes (like ADA)
so RTX cards across generations are distinguishable: RTX6000ADA vs
RTX6000BWL. LOVELACE remains a skip token as it duplicates ADA info.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 15:08:47 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 d58d52c5e7 fix: include model number and ADA suffix in GPU article token
RTX 6000 ADA and A6000 are distinct cards — RTX_4000_ADA_SFF now
produces RTX4000ADA instead of RTX, avoiding visual ambiguity with
the segment separator (10xRTX4000ADA vs 10xRTX-1x…).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 15:07:25 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 7a628deb8a feat: add СХД configuration type with storage-specific tabs and LOT catalog guide
- Add config_type field ("server"|"storage") to Configuration and LocalConfiguration
- Create modal: Сервер/СХД segmented control in configs.html and project_detail.html
- Configurator: ENC/DKC/CTL categories in Base tab, HIC section in PCI tab hidden for server configs
- Add SW tab (categories: SW) to configurator, visible only when components present
- TAB_CONFIG.pci: add HIC section for storage HIC adapters (separate from server HBA/NIC)
- Migration 029: ALTER TABLE qt_configurations ADD COLUMN config_type
- Fix: skip Error 1833 (Cannot change column used in FK) in GORM AutoMigrate
- Operator guide: docs/storage-components-guide.md with LOT naming rules and DE4000H catalog template

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:01:23 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 7f6be786a8 feat: redesign project pricing export — FOB/DDP basis, variant filename, article column
- Add FOB/DDP basis to export options; DDP multiplies all prices ×1.3
- Rename export file from "pricing" to "{FOB|DDP} {variant}" (e.g. "FOB v1")
- Fix server article missing from CSV summary row (PN вендора column)
- Skip per-row breakdown when neither LOT nor BOM is selected
- Remove empty separator rows between configurations
- Redesign export modal: split into Артикул / Цены / Базис поставки sections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 17:55:26 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 a360992a01 perf: enable WAL mode, batch price lookup, add DB diagnostics to schema_state
- Set PRAGMA journal_mode=WAL + synchronous=NORMAL on SQLite open;
  eliminates read blocking during background pricelist sync writes
- Replace N+1 per-lot price loop in QuoteService local fallback with
  GetLocalPricesForLots batch query (120 queries → 3 per price-levels call)
- Add CountAllPricelistItems, CountComponents, DBFileSizeBytes to LocalDB
- Report local_pricelist_count, pricelist_items_count, components_count,
  db_size_bytes in qt_client_schema_state for performance diagnostics

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 10:53:36 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 1ea21ece33 docs: add MariaDB user permissions reference to bible-local
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 17:22:16 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 7ae804d2d3 fix: prevent config creation hang on pricelist sync
SyncPricelistsIfNeeded was called synchronously in Create(), blocking
the HTTP response for several seconds while pricelist data was fetched.
Users clicking multiple times caused 6+ duplicate configurations.

- Run SyncPricelistsIfNeeded in a goroutine so Create() returns immediately
- Add TryLock mutex to SyncPricelistsIfNeeded to skip concurrent calls

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 12:34:57 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 da5414c708 fix: handle ErrCannotRenameMainVariant in PATCH /api/projects/:uuid
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 10:22:45 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 7a69c1513d chore: rename page titles from QuoteForge to OFS
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 17:41:42 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 f448111e77 fix: block renaming main project variant; dynamic page titles
- Add ErrCannotRenameMainVariant; ProjectService.Update now returns
  this error if the caller tries to change the Variant of a main
  project (empty Variant) — ensures there is always exactly one main
- Handle ErrCannotRenameMainVariant in PUT /api/projects/:uuid with 400
- Set document.title dynamically from breadcrumb data:
  - Configurator: "CODE / variant / Config name — QuoteForge"
  - Project detail: "CODE / variant — QuoteForge"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 17:29:02 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 a5dafd37d3 chore: update bible submodule
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 17:20:26 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 3661e345b1 fix: pricelist selection preserved when opening configurations
- Remove 'auto (latest active)' option from pricelist dropdowns; new
  configs pre-select the first active pricelist instead
- Stop resetting stored pricelist_id to null when it is not in the
  active list (deactivated pricelists are shown as inactive options)
- RefreshPricesNoAuth now accepts an optional pricelist_id; uses the
  UI-selected pricelist, then the config's stored pricelist, then
  latest as a last-resort fallback — no longer silently overwrites
  the stored pricelist on every price refresh
- Same fix applied to RefreshPrices (with auth)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 15:24:57 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 f915866f83 docs: document final RFQ_LOG MariaDB schema (2026-03-21)
Expand 03-database.md with complete table structure reference for all
23 tables in the final schema: active QuoteForge tables, competitor
subsystem, legacy RFQ tables, and server-side-only tables.

Also clarifies access patterns per group and notes removal of
qt_client_local_migrations from the schema.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 17:24:03 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 c34a42aaf5 Show build version in page footer
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 17:51:13 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 7de0f359b6 Pricing tab: per-LOT row expansion with rowspan grouping
- Reorder columns: PN вендора / Описание / LOT / Кол-во / Estimate / Склад / Конкуренты / Ручная цена
- Explode multi-LOT BOM rows into individual LOT sub-rows; PN вендора + Описание use rowspan to span the group
- Rename "Своя цена" → "Ручная цена", "Проставить цены BOM" → "BOM Цена"
- CSV export reads PN/Desc/LOT from data attributes to handle rowspan offset correctly
- Document pricing tab layout contract in bible-local/02-architecture.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 23:53:32 +03:00
Mikhail Chusavitin a8d8d7dfa9 Treat current configuration as main 2026-03-17 18:43:49 +03:00
Mikhail Chusavitin 20ce0124be Vendor frontend assets locally 2026-03-17 18:41:53 +03:00
Mikhail Chusavitin b0a106415f Make sync status non-blocking 2026-03-17 18:34:28 +03:00
Mikhail Chusavitin a054fc7564 Version BOM and pricing changes 2026-03-17 18:24:09 +03:00
Mikhail Chusavitin 68cd087356 Fix incomplete pricelist sync status 2026-03-17 12:05:02 +03:00
Mikhail Chusavitin 579ff46a7f fix(release): preserve release notes template - v1.5.4 2026-03-16 08:33:53 +03:00
Mikhail Chusavitin 35c5600b36 fix(qfs): project ui, config naming, sync timestamps - v1.5.4 2026-03-16 08:32:15 +03:00
Mikhail Chusavitin c599897142 Simplify project documentation and release notes 2026-03-15 16:43:06 +03:00
Mikhail Chusavitin c964d66e64 Harden local runtime safety and error handling 2026-03-15 16:28:32 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 f0e6bba7e9 Remove partnumbers column from all pricelist views (data mixed across sources)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 14:24:15 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 61d7e493bd Hide partnumbers column for competitor pricelist (data not linked locally)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 14:23:20 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 f930c79b34 Remove Поставщик column from pricelist detail (placeholder data)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 14:22:26 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 a0a57e0969 Redesign pricelist detail: differentiated layout by source type
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 13:14:14 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 b3003c4858 Redesign pricing tab: split into purchase/sale tables with unit prices
- Split into two sections: Цена покупки and Цена продажи
- All price cells show unit price (per 1 pcs); totals only in footer
- Added note "Цены указаны за 1 шт." next to each table heading
- Buy table: Своя цена redistributes proportionally with green/red coloring vs estimate; footer shows % diff
- Sale table: configurable uplift (default 1.3) applied to estimate; Склад/Конкуренты fixed at ×1.3
- Footer Склад/Конкуренты marked red with asterisk tooltip when coverage is partial
- CSV export updated: all 8 columns, SPEC-BUY/SPEC-SALE suffix, no % annotation in totals

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 12:55:17 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 e2da8b4253 Fix competitor price display and pricelist item deduplication
- 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>
2026-03-13 10:33:04 +03:00
Mikhail Chusavitin 06397a6bd1 Local-first runtime cleanup and recovery hardening 2026-03-07 23:18:07 +03:00
Mikhail Chusavitin 4e977737ee Document legacy BOM tables 2026-03-07 21:13:08 +03:00
Mikhail Chusavitin 7c3752f110 Add vendor workspace import and pricing export workflow 2026-03-07 21:03:40 +03:00
Mikhail Chusavitin 08ecfd0826 Merge branch 'feature/vendor-spec-import' 2026-03-06 10:54:05 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 42458455f7 Fix article generator producing 1xINTEL in GPU segment
MB_ lots (e.g. MB_INTEL_..._GPU8) are incorrectly categorized as GPU
in the pricelist. Two fixes:
- Skip MB_ lots in buildGPUSegment regardless of pricelist category
- Add INTEL to vendor token skip list in parseGPUModel (was missing,
  unlike AMD/NV/NVIDIA which were already skipped)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 10:53:31 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 8663a87d28 Fix article generator producing 1xINTEL in GPU segment
MB_ lots (e.g. MB_INTEL_..._GPU8) are incorrectly categorized as GPU
in the pricelist. Two fixes:
- Skip MB_ lots in buildGPUSegment regardless of pricelist category
- Add INTEL to vendor token skip list in parseGPUModel (was missing,
  unlike AMD/NV/NVIDIA which were already skipped)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 10:52:22 +03:00
Mikhail Chusavitin 6e0335af7c Fix pricing tab warehouse totals and guard custom price DOM access 2026-02-27 16:53:34 +03:00
Mikhail Chusavitin a42a80beb8 fix(bom): preserve local vendor spec on config import 2026-02-27 10:11:20 +03:00
Mikhail Chusavitin 586114c79c refactor(bom): enforce canonical lot_mappings persistence 2026-02-27 09:47:46 +03:00
Mikhail Chusavitin e9230c0e58 feat(bom): canonical lot mappings and updated vendor spec docs 2026-02-25 19:07:27 +03:00
Mikhail Chusavitin aa65fc8156 Fix project line numbering and reorder bootstrap 2026-02-25 17:19:26 +03:00
Mikhail Chusavitin b22e961656 feat(projects): compact table layout for dates and names 2026-02-25 17:19:26 +03:00
Mikhail Chusavitin af83818564 fix(pricelists): tolerate restricted DB grants and use embedded assets only 2026-02-25 17:19:26 +03:00
Mikhail Chusavitin 8a138327a3 fix(sync): backfill missing items for existing local pricelists 2026-02-25 17:18:57 +03:00
Mikhail Chusavitin d1f65f6684 feat(projects): compact table layout for dates and names 2026-02-24 15:42:04 +03:00
Mikhail Chusavitin 7b371add10 Merge branch 'stable'
# Conflicts:
#	bible/03-database.md
2026-02-24 15:13:41 +03:00
Mikhail Chusavitin 8d7fab39b4 fix(pricelists): tolerate restricted DB grants and use embedded assets only 2026-02-24 15:09:12 +03:00
Mikhail Chusavitin 1906a74759 fix(sync): backfill missing items for existing local pricelists 2026-02-24 14:54:38 +03:00
Mikhail Chusavitin 3c46cd7bf0 Fix auto pricelist resolution and latest-price selection; update Bible 2026-02-20 19:15:24 +03:00
Mikhail Chusavitin 7f8491d197 docs(bible): require updates on user-requested commits 2026-02-20 15:39:00 +03:00
Mikhail Chusavitin 3fd7a2231a Add persistent startup console warning 2026-02-20 14:37:21 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 c295b60dd8 docs: introduce bible/ as single source of architectural truth
- Add bible/ with 7 hierarchical English-only files covering overview,
  architecture, database schemas, API endpoints, config/env, backup, and dev guides
- Consolidate all docs from README.md, CLAUDE.md, man/backup.md into bible/
- Simplify CLAUDE.md to a single rule: read and respect the bible
- Simplify README.md to a brief intro with links to bible/
- Remove man/backup.md and pricelists_window.md (content migrated or obsolete)
- Fix API docs: add missing endpoints (preview-article, sync/repair),
  correct DELETE /api/projects/:uuid semantics (variant soft-delete only)
- Add Soft Deletes section to architecture doc (is_active pattern)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 14:15:52 +03:00
Mikhail Chusavitin 9b5d57902d Add project variants and UI updates 2026-02-13 19:27:48 +03:00
Mikhail Chusavitin 4e1a46bd71 Fix project selection and add project settings UI 2026-02-13 12:51:53 +03:00
Mikhail Chusavitin 857ec7a0e5 Fix article category fallback for pricelist gaps 2026-02-12 16:47:49 +03:00
Mikhail Chusavitin 01f21fa5ac Document backup implementation guide 2026-02-11 19:50:35 +03:00
Mikhail Chusavitin a1edca3be9 Add scheduled rotating local backups 2026-02-11 19:48:40 +03:00
Mikhail Chusavitin 7fbf813952 docs: add release notes for v1.3.0 2026-02-11 19:27:16 +03:00
Mikhail Chusavitin e58fd35ee4 Refine article compression and simplify generator 2026-02-11 19:24:25 +03:00
Mikhail Chusavitin e3559035f7 Allow cross-user project updates 2026-02-11 19:24:16 +03:00
Mikhail Chusavitin 5edffe822b Add article generation and pricelist categories 2026-02-11 19:16:01 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 99fd80bca7 feat: unify sync functionality with event-driven UI updates
- Refactored navbar sync button to dispatch 'sync-completed' event
- Configs page: removed duplicate 'Импорт с сервера' button, added auto-refresh on sync
- Projects page: wrapped initialization in DOMContentLoaded, added auto-refresh on sync
- Pricelists page: added auto-refresh on sync completion
- Consistent UX: all lists update automatically after 'Синхронизация' button click
- Removed code duplication: importConfigsFromServer() function no longer needed
- Event-driven architecture enables easy extension to other pages

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-10 11:11:10 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 d8edd5d5f0 chore: exclude qfs binary and update release notes for v1.2.2
- Add qfs binary to gitignore (compiled executable from build)
- Update UI labels in configuration form for clarity
- Add release notes documenting v1.2.2 changes

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-09 17:50:58 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 9cb17ee03f chore: simplify gitignore rules for releases binaries
- Ignore all files in releases/ directory (binaries, archives, checksums)
- Preserve releases/memory/ for changelog tracking
- Changed from 'releases/' to 'releases/*' for clearer intent

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-09 17:41:41 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 8f596cec68 fix: standardize CSV export filename format to use project name
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>
2026-02-09 17:22:51 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 8fd27d11a7 docs: update v1.2.1 release notes with full changelog
Added comprehensive release notes including:
- Summary of the v1.2.1 patch release
- Bug fix details for configurator component substitution
- API price loading implementation
- Testing verification
- Installation instructions for all platforms
- Migration notes (no DB migration required)

Release notes now provide full context for end users and developers.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-09 15:45:00 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 600f842b82 docs: add releases/memory directory for changelog tracking
Added structured changelog documentation:
- Created releases/memory/ directory to track changes between tags
- Each version has a .md file (v1.2.1.md, etc.) documenting commits and impact
- Updated CLAUDE.md with release notes reference
- Updated README.md with releases section
- Updated .gitignore to track releases/memory/ while ignoring other release artifacts

This helps reviewers and developers understand changes between versions
before making new updates to the codebase.

Initial entry: v1.2.1.md documenting the pricelist refactor and
configurator component substitution fix.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-09 15:40:23 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 acf7c8a4da fix: load component prices via API instead of removed current_price field
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>
2026-02-09 15:31:53 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 5984a57a8b refactor: remove CurrentPrice from local_components and transition to pricelist-based pricing
## Overview
Removed the CurrentPrice and SyncedAt fields from local_components, transitioning to a
pricelist-based pricing model where all prices are sourced from local_pricelist_items
based on the configuration's selected pricelist.

## Changes

### Data Model Updates
- **LocalComponent**: Now stores only metadata (LotName, LotDescription, Category, Model)
  - Removed: CurrentPrice, SyncedAt (both redundant)
  - Pricing is now exclusively sourced from local_pricelist_items

- **LocalConfiguration**: Added pricelist selection fields
  - Added: WarehousePricelistID, CompetitorPricelistID
  - These complement the existing PricelistID (Estimate)

### Migrations
- Added migration "drop_component_unused_fields" to remove CurrentPrice and SyncedAt columns
- Added migration "add_warehouse_competitor_pricelists" to add new pricelist fields

### Component Sync
- Removed current_price from MariaDB query
- Removed CurrentPrice assignment in component creation
- SyncComponentPrices now exclusively updates based on pricelist_items via quote calculation

### Quote Calculation
- Added PricelistID field to QuoteRequest
- Updated local-first path to use pricelist_items instead of component.CurrentPrice
- Falls back to latest estimate pricelist if PricelistID not specified
- Maintains offline-first behavior: local queries work without MariaDB

### Configuration Refresh
- Removed fallback on component.CurrentPrice
- Prices are only refreshed from local_pricelist_items
- If price not found in pricelist, original price is preserved

### API Changes
- Removed CurrentPrice from ComponentView
- Components API no longer returns pricing information
- Pricing is accessed via QuoteService or PricelistService

### Code Cleanup
- Removed UpdateComponentPricesFromPricelist() method
- Removed EnsureComponentPricesFromPricelists() method
- Updated UnifiedRepository to remove offline pricing logic
- Updated converters to remove CurrentPrice mapping

## Architecture Impact
- Components = metadata store only
- Prices = managed by pricelist system
- Quote calculation = owns all pricing logic
- Local-first behavior preserved: SQLite queries work offline, no MariaDB dependency

## Testing
- Build successful
- All code compiles without errors
- Ready for migration testing with existing databases

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-09 14:54:02 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 84dda8cf0a docs: document complete database user permissions for sync support
Add comprehensive database permissions documentation:
- Full list of required tables with their purpose
- Separate sections for: existing user grants, new user creation, and important notes
- Clarifies that sync tables (qt_client_local_migrations, qt_client_schema_state,
  qt_pricelist_sync_status) must be created by DB admin - app doesn't need CREATE TABLE
- Explains read-only vs read-write permissions for each table
- Uses placeholder '<DB_USER>' instead of hardcoded usernames

This helps administrators set up proper permissions without CREATE TABLE requirements,
fixing the sync blockage issue in v1.1.0.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-09 11:30:09 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 abeb26d82d fix: handle database permission issues in sync migration verification
Sync was blocked because the migration registry table creation required
CREATE TABLE permissions that the database user might not have.

Changes:
- Check if migration registry tables exist before attempting to create them
- Skip creation if table exists and user lacks CREATE permissions
- Use information_schema to reliably check table existence
- Apply same fix to user sync status table creation
- Gracefully handle ALTER TABLE failures for backward compatibility

This allows sync to proceed even if the client is a read-limited database user,
as long as the required tables have already been created by an administrator.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-09 11:22:33 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 29edd73744 projects: add /all endpoint for unlimited project list
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>
2026-02-09 11:19:49 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 e8d0e28415 export: add project name to CSV filename format
Update filename format to include both project and quotation names:
  YYYY-MM-DD (PROJECT-NAME) QUOTATION-NAME BOM.csv

Changes:
- Add ProjectName field to ExportRequest (optional)
- Update ExportCSV: use project_name if provided, otherwise fall back to name
- Update ExportConfigCSV: use config name for both project and quotation

Example filenames:
  2026-02-09 (OPS-1957) config1 BOM.csv
  2026-02-09 (MyProject) MyQuotation BOM.csv

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-09 11:02:36 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 08feda9af6 export: use filename from Content-Disposition header in browser
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>
2026-02-09 10:58:01 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 af79b6f3bf export: update CSV filename format to YYYY-MM-DD (PROJECT-NAME) BOM
Change exported CSV filename format from:
  YYYY-MM-DD NAME SPEC.csv
To:
  YYYY-MM-DD (NAME) BOM.csv

Applied to both:
- POST /api/export/csv (direct export)
- GET /api/configs/:uuid/export (config export)

All tests passing.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-09 10:49:56 +03:00
Mikhail ChusavitinandClaude Haiku 4.5 bca82f9dc0 export: implement streaming CSV with Excel compatibility
Implement Phase 1 CSV Export Optimization:
- Replace buffering with true HTTP streaming (ToCSV writes to io.Writer)
- Add UTF-8 BOM (0xEF 0xBB 0xBF) for correct Cyrillic display in Excel
- Use semicolon (;) delimiter for Russian Excel locale
- Use comma (,) as decimal separator in numbers (100,50 instead of 100.50)
- Add graceful two-phase error handling:
  * Before streaming: return JSON errors for validation failures
  * During streaming: log errors only (HTTP 200 already sent)
- Add backward-compatible ToCSVBytes() helper
- Add GET /api/configs/:uuid/export route for configuration export

New tests (13 total):
- Service layer (7 tests):
  * UTF-8 BOM verification
  * Semicolon delimiter parsing
  * Total row formatting
  * Category sorting
  * Empty data handling
  * Backward compatibility wrapper
  * Writer error handling
- Handler layer (6 tests):
  * Successful CSV export with streaming
  * Invalid request validation
  * Empty items validation
  * Config export with proper headers
  * 404 for missing configs
  * Empty config validation

All tests passing, build verified.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-09 10:47:10 +03:00
Mikhail Chusavitin 5f2969a85a Refine stock import UX with suggestions, ignore rules, and inline mapping controls 2026-02-06 19:58:42 +03:00
Mikhail Chusavitin eb8ac34d83 Fix stock mappings JSON fields and enable row selection for editing 2026-02-06 19:39:39 +03:00
Mikhail Chusavitin 104a26d907 Add stock pricelist admin flow with mapping placeholders and warehouse details 2026-02-06 19:37:12 +03:00
Mikhail Chusavitin b965c6bb95 WIP: save current pricing and pricelist changes 2026-02-06 19:07:22 +03:00
Mikhail Chusavitin 29035ddc5a configs: save pending template changes 2026-02-06 16:43:04 +03:00
Mikhail Chusavitin 2f0ac2f6d2 projects: add tracker_url and project create modal 2026-02-06 16:42:32 +03:00
Mikhail Chusavitin 8a8ea10dc2 Add tracker link on project detail page 2026-02-06 16:31:34 +03:00
Mikhail Chusavitin 51e2d1fc83 Fix local pricelist uniqueness and preserve config project on update 2026-02-06 16:00:23 +03:00
Mikhail Chusavitin 3d5ab63970 Make full sync push pending and pull projects/configurations 2026-02-06 15:25:07 +03:00
Mikhail Chusavitin c02a7eac73 Prepare v1.0.3 release notes 2026-02-06 14:04:06 +03:00
Mikhail Chusavitin 651427e0dd Add projects table controls and sync status tab with app version 2026-02-06 14:02:21 +03:00
Mikhail Chusavitin f665e9b08c sync: recover missing server config during update push 2026-02-06 13:41:01 +03:00
Mikhail Chusavitin 994eec53e7 Fix MySQL DSN escaping for setup passwords and clarify DB user setup 2026-02-06 13:27:57 +03:00
Mikhail Chusavitin 2f3c20fea6 update stale files list 2026-02-06 13:03:59 +03:00
Mikhail Chusavitin 80ec7bc6b8 Apply remaining pricelist and local-first updates 2026-02-06 13:01:40 +03:00
Mikhail Chusavitin 8e5c4f5a7c Use admin price-refresh logic for pricelist recalculation 2026-02-06 13:00:27 +03:00
Mikhail Chusavitin 1744e6a3b8 fix: skip startup sql migrations when not needed or no permissions 2026-02-06 11:56:55 +03:00
Mikhail Chusavitin 726dccb07c feat: add projects flow and consolidate default project handling 2026-02-06 11:39:12 +03:00
Mikhail Chusavitin 38d7332a38 Update pricelist repository, service, and tests 2026-02-06 10:14:24 +03:00
Mikhail Chusavitin c0beed021c Enforce pricelist write checks and auto-restart on DB settings change 2026-02-05 15:44:54 +03:00
Mikhail Chusavitin 08b95c293c Purge orphan sync queue entries before push 2026-02-05 15:17:06 +03:00
Mikhail Chusavitin c418d6cfc3 Handle stale configuration sync events when local row is missing 2026-02-05 15:11:43 +03:00
Mikhail Chusavitin 548a256d04 Drop qt_users dependency for configs and track app version 2026-02-05 15:07:23 +03:00