feat: connect Tiny through its v3 API with OAuth
All checks were successful
Build and deploy / Validate source (push) Successful in 9s
Build and deploy / Integration suite on a real stack (push) Successful in 2m49s
Build and deploy / Secret scan and release gate (push) Successful in 9s
Build and deploy / Publish images and notify Portainer (push) Has been skipped
All checks were successful
Build and deploy / Validate source (push) Successful in 9s
Build and deploy / Integration suite on a real stack (push) Successful in 2m49s
Build and deploy / Secret scan and release gate (push) Successful in 9s
Build and deploy / Publish images and notify Portainer (push) Has been skipped
Tiny v3 replaces the v2 token adapter. An operator connects Tiny once from the Kanban; the callback is authorised by a single-use state, because Tiny's cross-site redirect does not carry the SameSite=Strict operator cookie. Tokens are kept in provider_tokens, the refresh token rotates under a row lock, and the worker keeps the connection alive while order creation is off. Orders find or create the customer's contact by CNPJ, then POST /pedidos with product ids from TINY_PRODUCT_TEXTIL_FOLHA, _TEXTIL_AVULSA, _UV_FOLHA and _UV_AVULSA and numeroOrdemCompra DTF-<number>; a retry searches the customer's recent orders for that number first. The product settings avoid a _FILE suffix, which the secrets loader reads as a secret file path. Production passes the application credentials through but keeps TINY_ADAPTER fake: Tiny has no sandbox, so creating real orders waits for a supervised test. compose.providers.yaml gives the local API and worker an internet route for provider testing; the default local stack still has none. Verified with the full CI integration sequence locally, including the new tiny_oauth_test against the real database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -237,13 +237,23 @@ From the report already sent. These are dated promises, not backlog.
|
||||
packaging weight/dimensions per length, subsidy policy.
|
||||
- `[~]` 1.3 — Idempotent Tiny/Olist order creation with order-number traceability.
|
||||
Confirm endpoints, tag behaviour and rate limits first.
|
||||
**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.
|
||||
**Groundwork (2026-09-24), API v3 by decision:** OAuth2 against Tiny's
|
||||
Keycloak. An operator starts the connection from the Kanban; the callback is
|
||||
authorised by a single-use state (the operator cookie is SameSite=Strict and
|
||||
does not survive Tiny's cross-site redirect). Tokens live in
|
||||
`provider_tokens`; the refresh token rotates under a row lock and the worker
|
||||
keeps the connection alive. Orders: contact found by CNPJ or created, then
|
||||
`POST /pedidos` with product ids from `TINY_PRODUCT_TEXTIL_FOLHA` / `_TEXTIL_AVULSA` / `_UV_FOLHA`
|
||||
/ `_UV_AVULSA` (not `_<MODE>`: a name ending in `_FILE` is read as a secret
|
||||
file path by `app/core/secrets.py`) and
|
||||
`numeroOrdemCompra = DTF-<number>`; a retry searches the customer's last
|
||||
seven days of orders for that number first. Production passes the app
|
||||
credentials through but keeps `TINY_ADAPTER: fake`. Tested against fake
|
||||
transports (`tests.test_tiny`) and, for OAuth, the real database
|
||||
(`tests.tiny_oauth_test`). Tiny has no sandbox: the first real test creates
|
||||
real orders. Still to confirm on the client's account: plan (Construa+),
|
||||
product ids, token lifetimes, whether pickup needs a transportador, and
|
||||
rate limits.
|
||||
- `[~]` 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).
|
||||
**Built (2026-09-24):** each paid item gets a PDF the width of the film and
|
||||
|
||||
Reference in New Issue
Block a user