Skip to content

[ttp1-rust] Single current-batch screen with per-file cards (print-portal v2) - #24

Merged
FranciscoMateusVG merged 1 commit into
portal-rustfrom
team/ttp1-rust/coder
Oct 9, 2026
Merged

FranciscoMateusVG merged 1 commit into
portal-rustfrom
team/ttp1-rust/coder

Conversation

@FranciscoMateusVG

Copy link
Copy Markdown
Owner

TTP task 1 (trial ttp1-rust): replace "list of orders → open one order" with one home screen showing the supplier's current print batch, against the frozen monorepo-incluir print-portal-v2 contract (@ 27022467). No backend/contract change, no new dependency.

What changed

  • Domain (portal-domain/src/batch.rs): v2 DTOs: Batch, BatchItem (incl. previouslyCancelledIn), BatchQuote, BatchList, OpenBatchResponse, and kind-discriminated close items (batch / legacy_order). Strict serde (unknown keys rejected) plus schema/semantic checks (itemCount = items, unique orderId, each file exactly once per item, at least one file, LOT-/IMP- references).
  • Port / Hono adapter / memory fake: /api/print-portal/v2 (batches, batches/open, batches/:id, member file, collected {}, quotes multipart file+amountCents, quote file, printed {quoteId}, monthly closes). Same security as before: fixed origin, no redirects, strict parsing, bearer server-side, size caps. The fake keeps ETag CAS, Idempotency-Key replay/conflict, 428/412/409/EMPTY_BATCH, and has hooks for Financeiro decision, receipt and cancellation.
  • Use cases: getCurrentBatch returns the open batch, or else the active collected…printed batch found in history (the upstream hides open meanwhile). One span per operation; no content in spans or logs.
  • Web
    • / shows the current batch: LOT-xxxx, status, item and file counts, total copies, and the progress bar Pronto → Arquivos retirados → Orçamento enviado → Orçamento aprovado → Impresso.
    • Cards are grouped by request IMP-xxxx · título, one card per file (name, size, copies, instructions, Baixar arquivo). Residual files show "Não identificadas / Sem vínculo seguro"; residual Instruções gerais get their own block inside their own request.
    • Items with a cancelled-batch history show the warning Este item já esteve no lote LOT-xxxx, cancelado — confira antes de imprimir.
    • Actions by state, all with explicit confirmation, If-Match = batch ETag, Idempotency-Key kept per intent across retries:
      • open: Retirei os arquivos, which needs the "Conferi todos os arquivos" checkbox; a 412 tells the user to reload and confirm again.
      • files_collected / quote_rejected: Enviar orçamento (file + total in R$; client-side type and size check), with the rejection reason shown when rejected.
      • quote_pending / printed: waiting messages only.
      • quote_approved: Marcar como impresso.
    • Actions that a state doesn't allow are not rendered at all. No batch: Nenhum pedido aguardando.
    • Lotes anteriores: history list with a read-only detail view that reuses the same cards.
    • Notas fiscais works on v2 closes.
    • The old /orders screens and the /api/print/v1 BFF routes are removed. The data-ttp smoke markers sit on the real components.
  • Tests
    • Shared PrintApi conformance suite on the vendored frozen fixture and its real PDF assets, run against the memory fake and the HTTP adapter (via a fake Hono over a socket).
    • Web tests run the shared staging smoke (infra/ttp/staging.py) against the BFF over real sockets for every frozen checkpoint: open, collected, quote-pending, quote-rejected, quote-approved, printed, next-batch, rebatched, plus empty (no history / only received / only cancelled).
    • Also covered: the full journey open→printed→received→history→NF, stale-ETag 412 and recovery, disallowed type (415) and oversize (413), a 503 then a retry with the same Idempotency-Key (one quote, then a replay), hostile text escaping, and no secrets in spans or logs.
  • The examples/src/bin/portal_e2e.rs live-stack run and the README are updated to v2.

Gate

cargo xtask check → CHECK PASSED (fmt, architecture, clippy -D warnings, codegen drift on live PG16, full instrumented test suite + coverage, examples, hooks), locally and in pre-push.

🤖 Generated with Claude Code

Replace the per-order list/detail screens with one home screen showing the
supplier's current print batch (open or active), against the frozen
monorepo-incluir print-portal v2 contract (27022467):

- domain: v2 DTOs (Batch, BatchItem with previouslyCancelledIn, BatchQuote,
  BatchList, OpenBatchResponse, kind-discriminated monthly-close items),
  strict serde + schema/semantic checks (itemCount, unique orders/files)
- port/adapter/fake: /api/print-portal/v2 batch routes (open, list, detail,
  member file, collected, quotes, quote file, printed), ETag/If-Match,
  Idempotency-Key replay/conflict, EMPTY_BATCH; memory fake hooks for
  Financeiro decision, receipt and cancellation
- use cases: getCurrentBatch (open, else the active collected…printed batch
  from history) plus one span per batch operation
- web: `/` = current batch header, progress bar, per-file cards grouped by
  request, residual "Instruções gerais" per request, cancelled-batch warning,
  state-driven actions with confirmation (collect needs the checkbox; quote
  upload; mark printed; waiting messages), empty state; "Lotes anteriores"
  history + read-only detail; invoices on v2 closes; old /orders screens
  and /api/print/v1 BFF routes removed; data-ttp smoke markers
- tests: conformance suite on the frozen fixture + real PDF assets for the
  memory fake and the HTTP adapter; web tests run the shared staging smoke
  (infra/ttp/staging.py) for every frozen checkpoint, the full journey,
  stale-ETag recovery, 503 retry with the same Idempotency-Key

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@FranciscoMateusVG
FranciscoMateusVG merged commit 922b4bf into portal-rust Oct 9, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant