Finance-Accounts/ar-aging-app/README.md

122 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 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). ≈ $5055/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** — users change or recover passwords with a 6-digit code emailed
to their account address (Settings, or "Forgot password?" on the login screen). Sent via
the 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 (C1C6) 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) + Gitea Actions CI