The order page becomes the customer's area, one page at four addresses:
- /conta/entrar: sign in or create an account, side by side. "Esqueci
minha senha" points to the Dropstar WhatsApp until e-mail can be sent.
- /conta: the counts of orders waiting for payment, in production, in
correction and finished, and the latest one.
- /conta/pedidos: every order and the cart waiting for payment in one list,
newest first, filtered by group, order number and period, ten per page.
The cart shows "Aguardando pagamento" and its "Pagar" goes to the PIX
page when a PIX code is open. An order opens in place with its progress,
items, delivery, history, files and the correction form. A guest sees
the orders paid in this browser.
- /conta/dados: WhatsApp and a saved delivery address (the CNPJ is locked),
e-mail and password changes, both confirmed with the current password;
a password change signs the other devices out.
The cart fills in the account's details and saved address. New API routes
for the details, and the order list takes filters and pages and returns
the counts; only the newest unpaid quote whose files still exist is listed.
The Site's "Minha conta" and "Ver meus pedidos" point to the new addresses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each cart item has a checkbox and a thumbnail of its first file (or its
extension when there is none). Only checked items are priced, quoted,
uploaded and paid; an unchecked item stays in the cart, dimmed, for a later
order, and stays there after the others are paid. The header count is the
whole cart; the summary counts what is being paid.
Also removes the "A conta nasce aqui…" and "Carrinho salvo neste
navegador…" texts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The browser put the CNPJ, WhatsApp, e-mail, CEP and address back after a
reload without telling the page, which then showed them but could not pay
until they were typed again. The fields are now emptied on load and marked
autocomplete="off", and the saved cart holds only the items: the details and
address are typed again after a reload or a closed tab. The payment page
already takes them from the server.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Going back to home delivery with a CEP already typed, or restoring a saved
cart, now quotes the freight again by itself; before, only pressing Calcular
did. With every case covered, the button is gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A complete CEP now looks up its address on the server (ViaCEP, rate
limited, keeping the Site's CSP to its own origin) and fills street,
district, city and state, moving the cursor to the first field left, and
quotes the freight without pressing Calcular. The CEP keeps its mask when
the cart is restored. Freight and its delivery time appear in the order
summary instead of a line under the CEP, the delivery option says it ships
with Jadlog, and the address reminder is a hint rather than an error.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New landing (hero with a sheet preview, four steps, product cards priced
from the checkout table, price table and benefits), a progress bar that
follows the order through Montagem, Dados e entrega and Pagamento, the
live sheet beside the artworks, and a running total bar on phones.
The cart's saved-in-browser note no longer takes a grid column, which had
pushed the order into a narrow strip and the summary below it. The
previous look is kept in tag ui-v1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
The Site's page sat at the repository root while its scripts lived in
local/static, a split with no reason behind it. They are together in web/ now,
with the page as index.html, which is also what the image serves.
app.py held the adapters, the configuration, the shared query helpers and
nineteen routes; customer.py held fourteen more but could not import from it
without a cycle, so it was wired by passing nine callables into install_routes.
Configuration and shared helpers move to local/runtime.py, the rules for
attaching artwork to an order move to local/artwork.py where a customer
correction and an operator final-file set can share them, and the routes become
seven routers under local/api. app.py is 48 lines that create the application,
apply the middleware and include them. Routers import downwards only.
Three faults came out of the extraction and are worth recording, because each
passed a check that looked sufficient. ast reports a function's line at the def,
so every decorator on the line above fell outside the extracted range: twelve
routes and the security middleware were defined but never registered, and the
files still imported and parsed cleanly. Names the old closure renamed on the
way in, and a Jsonb import, were missing in three modules. A name-resolution
pass over every new module found those; the route count matching the original
exactly, 32, is what confirmed the first.
The release gate's marker for the fake payment adapter pointed at app.py and the
adapter moved to runtime.py, so the gate passed while the condition it guards was
unchanged. That is the same silent decay 2.5 set out to fix. A test now asserts
every marker still matches something in its file, so the next move fails loudly.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>