feat(cases): enforce purpose-bound case governance
Module Package Release / publish-packages (push) Successful in 12s

This commit is contained in:
2026-08-24 20:05:31 +02:00
parent 9435116299
commit 17415d8831
28 changed files with 786 additions and 142 deletions
+105 -5
View File
@@ -324,13 +324,66 @@ class CaseLifecycleTests(unittest.TestCase):
outsider = Principal(account_id="account-2")
self.assertIsNone(get_case(self.session, outsider, case_id="case-1"))
self.assertEqual(0, list_cases(self.session, outsider)[1])
self.assertEqual(
0,
list_cases(
self.session,
outsider,
purpose="cases.casework",
)[1],
)
self.assertEqual((), case_history(self.session, outsider, case_id="case-1"))
self.assertEqual((), case_timeline(self.session, outsider, case_id="case-1"))
reader = Principal(account_id="account-3", group_ids=("reviewers",))
self.assertIsNotNone(get_case(self.session, reader, case_id="case-1"))
self.assertEqual(1, list_cases(self.session, reader)[1])
self.assertIsNone(get_case(self.session, reader, case_id="case-1"))
self.assertIsNone(
get_case(
self.session,
reader,
case_id="case-1",
purpose="cases.unrelated",
)
)
self.assertIsNotNone(
get_case(
self.session,
reader,
case_id="case-1",
purpose="cases.casework",
)
)
administrator = Principal(
account_id="account-6",
scopes=frozenset({"cases:case:admin"}),
)
self.assertIsNone(
get_case(
self.session,
administrator,
case_id="case-1",
purpose="cases.casework",
)
)
self.assertEqual(
1,
list_cases(
self.session,
reader,
purpose="cases.casework",
)[1],
)
self.assertEqual(
1,
len(
case_history(
self.session,
reader,
case_id="case-1",
purpose="cases.casework",
)
),
)
with self.assertRaises(PermissionError):
update_case(
self.session,
@@ -396,9 +449,56 @@ class CaseLifecycleTests(unittest.TestCase):
self.session.commit()
self.assertEqual(3, shared.revision)
self.assertIsNotNone(
get_case(self.session, Principal(account_id="account-5"), case_id="case-1")
get_case(
self.session,
Principal(account_id="account-5"),
case_id="case-1",
purpose="cases.casework",
)
)
self.assertEqual(
3,
len(
case_history(
self.session,
self.principal,
case_id="case-1",
purpose="cases.casework",
)
),
)
revoked = update_case(
self.session,
self.principal,
case_id="case-1",
expected_revision=3,
changes={"access_grants": []},
recorded_at=NOW + timedelta(minutes=3),
change_reason="Removed direct collaboration access.",
idempotency_key="case-share-revoke",
purpose="cases.casework",
)
self.session.commit()
self.assertEqual(4, revoked.revision)
self.assertIsNone(
get_case(
self.session,
Principal(account_id="account-5"),
case_id="case-1",
revision=2,
purpose="cases.casework",
)
)
self.assertEqual(
"cases.casework",
case_timeline(
self.session,
self.principal,
case_id="case-1",
purpose="cases.casework",
)[0]["purpose"],
)
self.assertEqual(3, len(case_history(self.session, self.principal, case_id="case-1")))
def test_malformed_access_grant_is_rejected(self) -> None:
create_case(