OPC # 0001: Extract OPC into standalone repo
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
-- =============================================================================
|
||||
-- OPC Seed Script – seeded from TODO.md backlog
|
||||
-- Run against the ControlPlane database.
|
||||
-- OPC # 0001 is already live; this starts at 0002.
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO opc (id, number, title, description, type, status, priority, assignee, created_at, updated_at)
|
||||
VALUES
|
||||
|
||||
-- ── Keycloak / Auth ───────────────────────────────────────────────────────────
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0002',
|
||||
'Fix KeycloakStep 401 on realm provisioning',
|
||||
'KeycloakStep is the current blocker in the provisioning saga. The step returns 401 when attempting to create the tenant realm. Investigate the admin-client credentials, token scope, and the endpoint URL used inside the Docker network.',
|
||||
'Bug',
|
||||
'In Progress',
|
||||
'High',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0003',
|
||||
'KeycloakStep: full realm + user provisioning flow',
|
||||
'After the 401 is resolved, implement the full flow: create realm {subdomain}.clarity.io, create the admin role, create the day-zero admin user from AdminEmail, assign the admin role, and trigger execute-actions-email (verify email + set password).',
|
||||
'Feature',
|
||||
'New',
|
||||
'High',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0004',
|
||||
'Keycloak JWT backchannel issuer cleanup',
|
||||
'Keycloak advertises its issuer based on the incoming request URL. When the backchannel hits http://keycloak:8080 directly it returns http://keycloak.clarity.test:8080 as the issuer, forcing layered workarounds in ValidIssuers and the rewrite handler. Clean fix: boot Keycloak with KC_HOSTNAME_URL=https://keycloak.clarity.test, verify via /.well-known/openid-configuration, then simplify ValidIssuers back to two entries. Deferred until next planned maintenance window (requires nuke to apply env var).',
|
||||
'Tech Debt',
|
||||
'New',
|
||||
'Medium',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
|
||||
-- ── VaultStep ─────────────────────────────────────────────────────────────────
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0005',
|
||||
'VaultStep: read root token and write initial secrets',
|
||||
'Read the root token from /vault/file/init.json, enable KV-v2 secrets engine at {subdomain}/, then write the initial secrets: DB connection string and Keycloak client secret.',
|
||||
'Feature',
|
||||
'New',
|
||||
'High',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
|
||||
-- ── MigrationStep ─────────────────────────────────────────────────────────────
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0006',
|
||||
'MigrationStep: run EF Core migrations per provisioning mode',
|
||||
'Wire up EF Core migrations inside MigrationStep for all three provisioning modes. Shared: run against the shared DB scoped to the tenant schema. Isolated: run against the dedicated Postgres container registered in SagaContext. Dedicated: run against the full dedicated Postgres instance.',
|
||||
'Feature',
|
||||
'New',
|
||||
'Medium',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
|
||||
-- ── HandoffStep ───────────────────────────────────────────────────────────────
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0007',
|
||||
'HandoffStep: send magic-link email and mark saga complete',
|
||||
'Send a magic-link / welcome email to AdminEmail via SMTP or SendGrid, then mark CompletedSteps.HandoffSent on the provisioning job. Blocked until SMTP is wired (currently SendRequiredActionsEmailAsync is commented out in KeycloakStep.cs).',
|
||||
'Feature',
|
||||
'New',
|
||||
'Medium',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
|
||||
-- ── Observability ─────────────────────────────────────────────────────────────
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0008',
|
||||
'Stream tenant container logs into Aspire dashboard',
|
||||
'Use the Docker SDK to tail fdev-app-clarity-* container logs and forward them to Aspire''s structured log stream. Currently these logs are only visible via docker logs on the host.',
|
||||
'Feature',
|
||||
'New',
|
||||
'Low',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
|
||||
-- ── Kubernetes (backburner) ───────────────────────────────────────────────────
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0009',
|
||||
'Kubernetes migration path evaluation',
|
||||
'Currently managing containers directly via Docker.DotNet. Evaluate k8s when: scheduling across multiple nodes is needed, rolling deploys are required, or client count exceeds single-host capacity. Options: k3s (self-hosted), AKS/EKS (cloud), or keep Docker Compose per host for mid-scale. ClarityContainerService abstraction is intentional – swap Docker.DotNet for a k8s client without changing the saga.',
|
||||
'General',
|
||||
'New',
|
||||
'Low',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
);
|
||||
@@ -0,0 +1,119 @@
|
||||
-- =============================================================================
|
||||
-- OPC Seed Script 2 – completed work from TODO.md
|
||||
-- Run against the ControlPlane database.
|
||||
-- Picks up numbering at 0010 (0001–0009 covered in seed_opc.sql).
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO opc (id, number, title, description, type, status, priority, assignee, created_at, updated_at)
|
||||
VALUES
|
||||
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0010',
|
||||
'Aspire AppHost wired: Vault, MinIO, RabbitMQ, Postgres, Keycloak, Worker, API, UI',
|
||||
'Full Aspire AppHost configuration completed. All infrastructure services (Vault, MinIO, RabbitMQ, Postgres, Keycloak) and application services (Worker, API, UI) are registered and wired in the AppHost project.',
|
||||
'Feature',
|
||||
'Done',
|
||||
'High',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0011',
|
||||
'Fix CRLF → LF on entrypoint.sh (was breaking Vault container)',
|
||||
'entrypoint.sh had Windows-style CRLF line endings which caused the Vault container to fail on startup. Fixed by enforcing LF via .gitattributes.',
|
||||
'Bug',
|
||||
'Done',
|
||||
'High',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0012',
|
||||
'Vault initialises and unseals on first run',
|
||||
'Vault container now correctly initialises (generates root token + unseal keys) and auto-unseals on first run. Init output is written to /vault/file/init.json.',
|
||||
'Feature',
|
||||
'Done',
|
||||
'High',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0013',
|
||||
'Pin Keycloak bootstrap password (fix persistent container password drift)',
|
||||
'Keycloak was experiencing password drift between container restarts due to the bootstrap admin credentials not being pinned. Fixed by explicitly setting the admin password so it persists across restarts.',
|
||||
'Bug',
|
||||
'Done',
|
||||
'High',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0014',
|
||||
'Fix Keycloak endpoint name: tcp → http',
|
||||
'Keycloak Aspire resource was registered with a tcp endpoint name instead of http, causing service discovery failures. Renamed to http to align with the rest of the stack.',
|
||||
'Bug',
|
||||
'Done',
|
||||
'Medium',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0015',
|
||||
'Worker starts and correctly waits for all dependencies',
|
||||
'The Worker service was starting before infrastructure dependencies were healthy. Implemented proper wait/health-check logic so the Worker blocks until Postgres, Keycloak, Vault, RabbitMQ, and MinIO are all ready.',
|
||||
'Bug',
|
||||
'Done',
|
||||
'High',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0016',
|
||||
'MassTransit saga pipeline with compensation',
|
||||
'Implemented the full MassTransit-based provisioning saga with forward steps and compensating transactions. Each step registers its rollback so a mid-saga failure cleanly tears down any already-provisioned resources.',
|
||||
'Feature',
|
||||
'Done',
|
||||
'High',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0017',
|
||||
'SSE progress stream: Worker → RabbitMQ → API → browser',
|
||||
'Implemented a real-time Server-Sent Events pipeline. The Worker publishes step progress to RabbitMQ, the API consumes and streams events via SSE, and the browser receives live updates without polling.',
|
||||
'Feature',
|
||||
'Done',
|
||||
'High',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0018',
|
||||
'Frontend Diagnostics tab with full stack traces from worker',
|
||||
'Added a Diagnostics tab to the frontend that displays structured error messages and full stack traces forwarded from the Worker service, making provisioning failures debuggable directly in the UI.',
|
||||
'Feature',
|
||||
'Done',
|
||||
'Medium',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
),
|
||||
(
|
||||
gen_random_uuid(),
|
||||
'OPC # 0019',
|
||||
'Enforce LF line endings for *.sh and *.hcl via .gitattributes',
|
||||
'Added .gitattributes rules to enforce LF line endings for all *.sh and *.hcl files. Prevents CRLF issues from reappearing when contributors commit from Windows machines.',
|
||||
'Tech Debt',
|
||||
'Done',
|
||||
'Low',
|
||||
'amadzarak',
|
||||
NOW(), NOW()
|
||||
);
|
||||
Reference in New Issue
Block a user