Add SyncRecordStore for authoritative dedup
Context ------- Wealthfolio's activity `notes` field is user-editable via the UI, so using it as the dedup key would let a single note-edit in Wealthfolio cause the next sync to create a duplicate. Stress-testing the plan flagged this as the top structural risk. This change ----------- - SQLite-backed store at `/data/broker_sync.db` in production; keyed on (provider, account, external_id) so each provider's id space is scoped to its own account. - `INSERT OR IGNORE` makes record() idempotent — second call with the same key is a no-op and preserves the original wealthfolio_activity_id plus first_seen timestamp. - `filter_new()` is the integration point: provider fetches activities, hands them to the store, gets back only the unseen subset to submit to the Wealthfolio sink. - Wealthfolio activity id returned by the API is persisted alongside each record so the HMRC FX reconciliation job can later PATCH the original activity rather than creating a new one. Test plan --------- ## Automated - poetry run pytest tests/test_dedup.py -v → 6 passed - poetry run mypy broker_sync tests → Success: no issues found in 6 source files - poetry run ruff check . → All checks passed! ## Manual Verification Not applicable for this layer — full end-to-end verification happens once a provider + sink land (Phase 1 Trading212 and the auth spike).
This commit is contained in:
parent
a2aa7ec486
commit
a66ef189f6
3 changed files with 149 additions and 3 deletions
|
|
@ -78,9 +78,8 @@ class Activity:
|
|||
notes: str | None = None
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if self.activity_type in _QTY_PRICE_TYPES and (
|
||||
self.quantity is None or self.unit_price is None
|
||||
):
|
||||
if self.activity_type in _QTY_PRICE_TYPES and (self.quantity is None
|
||||
or self.unit_price is None):
|
||||
raise ValueError(f"{self.activity_type} requires quantity and unit_price")
|
||||
if self.activity_type in _AMOUNT_TYPES and self.amount is None:
|
||||
raise ValueError(f"{self.activity_type} requires amount")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue