Umbrella categories and dashboard settings (all services)

Admin-level umbrella categories so the same logical service (e.g. mold add-on) aggregates across instances where each company has a different service ID.

Requirements

  • Settings UI + persistence: create umbrella labels; map any service per instance/company into zero or more umbrellas (all-services scope, not a fixed short list).
  • APIs for dashboard: resolve umbrella label → list of (companyId, serviceId) for metric queries.
  • Works with ATT-1029 aggregations and focus-add-on filters.

Context: Mar 17 standup—"group all of those mold services under that category and that's what bubbles up on the dashboard."


Backend design notes (MongoDB) — schema review

What we have today

  • service is always company-scoped (_companyId required, ref: 'company'). Identity for aggregation is ( _companyId, service._id ).
  • Optional category on service is a free-form string, not a ref—useful for UI copy per company but not a stable, company-agnostic key for cross-tenant dashboards.
  • company does not embed services; linkage is only via service._companyId.

New global tree collection (company-agnostic)

  • Single collection, e.g. globalServiceCategory / serviceCategory, with adjacency-list tree fields: parentId (ObjectId | null for roots), name, optional description / slug, order (sibling sort), active.
  • Optional materialized path (path string or ancestors: ObjectId[]) for faster subtree queries and admin validation; index e.g. { parentId: 1, order: 1 }.
  • Leaf assignment rule: only bottom nodes (no children, or explicit isAssignable / isLeaf) should accept service mappings—enforce in API/app so parents are purely navigational.

Mapping company services → leaf categories (many-to-many)

  • Per issue: each service can map to zero or more leaf categories.
  • Option A — separate collection serviceGlobalCategoryAssignment (or similar): { _companyId, _serviceId, _globalCategoryIds: ObjectId[] } with unique index on (_companyId, _serviceId) — keeps service lean, easier audit/history in admin.
  • Option B — field on service: _globalCategoryIds: ObjectId[] — simpler reads; couples taxonomy to the service document.
  • Either way, refs target leaf globalServiceCategory ids only.

Dashboard API

  • Given globalCategoryId (or slug): query assignments → emit { _companyId, _serviceId }[] for metric pipelines (align with ATT-1029 aggregations / add-on filters).

Coexistence

  • Retain existing service.category string for legacy/display if needed; treat the global tree + assignments as the canonical cross-company grouping for dashboards.

Please authenticate to join the conversation.

Upvoters
Status

Completed

Board
🏠

Main App

Date

2 months ago

Author

Linear

Subscribe to post

Get notified by email when there are changes.