Commit Graph

5 Commits

Author SHA1 Message Date
Cauê Faleiros
24013458c9 fix: harden week-two ordering, artwork and operations 2026-09-23 10:40:18 -03:00
Cauê Faleiros
ccc25a2d5d feat: accept payment notifications, once, from a verified sender
There was no inbound payment path at all: a button called a fake synchronously
and wrote an order. A real provider does the opposite — it charges, then tells
us, repeatedly, out of order, and sometimes long afterwards.

POST /api/payments/webhook verifies the signature before the body is parsed, so
an unsigned or tampered delivery is refused and recorded without touching an
order. Verified deliveries are stored under the provider's own event id with a
unique constraint, and applied inside the same transaction that marks them
processed: a repeat is a no-op, a crash is retried rather than half-applied.

An approval whose amount disagrees with the reviewed quote does not become an
order. Underpayment would ship artwork nobody paid for, and overpayment means
something a person should look at.

Order creation moved to app/payments.py so the webhook and the local development
checkout share one implementation and cannot drift. That also closes 3.5: the
charge happens inside the transaction that persists the order, rather than
before it.

The adapter contract is create/verify/parse. FakePayment implements it with a
real HMAC scheme so the whole path is exercised now, by tests/payment_test.py:
unsigned, tampered, underpaid, duplicate, re-sent, unknown reference, and
non-approved statuses. Connecting Mercado Pago is one adapter; no service code
changes.

PAYMENT_WEBHOOK_SECRET is optional in production on purpose. Required would
break the next Portainer render, and a guessable default would be worse than
either: with no secret configured the adapter verifies nothing and therefore
accepts nothing, which is the right state until a provider is connected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 13:25:08 -03:00
Cauê Faleiros
7386469404 docs: move the engineering documents into docs/
All checks were successful
Build and deploy / Validate source (push) Successful in 5s
Build and deploy / Integration suite on a real stack (push) Successful in 1m18s
Build and deploy / Secret scan and release gate (push) Successful in 6s
Build and deploy / Publish images and notify Portainer (push) Successful in 1m26s
Thirteen files at the repository root, seven of them documents. Only README.md
earns a place there; the rest are now in docs/ beside the meeting notes, the
client roadmap and the historical material.

The compose files stay. docker-compose.yml is the path the dtf-cloud Portainer
stack reads, so moving it would break deployment, and Docker resolves a compose
file's relative build contexts against its own directory, so moving the other
two would silently break every build. Both reasons are now written down where
someone would otherwise try it.

Correcting references turned up a live fault: the Portainer stack creation
instructions still named deploy/stack.yaml as the compose path. That file was
removed, so anyone recreating the stack from these instructions would have
failed. It names docker-compose.yml now, with the reason it stays at the root.

ROADMAP.md keeps the paths its closed findings were written with, and says so at
the top. Those entries record where a fault was when it was found; rewriting
them to match a later layout would make the record less true, not more.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 17:52:20 -03:00
Cauê Faleiros
66ddb17f02 chore: untrack deliverables committed by mistake, and home the stray files
All checks were successful
Build and deploy / Validate source (push) Successful in 10s
Build and deploy / Integration suite on a real stack (push) Successful in 1m47s
Build and deploy / Secret scan and release gate (push) Successful in 7s
Build and deploy / Publish images and notify Portainer (push) Successful in 1m38s
The previous commit used git add -A and swept in four binaries that were
deliberately untracked: the week-1 client report as .docx and .pdf, a duplicate
of it under output/documents, and imagem-teste.jpg, an input dropped in to test
with. None of them are the repository's to version. They are untracked here,
left on disk, and covered by .gitignore so the mistake cannot repeat.

Three files had no sensible home. The meeting notes sat at the repository root
under a 78-character name with spaces and accents, the roadmap generator lived
in tmp/ — a directory otherwise ignored as scratch — and its output in output/,
which is otherwise generated evidence. They are now docs/reuniao-2026-09-09-
anotacoes.pdf, tools/generate_dtf_report.py and docs/roadmap-cliente.pdf, with
CONTEXT.md and ROADMAP.md updated to match and a docs/README.md saying what each
document is for.

.gitignore no longer needs four rules to keep one generator out of an ignored
directory; tmp/ is scratch again.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 16:47:36 -03:00
Cauê Faleiros
ca698434a2 chore: remove the abandoned prototypes and archive what described them
portal/, kanban/ and agente/ were 2,034 lines implementing the original
Tiny-first model: token upload links, a second SQLite Kanban, a factory agent.
Nothing imported or started any of it, and several endpoints took the acting
user from the request body with no authentication at all. Their real cost was
that a reader arriving at this repository found two Kanbans and two portals and
had to work out which one was real. The root schema.sql and .env.exemplo went
with them: both code paths load local/schema.sql, and having .env.exemplo beside
.env.example differing by one letter was a trap rather than a convenience.

The documents describing that model are archived rather than deleted. They
record decisions and reasoning the current documents do not repeat, so they are
worth keeping as background, with a header saying plainly that they are not
instructions.

README.md keeps its business case — the capacity figures and the cost argument
are still the reason this project exists — but now states where the prototype
documentation begins and that the code it describes is gone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 16:34:20 -03:00