Commit graph

4 commits

Author SHA1 Message Date
5b6c4c48e4 Test the shipment screen, its API rules and the date inputs
Cover access on GET and POST for a buyer, each required field when blank, an ETD
after the ETA, a batch that already has a shipment (queried, not blocked), a
status change, and an edit updating in place. Add the shipment routes to both
OPS_ROUTES sweeps so the detail and edit screens render clean markup, and assert
the native date inputs carry ISO values — the defect that left the intake and
batch edit dates blank.
2026-09-17 16:03:14 +00:00
dae025f600 Enforce the shipment form's rules in the API
The ops form refuses a shipment with no vessel, container, ETD or ETA, and one
whose departure is after its arrival. The serializer now requires the same
fields and refuses the same contradiction, so the API cannot accept a record the
portal would reject. Partial updates stay partial: a status change alone does
not require the other fields, and the date check falls back to the stored values.
2026-09-17 16:03:11 +00:00
8ad83a7a65 Restrict every data API to ops and admin
Batch writes were closed in 88eede5, but every other app's viewset still used
IsAuthenticated, which in this platform means any buyer. A buyer could rewrite a
document record, create a QC result (which moves the batch status and raises a
CAPA), and reach the write endpoints for CAPAs, certificates, ESG reports and
shipments.

- Use the one IsOpsOrAdmin from apps.compliance.permissions; drop the duplicate
  copy in apps/qc/views.py.
- Apply it to the whole viewset on shipments, qc, capa, esg, documents,
  certificates-of-analysis and regulatory-certs. The buyer portal is
  server-rendered through the ORM, so it needs none of these APIs.
- Keep the buyer chat working: AI interactions stay authenticated and scoped,
  and agent reads stay open while agent writes become ops/admin.
- Close a buyer-to-admin escalation in the users API: writes are admin-only and
  role/is_active are read-only, so a buyer can no longer PATCH their own row to
  role=admin and then pass every IsOpsOrAdmin check.
2026-09-17 15:53:44 +00:00
27b7fe7a13 Initial commit: IXG Platform 2026-07-29 16:48:48 +00:00