Files
git.stella-ops.org/docs/db/tasks/PHASE_1_AUTHORITY.md
StellaOps Bot 175b750e29 Implement InMemory Transport Layer for StellaOps Router
- Added InMemoryTransportOptions class for configuration settings including timeouts and latency.
- Developed InMemoryTransportServer class to handle connections, frame processing, and event management.
- Created ServiceCollectionExtensions for easy registration of InMemory transport services.
- Established project structure and dependencies for InMemory transport library.
- Implemented comprehensive unit tests for endpoint discovery, connection management, request/response flow, and streaming capabilities.
- Ensured proper handling of cancellation, heartbeat, and hello frames within the transport layer.
2025-12-05 01:00:10 +02:00

13 KiB
Raw Permalink Blame History

Phase 1: Authority Module Conversion

Sprint: 2 Duration: 1 sprint Status: DONE (2025-12-03) Dependencies: Phase 0 (Foundations)


Objectives

  1. Create StellaOps.Authority.Storage.Postgres project
  2. Implement full Authority schema in PostgreSQL
  3. Implement all repository interfaces
  4. (Retired) Dual-write mode used during cutover; removed in cleanup
  5. Switch Authority to PostgreSQL-only after verification

2025-12-03 Update

  • Dual-write wrappers removed post-cutover; Authority now runs Postgres-only with direct repositories.
  • Backfill harness retired; staging/production operate solely on PostgreSQL.
  • Sprint PG-T1.9PG-T1.12 closed; no remaining dual-write dependencies.

Execution Log

Date (UTC) Update Owner
2025-12-03 Cutover to PostgreSQL-only; dual-write removed; verification completed. Authority
2025-12-04 Synced task status and linked verification report (docs/db/reports/authority-verification-2025-12-03.md). PM

Deliverables

Deliverable Acceptance Criteria
Authority schema All tables created with indexes
Repository implementations All 9 interfaces implemented
Dual-write wrapper Optional, for safe rollout
Integration tests 100% coverage of CRUD operations
Verification report MongoDB vs PostgreSQL comparison passed

Schema Reference

See SPECIFICATION.md Section 5.1 for complete Authority schema.

Tables:

  • authority.tenants
  • authority.users
  • authority.roles
  • authority.user_roles
  • authority.service_accounts
  • authority.clients
  • authority.scopes
  • authority.tokens
  • authority.revocations
  • authority.login_attempts
  • authority.licenses
  • authority.license_usage

Task Breakdown

T1.1: Create Authority.Storage.Postgres Project

Status: TODO Assignee: TBD Estimate: 0.5 days

Description: Create the PostgreSQL storage project for Authority module.

Subtasks:

  • T1.1.1: Create project src/Authority/__Libraries/StellaOps.Authority.Storage.Postgres/
  • T1.1.2: Add reference to StellaOps.Infrastructure.Postgres
  • T1.1.3: Add reference to StellaOps.Authority.Core
  • T1.1.4: Create AuthorityDataSource class
  • T1.1.5: Create AuthorityPostgresOptions class
  • T1.1.6: Create ServiceCollectionExtensions.cs

Project Structure:

src/Authority/__Libraries/StellaOps.Authority.Storage.Postgres/
├── StellaOps.Authority.Storage.Postgres.csproj
├── AuthorityDataSource.cs
├── AuthorityPostgresOptions.cs
├── Repositories/
│   ├── PostgresUserRepository.cs
│   ├── PostgresRoleRepository.cs
│   ├── PostgresServiceAccountRepository.cs
│   ├── PostgresClientRepository.cs
│   ├── PostgresScopeRepository.cs
│   ├── PostgresTokenRepository.cs
│   ├── PostgresRevocationRepository.cs
│   ├── PostgresLoginAttemptRepository.cs
│   └── PostgresLicenseRepository.cs
├── Migrations/
│   └── V001_CreateAuthoritySchema.cs
└── ServiceCollectionExtensions.cs

Verification:

  • Project builds without errors
  • Can be referenced from Authority.WebService

T1.2: Implement Schema Migrations

Status: TODO Assignee: TBD Estimate: 1 day

Description: Create PostgreSQL schema migration for Authority tables.

Subtasks:

  • T1.2.1: Create V001_CreateAuthoritySchema migration
  • T1.2.2: Include all tables from SPECIFICATION.md
  • T1.2.3: Include all indexes
  • T1.2.4: Add seed data for system roles/permissions
  • T1.2.5: Test migration idempotency

Migration Implementation:

public sealed class V001_CreateAuthoritySchema : IPostgresMigration
{
    public string Id => "V001_CreateAuthoritySchema";
    public string Description => "Create Authority schema with all tables and indexes";

    public async Task UpAsync(NpgsqlConnection connection, CancellationToken ct)
    {
        await using var cmd = connection.CreateCommand();
        cmd.CommandText = AuthoritySchemaSql;
        await cmd.ExecuteNonQueryAsync(ct);
    }

    public Task DownAsync(NpgsqlConnection connection, CancellationToken ct)
        => throw new NotSupportedException("Rollback not supported for schema creation");

    private const string AuthoritySchemaSql = """
        CREATE SCHEMA IF NOT EXISTS authority;

        CREATE TABLE IF NOT EXISTS authority.tenants (
            id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
            code TEXT NOT NULL UNIQUE,
            display_name TEXT NOT NULL,
            status TEXT NOT NULL DEFAULT 'active'
                CHECK (status IN ('active', 'suspended', 'trial', 'terminated')),
            settings JSONB DEFAULT '{}',
            created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
            updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
        );

        -- ... rest of schema from SPECIFICATION.md
        """;
}

Verification:

  • Migration creates all tables
  • Migration is idempotent
  • Indexes created correctly

T1.3: Implement User Repository

Status: TODO Assignee: TBD Estimate: 1 day

Description: Implement IUserRepository for PostgreSQL.

Subtasks:

  • T1.3.1: Implement GetByIdAsync
  • T1.3.2: Implement GetByUsernameAsync
  • T1.3.3: Implement GetBySubjectIdAsync
  • T1.3.4: Implement ListAsync with pagination
  • T1.3.5: Implement CreateAsync
  • T1.3.6: Implement UpdateAsync
  • T1.3.7: Implement DeleteAsync
  • T1.3.8: Implement GetRolesAsync
  • T1.3.9: Implement AssignRoleAsync
  • T1.3.10: Implement RevokeRoleAsync
  • T1.3.11: Write integration tests

Interface Reference:

public interface IUserRepository
{
    Task<User?> GetByIdAsync(string tenantId, Guid userId, CancellationToken ct);
    Task<User?> GetByUsernameAsync(string tenantId, string username, CancellationToken ct);
    Task<User?> GetBySubjectIdAsync(Guid subjectId, CancellationToken ct);
    Task<PagedResult<User>> ListAsync(string tenantId, UserQuery query, CancellationToken ct);
    Task<User> CreateAsync(User user, CancellationToken ct);
    Task<User> UpdateAsync(User user, CancellationToken ct);
    Task<bool> DeleteAsync(string tenantId, Guid userId, CancellationToken ct);
    Task<IReadOnlyList<Role>> GetRolesAsync(string tenantId, Guid userId, CancellationToken ct);
    Task AssignRoleAsync(string tenantId, Guid userId, Guid roleId, CancellationToken ct);
    Task RevokeRoleAsync(string tenantId, Guid userId, Guid roleId, CancellationToken ct);
}

Verification:

  • All methods implemented
  • Integration tests pass
  • Tenant isolation verified

T1.4: Implement Service Account Repository

Status: TODO Assignee: TBD Estimate: 0.5 days

Description: Implement IServiceAccountRepository for PostgreSQL.

Subtasks:

  • T1.4.1: Implement GetByIdAsync
  • T1.4.2: Implement GetByAccountIdAsync
  • T1.4.3: Implement ListAsync
  • T1.4.4: Implement CreateAsync
  • T1.4.5: Implement UpdateAsync
  • T1.4.6: Implement DeleteAsync
  • T1.4.7: Write integration tests

Verification:

  • All methods implemented
  • Integration tests pass

T1.5: Implement Client Repository

Status: TODO Assignee: TBD Estimate: 0.5 days

Description: Implement IClientRepository for PostgreSQL (OpenIddict compatible).

Subtasks:

  • T1.5.1: Implement GetByIdAsync
  • T1.5.2: Implement GetByClientIdAsync
  • T1.5.3: Implement ListAsync
  • T1.5.4: Implement CreateAsync
  • T1.5.5: Implement UpdateAsync
  • T1.5.6: Implement DeleteAsync
  • T1.5.7: Write integration tests

Verification:

  • All methods implemented
  • Integration tests pass

T1.6: Implement Token Repository

Status: TODO Assignee: TBD Estimate: 1 day

Description: Implement ITokenRepository for PostgreSQL.

Subtasks:

  • T1.6.1: Implement GetByIdAsync
  • T1.6.2: Implement GetByHashAsync
  • T1.6.3: Implement CreateAsync
  • T1.6.4: Implement RevokeAsync
  • T1.6.5: Implement PruneExpiredAsync
  • T1.6.6: Implement GetActiveTokensAsync
  • T1.6.7: Write integration tests

Verification:

  • All methods implemented
  • Token lookup by hash is fast
  • Expired token pruning works

T1.7: Implement Remaining Repositories

Status: TODO Assignee: TBD Estimate: 1.5 days

Description: Implement remaining repository interfaces.

Subtasks:

  • T1.7.1: Implement IRoleRepository
  • T1.7.2: Implement IScopeRepository
  • T1.7.3: Implement IRevocationRepository
  • T1.7.4: Implement ILoginAttemptRepository
  • T1.7.5: Implement ILicenseRepository
  • T1.7.6: Write integration tests for all

Verification:

  • All repositories implemented
  • All integration tests pass

T1.8: Add Configuration Switch

Status: TODO Assignee: TBD Estimate: 0.5 days

Description: Add configuration-based backend selection for Authority.

Subtasks:

  • T1.8.1: Update ServiceCollectionExtensions in Authority.WebService
  • T1.8.2: Add conditional registration based on Persistence:Authority
  • T1.8.3: Test switching between Mongo and Postgres
  • T1.8.4: Document configuration options

Implementation:

public static IServiceCollection AddAuthorityStorage(
    this IServiceCollection services,
    IConfiguration configuration)
{
    var backend = configuration.GetValue<string>("Persistence:Authority") ?? "Mongo";

    return backend.ToLowerInvariant() switch
    {
        "postgres" => services.AddAuthorityPostgresStorage(configuration),
        "mongo" => services.AddAuthorityMongoStorage(configuration),
        _ => throw new ArgumentException($"Unknown Authority backend: {backend}")
    };
}

Verification:

  • Can switch between backends via configuration
  • Invalid configuration throws clear error

T1.9: Dual-Write Wrapper (Retired)

Status: N/A (Removed 2025-12-03 post-cutover) Notes: Dual-write path served migration; code and configuration removed in cleanup.


T1.10: Run Verification Tests

Status: TODO Assignee: TBD Estimate: 1 day

Description: Verify PostgreSQL implementation matches MongoDB behavior.

Subtasks:

  • T1.10.1: Run comparison tests for User repository
  • T1.10.2: Run comparison tests for Token repository
  • T1.10.3: Verify token issuance/verification flow
  • T1.10.4: Verify login flow
  • T1.10.5: Document any differences found
  • T1.10.6: Generate verification report

Verification Tests:

[Fact]
public async Task Users_Should_Match_Between_Mongo_And_Postgres()
{
    var tenantIds = await GetSampleTenantIds(10);

    foreach (var tenantId in tenantIds)
    {
        var mongoUsers = await _mongoRepo.ListAsync(tenantId, new UserQuery());
        var postgresUsers = await _postgresRepo.ListAsync(tenantId, new UserQuery());

        postgresUsers.Items.Should().BeEquivalentTo(mongoUsers.Items,
            options => options.Excluding(u => u.Id));
    }
}

Verification:

  • All comparison tests pass
  • No data discrepancies found
  • Verification report approved

T1.11: Backfill Data (If Required)

Status: TODO Assignee: TBD Estimate: 0.5 days

Description: Backfill existing MongoDB data to PostgreSQL.

Subtasks:

  • T1.11.1: Create backfill script for tenants
  • T1.11.2: Create backfill script for users
  • T1.11.3: Create backfill script for service accounts
  • T1.11.4: Create backfill script for clients/scopes
  • T1.11.5: Create backfill script for active tokens
  • T1.11.6: Verify record counts match
  • T1.11.7: Verify sample records match

Verification:

  • All Tier A data backfilled
  • Record counts match
  • Sample verification passed

T1.12: Switch to PostgreSQL-Only

Status: TODO Assignee: TBD Estimate: 0.5 days

Description: Switch Authority to PostgreSQL-only mode.

Subtasks:

  • T1.12.1: Update configuration to "Authority": "Postgres"
  • T1.12.2: Deploy to staging
  • T1.12.3: Run full integration test suite
  • T1.12.4: Monitor for errors/issues
  • T1.12.5: Deploy to production
  • T1.12.6: Monitor production metrics

Verification:

  • All tests pass in staging
  • No errors in production
  • Performance metrics acceptable

Exit Criteria

  • All repository interfaces implemented for PostgreSQL
  • All integration tests pass
  • Verification tests pass (MongoDB vs PostgreSQL comparison)
  • Configuration switch working
  • Authority running on PostgreSQL in production
  • MongoDB Authority collections archived

Risks & Mitigations

Risk Likelihood Impact Mitigation
Token verification regression Low High Extensive testing, dual-write
OAuth flow breakage Low High Test all OAuth flows
Performance regression Medium Medium Load testing before switch

Rollback Plan

  1. Change configuration: "Authority": "Mongo"
  2. Deploy configuration change
  3. MongoDB still has all data (dual-write period)
  4. Investigate and fix PostgreSQL issues
  5. Re-attempt conversion

Phase Version: 1.0.0 Last Updated: 2025-11-28