fix: persist rectification evidence corrections

This commit is contained in:
Jesse_Chen
2026-07-21 05:23:51 +08:00
parent c68f4e5f4f
commit 887b40df43
16 changed files with 801 additions and 27 deletions
@@ -489,6 +489,30 @@ def test_life_event_evidence_is_strictly_validated_before_insert() -> None:
assert "nullif(item ->> 'datevalue', '')" not in save
def test_evidence_correction_lineage_is_bounded_projected_and_validated_atomically() -> None:
schema = _normalized(SCHEMA)
transitions = _normalized(TRANSITIONS)
validator = _function(schema, "conversational_rectification_valid_life_event_evidence")
load = _function(transitions, "load_conversational_rectification_case")
limits = _function(transitions, "conversational_rectification_case_fits_load_limits")
save = _function(transitions, "save_conversational_rectification_turn")
assert "corrects_evidence_ids uuid[] not null default '{}'::uuid[]" in schema
assert "'correctsevidenceids'" in validator
assert "jsonb_array_length(p_value -> 'correctsevidenceids') > 1" in validator
assert "p_value ->> 'extractionstatus' = 'corrected'" in validator
assert "p_value ->> 'extractionstatus' = 'clear'" in validator
assert "'correctsevidenceids', pg_catalog.to_jsonb(evidence.corrects_evidence_ids)" in load
assert "'correctsevidenceids', pg_catalog.to_jsonb(evidence.corrects_evidence_ids)" in limits
assert "corrects_evidence_ids" in save
assert "item -> 'correctsevidenceids'" in save
assert "pg_catalog.unnest( evidence.corrects_evidence_ids )" in save
assert save.index("pg_catalog.unnest( evidence.corrects_evidence_ids )") < save.index(
"insert into public.birth_time_rectification_event_evidence"
)
assert "where evidence.case_id = p_case_id" in save
def test_case_mutations_enforce_cumulative_load_limits_under_the_case_lock() -> None:
transitions = _normalized(TRANSITIONS)
helper = _function(transitions, "conversational_rectification_case_fits_load_limits")
@@ -1018,6 +1018,144 @@ def test_save_rejects_invalid_evidence_without_discarding_or_coercing_fields(
) == "false"
def test_correction_lineage_is_append_only_owner_scoped_and_rejects_retired_targets(
pg14_database: PgDatabase,
) -> None:
user_id = "00000000-0000-4000-8000-000000001201"
case_id = "00000000-0000-4000-8000-000000001202"
first_action = "00000000-0000-4000-8000-000000001203"
second_action = "00000000-0000-4000-8000-000000001204"
third_action = "00000000-0000-4000-8000-000000001205"
rejected_action = "00000000-0000-4000-8000-000000001206"
missing_id = "00000000-0000-4000-8000-000000001207"
first_id = "00000000-0000-4000-8000-000000001211"
second_id = "00000000-0000-4000-8000-000000001212"
third_id = "00000000-0000-4000-8000-000000001213"
_create_user(pg14_database, user_id)
_reserve(pg14_database, user_id, case_id)
_create_case(pg14_database, user_id, case_id, _valid_declared_birth_input())
_complete(pg14_database, user_id, case_id)
first = {
"id": first_id,
"rawText": "2019 年 7 月开始第一份工作",
"domain": "career",
"eventSummary": "开始第一份工作",
"dateValue": "2019-07",
"datePrecision": "month",
"extractionStatus": "clear",
"scoreable": True,
}
pg14_database.sql(_save_statement(
user_id,
case_id,
0,
first_action,
[first],
turn={
**_valid_turn(case_id),
"turnVersion": 1,
"evidenceRecap": [{
"id": first_id,
"summary": "开始第一份工作",
"dateLabel": "2019-07",
"isCorrection": False,
}],
},
))
loaded_first = json.loads(pg14_database.sql(
f"select public.load_conversational_rectification_case('{user_id}'::uuid, '{case_id}'::uuid)::text"
))
assert loaded_first["event_evidence"][0]["correctsEvidenceIds"] == []
second = {
"id": second_id,
"rawText": "更正:2020 年 11 月离职",
"domain": "career",
"eventSummary": "离职",
"dateValue": "2020-11",
"datePrecision": "month",
"extractionStatus": "corrected",
"scoreable": True,
"correctsEvidenceIds": [first_id],
}
pg14_database.sql(_save_statement(
user_id,
case_id,
1,
second_action,
[second],
turn={
**_valid_turn(case_id),
"turnVersion": 2,
"evidenceRecap": [{
"id": second_id,
"summary": "离职",
"dateLabel": "2020-11",
"isCorrection": True,
}],
},
))
for invalid_target in (missing_id, first_id):
rejected = {
**second,
"id": third_id,
"correctsEvidenceIds": [invalid_target],
}
assert pg14_database.rejects(_save_statement(
user_id,
case_id,
2,
rejected_action,
[rejected],
))
assert pg14_database.sql(
f"select turn_version::text from public.birth_time_rectification_cases where id = '{case_id}'::uuid"
) == "2"
assert pg14_database.sql(
f"select count(*)::text from public.birth_time_rectification_event_evidence where case_id = '{case_id}'::uuid"
) == "2"
third = {
**second,
"id": third_id,
"rawText": "更正:2021 年 2 月入职",
"eventSummary": "入职",
"dateValue": "2021-02",
"correctsEvidenceIds": [second_id],
}
pg14_database.sql(_save_statement(
user_id,
case_id,
2,
third_action,
[third],
turn={
**_valid_turn(case_id),
"turnVersion": 3,
"evidenceRecap": [{
"id": third_id,
"summary": "入职",
"dateLabel": "2021-02",
"isCorrection": True,
}],
},
))
loaded = json.loads(pg14_database.sql(
f"select public.load_conversational_rectification_case('{user_id}'::uuid, '{case_id}'::uuid)::text"
))
assert len(loaded["event_evidence"]) == 3
assert loaded["event_evidence"][1]["correctsEvidenceIds"] == [first_id]
assert loaded["event_evidence"][2]["correctsEvidenceIds"] == [second_id]
assert loaded["latest_turn"]["evidenceRecap"] == [{
"id": third_id,
"summary": "入职",
"dateLabel": "2021-02",
"isCorrection": True,
}]
def test_save_rejects_cumulative_evidence_count_before_inserting(
pg14_database: PgDatabase,
) -> None: