112 lines
6 KiB
Markdown
112 lines
6 KiB
Markdown
|
|
# Fidelity UK PlanViewer provider
|
|||
|
|
|
|||
|
|
Viktor's UK workplace pension is hosted at `pv.planviewer.fidelity.co.uk`. There
|
|||
|
|
is no public API for individual members — the provider reverse-engineers the
|
|||
|
|
private JSON backend at `prd.wiciam.fidelity.co.uk/cvmfe/api/*` that the SPA
|
|||
|
|
itself calls, and uses Playwright only to keep a long-lived login session
|
|||
|
|
alive.
|
|||
|
|
|
|||
|
|
## Architecture
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────┐ storage_state.json ┌──────────────────┐
|
|||
|
|
│ Vault KV │◀─── (quarterly reseed) ───│ fidelity-seed │
|
|||
|
|
│ broker-sync │ │ (headed browser) │
|
|||
|
|
└──────┬──────┘ └──────────────────┘
|
|||
|
|
│ ▲
|
|||
|
|
│ loads on start │ Viktor runs once
|
|||
|
|
▼ when session expires
|
|||
|
|
┌────────────────────┐
|
|||
|
|
│ Monthly CronJob │
|
|||
|
|
│ broker-sync-fidelity│
|
|||
|
|
└────────────┬────────┘
|
|||
|
|
│ headless Chromium
|
|||
|
|
▼
|
|||
|
|
┌─────────────────────────────────┐ ┌────────────────────────────────┐
|
|||
|
|
│ pv.planviewer.fidelity.co.uk │◀─────│ navigate dashboard → capture │
|
|||
|
|
│ (SPA) │ │ fresh sid/fid/tbid/rid headers │
|
|||
|
|
└─────────────────────────────────┘ └──────────────┬─────────────────┘
|
|||
|
|
│
|
|||
|
|
┌───────────▼─────────────┐
|
|||
|
|
│ httpx JSON calls │
|
|||
|
|
│ prd.wiciam.../cvmfe/api│
|
|||
|
|
└───────────┬─────────────┘
|
|||
|
|
│
|
|||
|
|
┌────────────────────▼────────────────────┐
|
|||
|
|
│ DEPOSIT × N (employee + employer) │
|
|||
|
|
│ BUY × N (fund unit purchases, per date) │
|
|||
|
|
└────────────────────┬────────────────────┘
|
|||
|
|
│
|
|||
|
|
┌────────────────▼────────────────┐
|
|||
|
|
│ Wealthfolio account │
|
|||
|
|
│ type = WORKPLACE_PENSION │
|
|||
|
|
│ currency = GBP │
|
|||
|
|
└──────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## One-time seed (Viktor)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# on your laptop (macOS / Linux with a desktop):
|
|||
|
|
cd broker-sync
|
|||
|
|
poetry install
|
|||
|
|
poetry run playwright install chromium
|
|||
|
|
poetry run broker-sync fidelity-seed --out /tmp/fidelity_storage_state.json
|
|||
|
|
# chromium opens — log in to PlanViewer, tick "Remember device", press Enter
|
|||
|
|
|
|||
|
|
# stage to Vault
|
|||
|
|
vault kv patch secret/broker-sync \
|
|||
|
|
fidelity_storage_state=@/tmp/fidelity_storage_state.json \
|
|||
|
|
fidelity_plan_id=<your-plan-id>
|
|||
|
|
|
|||
|
|
rm /tmp/fidelity_storage_state.json # don't leave credentials lying around
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Re-seed when the monthly CronJob fails with `FidelitySessionError` (expect
|
|||
|
|
every 30-90 days, depending on how long Fidelity honours the remember-device
|
|||
|
|
cookie).
|
|||
|
|
|
|||
|
|
## One-time backfill
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
kubectl -n broker-sync create job fidelity-backfill \
|
|||
|
|
--from=cronjob/broker-sync-fidelity
|
|||
|
|
kubectl -n broker-sync logs -f job/fidelity-backfill
|
|||
|
|
# expect: fidelity-ingest: fetched=N new=N imported=N failed=0
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Monthly cron
|
|||
|
|
|
|||
|
|
- Schedule: `0 3 5 * *` (3am UTC on the 5th of each month — after mid-month payroll settles in Viktor's scheme)
|
|||
|
|
- CronJob: `broker-sync-fidelity` in namespace `broker-sync`
|
|||
|
|
- Resource: small, ≤512 MiB memory (Chromium for ~2 min, then idle)
|
|||
|
|
- Alert: `BrokerSyncFidelityFailed` fires on 2 consecutive failures
|
|||
|
|
|
|||
|
|
## Runbook — `BrokerSyncFidelityFailed`
|
|||
|
|
|
|||
|
|
1. Check pod logs: `kubectl -n broker-sync logs job/broker-sync-fidelity-<timestamp>`.
|
|||
|
|
2. If the error is `FidelitySessionError`: session expired, re-run the seed on
|
|||
|
|
Viktor's laptop (see above).
|
|||
|
|
3. If the error is a 404 / 5xx from `prd.wiciam.fidelity.co.uk`: likely an API
|
|||
|
|
path change. Check DevTools for the new endpoint, update the provider, ship
|
|||
|
|
a new image.
|
|||
|
|
4. If Playwright can't launch Chromium: check that the image still has Chromium
|
|||
|
|
installed (`playwright install chromium` at build time).
|
|||
|
|
|
|||
|
|
## Data model notes
|
|||
|
|
|
|||
|
|
- **Salary sacrifice scheme**: all employee + employer contributions are
|
|||
|
|
pre-tax from gross salary. No HMRC basic-rate relief line.
|
|||
|
|
- Emits two `DEPOSIT` per month (employee, employer) with `comment` carrying
|
|||
|
|
the source tag `fidelity:<doc-id>:<source>` for audit.
|
|||
|
|
- Emits one `BUY` per fund unit purchase, `symbol` = Fidelity fund code / ISIN.
|
|||
|
|
Units × unit price should reconcile to the cash deposited ±pennies.
|
|||
|
|
|
|||
|
|
## Not yet implemented
|
|||
|
|
|
|||
|
|
- Endpoint paths: waiting on Viktor's DevTools POST cURL for transactions +
|
|||
|
|
holdings views. Until pasted, `fidelity-ingest` raises
|
|||
|
|
`FidelityProviderConfigError` to fail loudly.
|
|||
|
|
- Infra: CronJob + Vault secret wiring + Prometheus alert in
|
|||
|
|
`infra/stacks/broker-sync/main.tf` — pending first successful manual run.
|