docs
/
Client Integration

SDK compatibility with AppEngine

Current JavaScript and Flutter behavior, route changes, session boundaries and source-verified integration guidance.

Reviewed on 13 October 2026 against the local client working tree and AppEngine checkout at f60e6b48. This is a source-contract review, not certification of a remote deployment. Existing uncommitted JavaScript app-key changes were inspected and preserved; fetch and build your reviewed revision before relying on them.

Important differences and current alternatives

AreaCurrent source behaviorIntegration guidance
App credential exchangeBackend /profile/app/key consumes appId, secret, optional domain; not legacy keyJavaScript appKey is optional. Flutter constructor still requires it; an empty string accommodates registrations without a legacy key.
App registrationPOST /profile/app/register permits ConfigAdmin; new app identity is a user with System groupOrganization-level app registration is not platform organization creation. Protect the resulting secret; do not embed a privileged credential in browser/mobile code.
RevocationRevoked app credential is refused by a new key exchangeDo not promise that revocation alone immediately invalidates every previously issued token.
JS current profileauth.profile() uses a parameterless route that is not the self-service routeUse client.get('client-data/profile').
JS own ordersorders.mine() omits the route's author parameterUse client.get('client-data/orders').
JS one orderorders.get() sends a query while the current alias uses path parametersUse client.get('storefront/order/get/me/' + encodeURIComponent(orderNumber)) or the customer-data detail route with its required order number.
JS signupHelper signature omits password and does not adopt returned tokensUse generic signup for a password-based flow, inspect response and establish your host's session.
JS verification/refreshNo challenge, refresh, logout or persistence managerComplete challenge via generic requests; trusted host owns renewal and cookies. A 200 challenge is not sign-in.
Header differencesJS forwards its person token unchanged; Flutter prefixes Bearer Supply an unprefixed issued token to Flutter. Follow the specific JS transport contract; avoid accidentally doubling a prefix in an adapter.
Ordinary customer bearerJS without app credentials still puts the customer token in x-client-authorizationUse a deliberate trusted-server adapter for routes authenticated by the ordinary Authorization bearer. See the portal companion.
Repository permissionsRead/write helpers remain subject to authorization; account writes have domain-only restrictionsDo not use repository CRUD to change passwords, roles, identity records or to bypass business side effects.
Sensitive partial writesGeneric partial update refuses user, customer, apikey, user_security, two_factor_backupUse the dedicated account/security endpoints with appropriate authority.
Generic account deletionRepository delete rejects user/customer deletionUse the documented user/customer deletion API and its permissions.
Account selectionCustomer shared-account selection reissues a sessionStore replacement access/refresh tokens before reloading purchasing data. Selecting a company does not grant manager status.
Flutter restoreLoads stored user/token without a network checkValidate with a protected call before claiming the restored session is accepted by the server.
Flutter remembered sessionsSaved tokens go into preferences; signInWithSaved does not switch org and may read another cached userUse a custom isolated secure store; explicitly sign in the desired staff/customer until cross-account restoration has been verified or corrected.
Flutter organization switchSigns out and changes org, retains app credentialsProvide credentials matching the new org and isolate its storage.
Flutter uploadsSeparate multipart path, not the ordinary send/retry pathVerify upload failures and renewal separately; do not promise shared retry semantics.
Retry differencesJS replays a server 401 once; Flutter additionally retries recognized transient failuresWrites need operation-specific reconciliation/idempotency. A lost response may follow a committed write.
ChatSeparate Flutter package; customer token is required; config affects AI/agent routingPersist server-issued chatSessionId and use the returned chatId. Email alone is not a general session identifier.

AppEngine-specific sequences

For reservations, start from the saved booking's definition and service, obtain actual availability, choose a returned slot and submit the documented business operation. Carry required form answers when creating a booking. Do not replace that with a repository status update. A conflict does not imply that the original booking should be cancelled.

For a customer portal, read the authenticated profile and owned-record endpoints. An order number, ticket number and reservation sk are different identifiers. A capability-style email/code cancellation route is different from a customer-owned route: the portal source first reads the owned booking on the trusted server, derives the saved values, then cancels.

For commerce, use server pricing and the complete checkout/provider flow. A quote is not a paid order; a configured gateway is not a completed payment. The JS package provides transport/helpers, not a payment UI, webhook processor or automatic shipping-provider setup.

For support chat, get the signed-in customer's token from the active session, connect the separate socket package, wait for authentication, and retain the server's chat session context. A backend supporting guest chat does not mean the Flutter support package currently supports guests: it refuses an empty token.

Source basis

Client implementation:

  • appmint_js_client/src/{index,config,transport,types,errors}.ts
  • appmint_flutter_client/lib/appmint_flutter_client.dart
  • appmint_flutter_client/lib/src/{config,http,repository,errors,call}.dart
  • appmint_flutter_client/lib/src/auth/{auth,results,session_store}.dart
  • appmint_flutter_chat/lib/src/{config,service,controller}.dart

AppEngine implementation in the sibling repository:

  • src/users/users.controller.ts, users.service.ts: app registration/exchange, customer sign-in/signup, refresh, magic code and account selection.
  • src/users/auth/jwt.auth.guard.ts: authenticated identity and organization boundaries.
  • src/client-account/client-account.controller.ts: self-service profile and shared-account routes.
  • src/storefront/storefront.controller.ts: current order aliases and checkout.
  • src/repositories/repository.controller.ts: query envelope, partial updates and guarded account deletion.
  • src/chat/chat.gateway.ts: socket authentication, session identifiers and configured routing.

Keep these guides focused on client behavior. Use the maintained AppEngine API reference for current business payloads and sequences rather than copying a frozen endpoint inventory into every application.