# discourse-operator-surface Specification ## Purpose TBD - created by archiving change discourse-integration. Update Purpose after archive. ## Requirements ### Requirement: Entitlement-to-group mapping management The integration SHALL provide operator pages, registered through the contract's route hook under the Integrations section, for viewing, adding, and removing entries of the entitlement→group mapping stored in the `discourse` schema. On save the integration SHALL validate against the Discourse API that the named group exists and is not an automatic group, rejecting the mapping otherwise. The integration SHALL NOT create or delete Discourse groups. #### Scenario: Mapping a valid group - **WHEN** an operator maps `discourse_posting` to an existing non-automatic Discourse group - **THEN** the mapping is saved and the group becomes managed by the reconciler #### Scenario: Mapping a nonexistent group - **WHEN** an operator submits a mapping naming a group the Discourse API does not report - **THEN** the save is rejected with an error identifying the unknown group and no mapping is stored #### Scenario: Unmapping a group - **WHEN** an operator removes a group mapping - **THEN** the reconciler stops managing that group and existing forum-side membership is left as-is ### Requirement: Link and sync visibility The operator surface SHALL display: entitled-but-unlinked persons, links in `conflict` status, and the outcome and timestamp of the most recent sweep. These states SHALL be distinguishable from one another and from configuration absence. #### Scenario: Operator reviews sync health - **WHEN** an operator opens the Discourse integration page after a sweep - **THEN** they see the last sweep time and outcome, a count and list of entitled-but-unlinked persons, and any conflicted links #### Scenario: Unconfigured integration - **WHEN** an operator opens the Discourse integration page while bootstrap config is absent - **THEN** the page states the integration is unconfigured and shows no error-state sync data