122 lines
6.6 KiB
Markdown
122 lines
6.6 KiB
Markdown
# Amazon Accounts Receivable Aging Dashboard
|
||
|
||
Automates the Finance team's month-end **Amazon Accounts Receivable Aging** workbook:
|
||
upload the month's Amazon *Custom Unified Transaction* files → get a structurally- and
|
||
financially-identical Accounts Receivable Aging workbook, with validation, settlement
|
||
reconciliation, exceptions, drill-down, and an audit trail.
|
||
|
||
**Amazon only** (no Walmart/TikTok/Temu/Shein/eBay/Shopify). Reverse-engineered from the
|
||
Jan-2026 files; the USA receivable reproduces to the penny (**11,110,433 = `Detail!D11`**).
|
||
See [docs/accounts-receivable-logic.md](docs/accounts-receivable-logic.md).
|
||
|
||
## Layout
|
||
```
|
||
backend/
|
||
app/core/ # streaming parser + receivable engine (stdlib + openpyxl only)
|
||
app/api/ # FastAPI app: routes, auth (login), deps
|
||
app/services/ # jobs, persistence, FX-rate fetch, controls, retention
|
||
app/db/ # SQLAlchemy models (20 tables) + engine (SQLite / MySQL)
|
||
tests/ # 150+ tests: engine, API, auth, FX, dedup, Jan-2026 integration
|
||
cli.py # process files from the command line
|
||
manage.py # admin: add-user / set-password / dedupe-files / …
|
||
migrate_sqlite_to_mysql.py # one-time data migration for the AWS cutover
|
||
frontend/ # React + TS + Vite dashboard (nginx-served in production)
|
||
scripts/ # launchers: start.ps1 / start.bat (Windows) · start.command (macOS)
|
||
deploy/ # DEPLOY.md runbook + backup.sh (nightly mysqldump + S3 sync)
|
||
docs/ # system guide · AR logic · audit reports
|
||
docker-compose.yml # dev stack docker-compose.prod.yml # production
|
||
.env.example # every setting, LOCAL + PRODUCTION sections
|
||
```
|
||
|
||
## Production deployment (AWS)
|
||
|
||
One 8 GB server runs the whole stack with automatic HTTPS, MySQL, per-user login, and
|
||
nightly S3 backups — see **[deploy/DEPLOY.md](deploy/DEPLOY.md)** for the full runbook
|
||
(provisioning, user creation, SQLite→MySQL migration, backups, updates). ≈ $50–55/month.
|
||
|
||
```bash
|
||
cp .env.example .env.production # fill the PRODUCTION section (domain, passwords, AR_SECRET_KEY)
|
||
docker compose --env-file .env.production -f docker-compose.prod.yml up -d --build
|
||
docker compose --env-file .env.production -f docker-compose.prod.yml exec backend \
|
||
python manage.py add-user <user> --name "Full Name"
|
||
```
|
||
|
||
Key production behaviors:
|
||
- **One closing per month** — every month stays saved and selectable (month switcher in the
|
||
closing header); creating a second closing for an existing month requires an explicit override.
|
||
- **Duplicate-proof uploads** — re-uploading a filename *replaces* it; identical content
|
||
under another name is skipped. A month can never count a file twice.
|
||
- **Login** (`AR_AUTH`) — per-user accounts via `manage.py add-user`; journal review/approval
|
||
and FX confirmations record the signed-in user's verified name.
|
||
- **Password self-service** — Settings changes the password with the current one; a
|
||
forgotten password is recovered from the login screen ("Forgot password?") via a 6-digit
|
||
code emailed to the account address (company Mail API `AR_MAIL_API_*`, SMTP fallback);
|
||
`manage.py set-password` remains the admin override.
|
||
- **Exchange rates** — "Fetch month-end rates" pulls central-bank rates (Frankfurter, free,
|
||
keyless; `AR_FX_PROVIDER`); fetched rates still require human confirmation (Control C5).
|
||
- **Completed closings are locked** read-only; corrections need an explicit Reopen.
|
||
- **Crash-safe jobs** — a restart mid-processing marks the closing as interrupted instead of
|
||
leaving it stuck; generated exports are purged after `AR_RETENTION_DAYS` (uploads never are).
|
||
|
||
## Run the app (development)
|
||
```bash
|
||
# 1. Configure the environment (SQLite by default — no database setup needed)
|
||
cp .env.example .env # then fill the LOCAL section (AR_SECRET_KEY at minimum)
|
||
|
||
# Option A — Docker (backend + Vite hot reload)
|
||
docker compose up --build
|
||
# → http://localhost:5173 (API on :8000; uploads/exports on the ar_data volume)
|
||
|
||
# Option B — local processes
|
||
make install # backend deps + npm install
|
||
make backend # terminal 1 → FastAPI on :8000
|
||
make frontend # terminal 2 → dashboard on http://localhost:5173
|
||
|
||
# Option C — Windows one-click (ports 8010/5174)
|
||
scripts\start.bat # or: powershell -ExecutionPolicy Bypass -File scripts\start.ps1
|
||
# macOS one-click:
|
||
scripts/start.command
|
||
```
|
||
Then open the dashboard → **New Closing** → pick the month → drag in the month's Amazon
|
||
files → **Run processing** → review → **Download Full A/R Aging Excel**.
|
||
|
||
Uploads and exports are stored under `AR_DATA_DIR` (default `backend/data` locally, `/data` in
|
||
Docker). The database is a local SQLite file by default; set `MYSQL_*` in `.env` to use MySQL.
|
||
|
||
## Run the engine headless (CLI)
|
||
```bash
|
||
cd backend && pip install -r requirements.txt
|
||
python cli.py "/path/USA…01 to 10 January,2026.xlsx" \
|
||
"/path/USA…11 to 20 January,2026.xlsx" \
|
||
"/path/USA…21 to 31 January,2026.xlsx" \
|
||
--month-end 2026-01-31 --lag 2 --reserve-standard 125.44 --out AR_Aging_Jan26.xlsx
|
||
```
|
||
|
||
## Tests
|
||
```bash
|
||
make test # 155 fast tests: engine, API, auth, FX, upload dedup, month locking
|
||
make test-all # + Jan-2026 reconciliation & sample-comparison (integration, ~4 min)
|
||
# point the integration tests at the sample files if not in the repo root:
|
||
AR_SAMPLE_DIR="/path/to/samples" make test-all
|
||
```
|
||
The suite runs against an isolated temporary database — it can never touch real data
|
||
(a session-scoped guard asserts the isolation before anything runs).
|
||
|
||
## Feature summary
|
||
|
||
**Calculation engine**
|
||
- Settlement classification + receivable; USA Jan-26 = **11,110,433** verified to the penny
|
||
- All 13 marketplaces reconcile to the penny vs the Finance workbook — per-market currency
|
||
& FX, settlement-owner logic for cross-market EU chains, helper-row/pivot-sheet detection
|
||
- AR roll-forward (opening + net revenue − payouts = closing) with auto carry-forward,
|
||
AR Ledger, Finance Summary, per-marketplace Journal Entry, Reconciliation Control
|
||
- Header mapping with localized alias tables + admin rules UI; unmapped amounts are never
|
||
silently excluded; storage-fee detection; full Excel audit workbook + Finance pack
|
||
|
||
**Operations & security**
|
||
- Per-user login with emailed password codes; verified names on every sign-off
|
||
- Six month-end controls (C1–C6) block publication of any untrusted figure
|
||
- Month-end FX fetched from central-bank data, gated by human confirmation
|
||
- Duplicate-proof uploads, one-closing-per-month guard, completed-month locking
|
||
- Production Docker stack (auto-HTTPS · MySQL · nightly S3 backups); CI/CD owned by DevOps
|