Skip to content
Updated Aug 28, 2026 by barcadvorakova-starkys · Owner: analysisactiveconceptgeneric Edit on GitHub

Scope Administration ​

Concept layer — frozen. The Multi-Organizations / tenant scoping generic. Nothing here is written by a normal playbook run; a project's own feature analysis is the live document and takes every edit. This layer names no project and links to none — the dependency runs one way, from an application to its concept.

Concept: Multi-Organizations / Tenant Scoping

Business Context ​

Someone has to create scopes, edit them, and turn them off. This page covers that administrative surface — the one place in the product where a scope is an object being managed rather than the boundary everything else operates inside.

Two audiences, and they are not the same:

  • Platform administrators manage the whole set: create a scope, edit any scope, activate, deactivate, delete.
  • Users of a scope manage their own scope's settings, and — where they belong to more than one — switch between scopes.

Keeping these apart matters. Scope creation is a platform capability; if it sits in the same screen as "edit my own details", then the permission that lets an administrator rename their own scope also lets them invent new ones.

Business-Level Definition ​

Provide administrative management of scopes — create, read, update, activate, deactivate, soft-delete — and a switcher that lets a multi-scope user change which scope the whole application acts in.

Requirements Definition ​

  • Scope management is restricted to an explicit administrative permission.
  • Scope switching is available wherever the user is inside a scope, not on one screen.
  • A scope's own administrators can maintain that scope's settings without platform rights.
  • A scope may own collections of child records that are edited as part of it.

Technical Context ​

User Stories / Use Cases ​

  1. As a platform administrator, I search and filter scopes.
  2. As a platform administrator, I create a scope and supply its identifying and branding details.
  3. As a platform administrator, I activate, deactivate or soft-delete a scope.
  4. As a user belonging to several scopes, I switch between them and the whole application follows.
  5. As an administrator of one scope, I edit that scope's own settings and read its history.

UI/UX Design ​

  • The active scope's name and, where the product has one, its logo sit in the application header, with the switcher next to them.
  • Scope-independent navigation (platform administration, including this surface) is visually separated from scope-specific navigation. A user must be able to tell, without experimenting, which parts of the interface the switcher affects.
  • A list with search and filtering, and a per-row detail view for editing. Nothing exotic: the value here is in the permissions and the audit trail, not the layout.
  • Child collections owned by the scope appear as sections of the detail view, with add and remove controls and inline fields, saved together with the parent in a single action.
  • The detail view carries a read-only History section: the shared activity feed, one chronological row per event reading as a sentence — who did what, and when — with the raw context behind a per-row expander. It is paginated, lightly filterable, and offers no create, edit or delete actions. The same section appears on a scope's own settings screen for that scope's administrators.

The history section is deliberately not the audit browser's table. The browser is a cross-entity investigation tool for someone asking "what happened in the system"; this section answers "what happened to this" for someone already looking at it. Reusing the browser here forces an investigation UI onto a routine screen and, worse, tends to drag the browser's much broader permission along with it.

Functional Requirements ​

  • CRUD over the scope entity: create, read, update, soft-delete, activate and deactivate.
  • The switcher is available in every scope-specific area.
  • Child collections owned by the scope are reconciled with replace-set semantics on save.
  • Deactivation is not deletion. A deactivated scope keeps its data and stops being enterable; a soft-deleted scope cascades the soft delete to its owned children.

Replace-set semantics, and the distinction that has to be documented

When a scope owns a collection edited as part of its detail screen, save reconciles the whole collection rather than diffing individual rows:

  • Items with a known identifier are updated.
  • Items without one are inserted.
  • Existing items absent from the submitted list are soft-deleted.

The trap is the difference between omitting the field and sending an empty list. Omitted must mean leave the collection alone; an empty list must mean remove everything. If the two collapse into one behaviour, then any client that does not know about the collection silently deletes it on every save — which is exactly what happens when a partial update is sent by an older client or by an unrelated screen.

Where a child carries a uniqueness constraint, soft-deleting it should free the value for reuse; otherwise removing a record makes its identifier permanently unusable, which users experience as a bug.

Scope change auditing

  • Every scope mutation writes exactly one audit entry through the Audit Log concept, with the scope as the referenced entity, inside the same transaction as the change. If the audit write fails, the change rolls back with it.
  • The audit metadata carries the changed fields as before/after pairs, plus display-ready values for anything the activity label renders. An audit entry is a point-in-time record: it shows names as they were, rather than resolving them at read time and quietly rewriting history when something is renamed. It never carries secrets.
json
{
  "changedFields": {
    "name": { "before": "Example Group", "after": "Example Group International" },
    "active": { "before": true, "after": false }
  }
}

Children are audited on the parent

Child collections are audited as update entries on the scope rather than as their own entity type. The reason is the screen: they are edited as a section of the parent's detail view and have no detail screen of their own, so a separate trail would split one scope's history across two places that nobody views together. The audit metadata records which child the entry concerns, so an entry is still identifiable without a reference of its own.

The rule generalises: audit at the granularity of the thing a person opens, not at the granularity of the tables.

Internationalization & Localization ​

Standard localization through the Translations concept, including the labels, actions and validation messages introduced by any child-collection section.

Non-Functional Requirements ​

None specific. The list is small — scopes are counted in tens or hundreds, not millions — so pagination is a convenience rather than a performance requirement.

API Analysis (API-A) ​

See child page: Scope Administration — API Analysis (API-A).

Domain Model & Data Attribute Table (DAT) ​

  • The scope entity.
  • Any child collections the scope owns, each carrying the scope key and the standard audit block.

Data ​

Nothing beyond the scopes themselves. A fresh deployment needs at least one scope and at least one member of it, or nobody can enter the product.

Logging & Monitoring ​

  • .info — scope create, update, activate, deactivate; child add, update, remove; membership add and remove; a user's scope switch.
  • .debug — list and search parameters, and the request and response of administrative writes.

Caching and Performance ​

None required. Take care that anything cached about a scope — its name and branding in the header, its active flag — is invalidated on update, or a deactivated scope keeps rendering as active.

Backward Compatibility and Migration ​

Adding a child collection to the scope is additive and safe, provided the omitted-versus-empty rule above is honoured, since existing clients send neither.


Not relevant beyond the parent concept's data-separation obligations.


Cybersecurity Considerations ​

  • Two permissions, not one. Platform-level scope management and in-scope settings management are distinct capabilities and must be distinct permissions, or every scope administrator becomes a platform administrator.
  • Deactivating or deleting a scope affects everyone inside it. It deserves confirmation and an audit entry, and it must take effect on sessions that are already open.

Risk Assessment ​

  • A single over-broad administrative permission that collapses platform and in-scope management.
  • Replace-set data loss through the omitted-versus-empty ambiguity described above.
  • Stale cached scope state keeping a deactivated scope usable.

Auditing, Reporting & Measurement ​

  • Audit trail — the events above are read through the Audit Log concept's reads, both the in-scope read and the platform-wide one. Entries are append-only and survive the soft deletion of the scope they describe, which is the point: the deletion is itself one of the entries.
  • Authorisation of the history read — a read that pins the entity type and id is authorised against the permission governing that entity, in whichever form matches the surface making the request. The audit browser's own permission is not involved; it gates only unpinned, cross-entity reads. Getting this backwards is a live risk in both directions: reuse the browser permission and a scope administrator cannot see their own scope's history, or grant it to them and they can see everyone's.
  • Entity-level audit — the standard created/updated/deleted metadata on the scope row and on its children.