Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ confirmation — and a declaration marked `preventDestroy: true` blocks even tha
| --- | --- | --- |
| Campuses | `ct.campus` | [config guide](docs/configuration.md) |
| Groups (fields, campus, multi-parent hierarchy) | `ct.group` | [config guide](docs/configuration.md) |
| Group types, roles, age/target groups, relationship types | `ct.groupType`, `ct.roleDefinition`, `ct.ageGroup`, `ct.targetGroup`, `ct.relationshipType` | reusable building blocks |
| Group types, roles, age/target groups, relationship types, person statuses | `ct.groupType`, `ct.roleDefinition`, `ct.ageGroup`, `ct.targetGroup`, `ct.relationshipType`, `ct.personStatus` | reusable building blocks |
| Permissions (group-role, group-type-role, person-status) | `ct.groupRole`, `ct.groupTypeRole`, `ct.status` | [permissions](docs/handbuch/permissions.md) |
| Auto-groups (dynamic groups) | the `dynamic` block on a group | [dynamic groups](docs/handbuch/dynamic-groups.md) |
| Repeated structure, parametrized | a plain function over the DSL | [blueprints](docs/handbuch/blueprints.md) |
Expand Down
5 changes: 4 additions & 1 deletion docs/api-coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ Methods marked only if they actually exist on the matched path. "Update" = PUT o
| 10 | `ct_target_group` | `/group/targetgroups`, `/group/targetgroups/{targetGroupId}` | list ✅ / by-id ✅ | ✅ | ✅ PUT | ✅ | **Full CRUD** |
| 11 | `ct_meeting_point` | — none — | ❌ | ❌ | ❌ | ❌ | **Not in API → fully manual.** Zero matches for `treffpunkt`/`meetingpoint`/`meeting point` anywhere in the spec. Closest neighbours are _meeting templates_ (`/group/meetingtemplates`, full CRUD) and _group meetings_ (`/groups/{groupId}/meetings`, CRUD) — different concepts; confirm with product whether "meeting point" was meant to be one of those. |
| 12 | `ct_relationship_type` | `/person/relationshiptypes`, `/person/relationshiptypes/{id}` | list ✅ / by-id ✅ | ✅ | ✅ PUT | ✅ | **Full CRUD** |
| 13 | `ct_person_status` | `/statuses`, `/statuses/{id}` | list ✅ / by-id ✅ | ✅ | ✅ PUT | ✅ | **Full CRUD, live-verified 2026-08-13** (eqrm prod, CT 3.135.2, read from the instance OpenAPI spec): `/statuses` → GET, POST; `/statuses/{id}` → GET, PUT, DELETE. `POST` requires `name`, `shorty`, `isMember`; `PUT` requires ALL of `name`, `shorty`, `isMember`, `isSearchable`, `sortKey`, `securityLevelId` — uniquely strict among managed types (every other managed PUT declares no required fields), and since PUT is a full replace the registry manages all six rather than a subset. The person/community **Status** master data (tag `Status`): "0 - First", "3 - Group Active", …, the domain a `ct.status` permission grant hangs off. Adoptable since #96, which is what makes a config using that domain self-sufficient across hosts. Do NOT conflate with `ct_group_status` (row 8, no endpoint at all) or `/group/memberstatus` (member statuses, string ids). Master data — never a person record; the people guard is unaffected. |
| 14 | `ct_department` | `/departments` | list ✅ / by-id ❌ | ❌ | ❌ | ❌ | **Read-only — a ref catalog, not a managed resource.** Live-probed 2026-08-13 (eqrm prod, CT 3.135.2): `GET /departments` returns `[{id, name, nameTranslated, sortKey, shorty}]`; no `POST`/`PUT`/`DELETE` on `/departments` exists in the spec, and there is no `/departments/{id}` path at all. Bereiche are the `cdb_bereich` permission scope dimension (`churchdb:view alldata`), so `ct` resolves them BY NAME for a `scope: [{ department: "…" }]` reference (#98) and surfaces them via `ct get departments` — but they can never be declared, adopted or created. |

> **Create-time required fields (#73).** The "POST ✅" marks above were spec-derived, not live-exercised for
> create. CT's POST validators require fields the tool does not manage for diffing: `group-type` needs
> `namePlural`/`shorty`/`color`/`permissionDepth`/`isLeaderNecessary`/`availableForNewPerson` (+ `sortKey`/`postsEnabled`),
> and `group-role` needs `shorty`. These are supplied as deterministic create-only defaults
> and `group-role` + `person-status` need `shorty`. These are supplied as deterministic create-only defaults
> (`AdoptableResource.createDefaults`, derived from the declared `name`) — merged into the POST body only, never
> recorded in state, so they stay unmanaged. `campus` (name+shorty, live-verified), `group`, `age-group`, and
> `target-group` need only `name` from their managed set and require no defaults.
Expand All @@ -51,6 +53,7 @@ Standard collection-POST + item-GET/PUT(-or-PATCH)/DELETE shape, safe to drive f
- `ct_age_group`
- `ct_target_group`
- `ct_relationship_type`
- `ct_person_status`

### Writable via non-standard verbs (support, but special-case the client) — 2 resources

Expand Down
4 changes: 2 additions & 2 deletions docs/handbuch/blueprints.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ sources:
- src/config/context.ts
- src/engine/graph.ts
- src/engine/hierarchy.ts
sources_hash: d69dbf11ba71e8eb
reviewed: 2026-08-10
sources_hash: e1bc9429a635e819
reviewed: 2026-08-13
---

# Blueprints (parametrized, reusable config)
Expand Down
15 changes: 13 additions & 2 deletions docs/handbuch/field-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ title: Field definitions & security levels
sources:
- src/commands/get.ts
- src/api/ctClient.ts
sources_hash: 580645532edbdf9a
reviewed: 2026-08-10
sources_hash: 24ea82f0326ed7d5
reviewed: 2026-08-13
---

# Field definitions & security levels (#47, #48)
Expand All @@ -21,6 +21,17 @@ the data-field definitions ("Datenfelder") for both persons and groups.
| The security-level model (levels + what visibility they gate) | Which persons exist, their memberships, their master-data values |
| The person master-data model (sexes, titles, statuses, campuses, …) | Assigning/reading a person's status, sex, campus, etc. |

> **Exception — person statuses are managed, not just read (#96).** The status
> *enumeration* ("0 - First", "3 - Group Active", …) is a declarable resource:
> `ct.personStatus({ key, name, shorty })`, adoptable with
> `ct adopt person-status <id>` and listable with `ct get statuses`
> (`/statuses`, full CRUD). That is what lets a config declare permission grants
> on a status (`ct.status`) and still stand up on a fresh host. Which *person*
> carries which status remains permanently out of scope, like every other
> per-record value. Campuses are likewise managed (`ct.campus`); the rest of the
> master-data model — sexes, titles, the security-level enumeration — stays
> read-only.

This mirrors the tool's permanent people boundary (README "People are never
managed"; `assertNotPeople` in `src/engine/guard.ts`). The commands below read
*definitions only*; none of them read or write a per-record field value.
Expand Down
Loading
Loading