mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 08:32:54 +00:00
68 lines
2.7 KiB
Markdown
68 lines
2.7 KiB
Markdown
# Contract seed driver
|
||
|
||
Creates freight contracts across every flow variant by driving the freight API
|
||
over HTTP end-to-end — from DRAFT through **both signatures** (customer sign +
|
||
staff counter-sign). It stops right after the staff counter-sign; no clearance
|
||
or booking steps are run.
|
||
|
||
## What it builds
|
||
|
||
20 real flows (movement × kind × customs × freight), each created twice → **40
|
||
contracts** on `all`.
|
||
|
||
| Movement | Kind | Customs | Freight | Count |
|
||
| --- | --- | --- | --- | --- |
|
||
| intercity (DOMESTIC) | one-time / general | without only¹ | bulk / container | 4 |
|
||
| import (IMPORT) | one-time / general | with / without | bulk / container | 8 |
|
||
| export (EXPORT) | one-time / general | with / without | bulk / container | 8 |
|
||
|
||
¹ intercity + customs is not a real combo — DOMESTIC has no clearance gate, so
|
||
the customs flag is ignored. Those four are skipped, leaving 20 (16 working + 4
|
||
`with-customs + bulk`).
|
||
|
||
The four `with-customs + bulk` flows are still built here: the known break is
|
||
downstream in clearance (customs output docs are container-only), which this
|
||
script does not reach, so all 20 reach a signed state.
|
||
|
||
## Terminal status after both signatures (by dimension)
|
||
|
||
- DOMESTIC one-time → `FULLY_EXECUTED`
|
||
- any GENERAL, and DOMESTIC general → `CONTRACT_ACTIVE`
|
||
- IMPORT/EXPORT one-time (customs or self-clearance) → `AWAITING_CLEARANCE_DOCUMENTS`
|
||
(fully signed; clearance not driven)
|
||
|
||
## Setup
|
||
|
||
```bash
|
||
cd apps/edr-freight-api/py
|
||
python -m venv .venv && source .venv/bin/activate
|
||
pip install -r requirements.txt
|
||
cp .env.example .env # then fill it in
|
||
```
|
||
|
||
Fill `.env`: customer + admin IAM credentials (admin should be a **super_admin**),
|
||
`OTP_PHONE`, and the Postgres connection (used only to read the sign-OTP).
|
||
|
||
## Run
|
||
|
||
```bash
|
||
python create_contracts.py # all 20 flows
|
||
python create_contracts.py intercity # only DOMESTIC flows (4)
|
||
python create_contracts.py import # only IMPORT flows (8)
|
||
python create_contracts.py import export # IMPORT + EXPORT (16)
|
||
```
|
||
|
||
Filters are by movement: `intercity`, `import`, `export` (pass one or many);
|
||
no arg or `all` runs everything.
|
||
|
||
## How auth + OTP work
|
||
|
||
- **Login**: `POST /api/auth/login` with `{ email, password }` returns a JWT
|
||
(`token`), sent as `Authorization: Bearer <token>`. MFA accounts are not
|
||
supported — the script errors out clearly if MFA is required.
|
||
- **Actors**: the customer token does create/submit/customer-sign; the admin
|
||
token does staff-accept/approve/generate/counter-sign.
|
||
- **Sign OTP**: customer sign needs a fresh 6-digit OTP. The script calls
|
||
`POST /api/otp/send { phone }`, reads the plaintext code from
|
||
`<schema>.otp_verifications` in Postgres, then signs within the 5-minute TTL.
|