Refactor vendor mappings to canonical PN catalog
This commit is contained in:
@@ -168,13 +168,12 @@ Reworked partnumber book storage so `qt_partnumber_book_items` is a deduplicated
|
||||
- `qt_partnumber_book_items` now stores one row per `partnumber` with fields:
|
||||
- `partnumber`
|
||||
- `lots_json` (`[{lot_name, qty}, ...]`)
|
||||
- `is_primary_pn`
|
||||
- `description`
|
||||
- `qt_partnumber_books` now stores `partnumbers_json`, the sorted list of PN values included in that book.
|
||||
- QuoteForge read contract is now:
|
||||
- read active book from `qt_partnumber_books`
|
||||
- parse `partnumbers_json`
|
||||
- load PN payloads via `SELECT partnumber, lots_json, is_primary_pn, description FROM qt_partnumber_book_items WHERE partnumber IN (...)`
|
||||
- load PN payloads via `SELECT partnumber, lots_json, description FROM qt_partnumber_book_items WHERE partnumber IN (...)`
|
||||
- `PartnumberBookService.CreateSnapshot` now:
|
||||
- builds one logical item per PN,
|
||||
- serializes bundle composition into `lots_json`,
|
||||
@@ -209,6 +208,106 @@ Reworked partnumber book storage so `qt_partnumber_book_items` is a deduplicated
|
||||
- Tests: `internal/services/partnumber_book_test.go`
|
||||
- Docs: `bible-local/vendor-mapping.md`
|
||||
|
||||
## 2026-03-07: Remove `is_primary_pn` From Partnumber Books
|
||||
|
||||
### Decision
|
||||
|
||||
Removed `is_primary_pn` from PriceForge partnumber book storage and from the PriceForge → QuoteForge sync contract.
|
||||
|
||||
### What changed
|
||||
|
||||
- Added migration `031_drop_is_primary_pn.sql` dropping `is_primary_pn` from:
|
||||
- `lot_partnumbers`
|
||||
- `qt_partnumber_book_items`
|
||||
- Removed `IsPrimaryPN` from `internal/models/lot.go`.
|
||||
- `PartnumberBookService` no longer copies, compares, or upserts `is_primary_pn`.
|
||||
- `VendorMappingService` no longer writes `is_primary_pn` into `qt_partnumber_book_items`.
|
||||
- The sync contract for QuoteForge is now:
|
||||
`SELECT partnumber, lots_json, description FROM qt_partnumber_book_items WHERE partnumber IN (...)`
|
||||
|
||||
### Rationale
|
||||
|
||||
- The flag is obsolete and does not participate in current business logic.
|
||||
- PN composition is now fully represented by `lots_json`; qty semantics belong there.
|
||||
- Keeping a dead compatibility field increases drift between documented and actual architecture.
|
||||
|
||||
### Constraints
|
||||
|
||||
- `lots_json` is the only quantity-bearing field in the PN book contract.
|
||||
- Any consumer still relying on `is_primary_pn` must be updated in the same change wave.
|
||||
|
||||
### Files
|
||||
|
||||
- Migration: `migrations/031_drop_is_primary_pn.sql`
|
||||
- Models: `internal/models/lot.go`
|
||||
- Services: `internal/services/partnumber_book.go`, `internal/services/vendor_mapping.go`
|
||||
- Docs: `bible-local/vendor-mapping.md`
|
||||
|
||||
## 2026-03-07: Drop Legacy `lot_partnumbers` And Bundle Tables
|
||||
|
||||
### Decision
|
||||
|
||||
Removed `lot_partnumbers`, `qt_lot_bundles`, and `qt_lot_bundle_items` from active runtime architecture. The only canonical PN mapping store is `qt_partnumber_book_items`, one row per `partnumber`, with full composition in `lots_json`.
|
||||
|
||||
### What changed
|
||||
|
||||
- Added migration `032_drop_legacy_vendor_mapping_tables.sql` dropping:
|
||||
- `qt_lot_bundle_items`
|
||||
- `qt_lot_bundles`
|
||||
- `lot_partnumbers`
|
||||
- `internal/models/models.go` no longer auto-migrates legacy mapping and bundle tables.
|
||||
- Active runtime paths now read canonical mappings from `qt_partnumber_book_items`.
|
||||
- Tests were updated to seed `qt_partnumber_book_items` instead of `lot_partnumbers` and bundle tables.
|
||||
- Active Bible docs now describe `qt_partnumber_book_items` as the only source of truth.
|
||||
|
||||
### Rationale
|
||||
|
||||
- QuoteForge and partnumber books already use `lots_json`.
|
||||
- Keeping legacy mapping tables in runtime created two conflicting contracts.
|
||||
- Multi-LOT PN composition belongs in `lots_json`, not in auxiliary bundle tables.
|
||||
|
||||
### Constraints
|
||||
|
||||
- `qt_partnumber_book_items` must remain deduplicated by `partnumber`.
|
||||
- Multi-LOT PN composition exists only in `lots_json`.
|
||||
- Vendor is metadata in `qt_vendor_partnumber_seen`, not part of the canonical mapping key.
|
||||
- Deprecated Go structs may remain temporarily for in-memory test compatibility, but runtime must not auto-create or depend on the dropped tables.
|
||||
|
||||
### Files
|
||||
|
||||
- Migration: `migrations/032_drop_legacy_vendor_mapping_tables.sql`
|
||||
- Models: `internal/models/models.go`, `internal/models/lot.go`
|
||||
- Services: `internal/services/vendor_mapping.go`, `internal/services/stock_import.go`, `internal/services/partnumber_book.go`
|
||||
- Warehouse: `internal/warehouse/snapshot.go`
|
||||
- Matcher: `internal/lotmatch/matcher.go`
|
||||
- Docs: `bible-local/BIBLE.md`, `bible-local/vendor-mapping.md`, `bible-local/architecture.md`, `bible-local/pricelist.md`, `bible-local/data-rules.md`
|
||||
|
||||
## 2026-03-07: Vendor Mapping LOT Autocomplete Must Not Clip Long Names
|
||||
|
||||
### Decision
|
||||
|
||||
LOT autocomplete in the Vendor Mapping modal must use a custom popup, not native browser `datalist`, because operators work with long monospaced LOT names that must remain fully readable.
|
||||
|
||||
### What changed
|
||||
|
||||
- Vendor Mapping modal uses a custom positioned suggestion popup for LOT inputs.
|
||||
- Popup width may exceed the input width and is constrained by viewport, not by the text field width.
|
||||
- Native `datalist` is not used for this field anymore.
|
||||
|
||||
### Rationale
|
||||
|
||||
- Native browser suggestion UIs clip long LOT names unpredictably and differ across platforms.
|
||||
- Operators need to distinguish long hardware LOT names visually before selection; clipped suffixes are operationally unsafe.
|
||||
|
||||
### Constraints
|
||||
|
||||
- LOT suggestion popup must allow long names to be fully visible or significantly less clipped than the input width.
|
||||
- Popup must stay above the modal overlay and follow the active LOT input.
|
||||
|
||||
### Files
|
||||
|
||||
- UI: `web/templates/vendor_mappings.html`
|
||||
|
||||
---
|
||||
|
||||
## 2026-02-20: Pricelist Formation Hardening (Estimate/Warehouse/Meta)
|
||||
|
||||
Reference in New Issue
Block a user