Skip to content

Identity ​

Responsibility and models ​

Identity owns user accounts, passwords, account status, account-level profile fields, JWT access tokens, refresh sessions, email verification, password recovery, login limits, and audit records. Professional doctor profiles belong to Doctor; organization membership and affiliations belong to Organization. Its PostgreSQL tables use the auth_ prefix retained by the existing migrations.

Current implementation ​

Authentication operations are implemented with pgx repositories, password hashing, token signing, and shared email delivery. The module validates signing configuration at startup, exposes Administration(), Identity(), and Authentication() services, and registers Huma routes under /api/v1/auth. public/ defines the curated account/token boundary; internal/usecase holds individual operations; cryptographic and PostgreSQL adapters stay private.

Module.Administration() returns the public AdminIdentityService for CreateAccount, GetAccount, and GetAccounts. Admin receives it through Dependencies.AdminIdentityService. The read-only AccountReader capability remains available for organization authentication, authorization, and audit integrations. Account management and credential verification have separate contracts.

internal/services.IdentityService implements the shared types.IIdentityService contract. Obtain it through Module.Identity() and call Verify(ctx, authorization) with the complete Authorization header. It reuses ValidateAuthorizationUseCase to validate the JWT, confirm an active persistent session belonging to the token's user, and require an active account. Success returns shared types.Identity user/session IDs. The existing Authentication() capability adapts this same service for current consumers.

Verification needs the existing JWT validator (JWT_SECRET of at least 32 bytes) and user/session repositories backed by migrated PostgreSQL auth_users and auth_sessions tables. NewModule already supplies these dependencies through usecase.Auth; no additional configuration or schema changes are required. Missing authentication dependencies return public.ErrUnavailable; rejected credentials or sessions return public.ErrInvalidAccessToken. Storage and context errors propagate to the caller.

Workflows and integration ​

Authentication setup and request flow covers registration, login, refresh rotation, logout, profile updates, sessions, verification, and recovery with request examples and failure responses. Admin receives account creation/lookup and access-token validation capabilities from this module. Identity creates verification/reset content and sends synchronously through the injected email.Sender; the composition root currently chooses console delivery.

Refresh/session and email-token state is persisted. Login and recovery flows intentionally use generic responses where account enumeration would otherwise occur. User-registration events are published by the owning use case, but email sending is not provided by a generic event subscriber or outbox.

Storage, authorization, and verification ​

Run the identity embedded migrations with pcli database migrate --service identity. Bearer validation belongs to the authentication capability and protected HTTP handlers. Account state, consumed tokens, rotation/reuse, expiry, and password changes are covered by identity tests. PostgreSQL integration tests require AUTH_TEST_DATABASE_URL and skip in short mode. Do not log passwords, access/refresh tokens, or real patient data in usage examples.

Development commands ​

Identity runs inside the API composition root. Use root make dev-api for Air, make build-api / make serve-api for the API image, and make lint / make tidy for workspace maintenance. Run tests from the repository root:

CommandPurpose
make testRun unit and contract tests across all modules; skip integration tests
make test:e2eRun integration test packages across all modules; require AUTH_TEST_DATABASE_URL for identity
go test -race -short -cover ./services/identity/...Run only identity unit and contract tests

The root make test runs all modules in short mode and skips integration tests. The root make test:e2e discovers packages containing *_integration_test.go under pkg/, services/, and tools/ and runs their tests. It starts the isolated test database, waits for it to become healthy, and removes the test containers and network afterward, including on failures or interruptions. There are currently no automated E2E tests attached to this target.

Use the repository CLI for database operations and shared generation:

sh
go run ./tools/cli generate sqlc --service identity
go run ./tools/cli generate migration --service identity --name add_example
go run ./tools/cli database migrate --service identity
go run ./tools/cli database status --service identity
go run ./tools/cli generate openapi
go run ./tools/cli generate protobuf

generate sqlc regenerates private query accessors from sqlc.yaml and requires sqlc on PATH. generate migration writes a timestamped SQL migration in internal/postgres/migrations using the Goose library built into the CLI; it requires no separate Goose executable. Both commands work from repository subdirectories without loading database configuration or connecting to a database.

See CLI requirements and database protections. The old direct Goose rollback/reset targets have been removed. pcli database reset --yes rebuilds and seeds all services in a local database; it does not replace a single-service rollback.

Code reference ​

See public contracts, module construction, and use cases.

Documentation follows the source. Planned contracts are marked explicitly.