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:
@@ -99,6 +99,20 @@ CREATE TABLE IF NOT EXISTS dtf_local.payment_intents (
|
||||
created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE(provider, provider_payment_id)
|
||||
);
|
||||
-- OAuth connections to providers (Tiny). One row per provider; the refresh
|
||||
-- token rotates on use, so it lives here, never in configuration.
|
||||
CREATE TABLE IF NOT EXISTS dtf_local.provider_tokens (
|
||||
provider text PRIMARY KEY, access_token text NOT NULL, refresh_token text NOT NULL,
|
||||
access_expires_at timestamptz NOT NULL, refresh_expires_at timestamptz,
|
||||
connected_by text NOT NULL, connected_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
-- Single-use states for an operator-started OAuth connection. They protect the
|
||||
-- callback, which arrives cross-site without the operator's cookie.
|
||||
CREATE TABLE IF NOT EXISTS dtf_local.oauth_states (
|
||||
state text PRIMARY KEY, provider text NOT NULL, operator text NOT NULL,
|
||||
expires_at timestamptz NOT NULL
|
||||
);
|
||||
-- The print file generated from each paid item's approved layout. One row per
|
||||
-- item: the worker claims it, renders, and records either the file or why the
|
||||
-- item has to be prepared by hand. Regenerating replaces the row's result.
|
||||
|
||||
Reference in New Issue
Block a user