# TASK 1.2: Persist and expose async provisioning state for the admin UI

## Summary

Define and implement the persisted provisioning state model required for the UI to show pending, running, succeeded, and failed provisioning after credential writes become asynchronous.

This task exists because the current `EtlProvisioningStatus` shape only describes current readiness and mapping state, not background execution progress.

## Dependencies

- [TASK 1.1](./TASK1.1.md) - Define split admin flow and credential-trigger boundaries

## Files to Modify

Expected implementation touch points:

- tenant warehouse mapping metadata in `backend/Kds.Ai.Data/`
- `backend/Kds.Ai.ApiService/Services/CustomerEtlProvisioningService.cs`
- `backend/Kds.Ai.ApiService/Endpoints/AdminCustomerEndpoints.cs`
- related data and API tests under `backend/tests/`

## Required Behavior

- Persist explicit provisioning execution state in tenant-scoped control-plane metadata.
- Keep `IsActive` as the warehouse activation flag.
- Add explicit async state fields sufficient for the UI, such as:
  - `ProvisioningState`
  - `ProvisioningRequestedAt`
  - `ProvisioningStartedAt`
  - `ProvisioningCompletedAt`
  - `ProvisioningError`
- `CustomerEtlProvisioningService.GetStatusAsync(...)` must return the persisted async state to the admin API.
- The returned status must let the UI distinguish at least:
  - not requested,
  - pending,
  - running,
  - succeeded,
  - failed.

## Acceptance Criteria

- [ ] Provisioning execution state is stored persistently
- [ ] Admin customer status response exposes async provisioning state
- [ ] The UI can distinguish pending, running, succeeded, and failed
- [ ] Existing readiness flags remain available

## Notes

- The tenant warehouse mapping metadata is the preferred home for this state because provisioning is tenant-scoped.
- Keep the contract small and operationally useful.
