Modularize Go files, extract JS to static, implement competitor pricelists
Go refactoring: - Split handlers/pricing.go (2446→291 lines) into 5 focused files - Split services/stock_import.go (1334→~400 lines) into stock_mappings.go + stock_parse.go - Split services/sync/service.go (1290→~250 lines) into 3 files JS extraction: - Move all inline <script> blocks to web/static/js/ (6 files) - Templates reduced: admin_pricing 2873→521, lot 1531→304, vendor_mappings 1063→169, etc. Competitor pricelists (migrations 033-039): - qt_competitors + partnumber_log_competitors tables - Excel import with column mapping, dedup, bulk insert - p/n→lot resolution via weighted_median, discount applied - Unmapped p/ns written to qt_vendor_partnumber_seen - Quote counts (unique/total) shown on /admin/competitors - price_method="weighted_median", price_period_days=0 stored explicitly Fix price_method/price_period_days for warehouse items: - warehouse: weighted_avg, period=0 - competitor: weighted_median, period=0 - Removes misleading DB defaults (was: median/90) Update bible: architecture.md, pricelist.md, history.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -459,6 +459,92 @@ Commit `edff712` switched from `weighted_median` to `weighted_avg`.
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 2026-03-13: Go File Modularization
|
||||
|
||||
### Decision
|
||||
|
||||
Split three large Go files into focused modules within the same package.
|
||||
|
||||
### What changed
|
||||
|
||||
- `handlers/pricing.go` (2446 lines) → `pricing.go` (struct + helpers) + `pricing_components.go` + `pricing_alerts.go` + `pricing_stock.go` + `pricing_vendor.go` + `pricing_lots.go`
|
||||
- `services/stock_import.go` (1334 lines) → `stock_import.go` (core) + `stock_mappings.go` + `stock_parse.go`
|
||||
- `services/sync/service.go` (1290 lines) → `service.go` (struct + status) + `sync_pricelists.go` + `sync_changes.go` + `sync_import.go`
|
||||
|
||||
### Rationale
|
||||
|
||||
Files exceeding ~1000 lines are hard to edit safely with AI tooling. Same-package split preserves all existing APIs with zero behavior change.
|
||||
|
||||
---
|
||||
|
||||
## 2026-03-13: JS Extraction to Static Files
|
||||
|
||||
### Decision
|
||||
|
||||
All inline `<script>` blocks extracted from HTML templates to `web/static/js/`.
|
||||
|
||||
### What changed
|
||||
|
||||
- `admin_pricing.html` 2873 → 521 lines; JS → `web/static/js/admin_pricing.js`
|
||||
- `lot.html` 1531 → 304 lines; JS → `web/static/js/lot.js`
|
||||
- `vendor_mappings.html` 1063 → 169 lines; JS → `web/static/js/vendor_mappings.js`
|
||||
- `competitors.html` 809 → 185 lines; JS → `web/static/js/competitors.js`
|
||||
- `pricelists.html` 333 → 72 lines; JS → `web/static/js/pricelists.js`
|
||||
- `pricelist_detail.html` 461 → 107 lines; JS → `web/static/js/pricelist_detail.js`
|
||||
|
||||
### Rationale
|
||||
|
||||
No Go template interpolations exist inside any `<script>` block — extraction is safe. Static files served via existing `/static/` route.
|
||||
|
||||
### Constraint
|
||||
|
||||
Never put `{{.GoVar}}` interpolations inside JS files. Pass server data via API calls or `data-*` attributes on HTML elements.
|
||||
|
||||
---
|
||||
|
||||
## 2026-03-13: Competitor Pricelist Implementation
|
||||
|
||||
### Decision
|
||||
|
||||
Competitor pricelist source is now fully implemented (previously "Reserved").
|
||||
|
||||
### What changed
|
||||
|
||||
- Tables: `qt_competitors`, `partnumber_log_competitors`
|
||||
- Migrations: 033–039
|
||||
- Import: Excel upload → parse → dedup → bulk insert → p/n→lot resolution → weighted_median → create pricelist
|
||||
- Unmapped p/ns written to `qt_vendor_partnumber_seen` (source_type = `"competitor:<code>"`)
|
||||
- Quote counts (unique p/n, total historical) shown on `/admin/competitors`
|
||||
- `price_method = "weighted_median"`, `price_period_days = 0` stored explicitly in pricelist items
|
||||
|
||||
### Rationale
|
||||
|
||||
Competitors upload Excel price lists from B2B portals. Prices are DDP — no recalculation needed. Expected discount applied at pricelist build time.
|
||||
|
||||
---
|
||||
|
||||
## 2026-03-13: price_method / price_period_days for Warehouse and Competitor
|
||||
|
||||
### Decision
|
||||
|
||||
Warehouse and competitor pricelist items now store explicit, meaningful values instead of DB defaults.
|
||||
|
||||
| Source | `price_method` | `price_period_days` |
|
||||
|--------|---------------|---------------------|
|
||||
| `estimate` | `median` / `average` / `weighted_median` | configurable (default 90) |
|
||||
| `warehouse` | `weighted_avg` | `0` |
|
||||
| `competitor` | `weighted_median` | `0` |
|
||||
|
||||
`price_period_days = 0` means "all available data" (no time window). Previously these fields held the DB default (`median`, `90`) which was misleading — warehouse and competitor prices are frozen snapshots, not recalculated from `lot_log`.
|
||||
|
||||
### Constraint
|
||||
|
||||
`price_period_days` and `price_method` are only acted upon when recalculating estimate pricelists from `lot_log`. For warehouse and competitor these fields are informational only.
|
||||
|
||||
---
|
||||
|
||||
## Architecture Conventions
|
||||
|
||||
> All future architectural decisions must be documented here with:
|
||||
|
||||
Reference in New Issue
Block a user