Skip to content

Add shared service, configuration, operation, and durable-job primitives #31

Description

@alexeygrigorev

Parent epics: #2, #7

Normative specs: 01 — Platform architecture, 06 — Studio/admin API

Scope

Create boring shared primitives that domain issues can use consistently: typed bootstrap/database configuration, database-backed safe operational settings, command/query service conventions, request/correlation IDs, revisions, idempotency records, long-running operation resources, transaction-after-commit dispatch, Django-Q2 ORM-broker worker/scheduler ownership, leases/retries/heartbeats, and redacted append-only audit foundations.

Non-goals

No domain-specific content sync, course scoring, registration, email send, Studio screens, or API resource implementation. Do not put network side effects in transactions or model save() methods.

Acceptance criteria

  • Bootstrap secrets/settings fail closed outside local/test; safe DB-backed settings are typed, source-visible, versioned, and audited.
  • Commands/queries have one documented service boundary callable by HTML, API, jobs, and tests.
  • Idempotency, revision conflict, operation progress/cancellation, job lease/retry, heartbeat, and after-commit dispatch primitives are reusable and PostgreSQL-safe.
  • Exactly one scheduler owner registers recurring jobs; duplicate process startup cannot duplicate schedules.
  • Audit/request/job/correlation IDs propagate without logging credentials, tokens, bodies, or unnecessary PII.
  • Worker outage preserves committed work and readiness does not call optional external providers.

Test scenarios

  1. Concurrent identical idempotency keys return one result; conflicting payloads fail deterministically.
  2. Stale revisions return conflict without overwrite.
  3. Worker crash/expired lease is recovered without duplicate completed side effect.
  4. Transaction rollback dispatches no job; successful commit dispatches once.
  5. Two scheduler contenders elect one effective owner.
  6. Redaction/property tests prove protected fields never enter audit/log metadata.

No Playwright scenario is required because this issue exposes no user-facing surface; Studio operation presentation is covered by #32.

Dependencies

Depends on #1. Blocks domain mutation and asynchronous-operation issues.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0Must-have or release-blockingfoundationArea: foundationoperationsArea: operations

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions