Categories
Implementation Specs (157)
- specs/AnomalyDetection/TASK1.1.md
- specs/AnomalyDetection/TASK1.2.md
- specs/AnomalyDetection/TASK1.3.md
- specs/AnomalyDetection/TASK1.4.md
- specs/AnomalyDetection/TASK2.1.md
- specs/AnomalyDetection/TASK2.2.md
- specs/AnomalyDetection/TASK3.1.md
- specs/AnomalyDetection/TASK3.2.md
- specs/AnomalyDetection/TASK3.3.md
- specs/AnomalyDetection/TASK4.1.md
- specs/AnomalyDetection/TASK4.2.md
- specs/AnomalyDetection/TASK4.3.md
- specs/AnomalyDetection/TASK4.4.md
- specs/AnomalyDetection/TASK5.1.md
- specs/AnomalyDetection/TASK5.2.md
- specs/AnomalyDetection/TASK5.3.md
- specs/AnomalyDetection/TASK6.1.md
- specs/AnomalyDetection/TASK6.2.md
- specs/AnomalyDetection/TASK6.3.md
- specs/AnomalyDetection/TASKS.md
- specs/ApiServicePostgresTestStability/TASK.md
- specs/BackendDatabaseConsolidation/TASK.md
- specs/BackendDatabaseConsolidation/TASK1.1.md
- specs/BackendDatabaseConsolidation/TASK1.2.md
- specs/BackendDatabaseConsolidation/TASK1.3.md
- specs/BackendDatabaseConsolidation/TASK2.1.md
- specs/BackendDatabaseConsolidation/TASK2.2.md
- specs/BackendDatabaseConsolidation/TASK2.3.md
- specs/BackendDatabaseConsolidation/TASK3.1.md
- specs/BackendDatabaseConsolidation/TASK3.2.md
- specs/BackendDatabaseConsolidation/TASK4.1.md
- specs/BackendDatabaseConsolidation/TASK4.2.md
- specs/BackendDatabaseConsolidation/TASK4.3.md
- specs/BackendDatabaseConsolidation/TASK5.1.md
- specs/BackendDatabaseConsolidation/TASK5.2.md
- specs/BrinkLaborGetShiftsStaging/TASK.md
- specs/BrinkPosOrdersFirstEtlJob/TASK.md
- specs/BrinkPosOrdersFirstEtlJob/TASK0.md
- specs/BrinkPosOrdersFirstEtlJob/TASK1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK2.1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK2.2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK2.3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK2.4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK3.1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK3.2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK3.3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK3.4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK4.1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK4.2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK4.3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK4.4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK5.1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK5.2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK5.3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK5.4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK5.md
- specs/BrinkPosOrdersFirstEtlJob/TASK6.1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK6.2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK6.3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK6.4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK6.md
- specs/BrinkPosOrdersFirstEtlJob/TASK7.md
- specs/BrinkPosOrdersFirstEtlJob/TASK8.md
- specs/BrinkPosOrdersFirstEtlJob/TASK9.md
- specs/BrinkSettings2ToStaging/TASK.MD
- specs/CuratedToS3Stage/TASK.md
- specs/CuratedToS3Stage/TASK0.md
- specs/CuratedToS3Stage/TASK1.md
- specs/CuratedToS3Stage/TASK2.md
- specs/CuratedToS3Stage/TASK3.md
- specs/CuratedToS3Stage/TASK4.md
- specs/CustomerCredentialCustomHeaders/TASK.md
- specs/CustomerCredentialCustomHeaders/TASK1.1.md
- specs/CustomerCredentialCustomHeaders/TASK1.2.md
- specs/CustomerCredentialCustomHeaders/TASK2.1.md
- specs/CustomerCredentialCustomHeaders/TASK2.2.md
- specs/CustomerCredentialCustomHeaders/TASK3.1.md
- specs/CustomerCredentialTriggeredProvisioning/TASK.md
- specs/CustomerCredentialTriggeredProvisioning/TASK1.1.md
- specs/CustomerCredentialTriggeredProvisioning/TASK1.2.md
- specs/CustomerCredentialTriggeredProvisioning/TASK2.1.md
- specs/CustomerCredentialTriggeredProvisioning/TASK2.2.md
- specs/CustomerCredentialTriggeredProvisioning/TASK3.1.md
- specs/CustomerCredentialTriggeredProvisioning/TASK3.2.md
- specs/CustomerCredentialTriggeredProvisioning/TASK4.1.md
- specs/EtlSourceAdapterFramework/TASK.md
- specs/EtlSourceAdapterFramework/TASK0.md
- specs/EtlSourceAdapterFramework/TASK1.md
- specs/EtlSourceAdapterFramework/TASK2.md
- specs/EtlSourceAdapterFramework/TASK3.md
- specs/EtlSourceAdapterFramework/TASK4.md
- specs/EtlSourceAdapterFramework/TASK5.md
- specs/EtlSourceAdapterFramework/TASK6.md
- specs/KdsCdcDebeziumIntegration/TASK.md
- specs/KdsCdcDebeziumIntegration/TASK1.md
- specs/KdsCdcDebeziumIntegration/TASK2.md
- specs/KdsCdcDebeziumIntegration/TASK3.md
- specs/KdsCdcDebeziumIntegration/TASK4.md
- specs/KdsCdcDebeziumIntegration/TASK5.md
- specs/KdsCdcDurableRelationRouting/TASK.md
- specs/KdsCdcDurableRelationRouting/TASK1.md
- specs/KdsCdcDurableRelationRouting/TASK2.md
- specs/KdsCdcDurableRelationRouting/TASK3.md
- specs/KdsCdcDurableRelationRouting/TASK4.md
- specs/KdsCdcDurableRelationRouting/TASK5.md
- specs/KdsCdcIngestion/TASK.md
- specs/KdsCdcIngestion/TASK1.md
- specs/KdsCdcIngestion/TASK2.md
- specs/KdsCdcIngestion/TASK3.md
- specs/KdsCdcIngestion/TASK4.md
- specs/KdsCdcIngestion/TASK5.md
- specs/KdsCdcIngestion/TASK6.md
- specs/KdsCdcIngestion/TASK7.md
- specs/KdsCdcIngestion/TASK8.md
- specs/KdsCdcIngestion/TASK9.md
- specs/KdsCdcReplayExecution/TASK.md
- specs/KdsCdcReplayExecution/TASK1.md
- specs/KdsCdcReplayExecution/TASK2.md
- specs/KdsCdcReplayExecution/TASK3.md
- specs/KdsCdcReplayExecution/TASK4.md
- specs/KdsMonitorServingContractMigration/TASK.md
- specs/KdsMonitorServingContractMigration/TASK1.1.md
- specs/KdsMonitorServingContractMigration/TASK1.2.md
- specs/KdsMonitorServingContractMigration/TASK2.1.md
- specs/KdsMonitorServingContractMigration/TASK2.2.md
- specs/KdsMonitorServingContractMigration/TASK3.1.md
- specs/KdsMonitorServingContractMigration/TASK3.2.md
- specs/RedshiftFoundation/TASK.md
- specs/RedshiftFoundation/TASK1.1.md
- specs/RedshiftFoundation/TASK1.2.md
- specs/RedshiftFoundation/TASK1.3.md
- specs/RedshiftFoundation/TASK1.4.md
- specs/RedshiftFoundation/TASK2.1.md
- specs/RedshiftFoundation/TASK2.2.md
- specs/RedshiftFoundation/TASK3.1.md
- specs/RedshiftFoundation/TASK3.2.md
- specs/RedshiftFoundation/TASK3.3.md
- specs/RedshiftSyntheticDataFeed/TASK.md
- specs/RedshiftSyntheticDataFeed/TASK1.1.md
- specs/RedshiftSyntheticDataFeed/TASK1.2.md
- specs/RedshiftSyntheticDataFeed/TASK1.3.md
- specs/RedshiftSyntheticDataFeed/TASK2.1.md
- specs/RedshiftSyntheticDataFeed/TASK2.2.md
- specs/RedshiftSyntheticDataFeed/TASK3.1.md
- specs/RedshiftSyntheticDataFeed/TASK3.2.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK1.1.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK1.2.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK2.1.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK2.2.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK2.3.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK3.1.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK3.2.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK4.1.md
TASK 1: Source Binding And Dispatch
Summary
Implement the first job-start boundary for the Brink POS orders ETL flow.
This task establishes the control-plane and scheduling layer that starts one tenant-day ETL run for the first Brink slice defined in TASK0.md.
Analysis of specs/BackendDatabaseConsolidation shows that this stream provides important reusable groundwork for:
- backend-owned customer and tenant persistence
- identity-backed tenant membership
- authenticated tenant resolution in backend APIs
However, it does not yet define the ETL source-binding model needed for Brink API pull execution.
This means Module 1 should:
- reuse the future consolidated tenant/customer foundation where possible
- avoid creating a conflicting tenant model
- add the missing ETL source-binding and dispatch model explicitly
This task owns:
- verification and reuse analysis of source-binding groundwork from
specs/BackendDatabaseConsolidation - source binding persistence and lookup
- company-level dispatch
- tenant-level child job contract
- scheduled versus manual trigger convergence
- required business-date resolution rule at child-job level
- dispatch and child-entry observability
This task does not implement raw extraction, S3 persistence, normalization, Redshift load, or curated mapping yet.
Dependencies
- TASK 0 - Module 0 decision record
Files to Create
1. Source binding model and repository contracts
First verify whether the source-binding groundwork already being created in:
specs/BackendDatabaseConsolidation
can be reused directly, or reused with narrow extensions.
Do not create a parallel competing source-binding model for Brink ETL if the consolidation stream already provides the right persistence and repository direction.
Analysis result for this task:
BackendDatabaseConsolidationis relevant for tenant/customer ownership and tenant membership resolution- it is not yet sufficient as the ETL source-binding model for Brink pull jobs
- no reusable source connection contract is currently defined there for external integrations, schedules, or ETL dispatch
Create or finalize the generic source binding model used to resolve one active Brink connection for one tenant.
Minimum logical fields:
idcompany_idtenant_idsource_system_typedisplay_nameservice_urlaccess_tokenlocation_tokenlocation_key- optional
configuration_json cron_expressiontime_zone_idis_activecreated_atupdated_at
This model must stay reusable, but for this implementation the Brink connection data is persisted in the database.
Current implementation decision for this stream:
- implement this entity now in backend persistence rather than waiting for
BackendDatabaseConsolidation - later streams may reuse this entity and extend it if needed
- add one seeded mock Brink binding record so live test credentials can be filled directly in the database
Required implementation rule:
- prefer reuse of the consolidation-stream tenant/customer foundations where compatible
- add a dedicated ETL source-binding model for external source connections because the consolidation stream does not currently define one
- document the relationship between the ETL source-binding model and the consolidated tenant/customer model explicitly
2. Dispatch and child job contracts
Create the first-job contracts used by scheduled and manual execution.
Required logical contracts:
BrinkPosDispatchJobInputBrinkPosExtractJobInputBrinkPosExtractTrigger
Required fields:
CompanyIdTenantIdon the child contract- optional
BusinessDate TriggerForceReset- optional
RequestedBy
3. Cron sync and dispatch services
Create or finalize the services responsible for:
- syncing TickerQ cron entries from active source bindings
- company-level dispatch
- child extract job entry
Recommended logical services:
BrinkPosExtractCronSyncServiceBrinkPosDispatchJobsBrinkPosExtractJobs
Exact names may differ, but these responsibilities must be represented clearly.
4. Source binding and secret resolution abstractions
Create or finalize abstractions needed so dispatch and child execution can resolve runtime Brink connectivity without leaking secret logic into scheduler code.
Minimum logical responsibilities:
- enumerate active bindings by
company_id - resolve one active binding by
tenant_id - read Brink connection data from the persisted source-binding record
- build the runtime
BrinkConnectionDefinitionin Warehouse/app-layer and pass it into the Brink integration boundary explicitly
Files to Modify
5. Dependency injection and host wiring
Register the source binding repository, secret-provider path, dispatch services, child job entry, and cron sync service in the appropriate backend modules.
Likely modules:
backend/Kds.Ai.Databackend/Kds.Ai.Warehousebackend/Kds.Ai.ApiServicebackend/Kds.Ai.Clibackend/Kds.Ai.AppHostbackend/Kds.Ai.Integrations.BrinkPosonly for adapting its public API to consume externally provided connection context
5a. Cross-stream spec touch points
If reuse or extension is needed, update the relevant Brink ETL spec and note the dependency on:
specs/BackendDatabaseConsolidation/TASK.md- related
BackendDatabaseConsolidationsubtasks that define or implement reusable persistence and tenant-binding foundations
6. Manual trigger entry point
Add or finalize one API entry point for manual execution.
The manual path must enqueue the same contract family used by scheduled execution. It must not bypass the job orchestration model.
Required Behavior
Source binding rules
- reuse the source-binding foundation from
BackendDatabaseConsolidationwhere possible - one active Brink binding maps to one tenant execution target
company_idis the dispatch grouping boundarytenant_idis the atomic execution boundary- active uniqueness must be enforced for Brink bindings per tenant
service_url,access_token,location_token, andlocation_keyare stored in the database as part of the source-binding data owned by backend- runtime Brink connection details are resolved from the persisted binding record, not from global app settings
- runtime tenant resolution, source-connection lookup, and binding validation are Warehouse/app-layer responsibilities, not Brink integration responsibilities
- scheduler code still must not interpret or manipulate Brink transport details beyond passing the tenant/job contract forward
- if the reused model is insufficient, Brink ETL may extend it only through explicit documented additions
Reuse analysis result
For this task, reuse from BackendDatabaseConsolidation should be interpreted as follows:
- reuse the consolidated tenant/customer identity and membership direction
- reuse tenant ownership concepts and IDs that become the backend source of truth
- do not create a second incompatible tenant model for ETL
- do create a new ETL source-binding persistence model because the consolidation stream does not yet model:
- external source connections
- integration credentials
- service URLs
- source-system-specific schedule metadata
- company-level ETL dispatch enumeration
Scheduling and dispatch rules
- scheduling uses two levels only:
- company dispatch
- tenant extract
- scheduled and manual execution must converge into the same child contract
- dispatch enumerates active tenant bindings for one company
- dispatch enqueues one tenant child job per active binding
- dispatch passes through
BusinessDate,Trigger,ForceReset, andRequestedByunchanged - dispatch does not resolve secrets
- dispatch does not determine endpoint ordering
- dispatch does not persist ETL batch state
- one tenant enqueue failure must not fail the whole dispatch cycle
- no-active-binding dispatch should log a warning and finish cleanly
Business-date rule
GetCurrentBusinessDate is required for this slice because the job runs daily.
The child extract contract must follow this rule:
- if
BusinessDateis provided, use it exactly - otherwise resolve the effective date through
Sales2.GetCurrentBusinessDate - use the resolved business date as the tenant-day execution boundary
Child entry rule
- the child extract job owns one tenant-day execution boundary only
- this task stops at child-job readiness and contract definition
- endpoint execution, raw capture, validation, and downstream ETL stages belong to later tasks
Testing
Unit tests
Unit tests are mandatory for this task.
Add unit tests for:
- reuse/extension rules for the source-binding model when integrating with
BackendDatabaseConsolidation - source binding uniqueness rules
- active binding lookup by
company_idandtenant_id - persisted Brink connection-data resolution from the database
- mapping from dispatch input to child input
- pass-through of
BusinessDate,Trigger,ForceReset, andRequestedBy - no-active-binding dispatch behavior
- partial enqueue-failure dispatch behavior
- manual API path enqueueing the same contract family as scheduled execution
- child business-date resolution routing
Integration or host-level tests
Add integration or host-level tests for:
- repository-backed source-binding resolution using the consolidated persistence model when available
- cron sync creation/update from active source bindings
- scheduled dispatch enqueueing tenant child jobs
- manual API enqueueing tenant child jobs
Live E2E expectation
This module is not yet a finished ETL data boundary, so a full live E2E against AWS or raw S3 output is not required here.
However, if practical through Aspire wiring, add a live host-level verification that:
- the app can resolve one active Brink binding from persisted metadata
- the manual or scheduled path can enqueue the child extract job with the expected payload
- the child path can resolve the effective business date using real Brink credentials when
BusinessDateis omitted
If this live verification is not implemented in this task, document the blocker explicitly and keep the requirement attached to the first extract task.
Acceptance Criteria
- [x] Source-binding groundwork from
BackendDatabaseConsolidationis reviewed before introducing Brink-specific persistence changes - [x] Reusable tenant/customer foundations from
BackendDatabaseConsolidationare adopted where compatible - [x] The gap between consolidated tenant/customer persistence and ETL source-binding needs is documented explicitly
- [x] A dedicated ETL source-binding model is defined because
BackendDatabaseConsolidationdoes not currently provide one - [x] Source binding model exists or is finalized with generic metadata fields
- [x] Active uniqueness is enforced for Brink tenant bindings
- [x] Repository access exists for active binding enumeration by
company_id - [x] Repository access exists for active binding resolution by
tenant_id - [x]
service_url,access_token,location_token, andlocation_keyare persisted in the database for active Brink bindings - [x] Runtime Brink connection resolution no longer depends on one global temporary connection or
BrinkPosConnectionOptions - [x] Runtime Brink connection resolution no longer lives inside
Kds.Ai.Integrations.BrinkPos - [x]
BrinkPosDispatchJobInputexists - [x]
BrinkPosExtractJobInputexists - [x]
BrinkPosExtractTriggerexists withScheduledandManual - [x] Scheduled and manual execution converge into the same child contract family
- [x] Cron sync is driven by active source bindings
- [x] Dispatch logs no-binding warnings and enqueue failures
- [x] Child contract supports explicit or resolved business date
- [x] Unit tests cover binding rules, dispatch behavior, and business-date routing
- [x] Integration or host-level tests cover cron sync and enqueue paths
- [x] Solution builds without errors
Notes
- Follow
TASK0.mdas the authoritative scope document. - Keep this task strict: it starts the
ordersandorder_itemsETL path, but does not widen business scope. - The source binding contract should remain reusable for future API pull integrations.
specs/BackendDatabaseConsolidationis relevant mainly for tenant/customer ownership and membership, not yet for ETL source bindings.- The current
TemporaryBrinkConnectionResolverandBrinkPosConnectionOptionspath should be treated as transitional and replaced by repository-backed database resolution. Kds.Ai.Integrations.BrinkPosshould consume an externally providedBrinkConnectionDefinitionor a factory-created bound client, not resolve tenant binding from DB on its own.- For this implementation, Brink connection data is stored in backend persistence rather than in an external secret store.
- The live data-boundary E2E requirement starts fully in the next ETL task where raw extraction and S3 persistence are implemented.