diff --git a/auth/handoffs/liturgicalcalendar.md b/auth/handoffs/liturgicalcalendar.md index 93e19fd..d173172 100644 --- a/auth/handoffs/liturgicalcalendar.md +++ b/auth/handoffs/liturgicalcalendar.md @@ -78,6 +78,8 @@ Everything in this Zitadel section was re-verified against production on 2026-08 `rite_calendar` (relations `admin`/`editor`/`viewer`, mirroring `general_roman_calendar` exactly, no `deleter`) is **deployed** as of model `01M1FHYEDWG8E1CKD4VAKCYZ9V`. It is the production-tier counterpart of the test type above: `general_roman_calendar`'s single fixed id could only ever name the Roman rite-level calendar, so the new type's object ids carry their rite (`rite_calendar:roman/decrees`, `rite_calendar:ambrosian/EDITIO_TYPICA_2024`). Purely additive: `general_roman_calendar` is untouched, so live editor grants on it keep authorizing until `scripts/migrate-rite-calendar-tuples.php --apply --prune` (LiturgicalCalendarAPI#965) has run in every environment. Dropping `general_roman_calendar` and `general_roman_calendar_test` is a separate, later model version. + **Not yet deployed:** `general_roman_calendar` and `general_roman_calendar_test` were REMOVED from the model *file* at the #955 prune milestone (LiturgicalCalendarAPI#970 dropped the last code paths that named them, and `scripts/migrate-rite-calendar-tuples.php --apply --prune` deleted the last legacy tuple on 2026-09-01). The list above deliberately still describes model `01M1FHYEDWG8E1CKD4VAKCYZ9V`, which still HAS both. They go away only when an operator runs `./setup-openfga.sh --target production --create-litcal-store` in `/opt/cdcf-auth/auth` and the resulting model ID lands in `LiturgicalCalendar.lock.json` via a follow-up PR; update both this list and the model ID above at that point. Unlike every earlier change in this family this one is SUBTRACTIVE — a consumer still pinned to an older model ID keeps seeing both types, since a pin names a specific model that still exists in the store's history, but anything re-pinned to the new model loses them. The API's `authz/openfga-expectations.json` now lists both under `forbidden_types`, so `validate-expectations.sh` fails until this model change is the one being validated. + Consumers pinning `OPENFGA_MODEL_ID` do **not** pick this up by redeploying — a pin names a specific model ID, so they keep resolving against whatever they pinned until the value below is updated. Local dev and frontend-e2e stores refresh themselves; there is no manual model upload to perform. `LiturgicalCalendarFrontend`'s `authz-seed` service clones this repo at `CDCF_INFRA_REF` (default `main`), writes its own `.env.local`, and runs `./setup-openfga.sh --target local --create-litcal-store` — so bringing the stack up again once the change is on `main` is what picks it up. Those stores get a **new model ID of their own**; the lock guard does not fire against them, because a lock scoped to the production store is `foreign` to a local one and is bypassed. Re-pin `OPENFGA_STORE_ID`/`OPENFGA_MODEL_ID` in that stack from *its* IDs, never from the production values above — model IDs are meaningless across stores. diff --git a/auth/models/LiturgicalCalendar.json b/auth/models/LiturgicalCalendar.json index 6db1ece..841cba9 100644 --- a/auth/models/LiturgicalCalendar.json +++ b/auth/models/LiturgicalCalendar.json @@ -108,36 +108,6 @@ } } }, - { - "type": "general_roman_calendar", - "relations": { - "admin": { "this": {} }, - "editor": { - "union": { - "child": [ - { "this": {} }, - { "computedUserset": { "relation": "admin" } } - ] - } - }, - "viewer": { - "union": { - "child": [ - { "this": {} }, - { "computedUserset": { "relation": "editor" } }, - { "computedUserset": { "relation": "admin" } } - ] - } - } - }, - "metadata": { - "relations": { - "admin": { "directly_related_user_types": [{ "type": "user" }] }, - "editor": { "directly_related_user_types": [{ "type": "user" }] }, - "viewer": { "directly_related_user_types": [{ "type": "user" }] } - } - } - }, { "type": "rite_calendar", "relations": { @@ -228,36 +198,6 @@ } } }, - { - "type": "general_roman_calendar_test", - "relations": { - "admin": { "this": {} }, - "editor": { - "union": { - "child": [ - { "this": {} }, - { "computedUserset": { "relation": "admin" } } - ] - } - }, - "viewer": { - "union": { - "child": [ - { "this": {} }, - { "computedUserset": { "relation": "editor" } }, - { "computedUserset": { "relation": "admin" } } - ] - } - } - }, - "metadata": { - "relations": { - "admin": { "directly_related_user_types": [{ "type": "user" }] }, - "editor": { "directly_related_user_types": [{ "type": "user" }] }, - "viewer": { "directly_related_user_types": [{ "type": "user" }] } - } - } - }, { "type": "rite_calendar_test", "relations": { diff --git a/auth/models/testdata/expectations-valid.json b/auth/models/testdata/expectations-valid.json index 7b841f5..83cf70e 100644 --- a/auth/models/testdata/expectations-valid.json +++ b/auth/models/testdata/expectations-valid.json @@ -1,5 +1,5 @@ { - "_comment": "Fixture for auth/validate-expectations.sh's own tests. Asserts exactly what auth/models/LiturgicalCalendar.json provides today: the eight deployed types, admin/editor/viewer on each calendar type plus member_nation on wider_region, test_definition and deleter forbidden, and the editor/viewer union rewrites.", + "_comment": "Fixture for auth/validate-expectations.sh's own tests. Asserts exactly what auth/models/LiturgicalCalendar.json provides today: the eight deployed types, admin/editor/viewer on each calendar type plus member_nation on wider_region, test_definition and both retired general_roman_calendar types forbidden, the deleter relation forbidden model-wide, and the editor/viewer union rewrites.", "consumer": "LiturgicalCalendarAPI", "store": "LiturgicalCalendar", "required_types": [ @@ -7,28 +7,68 @@ "wider_region", "national_calendar", "diocesan_calendar", - "general_roman_calendar", + "rite_calendar", "national_calendar_test", "diocesan_calendar_test", - "general_roman_calendar_test" + "rite_calendar_test" ], "required_relations": { - "wider_region": ["admin", "editor", "viewer", "member_nation"], - "national_calendar": ["admin", "editor", "viewer"], - "diocesan_calendar": ["admin", "editor", "viewer"], - "general_roman_calendar": ["admin", "editor", "viewer"], - "national_calendar_test": ["admin", "editor", "viewer"], - "diocesan_calendar_test": ["admin", "editor", "viewer"], - "general_roman_calendar_test": ["admin", "editor", "viewer"] + "wider_region": [ + "admin", + "editor", + "viewer", + "member_nation" + ], + "national_calendar": [ + "admin", + "editor", + "viewer" + ], + "diocesan_calendar": [ + "admin", + "editor", + "viewer" + ], + "rite_calendar": [ + "admin", + "editor", + "viewer" + ], + "national_calendar_test": [ + "admin", + "editor", + "viewer" + ], + "diocesan_calendar_test": [ + "admin", + "editor", + "viewer" + ], + "rite_calendar_test": [ + "admin", + "editor", + "viewer" + ] }, - "forbidden_types": ["test_definition"], + "forbidden_types": [ + "general_roman_calendar", + "general_roman_calendar_test", + "test_definition" + ], "forbidden_relations": { - "*": ["deleter"] + "*": [ + "deleter" + ] }, "relation_includes": { "*": { - "editor": ["admin"], - "viewer": ["admin", "editor"] + "editor": [ + "admin" + ], + "viewer": [ + "admin", + "editor" + ] } } }