Commit Graph
14 Commits
Author SHA1 Message Date
lauadminandClaude Opus 5.5 2b7a92645a Add CRM stub flag, deploy/backup scripts, CI and prod runbook
CI / backend (pull_request) Successful in 3m7s
CI / frontend (pull_request) Failing after 15m55s
- CRM_USE_STUB: local runs no longer reach the live CRM. With only the
  Checkbox stub, a stub receipt would still move the real order to PACKED.
  Refused in production, same as CHECKBOX_USE_STUB.
- scripts/deploy.sh: backup, fast-forward main, build, health check and
  code rollback on failure. scripts/backup.sh: pg_dump with verification
  and 14-day rotation (used by cron and deploy.sh).
- Gitea Actions CI: ruff + pytest, oxlint + build.
- DEPLOY.md runbook; CLAUDE.md rules for safe local development.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 20:52:20 +03:00
lauadminandClaude Opus 5.5 b8f2fe6b6e Translate UI and user-facing messages to Ukrainian (#5)
- All frontend pages, labels, notices and errors; html lang=uk, uk-UA money format
- Brand "Assistant System" in the top bar and page title
- Backend error details returned to the UI (auth, orders, receipts,
  cash registers, Checkbox/CRM/NP errors) and CLI output
- Tests updated for the new messages

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:27:39 +03:00
lauadminandClaude Opus 5.5 8b3c2b6d63 Bind Nova Poshta API key to cash register (#3)
Each cash register stores its own encrypted NP API key. Status polling uses
register keys and binds an order to the register whose key sees the TTN as
its own (PhoneSender present); ETTN receipts are created from that register.
Migration 0008 moves the old NOVA_POSHTA_API_KEY into the default register.

Closes #3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 13:02:40 +03:00
lauadminandClaude Opus 5.5 a6072800b2 Add COD-in-transit summary and received tab to the dashboard
- GET /orders/summary: count and sum of cash-on-delivery for parcels not
  yet picked up (excludes received, refused, deleted/unknown TTNs, paid COD);
  shown as a card above the tabs.
- New «Полученные» tab: orders with NP received codes (9, 10, 11, 106) move
  there automatically, regardless of receipt; 106 is now a final status.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 01:23:39 +03:00
lauadminandClaude Opus 5.5 528a869657 Retry ETTN creation on Nova Poshta rate limit instead of failing
Checkbox relays Nova Poshta's "To many requests" (20000401501) as a 4xx
third_party.generic error, not a 429, so bursts of receipt requests ended
up as failed receipts. Such responses are now CheckboxRateLimitedError:
the receipt stays pending and the worker job is retried with arq.Retry
after the "Try again after N seconds" delay plus backoff. NP timeouts
relayed the same way are treated as unavailable (unknown outcome).

The HTTP client also sends Checkbox requests one at a time with a
CHECKBOX_MIN_REQUEST_INTERVAL_MS pause and signs the cashier in once for
concurrent jobs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:25:59 +03:00
lauadminandClaude Opus 5.5 f88b5cccc0 Add refusals tab to the order dashboard
Orders whose Nova Poshta status is a refusal (102/103/105/108) now show
only under «Отказы», whether or not they have a receipt. GET /orders takes
tab=no_receipt|has_receipt|refused instead of has_receipt. NP statuses are
also polled for orders that already have a receipt, until NP reports a
final status.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:25:59 +03:00
lauadminandClaude Opus 5.5 56ac0fc370 Allow editing orders in the order card
Cashiers can edit recipient, TTN, notes, goods and total in the order
modal and save via PATCH /orders/{id}. Edited orders get edited_at and
are no longer overwritten by CRM sync. Editing is blocked once a receipt
exists; changing the TTN resets Nova Poshta tracking fields.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 17:23:41 +03:00
lauadminandClaude Opus 5.5 cbf9832e5b Set CRM order status to PACKED after Checkbox accepts the receipt
- ExoCrmClient.set_status: live SetStatus needs {Orders: [id], Status} and
  replies per order, unlike the documented {ID, Status}
- receipts.crm_status_set_at (migration 0006); set right after creation,
  retried by cron, row-locked to avoid a repeat PACKED overwriting a newer status
- CRM errors under capitalized 'Errors' and non-JSON replies are reported

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 14:04:26 +03:00
lauadminandClaude Opus 5.5 3a6ad85d11 Fix ETTN creation on live Checkbox
- prepayment as DISCOUNT: live API rejects PRE_PAYMENT with 400 third_party.generic
- normalize lowercase ETTN statuses returned by the live API
- show Checkbox error code instead of bare 'Internal Server Error'
- page size 50 for ETTN list, 429 rate limit is retryable, pause polling on it
- phone in 380XXXXXXXXX format like portal receipts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 13:49:50 +03:00
lauadminandClaude Opus 5.5 089e0a4011 Send ETTN payment type and label explicitly, verify receipt total
Payments now carry type=ETTN / label=Експрес-накладна instead of relying on
Checkbox defaults; body build fails fast if goods - discounts - prepayment
does not equal the COD amount.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 13:33:29 +03:00
lauadminandClaude Opus 5.5 518a99197f Add Checkbox ETTN receipts for Nova Poshta COD waybills
Cashier creates an ETTN receipt in Checkbox bound to the TTN with payment
control; Checkbox fiscalizes it itself when the parcel is paid for.

- cash_registers (Fernet-encrypted license key / PIN) and receipts tables
- Checkbox HTTP client + stub (ETTN does not work on test registers)
- two-phase create via ARQ job, timeout reconciliation, cron status polling
- /receipts and /cash-registers API, audit records
- dashboard: per-order and bulk create, prepayment, cancel; cash registers page

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 23:39:00 +03:00
lauadminandClaude Sonnet 5 d13e7ce2b3 Add Nova Poshta tracking: TTN status, COD amount, payment status
Adds NpTrackingClient (Protocol + real/stub impls) and an ARQ worker that
polls Nova Poshta every minute for orders without a receipt, writing
status, net COD amount (Контроль оплати), and payment status onto the
order. Surfaced in the orders table and detail modal. Marks plan stages
3-4 done in README.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 22:33:58 +03:00
lauadminandClaude Sonnet 5 f4072be451 Add CRM order queue: live sync, view modal, receipt tabs, delete
Wires the CRM (exoCRM GetOrders) into the dashboard as a locally
persisted order queue instead of the previous static mockup:

- CrmClient Protocol + ExoCrmClient/StubCrmClient for the CRM's
  signed JSON-RPC API
- Order model + migration, synced from CRM on each queue view;
  soft-deleted orders stay hidden across re-syncs
- GET/DELETE /api/v1/orders with "no receipt"/"receipt issued" tabs
  (the latter is empty until Checkbox fiscalization lands)
- Dashboard: real order list, item-detail modal, tab switcher,
  one-click delete

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 21:39:03 +03:00
lauadminandClaude Sonnet 5 2664cb8213 Initial commit: backend scaffold, auth, frontend login
- FastAPI + SQLAlchemy async + Alembic + Postgres backend
- Auth: JWT access + rotating refresh tokens, argon2, roles, audit log
- React 19 + Vite frontend: login page, protected route, auth context
- Docker Compose: postgres, redis, migrate, api, worker (placeholder), frontend/nginx

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 15:07:15 +03:00