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:
@@ -7,7 +7,18 @@
|
||||
> Update the **Current step** line and the item status every time something moves.
|
||||
> Add new findings at the bottom of the relevant block rather than rewriting history.
|
||||
|
||||
**Current step (2026-09-23, Week 2):** Payment safety fixes 2.13 and 2.14 and
|
||||
**Current step (2026-09-24, Week 2):** Client inputs for Mercado Pago and
|
||||
freight were requested on 2026-09-24; Tiny access is already with the client.
|
||||
Built without them: server-side print-file generation (1.4), the delivery
|
||||
address (3.8), the Kanban's payment-issue and print-file views (1.5), and
|
||||
Mercado Pago and Tiny adapters written from the public API documentation and
|
||||
tested against fake transports (1.1, 1.3). None of the provider work is a
|
||||
verified integration. The complete CI integration sequence passed locally on
|
||||
2026-09-24 (all API suites including the new `print_file_test`, adapter and
|
||||
generator unit suites, retention, runtime security, and both browser suites),
|
||||
run with Docker Engine in WSL against a fresh build; pending a Gitea runner run.
|
||||
|
||||
**Previous step (2026-09-23):** Payment safety fixes 2.13 and 2.14 and
|
||||
the local order-correctness work in 3.6/3.9 have passed integration checks.
|
||||
Production specification v2 now records each copy's film coordinates and is
|
||||
kept through the approved order; 4.6 now pages pending and approved unpaid
|
||||
@@ -211,14 +222,49 @@ From the report already sent. These are dated promises, not backlog.
|
||||
A refused paid event must be visible for operator resolution rather than silently
|
||||
treated as finished. See 2.14 and 3.7. Requires sandbox access, webhook
|
||||
administration, event mapping and an approved refund policy.
|
||||
**Groundwork (2026-09-24):** `app/mercadopago.py` creates PIX or card-token
|
||||
payments with the quote as idempotency key, verifies `x-signature` as
|
||||
documented (HMAC-SHA256 over `id;request-id;ts`, 30-minute replay window),
|
||||
and treats the notification as a pointer: the payment is fetched from the
|
||||
API and only a BRL amount in whole centavos is compared. `payment_intents`
|
||||
binds each provider payment to its quote; `/api/payments/intent` starts a
|
||||
PIX and the Site shows its QR code. Refused paid events and refunds on
|
||||
existing orders now stay on the Kanban until an operator records a
|
||||
resolution. Unit-tested against a fake transport only; card form (needs the
|
||||
public key), sandbox run and refund policy remain.
|
||||
- `[ ]` 1.2 — Real freight quotation. **Blocked on client inputs** (see
|
||||
`PRODUCTION_INPUTS.md`): source platform, credentials, origin CEP, services,
|
||||
packaging weight/dimensions per length, subsidy policy.
|
||||
- `[ ]` 1.3 — Idempotent Tiny/Olist order creation with order-number traceability.
|
||||
- `[~]` 1.3 — Idempotent Tiny/Olist order creation with order-number traceability.
|
||||
Confirm endpoints, tag behaviour and rate limits first.
|
||||
- `[ ]` 1.4 — Final print-file generation (see 3.2 and 3.6: production instructions
|
||||
**Groundwork (2026-09-24):** `app/tiny.py` (API 2.0) maps the approved
|
||||
snapshot to `pedido.incluir` with `numero_pedido_ecommerce = DTF-<number>`,
|
||||
searches for that number before creating, and treats Tiny's in-body errors
|
||||
as failures so the outbox retries. Pickup keeps the existing `forma_envio X`
|
||||
/ DropStar convention. Selected with `TINY_ADAPTER=tiny`; tested against a
|
||||
fake transport only. Product codes (`TINY_SKU_<MODE>`), the tag, API version
|
||||
(2.0 vs 3.0) and rate limits must be confirmed on the client's account.
|
||||
- `[~]` 1.4 — Final print-file generation (see 3.2 and 3.6: production instructions
|
||||
must survive checkout before an output engine can reproduce the approved job).
|
||||
- `[ ]` 1.5 — Main Kanban production states consolidated.
|
||||
**Built (2026-09-24):** 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 (`app/printfile.py`, rendered by the worker from
|
||||
`app/printjobs.py`). Sources are embedded once at original resolution; JPEG
|
||||
bytes pass through, PNG alpha becomes a soft mask, EXIF orientation is
|
||||
honoured. A file whose proportions differ from the quote, a layout longer than
|
||||
billed, or PDF/PSD/AI/CDR artwork goes to hand preparation with the reason.
|
||||
The operator approves the generated PDF as the final file through the
|
||||
existing review. Unit tests include a raster check of every rotation and
|
||||
mirror, and `tests.print_file_test` passes on the running stack (generate,
|
||||
download, approve as final, queue; hand-preparation routing and retry).
|
||||
**Still open:** a FlexiPRINT import of real
|
||||
generated files (including one longer than 5 m, which uses `UserUnit`), and
|
||||
PDF artwork, which this generator does not compose.
|
||||
- `[~]` 1.5 — Main Kanban production states consolidated. The six states and
|
||||
their transitions are unchanged; cards now show the delivery address, the
|
||||
print-file status per item, and a panel lists payments that need a person
|
||||
(money without an order, refunds after an order) until resolved. Confirm
|
||||
with the operation that these are the main states before closing.
|
||||
- `[x]` 1.6 — **Block 0.2 + 0.3** were completed and verified on 2026-09-18.
|
||||
|
||||
`[!]` The production compose currently blocks `dev_paid` (`ENVIRONMENT != 'local'`)
|
||||
@@ -497,12 +543,20 @@ overpayment and provider success followed by database failure. Record refused
|
||||
paid events for resolution. Decide who reconciles them and when production must
|
||||
stop or refund. Implement with 1.1 after the checkout/refund policy is approved.
|
||||
|
||||
### `[ ]` 3.8 — Collect a deliverable destination before charging freight
|
||||
### `[~]` 3.8 — Collect a deliverable destination before charging freight
|
||||
|
||||
The quote has a shipping service and CEP but no recipient, street, number,
|
||||
city/state or delivery snapshot. Add and validate these fields with 1.2, then
|
||||
bind the chosen service and final freight amount to the payment intent.
|
||||
|
||||
**Local progress 2026-09-24:** the Site collects recipient, street, number,
|
||||
complement, district, city and UF for delivery; the API requires them for any
|
||||
non-pickup quote, requires the CEP to be the one freight was quoted for, and
|
||||
refuses an address on pickup. The address is part of the reviewed quote, the
|
||||
order snapshot, the Kanban card and the Tiny payload. Changing it after a quote
|
||||
invalidates that quote in the browser like any other cart change. Binding the
|
||||
chosen freight service to the payment intent waits on 1.2.
|
||||
|
||||
### `[~]` 3.9 — Make artwork quality and geometry evidence explicit
|
||||
|
||||
Reject or route for review when PDF page count/geometry, image decoding or DPI
|
||||
@@ -622,6 +676,19 @@ print-file evidence still need correction before this item can close.
|
||||
data, a production API image import, local security status, and a local
|
||||
backup/restore of the database plus 78 clean objects. Production offsite
|
||||
recovery and signature freshness remain separate open items.
|
||||
- `[x]` 5.15 — MinIO stopped publishing public images: by 2026-09-24 both
|
||||
Docker Hub and quay.io answered anonymous pulls with 401, so a runner or
|
||||
machine without a cached image could not start the stack. The local/CI
|
||||
storage and storage-init now use Chainguard's MinIO build (ships `sh` and
|
||||
`mc`, non-root), pinned by digest. Verified with a fresh local build and the
|
||||
full integration sequence. Production uses R2 and is unaffected.
|
||||
- `[ ]` 5.16 — The operator login limit (10 per account per 15 minutes) counts
|
||||
successful logins too, and every test client signs in separately. The CI
|
||||
sequence sits close to that limit: one extra login made the final browser
|
||||
test's sign-in fail with 429 until `print_file_test` was changed to reuse
|
||||
one session. Either count only failures toward the account bucket or give
|
||||
the suites a shared operator session, so adding a suite cannot break
|
||||
another.
|
||||
- `[ ]` 5.13 — Define production recovery: scheduled encrypted offsite database
|
||||
and object backups, a consistent snapshot boundary, Swarm data placement and
|
||||
a restore rehearsal that opens every required live order file.
|
||||
|
||||
Reference in New Issue
Block a user