feat(expense): add persistent zero-entry receipt association

This commit is contained in:
caoxiaozhu
2026-07-16 10:23:23 +08:00
parent 54754b5502
commit ae3f02c35a
30 changed files with 4450 additions and 810 deletions

View File

@@ -19,7 +19,7 @@ from app.db.schema_ownership import MIGRATION_OWNED_TABLES, create_legacy_schema
MIGRATION_TEST_DATABASE_URL = os.getenv("MIGRATION_TEST_DATABASE_URL", "").strip()
LEGACY_PROBE_TABLE = "legacy_migration_probe_records"
HEAD_REVISION = "20260714_0005"
HEAD_REVISION = "20260716_0006"
SERVER_DIR = Path(__file__).resolve().parents[1]
ALEMBIC_INI_PATH = SERVER_DIR / "alembic.ini"
@@ -274,11 +274,27 @@ def _assert_head_schema(engine: Engine) -> None:
"uq_memory_evidence_links_entry_case",
("tenant_id", "memory_entry_id", "expense_case_id"),
)
_assert_unique_constraint(
engine,
"attachment_association_jobs",
"uq_attachment_association_jobs_owner_dedupe",
("tenant_id", "owner_username", "dedupe_key", "generation"),
)
_assert_check_constraint(
engine,
"memory_entries",
"ck_memory_entries_expired_fields",
)
_assert_check_constraint(
engine,
"attachment_association_jobs",
"ck_attachment_association_jobs_running_lease",
)
_assert_check_constraint(
engine,
"attachment_association_jobs",
"ck_attachment_association_jobs_generation",
)
_assert_indexes(
engine,
@@ -318,6 +334,21 @@ def _assert_head_schema(engine: Engine) -> None:
"ix_auth_sessions_tenant_username": ("tenant_id", "username"),
},
)
_assert_indexes(
engine,
"attachment_association_jobs",
{
"ix_attachment_association_jobs_owner_time": (
"tenant_id",
"owner_username",
"created_at",
),
"ix_attachment_association_jobs_status_lease": (
"status",
"lease_expires_at",
),
},
)
_assert_indexes(
engine,
"ai_application_preview_decisions",

File diff suppressed because it is too large Load Diff

View File

@@ -48,7 +48,7 @@ def test_unversioned_database_without_migration_owned_tables_is_safe(engine: Eng
@pytest.mark.parametrize(
"owned_table",
sorted(MIGRATION_OWNED_TABLES_BY_REVISION["20260714_0005"]),
sorted(MIGRATION_OWNED_TABLES_BY_REVISION["20260716_0006"]),
)
def test_unversioned_database_with_any_migration_owned_table_is_rejected(
engine: Engine,
@@ -100,6 +100,11 @@ def test_known_revision_requires_and_accepts_its_exact_owned_table_set(
"20260714_0005",
MIGRATION_OWNED_TABLES_BY_REVISION["20260714_0005"] - {"memory_entries"},
),
(
"20260716_0006",
MIGRATION_OWNED_TABLES_BY_REVISION["20260716_0006"]
- {"attachment_association_jobs"},
),
],
)
def test_known_revision_with_missing_or_unexpected_owned_tables_is_rejected(

View File

@@ -20,6 +20,7 @@ def test_create_legacy_schema_never_creates_migration_owned_tables() -> None:
"ai_decision_feedback",
"ai_decisions",
"auth_sessions",
"attachment_association_jobs",
"business_events",
"expense_case_links",
"expense_cases",