Test / backend-test (pull_request) Waiting to runDetails
Test / frontend-unit (pull_request) Waiting to runDetails
Test / api-e2e (pull_request) Waiting to runDetails
Test / frontend-e2e (pull_request) Waiting to runDetails
Fixes 4 bugs blocking AE1 acceptance scenario (rollup returns 0):
1. Decimal not recognized as numeric: PostgreSQL JSONB returns numbers
as Decimal; _evaluate_rollup's isinstance(v, (int,float)) missed them.
Added _to_float() helper (also excludes bool, an int subclass).
Applied to _evaluate_lookup for JSON serialization safety.
2. add_relation_link clobbers record values: update_record_values does
full-replace, so setting the relation field wiped amount/etc.
Added merge_record_values (|| operator) and switched all relation
link mutations to use it (add + remove + reverse cleanup).
3. enqueue_recalc ON CONFLICT DO NOTHING swallowed re-enqueues: once a
task reached 'done', the unique constraint silently dropped new
requests for the same (record_id, field_id) — field showed stale
data forever. Changed to ON CONFLICT DO UPDATE: reset done/error
tasks to pending; leave pending/calculating as-is (no double-process).
4. No cross-table recalc on record update: update_record_values only
triggered recalc on the record's own table; rollup on the target
table never updated when source values changed. Added
_trigger_cross_table_recalc() — finds relation fields on the
record's table, triggers recalc on linked target records.
Tests:
- AE1 acceptance: 3 e2e tests (SUM on insert, update-triggered recalc,
AVG aggregation) — all pass against real PG.
- Bidirectional relation deletion: verifies _cleanup_reverse_link
removes source from target's reverse field.
- SSRF guard: 3 tests blocking loopback, private IP, non-HTTP scheme.
- Updated test_recalc_deduplication for new ON CONFLICT DO UPDATE
semantics (returns existing task, not None).
- Fixed test_crash_recovery to use stale_threshold=0 (was always broken
with default 600s threshold).