Files
sxchnge/docs/architecture/bff.md

8.4 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.

backend/ groups Go modules. The implemented executable is backend/product, with its own main.go and go.mod. backend/shared is a separate library module. Backoffice will be a separate executable module (backend/backoffice) with its own entry point, operator identity, configuration and deployment. Product's entry point is not the entry point for every future backend.

Owner Retained implementation
product/app HTTP runtime, startup, composition and health
product/customers Local customer models, service and account repository
product/auth Login/protected routes, local DTOs/mappers and auth configuration
product/sessions Session/client models, refresh storage, cookies and token generation
product/verification Verification models, configuration and storage
shared Generic database/transaction/query code, errors, logging and HTTP helpers

Shared infrastructure imports no executable module. Customer repositories are constructed by the product module rather than the generic database factory. There is no global customer/session model package or Sendico edge/product source hierarchy. Source provenance follows the moved files across Go modules.

Local customers have no organization membership, roles, policies or tenant ID. Creation validates/hashes passwords and commits the account and activation token atomically. Deletion revokes that customer's sessions. The runtime starts without any seed. Casbin, invitations and platform provisioning are absent.

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 bootstrap has no Sendico runtime calls and therefore no copied public wire snapshot. When implementing an adapter, keep only its consumed request/response contracts within that adapter. Pin their upstream revision separately from local customer DTOs/models; do not copy the entire platform contract or synchronize source 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. Use the public contract and response conventions for each implemented operation; do not invent a parallel provider facade or call internal services.

Required public Sendico capabilities

The source reviewed at the pinned revision describes API version 4.2.37. Its public 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. Configure the SXCHNGE application client for web/native sessions; keep signup independent of Sendico availability. Never add local organization, membership, role or policy requirements.
  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 selected copied starting point in independently buildable Go modules and a public API integration plan. The local runtime installs the existing authentication transport and account service. Local signup/profile HTTP endpoints, verification delivery/completion, application client setup, 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.