Commit graph

5 commits

Author SHA1 Message Date
f6aedc0002 Add the compliance registers to the ops portal
Facility, origin zone and collector group could only be registered in the
Django admin, which left the portal unable to onboard a new supply site,
zone or group. Add list/create/edit screens for all three, and create/edit
for mitigation actions, EUDR evidence and external-submission references
on a due-diligence case.

The origin-zone form keeps the map a view of the stored geometry, not a
check of it: the map wording is unchanged and geometry is only required to
be valid JSON. Verification is stamped from the acting user when the status
moves to verified/rejected, and cleared when it returns to unverified.

Nothing is removed from the admin; it stays as the superuser fallback.
Adds an nginx /tiles/ route on the ops host so the map imagery loads there
too (the tile view is root-mounted but ops remaps / to /ops/).
2026-09-25 16:26:59 +00:00
8d209f3cbf Move conditional status classes inside the class attribute
A class list written outside the quotes left the badge colour as a bare
attribute, so the status rendered white-on-white. Also repair a stray quote on
the CoA release message, where class=text-muted mb-0 left the class unapplied.
2026-09-17 14:48:14 +00:00
db05d6052a Quote the ops templates' HTML attributes so the classes apply
An unquoted attribute value ends at the first whitespace, so
``class=badge bg-danger`` is read by every browser as ``class="badge"`` plus two
meaningless attributes. Bootstrap was loading perfectly well; the markup simply
never asked for the styles. Across the ops portal that meant buttons rendered as
plain links, status badges were invisible (white text on a white background: a
failed result showed as nothing at all), the active sidebar item never
highlighted, and the flex utility classes did nothing. The buyer portal templates
quote their attributes, which is why only the ops portal looked unstyled.

346 attributes across 20 templates, rewritten mechanically with a conservative
transform that handles the three shapes in use — a Django tag as the value, a
multi-token class list, and a trailing simple conditional (the active-nav
highlight) — and leaves anything it does not recognise exactly as it was.
2026-09-17 13:57:53 +00:00
c568a34dc0 Ops templates: show '-' when the acting user is null
Six ops list and detail pages dereferenced a nullable user to print their name,
which renders an empty cell when the field is unset. Guard each one so the cell
reads "-" instead.

Screens: batch detail, CoA review detail, document list, EUDR detail, and the two
QC verification pages.
2026-09-16 16:39:07 +00:00
08096e168f P99C: compliance automation - CoA auto-generation and EUDR due diligence
- Versioned product specification table (Unrefined Shea Butter v1.0 seed) with
  spec-based QC evaluation replacing hard-coded thresholds
- Structured QC results with test methods and four-eyes verification
  (submitter cannot self-approve)
- reportlab IXG Quality Summary PDF auto-generated on quality approval,
  SHA-256 hashed; original independent lab PDF kept authoritative
- CertificateOfAnalysis version/status/hash/approval/supersede lifecycle;
  commercial release publishes to buyers and triggers notification
- EUDR evidence workflow: Facility, OriginZone, CollectorGroup, HarvestIntake,
  IntakeBatchLineage, DueDiligenceCase, EUDREvidence, RiskAssessment,
  MitigationAction, DueDiligenceStatementReference with rule-based
  completeness check and risk assessment (no AI legal conclusions)
- Ops portal: QC Approvals, CoA Reviews, EUDR Compliance screens
- Buyer portal: /portal/compliance page
- 22 automated tests covering four-eyes, CAPA, PDF+hash, publish/notify,
  EUDR blocks and buyer isolation
2026-08-05 13:58:39 +00:00