Files
user-engine/docs/development.md

2.8 KiB

Development

Stack

The initial implementation uses Python 3.12 and the standard library. The first slice intentionally avoids runtime dependencies so the repository can be tested immediately in local and agent environments.

Layout

src/user_engine/
  adapters/    local standalone adapters, Postgres adapter, and test doubles
  domain/      transport- and persistence-neutral domain schemas
  errors.py    typed service exceptions for callers and future transports
  migrations.py ordered durable-store migration manifest
  ports.py     adapter protocols for identity, authorization, events, audit,
               membership export, application bindings, and secrets
  service.py   headless service API for the isolated MVP
  store_records.py JSON-safe durable-store record serialization
  testing/     local fixtures for tests and examples
tests/         standard-library unittest suite

The domain layer should not import HTTP frameworks, database clients, or platform-specific SDKs. Those integrations belong behind ports.

Commands

make test

The command runs:

PYTHONPATH=src python3 -m unittest discover -s tests -p 'test_*.py'

Live Postgres conformance tests are skipped by default. To run them against a dedicated disposable database, install psycopg or psycopg2 in the active environment and set:

USER_ENGINE_POSTGRES_TEST_DSN='postgresql://...' \
USER_ENGINE_POSTGRES_TEST_RESET=1 \
make test

The reset flag is required because those tests delete rows from the bootstrap-owned user_engine_* tables.

Implementation Rule

Add new behavior in this order:

  1. domain schema or port;
  2. local fixture or adapter;
  3. test that proves the boundary;
  4. infrastructure adapter or API surface.

Isolated MVP Surface

The initial headless API is UserEngineService. It exposes health, readiness, me, user/account lifecycle, identity linking, application registration, catalog publication, profile writes, effective profile resolution, projections, audit inspection, and outbox inspection. The first store is InMemoryUserEngineStore, which carries a schema version from user_engine.migrations and a migration hook so later database-backed stores have a contract to match. Future store adapters should run user_engine.testing.assert_user_engine_store_conformance with their own factory before being wired into service tests.

Tenant Surface

Tenant-aware operations resolve an explicit TenantContext before mutating tenant-scoped state. Tenant admins can operate inside their own tenant, while platform-root and cross-tenant operations require the platform-operator role. Tenant account state, memberships, tenant profile layers, authorization facts, audit records, outbox events, and diagnostics all carry the resolved tenant.