# TASK 2: Add Relation-Aware Tenant Resolution

## Summary

Update KDS CDC tenant resolution so child entities can resolve through durable relation state instead of requiring direct `store_guid` on every payload.

## Current Codebase Findings

Repository analysis shows:

- `orders` and `customers` typically resolve directly by `store_guid`,
- `items` may arrive without direct `store_guid`,
- `item_bumps` may arrive without direct `store_guid`,
- current resolver returns `TenantUnresolved` when direct `store_guid` is missing,
- no durable relation lookup is currently used during resolution.

## Dependencies

- TASK 1

## Source References

- `../../docs/features/ETL/kds-cdc/debezium-payload-compatibility-notes.md`
- `../../docs/features/ETL/kds-cdc/branch-direction-and-flow.md#6-tenant-resolution`
- `../KdsCdcDebeziumIntegration/TASK2.md`

## Scope From Breakdown

This task covers:

- entity-specific relation lookup rules,
- resolver API changes,
- write-after-resolve rules for parent/child relations,
- unresolved reason clarity and deterministic retry behavior.

## Files to Modify

- `backend/Kds.Ai.Integrations/KdsCdc/KdsCdcTenantResolver.cs`
- `backend/Kds.Ai.Integrations/KdsCdc/KdsCdcTenantResolution.cs`
- any supporting KDS CDC contracts carrying resolved tenant/store context
- DI registration for relation repositories/services
- tests under `backend/tests/Kds.Ai.Integrations.Tests/KdsCdc/`

## Required Behavior

### Resolution rules by entity

Required routing rules:

- `orders`
  - require direct `store_guid`
  - resolve tenant directly from `store_guid`
  - on success, write `order_guid -> store_guid`

- `customers`
  - require direct `store_guid`
  - resolve tenant directly from `store_guid`

- `items`
  - if direct `store_guid` exists, resolve directly
  - otherwise read `order_guid`
  - lookup durable `order_guid -> store_guid`
  - if relation found, resolve tenant from relation-derived store
  - after success, write `item_guid -> store_guid`
  - if relation missing, return retryable `TenantUnresolved`

- `item_bumps`
  - if direct `store_guid` exists, resolve directly
  - otherwise read `item_guid`
  - lookup durable `item_guid -> store_guid`
  - if relation found, resolve tenant from relation-derived store
  - if relation missing, return retryable `TenantUnresolved`

### Mapping resolution after store resolution

Once effective `store_guid` is known, tenant mapping must still use authoritative mapping repository semantics:

```text
source_type + store_guid -> company_id + tenant_id + tenant warehouse
```

Do not bypass current warehouse/mapping validation.

### Unresolved semantics

When relation lookup misses:

- do not quarantine valid child payload,
- do not guess tenant,
- return explicit retryable unresolved outcome,
- include missing relation type in reason, for example:
  - missing order relation for item,
  - missing item relation for item bump.

## Testing

Add tests for:

- order resolves directly and writes order relation,
- customer resolves directly,
- item resolves directly when payload has `store_guid`,
- item resolves through durable order relation,
- item unresolved when order relation missing,
- resolved item writes item relation,
- item bump resolves through durable item relation,
- item bump unresolved when item relation missing,
- warehouse/mapping missing still fails correctly after relation-derived store is found.

## Acceptance Criteria

- [ ] Resolver supports entity-specific child relation lookups
- [ ] `items` can resolve through order relation
- [ ] `item_bumps` can resolve through item relation
- [ ] Resolved orders write order relation
- [ ] Resolved items write item relation
- [ ] Missing child relation returns retryable unresolved outcome, not quarantine
- [ ] Direct mapping and warehouse validation still apply after relation lookup
- [ ] Tests cover direct, relation-derived, and unresolved flows

## Notes

- Do not add warehouse/Redshift fallback lookup in this task.
- Do not add historical backfill assumptions in this task.
