| 37525 |
amit |
1 |
-- Circular -> web offer sync: provenance on dtr.web_offer, plus the shadow that lets a
|
|
|
2 |
-- human edit win over the sync.
|
|
|
3 |
--
|
|
|
4 |
-- See docs/superpowers/specs/2026-09-03-circular-to-web-offer-sync-design.md
|
|
|
5 |
--
|
|
|
6 |
-- Safe to run on a live table: every column is nullable or defaulted, and `source`
|
|
|
7 |
-- defaults to MANUAL so every existing row is correctly labelled as hand-authored and is
|
|
|
8 |
-- never touched by the sync.
|
|
|
9 |
|
|
|
10 |
ALTER TABLE dtr.web_offer
|
|
|
11 |
ADD COLUMN source ENUM('MANUAL','CIRCULAR') NOT NULL DEFAULT 'MANUAL',
|
|
|
12 |
-- The PDF's own coordinates, stored as VALUES rather than a foreign key.
|
|
|
13 |
-- offers.offer.id is deliberately NOT used: ids are recreated on every re-ingest, so a
|
|
|
14 |
-- stored id would dangle after the next parse. (document, page, row) comes from the PDF
|
|
|
15 |
-- layout and is stable across re-parses.
|
|
|
16 |
ADD COLUMN circular_document_id INT NULL,
|
|
|
17 |
ADD COLUMN circular_page_no SMALLINT NULL,
|
|
|
18 |
ADD COLUMN circular_row_no SMALLINT NULL,
|
|
|
19 |
ADD COLUMN synced_at DATETIME NULL,
|
|
|
20 |
ADD UNIQUE KEY uk_circular_row
|
|
|
21 |
(circular_document_id, circular_page_no, circular_row_no);
|
|
|
22 |
|
|
|
23 |
-- What the sync last wrote. Per field, on each run: live value == shadow means the sync
|
|
|
24 |
-- still owns it and may overwrite; live value != shadow means a human edited it, so the
|
|
|
25 |
-- sync leaves that field alone from then on.
|
|
|
26 |
--
|
|
|
27 |
-- Chosen over a locked_fields flag on web_offer because flags would require every
|
|
|
28 |
-- existing edit endpoint (/web-offer/add, /web-offer-duration/update, and the V2 mirror)
|
|
|
29 |
-- to record each change - and one that forgot would silently lose a human's edit. The
|
|
|
30 |
-- shadow needs no change to any existing write path.
|
|
|
31 |
CREATE TABLE IF NOT EXISTS dtr.web_offer_sync_shadow (
|
|
|
32 |
web_offer_id INT NOT NULL PRIMARY KEY,
|
|
|
33 |
title VARCHAR(256) NULL,
|
|
|
34 |
small_text VARCHAR(256) NULL,
|
|
|
35 |
detailed_text VARCHAR(1024) NULL,
|
|
|
36 |
start_date DATETIME NULL,
|
|
|
37 |
end_date DATETIME NULL,
|
|
|
38 |
synced_at DATETIME NOT NULL,
|
|
|
39 |
CONSTRAINT fk_wos_offer FOREIGN KEY (web_offer_id)
|
|
|
40 |
REFERENCES dtr.web_offer(id) ON DELETE CASCADE
|
|
|
41 |
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|