feat: generate print files, collect delivery addresses, add provider adapters
All checks were successful
Build and deploy / Validate source (push) Successful in 1m45s
Build and deploy / Integration suite on a real stack (push) Successful in 4m48s
Build and deploy / Secret scan and release gate (push) Successful in 11s
Build and deploy / Publish images and notify Portainer (push) Has been skipped
All checks were successful
Build and deploy / Validate source (push) Successful in 1m45s
Build and deploy / Integration suite on a real stack (push) Successful in 4m48s
Build and deploy / Secret scan and release gate (push) Successful in 11s
Build and deploy / Publish images and notify Portainer (push) Has been skipped
Week 2 work that did not need client inputs. Print files (1.4): each paid item gets a PDF the width of the film and the length of the approved layout, with every copy at its reviewed position, rotation and mirror. Sources are embedded once at original resolution; JPEG bytes pass through and PNG alpha becomes a soft mask. Artwork the generator cannot reproduce goes to hand preparation with the reason. The worker renders outside any transaction, and the operator approves the generated file as the final one through the existing review. Delivery address (3.8): required for any non-pickup quote, bound to the quoted CEP, carried into the order snapshot, the Kanban card and Tiny. Kanban (1.5): print-file status per item, and a panel of payment events that need a person (money without an order, refunds after an order) until an operator records the resolution. Mercado Pago and Tiny (1.1, 1.3): adapters written from the public API documentation and tested against fake transports only. Selectable for sandbox testing with their credentials; the production preflight still blocks release. Adds payment intents and a PIX step on the Site. MinIO: Docker Hub and quay.io now refuse anonymous pulls, so local and CI storage use Chainguard's MinIO build, pinned by digest. Verified with the full CI integration sequence on a fresh local build, including the new print_file_test and both browser suites. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -72,7 +72,9 @@ operator interfaces.
|
||||
the buttons or drag and drop to **Arte tratada**. Open **Arquivos de produção**,
|
||||
select the manually prepared final files for every item, enter a review note,
|
||||
tick the confirmation and click **Aprovar arquivos finais**. Use the harmless
|
||||
fixture again only for this local test; no printable file is generated.
|
||||
fixture again only for this local test. The text fixture is not an image, so
|
||||
its print file shows **preparar à mão**; with a PNG or JPEG artwork the
|
||||
generated PDF is preselected instead (see "Print files").
|
||||
Continue through **Fila de impressão →
|
||||
Imprimindo → Finalizado**. A move to **Correção** requires a reason; it can
|
||||
return to **Arte recebida** or **Arte tratada**. Finalizado is terminal locally.
|
||||
@@ -193,8 +195,10 @@ must resolve from the browser; keep `http://localhost:9000` for this stack.
|
||||
Parts use 15-minute presigned URLs and unfinished reservations expire after
|
||||
one hour. Clients can cancel a reservation through the upload DELETE endpoint.
|
||||
|
||||
Only fake integration adapters and `s3-local` storage are accepted. Startup fails
|
||||
if a production adapter/environment or nonlocal S3 endpoint is selected.
|
||||
Fake integration adapters and `s3-local` storage are the default. Mercado Pago
|
||||
and Tiny can be selected for sandbox testing only (see "Provider sandboxes");
|
||||
startup fails if their credentials are missing, if any other adapter is
|
||||
selected, or if a production environment or nonlocal S3 endpoint is used.
|
||||
The API, worker, and database run on an internal Docker network; web gateways
|
||||
and MinIO also join a network that permits loopback port publishing.
|
||||
|
||||
@@ -216,6 +220,64 @@ storage permits; otherwise reselect them. Saved quote IDs also survive reloads.
|
||||
Clearing cookies loses a guest session, while registered customers can sign in
|
||||
again. The operator can still inspect order records.
|
||||
|
||||
## Print files
|
||||
|
||||
Every paid order queues one print-file job per item. The worker renders a PDF
|
||||
exactly as wide as the film and as long as the approved layout, placing each
|
||||
copy at the position, rotation and mirror the customer reviewed. Each source
|
||||
image is embedded once at its original resolution (JPEG bytes unchanged, PNG
|
||||
transparency kept as a soft mask), so nothing is resampled. The Kanban card
|
||||
shows the status per item, the page size and the lowest DPI, and offers
|
||||
**Baixar PDF**. In **Arquivos de produção** the generated file is preselected
|
||||
as the final file; untick it to upload one by hand instead.
|
||||
|
||||
Only JPEG, PNG, WebP and TIFF are generated. PDF, PSD, AI and CDR artwork, a
|
||||
file whose proportions do not match the quoted size, a layout longer than was
|
||||
billed, or an image above `PRINT_MAX_PIXELS` (250 Mpx by default) goes to
|
||||
**preparar à mão** with the reason, and the operator prepares it as before.
|
||||
**Gerar arquivos de impressão** retries those items and generates files for
|
||||
orders paid before the generator existed. After a customer correction the
|
||||
generated file is no longer offered: it reproduces the replaced artwork.
|
||||
|
||||
Layouts longer than about 5 m use the PDF `UserUnit` page scale instead of
|
||||
being split into pages. Confirm on the factory's FlexiPRINT that such a file
|
||||
imports at full length before relying on it for long orders.
|
||||
|
||||
```bash
|
||||
docker compose -f compose.local.yaml exec -T api python -m unittest tests.test_printfile -v
|
||||
docker compose -f compose.local.yaml exec -T api python -m tests.print_file_test
|
||||
```
|
||||
|
||||
With PyMuPDF installed locally (`pip install pymupdf`), the unit suite also
|
||||
draws each page and checks where every quadrant of the artwork lands.
|
||||
|
||||
## Provider sandboxes
|
||||
|
||||
`app/mercadopago.py` and `app/tiny.py` follow the providers' public API
|
||||
documentation and pass their unit suites against a fake transport. They are not
|
||||
verified integrations until they pass with the client's sandbox accounts.
|
||||
Put only **test** credentials in `.env`:
|
||||
|
||||
```bash
|
||||
PAYMENT_ADAPTER=mercadopago
|
||||
MP_ACCESS_TOKEN=TEST-...
|
||||
MP_WEBHOOK_SECRET=... # "Assinatura secreta" in the webhook settings
|
||||
MP_NOTIFICATION_URL=https://<public tunnel>/api/payments/webhook
|
||||
TINY_ADAPTER=tiny
|
||||
TINY_TOKEN=...
|
||||
TINY_TAG=Site DTF # optional marker on created orders
|
||||
```
|
||||
|
||||
With Mercado Pago selected, an approved quote shows **Pagar com PIX** on the
|
||||
Site instead of the local test button. The order is created only by the signed
|
||||
notification, after the payment is fetched from the Mercado Pago API and its
|
||||
BRL amount matches the approved total. Mercado Pago must be able to reach the
|
||||
webhook, so a local run needs a public HTTPS tunnel to the Site port. A paid
|
||||
notification that cannot become an order, or a refund on an existing order,
|
||||
appears under **Pagamentos que precisam de atenção** on the Kanban until an
|
||||
operator records the resolution. Card payment needs the Mercado Pago public key
|
||||
and its card form on the Site; that part is not built yet.
|
||||
|
||||
## Local backup and restore check
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user