Files
sxchnge/docs/architecture/bff.md
T

8.1 KiB

SXCHNGE BFF and Sendico public API boundary

SXCHNGE is one organization in Sendico, just like any other organization. SXCHNGE owns its customers, registration, credentials, sessions, profile settings and application UX. Sendico is the financial platform. All provider access goes through its public HTTP API using SXCHNGE's organization and an integration principal. A customer is not a Sendico organization or the integration principal.

This replaces the earlier proposal for a new BFF shell and delegated Sendico customer provisioning. The starting point is copied Sendico BFF code, maintained and allowed to diverge within this repository.

Copied starting point

Source: S_I/sendico, commit 8bb20dcd622dd8eb92d289b6b34411e7eccab083. The source checkout's unrelated dependency edits were not copied.

Local component Reused implementation
backend/edge/shared Chi HTTP runtime, middleware, JWT login/pending sessions, refresh/rotation/logout, CSRF/cookies, rate limiting, Mongo verification and refresh-token stores
backend/edge/product/interface/accountservice Account validation, bcrypt passwords, creation, local membership/roles, activation tokens, password reset and email-change token issuance, deletion
backend/pkg Canonical local account/domain models, Mongo repositories/transactions, authorization, errors, structured logging, process bootstrap and health
backend/internal/profile Small SXCHNGE composition layer selecting the copied local account service
backend/contracts/sendico Separate snapshot of Sendico's public OpenAPI contract and its referenced schemas

Source provenance and the bounded adaptations are in PROVENANCE.md. There is no sibling source import, private Sendico module requirement, gRPC client, discovery subscription or broker connection. Platform engines and Product's platform-provisioning bootstrap were not copied. The original handwritten shell and tiny replacement helpers were removed.

The existing local account service retains local organization membership and role semantics. Use one SXCHNGE local tenant when wiring registration; this does not create an organization in Sendico for each customer. Local database collections, JWT keys and registered application clients belong exclusively to SXCHNGE.

Identity and ownership

Keep three distinct identifiers:

  1. The configured SXCHNGE Sendico organization reference.
  2. SXCHNGE's backend integration principal, with the public API permissions it needs.
  3. The authenticated local customer and its persisted provider resource references.

The browser supplies neither the authoritative organization nor customer owner. Resolve both from server configuration and the authenticated local customer. Validate ownership before returning balances/history or submitting operations. Never give a customer organization-wide data because the integration principal can see it. Do not pass SXCHNGE customer passwords or session tokens to Sendico.

Sendico's /accounts/login/api is an existing password/client-secret grant with client/account binding and IP policy, not a generic OAuth client-credentials flow. Its tokens are server-side platform credentials, separate from customer sessions. Confirm the deployed credential policy before configuring a provider client.

Contract and service structure

The copied OpenAPI files are a pinned upstream wire contract, not SXCHNGE's app API or domain model. Preserve them as an isolated snapshot. Changes require an explicit contract update; do not follow Sendico source updates automatically.

When wiring a feature, keep the existing architecture:

app DTO → mapper → service → data model → provider → UI

On the backend, local HTTP request/response DTOs map into account/application services. A Sendico adapter maps those local models to/from the public HTTP wire contract. Only the adapter handles provider URLs, credentials, response envelopes and provider-specific errors. Do not expose provider wire types in Flutter models or replace local account services with Sendico login/customer calls.

The next adapter will use a configured public HTTPS base URL, a fixed organization reference, bounded request timeouts and an injected HTTP transport. It must reject cross-origin credential redirects. Reuse the existing public contract and response conventions; do not invent a parallel provider facade or call internal services.

Required public Sendico capabilities

The snapshot is API version 4.2.37. Source routes and schemas establish available shapes; they do not prove that a deployment enables every feature.

Need Existing public surface / work required
Integration session /accounts/login/api, /accounts/refresh, /accounts/rotate; provision SXCHNGE integration credentials and permissions
Organization context /organizations and organization lookup; configure the existing SXCHNGE organization, no customer organization provisioning
Currency accounts and history Organization-scoped ledger account listing, balance and operation routes; confirm supported external-customer ownership and available-balance semantics
Top-up instructions Wallets, assets and ledger inbound-route HTTP handlers; confirm customer allocation, expiry, observed versus credited states, fees and settlement callbacks
Exchange and payout Public quote/multiquote, by-quote execution, payment lookup/history, payment methods and recipients; verify external-customer resource scope and idempotent retry/reconciliation behavior
KYC and limits usage Product has /accounts/compliance, /accounts/compliance/evidence, /accounts/compliance/submit; they use the authenticated Sendico account and organization ownership. A supported public external-customer contract is needed for SXCHNGE customers
Manual review Agree on public submission/status/reason contracts for passport plus passport-selfie review, resubmission and denial; do not invoke internal case/KYC services directly
Status updates Public callback subscription and signing contracts exist. Confirm supported events, replay, deduplication and reconciliation before relying on them

Required platform capabilities stay inside Sendico: ledger, quotation/execution, receiving routes, payment methods/rails, KYC decisions, policy and limit enforcement. If the public API lacks a needed capability, extend that public API in a separate Sendico task. No private transport fallback is allowed.

Next wiring sequence

  1. Wire local signup, verification delivery/completion and profile endpoints onto the copied account and verification services. Create SXCHNGE-owned tenant, client and role records; keep signup independent of Sendico availability.
  2. Implement the public HTTP adapter and confirm organization/resource scoping with the integration principal. Agree on external-customer contracts where the existing public API assumes a Sendico account.
  3. Wire read-only accounts, available funds, operation history and usage/limits. Return local models to the existing shared Flutter services/providers.
  4. Wire top-up, quote/review, exchange/payout execution and reconciliation with local two-factor approval bound to the exact operation and idempotency key.
  5. Wire KYC uploads/status/review and callback processing through public APIs.

Before enabling money operations, test customer isolation within the same organization, expired credentials/quotes, denied KYC, exhausted limits, duplicate submission, timeout-after-acceptance and delayed settlement. An uncertain response must remain pending until reconciled. UI balances show available funds, while operation details explain what has happened and what remains pending.

Current delivery boundary

This task supplies the copied starting point and isolated public contracts. The local runtime installs the existing authentication transport and account service. Local signup/profile HTTP endpoints, verification delivery/completion, initial tenant/client provisioning, Flutter HTTP adapters and live Sendico calls are not connected yet. The frontend continues using its existing dummy services. No new provider organization, customer or payment has been created.