fix(migration): make Phase B additive sync actually work + verify end-to-end
The --sync path had never been run and was broken in several ways. Fixed and verified against the dev DB (two consecutive syncs, both exit 0, 32/32 assertions: stable PKs, manual-row preservation, changed-row updates, legacy-delete, no child duplication, zero FK orphans; idempotent). - policies/properties: reuse each legacy row's existing id (by provenance) BEFORE building child rows, so children no longer point at a discarded fresh uuid; rebuild legacy-owned children via scoped delete + reinsert. - customers: replace zip(customers, refs) (mispaired almost every row) with a ref-grouped id remap; names now restore and no spurious customers appear. - drop the invalid Vehicle @@unique(legacySourceTable, legacyId) — one legacy policy row carries up to 3 vehicles sharing a legacyId; handle via delete+reinsert. - upsert lookup tables (policy_types, insurance_providers, type_transactions, adjusters) by natural name and remap child FKs instead of inserting fresh uuids that nothing points at. - transactions: drop updatedAt=NOW() (no such column); guard report formatting on NULL legacySourceTable (manual rows). Same report guard in bank. - add manual-safe prune (prune_empty_customers.py --sync, in SYNC_STEPS): prune only legacy-owned empties, never manually-added customers. web: customer-detail mini tx list now strikes voided rows with an "(anulado)" tag (was the last void-UI rendering gap; /estado-cuenta already handled it). docs: RESUME.md updated — Phase B sync marked verified end-to-end, void-UI browser pass recorded. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -781,9 +781,10 @@ function TxRow({ t }: { t: Transaction }) {
|
||||
const tipo =
|
||||
t.type?.nameEs || t.type?.nameEn || "—";
|
||||
const concept = t.message || t.period || "—";
|
||||
const voided = !!t.voidedAt;
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<tr style={voided ? { textDecoration: "line-through", opacity: 0.55 } : undefined}>
|
||||
<td className="mono" style={{ whiteSpace: "nowrap" }}>
|
||||
{formatDate(t.transactionDate)}
|
||||
</td>
|
||||
@@ -793,7 +794,14 @@ function TxRow({ t }: { t: Transaction }) {
|
||||
</td>
|
||||
<td>{tipo}</td>
|
||||
<td className="tx-ref">{t.reference || "—"}</td>
|
||||
<td className="tx-concept">{concept}</td>
|
||||
<td className="tx-concept">
|
||||
{concept}
|
||||
{voided && (
|
||||
<span className="tx-cur" style={{ marginLeft: 6, textDecoration: "none" }}>
|
||||
(anulado)
|
||||
</span>
|
||||
)}
|
||||
</td>
|
||||
<td className="num">
|
||||
<span className={`tx-amount ${sign}`}>
|
||||
{formatMoney(t.amount, t.currency)}
|
||||
|
||||
@@ -667,6 +667,8 @@ export interface Transaction {
|
||||
period?: string | null;
|
||||
message: string | null;
|
||||
checkNumber: string | null;
|
||||
/** App-voided (`voidedAt` set). UI strikes; totals exclude. */
|
||||
voidedAt?: string | null;
|
||||
type: TransactionType | null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user