feat: add Colour and ElementColour liturgical colour value objects #203

Merged
manlycucumber merged 1 commit from feature/11-colour into develop 2026-07-01 05:25:17 +00:00
manlycucumber commented 2026-07-01 05:24:45 +00:00 (Migrated from github.com)

Closes #11.

Models liturgical colour as a per-edition attribute — never part of an observance's identity — under src/Attribute/, alongside RankClass/LegacyRank (#10).

What lands

  • Colour — the closed traditional Roman colour set (white, red, green, violet, black, rose). Guarded fromString() + named factories, value()/equals()/__toString(), and isViolet()/isRose() predicates. Constructed from edition attribute data, not parsed from an ID token.
  • ElementColour — the colour borne by a single celebration element (the principal or one commemoration), so a day is not reduced to one colour: principal and each commemoration may each wear a distinct colour. Rose is expressed as a roseAllowed flag on a violet base (ElementColour::violetWithRose() for Gaudete / Laetare), never stored as a base colour; invalid states (rose-allowed on a non-violet base) are unrepresentable.

Acceptance criteria

  • Enumerates the traditional Roman colours (white, red, green, violet, black, rose)
  • Constructs from an edition attribute record, not an ID token
  • Each celebration element (principal + commemorations) carries its own colour
  • roseAllowed expressible as a flag on violet
  • Unit tests cover each colour and the per-element case

Verification

Local (portable toolchain): composer lint 20/20 · composer analyse PHPStan L6 [OK] · composer test 64/64 green.

Closes #11. Models liturgical colour as a **per-edition attribute** — never part of an observance's identity — under `src/Attribute/`, alongside `RankClass`/`LegacyRank` (#10). ## What lands - **`Colour`** — the closed traditional Roman colour set (`white`, `red`, `green`, `violet`, `black`, `rose`). Guarded `fromString()` + named factories, `value()`/`equals()`/`__toString()`, and `isViolet()`/`isRose()` predicates. Constructed from edition attribute data, not parsed from an ID token. - **`ElementColour`** — the colour borne by a single celebration *element* (the principal or one commemoration), so a day is not reduced to one colour: `principal` and each `commemoration` may each wear a distinct colour. Rose is expressed as a `roseAllowed` flag on a violet base (`ElementColour::violetWithRose()` for Gaudete / Laetare), never stored as a base colour; invalid states (rose-allowed on a non-violet base) are unrepresentable. ## Acceptance criteria - [x] Enumerates the traditional Roman colours (white, red, green, violet, black, rose) - [x] Constructs from an edition attribute record, not an ID token - [x] Each celebration element (principal + commemorations) carries its own colour - [x] `roseAllowed` expressible as a flag on violet - [x] Unit tests cover each colour and the per-element case ## Verification Local (portable toolchain): `composer lint` 20/20 · `composer analyse` PHPStan L6 `[OK]` · `composer test` 64/64 green.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Directorium/Core!203
No description provided.