Skip to content
This repository was archived by the owner on Aug 11, 2026. It is now read-only.
This repository was archived by the owner on Aug 11, 2026. It is now read-only.

feat(service-catalog): add versioned SaaS plans, features, quotas, pricing, and offer lifecycle #870

Description

@ahliweb

Parent epic: #868
Depends on: #869

Context

Derived SaaS applications need a reusable commercial service catalog, but this must remain distinct from ERP item/product masters and vertical application catalogs. Plan changes must be versioned so existing subscriptions can be explained and reproduced later.

Objective

Implement a provider-neutral service_catalog capability for plans, offer versions, feature/module grants, quotas, price components, availability, and lifecycle management.

Scope

  • Add the admitted module/extension descriptor, permissions, navigation, capability contracts, and ownership metadata.
  • Add safe sequential migrations for:
    • service/plan definitions;
    • immutable published versions;
    • feature and module-entitlement declarations;
    • quota/limit definitions with units and reset policy metadata;
    • price components using exact decimal/minor-unit representation;
    • trial/availability/market/currency metadata;
    • draft, published, retired, and archived states.
  • Support draft → validate → publish → retire; published versions are immutable.
  • Support derived-application contributions for allowed feature keys and meter keys through static registries.
  • Expose bounded list/detail/create/update/publish/retire APIs with OpenAPI.
  • Emit versioned domain events for published/retired offer versions.
  • Add admin UI with clear draft/published states, validation errors, and version history.
  • Add audit events and idempotency for publish/retire mutations.

Out of scope

  • ERP product/item/service inventory master.
  • Tenant subscription assignment, usage measurement, invoice generation, tax calculation, or payment collection.
  • Arbitrary pricing scripts or tenant-supplied executable rules.

Security and integrity requirements

  • Catalog mutation is platform-operator only and default-deny.
  • Published versions cannot be edited in place; corrections create a new version.
  • Currency, amount, quota, interval, and date ranges are bounded and validated.
  • Feature/module keys must resolve through reviewed static registries; unknown keys fail closed.
  • No secret/provider credential is stored in catalog records.
  • Global versus tenant-scoped placement must follow docs(saas-control-plane): decide module admission, control-plane boundary, trust model, and lifecycle contracts #869 and be protected by the corresponding access model.

Acceptance criteria

  • A plan can be drafted, validated, published, listed, and retired.
  • Publishing creates an immutable version with reproducible features, quotas, and prices.
  • Existing published versions remain readable after newer versions are published.
  • Duplicate keys/version conflicts return deterministic 409 responses.
  • Unknown module/feature/meter keys are rejected.
  • Exact monetary representation is used; no floating-point amount storage.
  • API, admin UI, audit, events, permissions, and docs are synchronized.
  • LAN/offline deployments can keep the module absent/disabled without startup or network dependency.

Testing

  • Unit tests for versioning, amount/quota validation, state transitions, and registry resolution.
  • PostgreSQL integration tests for constraints, concurrency, immutable published versions, and least-privilege grants.
  • Authorization tests for platform/tenant role separation.
  • OpenAPI response-contract tests and E2E admin publish flow.
  • Mutation test: editing a published version or accepting an unknown feature key must make tests fail.

Documentation

  • ADR/admission outcome linkage, ERD/data dictionary, module README, OpenAPI/AsyncAPI, admin guide, release/versioning semantics, and changeset.

Dependencies

Blocks effective entitlement implementation in #871.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:apiKontrak OpenAPI/RESTarea:databaseSchema, migration, pooling, RLSpriority:p1Prioritas tinggi - core domaintype:taskAtomic implementation task

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions