Spensara Spensara Knowledge Base & Documentation Repository

Repository Docs & Knowledge Base

Consolidated Spensara documentation repository (722 Markdown & architecture documents in ../repository)
Built Word Documents (.docx): Spensara Overview (.docx) Capability Assessment (.docx) Brink POS Ingestion Analysis (.docx) The Borg Ingestion Architecture (.docx)

Implementation Specs (157)

Detailed engineering and feature implementation specifications.
implementation-specs/specs/BrinkPosOrdersFirstEtlJob/TASK9.md 6,470 bytes · Updated Oct 23, 2026 10:44 AM EDT
Raw File

TASK 9: Customer Onboarding, Warehouse Provisioning, And Manual Brink ETL Alignment

Summary

Add the missing application-level flow that makes a Brink-enabled customer ETL-ready on the Keycloak branch without changing the existing CLI operational path.

This task connects the already existing pieces that are still separate today:

  • backend customer creation and update
  • Keycloak-backed membership assignment
  • tenant warehouse mapping registration
  • Redshift tenant bootstrap
  • Brink credential persistence
  • manual Brink ETL request alignment with stored customer identity

The goal is small and focused: after this task, admin onboarding in the application should be able to create or update a Brink-enabled customer and leave that customer ready for scheduled or manual Brink ETL, while the current CLI commands remain available as they are.

Dependencies

  • ./TASK1.md - source binding and dispatch
  • ./TASK2.md - extract boundary and tenant-aware ETL runtime
  • ./TASK5.md - warehouse staging load depends on tenant warehouse mapping
  • ./TASK6.md - curated flow depends on tenant warehouse mapping and bootstrap
  • ./THN-106-keycloak-connection-data-analysis.md - Keycloak/customer credential storage direction

Files to Modify

1. Customer onboarding orchestration

Modify the admin customer application flow so a Brink-enabled customer can be provisioned for warehouse-backed ETL from the backend application layer.

Likely touchpoints:

  • backend/Kds.Ai.ApiService/Services/CustomerManagementService.cs
  • backend/Kds.Ai.ApiService/Endpoints/AdminCustomerEndpoints.cs
  • backend/Kds.Ai.ApiService/Services/ for a new orchestration service if needed

2. Tenant warehouse naming and provisioning seam

Add or finalize one backend seam that:

  • derives the tenant warehouse registration key from tenant identity
  • derives the Redshift database name from customer data
  • registers the mapping
  • triggers bootstrap through the existing warehouse bootstrapper

This task must not redesign the existing CLI commands. CLI stays as-is.

3. Manual Brink ETL request alignment

Modify the manual Brink ETL entry so the request no longer trusts a free-form companyId + tenantId pair.

The backend should resolve customer-backed identity and pass the canonical values into the existing pipeline.

Likely touchpoints:

  • backend/Kds.Ai.ApiService/Endpoints/BrinkPosEtlEndpoints.cs
  • backend/Kds.Ai.ApiService/Jobs/BrinkPosEtlJobs.cs

Required Behavior

Onboarding rule

When an admin creates or updates a Brink-enabled customer through the application flow, the backend should be able to coordinate:

  1. customer persistence
  2. membership assignment when requested
  3. tenant warehouse mapping registration
  4. tenant warehouse bootstrap
  5. Brink credential persistence

This should be one application flow, not a sequence of manual post-steps.

CLI compatibility rule

  • the current CLI warehouse commands must remain available
  • this task adds a new application onboarding path
  • this task does not replace, remove, or redesign the CLI path

Database naming rule

The tenant warehouse database name must be created by backend application logic, not manually supplied by UI callers.

Required direction:

  • normalize the customer company/name into a database-safe slug
  • append customer.Id to keep the final database name unique and stable
  • use a deterministic format such as <normalized-customer-name>-<customer-id>
  • keep customer.TenantId.ToString("D") as the registration key for tenant mapping

The database name and tenant id are related, but they are not the same string.

Manual ETL identity rule

Manual Brink ETL must not rely on the caller submitting an arbitrary companyId + tenantId pair.

This task should change the manual path so backend code resolves the stored customer and derives:

  • companyId = customer.Id.ToString("D")
  • tenantId = customer.TenantId.ToString("D")

Authorization rule

The manual Brink ETL endpoint must be aligned with the Keycloak-backed admin authorization model used by the rest of the admin operational surface.

Minimum expected behavior:

  • /etl/brink/run requires admin authorization

Status visibility rule

Admin customer flows should expose enough status to understand whether Brink ETL provisioning is complete.

Minimum useful state:

  • warehouse mapping exists or not
  • mapped tenant database
  • warehouse mapping active or not
  • Brink credential configured/enabled state

Testing

Unit tests

Add unit tests for:

  • deterministic tenant warehouse database-name generation from customer data
  • onboarding orchestration behavior when warehouse mapping does not exist yet
  • onboarding behavior when the mapping already exists
  • manual ETL request resolution from stored customer identity
  • manual ETL authorization behavior

Integration tests

Add integration coverage that proves at least:

  • creating a Brink-enabled customer through the application flow can leave the customer ETL-ready
  • the tenant warehouse mapping is registered with the expected tenant id and generated database name
  • the bootstrap path is invoked from the application flow
  • the manual Brink ETL path resolves canonical identifiers from stored customer data instead of trusting free-form request identity

Acceptance Criteria

  • [ ] A Brink-enabled customer can be onboarded through backend application flow without separate manual warehouse setup in the normal case
  • [ ] Tenant warehouse mapping registration uses customer.TenantId.ToString("D") as the mapping key
  • [ ] Redshift tenant database name is generated by backend code from normalized customer name plus customer.Id
  • [ ] Existing CLI warehouse commands remain unchanged and usable
  • [ ] Manual Brink ETL no longer relies on a caller-provided free-form companyId + tenantId pair
  • [ ] Manual Brink ETL endpoint is protected by admin authorization
  • [ ] Admin flows expose enough provisioning state to diagnose ETL readiness
  • [ ] Relevant tests cover onboarding, naming, provisioning, and manual-trigger alignment

Notes

  • Keep the implementation scope small. This is not a redesign of the whole ETL pipeline.
  • The ETL stage implementations already work with tenant warehouse mapping and customer-backed Brink credentials. The missing piece is orchestration.
  • Prefer adding one focused application service over spreading provisioning logic across endpoints and controllers.