# ADR-058: Credit Card PWA Reads vehicle.cc_transactions via View — Zero Writes to Vehicle Schema

## Status

Accepted, 2026-06-22.

## Status History

```yaml
status_history:
  - date: 2026-06-22
    status: Proposed
    changed_by: hkl
    reason: Formalising read-only cross-schema view boundary between Credit Card and Vehicle PWAs
    changed_via: adr-kit (360lm)
  - date: 2026-06-22
    status: Accepted
    changed_by: hkl
    reason: creditcard.transactions_v view live; zero writes to vehicle.* from creditcard
    changed_via: adr-kit (360lm)
  ```

## Context

Company credit card transactions (fuel purchases, highway tolls, vehicle maintenance) are recorded by the Vehicle PWA in `vehicle.cc_transactions` and `vehicle.fuel_events` — the vehicle manager logs them as part of fleet operations. The Credit Card Reconciliation PWA needs to reconcile these same transactions against the monthly CC statement. Two approaches exist: (a) copy or migrate the data into the creditcard schema, or (b) read it directly from the vehicle schema via a view. The creditcard PWA must not modify or duplicate vehicle data — it is a read-only consumer.

## Decision

`creditcard.transactions_v` is a view that reads from `vehicle.cc_transactions` and `vehicle.fuel_events` with no data duplication. The Credit Card PWA reads only from this view — it never writes to or migrates data from the Vehicle schema.

The view presents vehicle transactions in the shape expected by the reconciliation workflow (standardised fields: amount, date, merchant, vehicle_id, category). Reconciliation metadata (match_status, linked_expense_id) is stored in `creditcard.reconciliation_lines` — a separate table that references the vehicle transaction by ID, not by copying it.

**Zero Touch to Vehicle PWA** — `vehicle.cc_transactions` and `vehicle.fuel_events` are never modified by the creditcard PWA.

**Decision Maker:** hkl

## Alternatives Considered

- **Copy transactions into creditcard schema (ETL at import time).** Rejected: creates a second copy of vehicle financial data; if vehicle team corrects a transaction (wrong amount, wrong date), the copy in creditcard is stale; reconciliation would be against stale data.
- **Vehicle PWA exposes an export endpoint; creditcard imports from it.** Rejected: adds an import step to the reconciliation workflow; requires scheduling or triggering; same staleness risk as copy.
- **Vehicle and Credit Card share the vehicle schema directly (no view).** Rejected: creditcard would need grants on vehicle schema tables; any future Vehicle schema refactor would require coordinated creditcard updates; view provides an isolation boundary — internal vehicle schema can change as long as the view contract is maintained.

## Consequences

**Positive:**
- No data duplication — vehicle transaction data has a single authoritative source.
- Vehicle team can correct transactions in their PWA and reconciliation immediately sees the corrected data.
- Clear read-only boundary — creditcard never has write grants on vehicle schema.
- View provides an abstraction layer: vehicle schema internals can change without breaking creditcard.

**Negative / Trade-offs:**
- `creditcard.transactions_v` requires `web_anon` SELECT on `vehicle.cc_transactions` and `vehicle.fuel_events` — cross-schema grant.
- If vehicle schema is renamed or table is dropped, the view breaks — this is a schema lifecycle dependency.

**Risks and mitigations:**
- Vehicle team drops `vehicle.cc_transactions` during a refactor: mitigated by documenting the creditcard view dependency in dbt_vehicle.md; schema drop requires checking dependent views first.
- Cross-schema SELECT grant overly broad: mitigated by granting only on specific columns needed by the view, not full table access.

## Related Decisions

- ADR-009 (per-PWA schema isolation) — documented exception: creditcard reads vehicle schema via view.
- ADR-043 (sales.catalog shared product master) — same read-only cross-schema access pattern.
- ADR-032 (expense.employees FK anchor) — analogous cross-schema dependency.

## References

- `memory/dbt_creditcard.md` — "Zero touch to Vehicle PWA — vehicle.cc_transactions and vehicle.fuel_events untouched. transactions_v view reads them"
- `creditcard/index.html` — creditcard.transactions_v queries
- `vehicle/index.html` — vehicle.cc_transactions + vehicle.fuel_events as source of truth
