Commit Graph

20 Commits (main)

Author SHA1 Message Date
Talha Ahmed 367a64b59d Audit trail: record who uploads, processes, exports, deletes; admin-only log view
Deploy to S3 / deploy (push) Successful in 23s Details
Every business action now lands in a new append-only audit_log table with the
verified signed-in identity: logins, closing create/delete/reopen, file upload
(incl. replacements) and delete, processing runs, export generation and
downloads. Rows carry no FK so history survives a closing's deletion.

Admins (new users.is_admin flag, granted via `manage.py set-admin <username>`)
can read it at /api/audit and in a new Audit Log page in the sidebar; everyone
else gets 403 and no nav entry. login/me responses now carry is_admin.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-01 21:01:58 +05:00
Talha Ahmed f46fc69562 Convert at the transaction date's FX rate, auto-fetched from the API
Deploy to S3 / deploy (push) Successful in 28s Details
Processing now seeds fx_rates_daily from the provider (Frankfurter) over the
closing's actual transaction span, and the AR Ledger / daily FX table convert
each dated movement at the rate effective on its own date: exact fixing, else
the previous banking day's fixing (weekends/holidays), else the month rate.
Manual daily overrides are preserved by the auto-fetch and never carry forward.
Provider outages never block the close - they surface as a warning exception.
New AR_FX_AUTO_DAILY env toggle (default on; forced off in tests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 15:23:59 +05:00
Talha Ahmed c2e1840f5b Aging report: selectable band width (weekly / monthly / 6 months / yearly)
Deploy to S3 / deploy (push) Successful in 29s Details
GET /sessions/{id}/aging?scheme=... rebands the same days-past-due data;
the Aging page gets a segmented filter and renders whatever bands the API
returns. Totals tie to the headline receivable in every scheme. Also carries
the alias-guard test for the reference-workbook headers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 22:09:55 +05:00
Talha Ahmed 04dfbcf0e6 Import bank disbursements Excel as payout receipts
POST /sessions/{id}/payouts/receipts/import parses the bank workbook (Payouts
sheet), matches deposits to the closing's Transfer payouts by marketplace +
date window + amount (currency-aware: converted deposits match by date only),
and returns a preview; the UI applies selected matches through the existing
PUT so upsert/reprocess semantics stay in one place. Replaces hand-typing
bank dates in the Bank receipts grid.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 22:09:49 +05:00
Talha Ahmed 089f775eeb Recognize 40 more marketplace header variants from the finance reference workbook
Promotional Discounts (9 marketplaces), German singular credit forms, Belgian
Total Discounts, Italian Marketplace Withheld VAT, the Turkish native headers,
and 8 Transaction Release Date translations. Unmapped amount columns raise
unmapped_amounts errors that block control C2, so these close real gaps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 22:09:48 +05:00
Talha Ahmed 4ec322da71 Forgot-password: unregistered emails get an explicit 404
Deliberate for the small internal team - a clear 'is not a registered
account' beats the anti-enumeration non-answer that read as success.
Successful sends now name the address and expiry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 22:05:34 +05:00
Talha Ahmed 8677117e66 Forgot-password is now a 3-step wizard: email -> verify code -> new password
New POST /api/auth/verify-code checks the code without consuming it
(wrong guesses still count toward the 5-attempt lockout); the password
fields only appear after the code verifies. Email step hints that codes
go only to registered @utopiabrands.com accounts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 21:49:29 +05:00
Talha Ahmed b77c2cc9f7 Settings changes password with the CURRENT password; email code is the
login-screen forgot-password flow only

Also fix: the auth middleware now attaches the signed-in identity on
open paths too (a signed-in request-code call previously saw no user
and demanded a username).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 21:41:21 +05:00
Talha Ahmed 984069b368 Password codes via the company Mail API (primary), SMTP stays fallback
Same internal mail service the TikTok dashboard uses for its
verification codes: bearer-token multipart POST (stdlib urllib, no new
deps). Configured with AR_MAIL_API_URL/TOKEN; credentials live only in
the gitignored env files. Live send verified ({status:sent}).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 19:54:50 +05:00
Talha Ahmed 2aed450f4c Password updates via emailed 6-digit code
New flow (active once AR_SMTP_* is configured; hidden otherwise):
- POST /api/auth/request-code emails a code to the account address
  (usernames are emails). HMAC-stored, 10-min expiry, single-use,
  5-attempt lockout, 60s resend throttle, no user enumeration.
- POST /api/auth/reset-password sets the new password with the code —
  works signed-in (Settings) and from the login screen (Forgot
  password?), so users can self-recover without the admin.
- Mailer: stdlib smtplib (STARTTLS/SSL, certifi CA bundle); SMTP
  settings documented in .env templates.
- Settings switches to the code flow when email is on; the
  current-password form remains the fallback.

Note: CRAI_Report was checked as the reference for code-sending — it
has no email/OTP functionality, so this is a fresh implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 19:35:07 +05:00
Talha Ahmed 11bceedaca Add change-password: users update their own password from Settings
POST /api/auth/change-password requires the current password; admins
still reset others via manage.py set-password. UI on the Settings page
(signed-in users only) with match/length validation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 19:07:28 +05:00
Talha Ahmed d823a45cb2 Production readiness: month separation, auth, FX service, AWS deployment
Month management & data separation:
- Fix double-count bug: re-uploading a filename updates the existing
  session_files row in place; identical content (sha256) is skipped —
  a closing can never parse the same file twice
- Guard against duplicate closings per reporting month (409 unless
  explicitly overridden); dashboard flags duplicates
- Default new closings to carry-forward openings; month switcher in the
  closing header; publish state visible everywhere; Accounts Summary
  lists unpublished months with the reason instead of dropping them
- Completed closings are locked read-only with an explicit reopen

Authentication (stdlib only, no new deps):
- Per-user login (scrypt + HMAC tokens), AR_AUTH=auto turns on with the
  first user; manage.py add-user/set-password/deactivate-user
- Verified identity feeds reviewed_by/approved_by/confirmed_by

Exchange rates:
- fx_service with provider abstraction: Frankfurter (free, keyless,
  ECB) default, exchangerate-api stub; month-end + daily fetch
  endpoints and UI buttons; rates arrive unconfirmed so Control C5
  still gates the close; cache table; certifi CA bundle

Deployment & hardening:
- Production Docker stack: caddy (auto-HTTPS) + nginx + single-worker
  backend + mysql:8.4; per-context .dockerignore (images carry no
  financial data); .env.example with local+production sections
- deploy/DEPLOY.md runbook + nightly S3 backup script
- Stale-job recovery on startup; export retention (AR_RETENTION_DAYS);
  deep /api/health; request/job logging; Gitea Actions CI
- Repo reorganized: launchers in scripts/, dated lowercase docs,
  root README, .gitattributes for deterministic line endings

Tests: 152 passed (25+ new: dedup, month locking, auth, FX orientation)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 18:46:47 +05:00
Talha Ahmed c322437599 fix isuses 2026-08-18 19:37:57 +05:00
sheheryarsoomro12 60c4489415 New 2026-08-17 15:41:46 +05:00
sheheryarsoomro12 bacd13c8b5 New 2026-08-04 11:41:50 +05:00
sheheryarsoomro12 1fe6487681 Merge origin/main into new-changes.
Resolve models.py conflict by keeping session controls/payout fields and MySQL column lengths.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-03 12:26:31 +05:00
sheheryarsoomro12 b795d51aa7 Enhance API functionality and session management 2026-08-03 11:38:48 +05:00
bahawal.baloch 2135dc873c Implement MySQL support in AR aging app. Update README with configuration instructions, modify requirements for PyMySQL and dotenv, and refactor database setup to use MySQL. Adjust models and queries for compatibility with MySQL, including column size specifications. Enhance Vite config for API proxying. 2026-07-29 18:52:37 +05:00
sheheryarsoomro12 73a004d2e1 Stop tracking SQLite WAL/SHM runtime files.
Extend gitignore so local database sidecars are not committed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-29 18:07:50 +05:00
sheheryarsoomro12 bf0cdc14c3 Initial commit: AR aging app with root gitignore.
Ignore financial workbooks, OS junk, and build artifacts; track app source and project skills.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-29 18:07:21 +05:00