Skip to main content

Store Architecture Guide

Audience: Engineers and architects designing a Dr Green-backed storefront. This document explains the complete moving parts so you can decide where each piece of your store lives.

The big picture


Components and ownership

Owned by you (the store builder)

  • Store UI — the storefront the customer sees. Web, mobile, both. Yours.
  • Store backend — your service that calls Dr Green’s API on behalf of the customer. Keeps your own customer DB, cart/order state, polling jobs.
  • Customer DB — typically you mirror Dr Green’s clients/orders records to your own DB so you can render fast (don’t hit Dr Green for every page load). Keep it lean: store IDs, status, last-known shape; don’t duplicate PII unless you have a clear retention reason.
  • Polling infrastructure — background jobs that periodically check order/KYC status and notify customers of changes.

Owned by Dr Green

  • API backend (api.drgreennft.com) — NestJS, Postgres, behind Envoy proxy
  • Auth — both the DAPP UI’s JWT auth flow and your API-key signature flow
  • Catalogue & inventory — the strain catalogue, country-availability, pricing
  • Order fulfilment — admin approval, payment processor integration, dispatch
  • KYC integration — the FirstAML relationship and case management
  • Smart-contract integration — NFT ownership, on-chain commission settlements
  • Email — transactional emails to customers (KYC, order updates)

Owned by third parties

  • FirstAML — KYC/AML verification (customer interacts directly with their portal)
  • CoinRemitter — crypto payment gateway
  • Payinn / PGPay — fiat payment gateways
  • Sumsub ❌ — not used. (Older versions of these docs incorrectly listed Sumsub as the KYC provider; that was based on a mis-read of the codebase. The provider is FirstAML.)

Data flows in detail

Read flow (browsing the catalogue)

Caching: Catalogue changes infrequently. Cache strain lists in your backend for 5 minutes per (countryCode, page, limit) cache key. Cache strain detail for 10 minutes per strainId. Drop on 404.

Write flow (customer onboarding)

Order lifecycle flow

See order-lifecycle.md for the detailed version.

Where to put which logic


Auth boundaries

Three auth layers, each with their own use cases:
  1. No auth — public endpoints (/auth/nonce, /public/healthStatus, customer-facing KYC/payment redirects)
  2. JWT — used by the DAPP UI when the holder is logged in. Generated via wallet sign-in. Required for /keys/*, /user/me, /dapp/users/nfts. Store builders do not have a JWT — they have the API key pair the holder generated using their JWT.
  3. API-key + signature — used by stores. Long-lived (no expiry, no refresh), per-NFT scope, signed per-request with ECDSA secp256k1.
The DualAuthGuard on /dapp/* routes accepts either JWT or API-key+signature — meaning the same endpoints serve the DAPP UI and external stores.

Scoping: per-NFT, per-key

Every API key pair is scoped to one primary NFT. If a holder owns multiple NFTs and runs separate businesses for each:
  • Generate one key pair per NFT
  • Treat them as separate stores in your code (or as separate accounts in your multi-tenant setup)
  • Don’t try to “swap NFTs” mid-session — switching primary NFT is a DAPP-UI-only operation, and doing it from your store would corrupt your in-flight state
Your nft.tokenId from any authenticated response tells you which NFT the current key is scoped to. Cache it on first call; verify on startup if you’ve encoded NFT-specific config.

Network topology

Production

  • API base: https://api.drgreennft.com/api/v1
  • TLS enforced
  • Reverse proxy: Envoy (production deployment)
  • The OpenAPI spec is publicly accessible at /api-json

Staging

  • API base: https://stage-api.drgreennft.com/api/v1
  • ⚠️ Currently HTTP 503 (Envoy upstream connect error) — has been since at least 8 May 2026. If you need staging access, contact Dr Green.

Your topology (recommendations)

  • Outbound from your backend → Dr Green: stable IPs are not currently required by Dr Green, but expect this to change. If your hosting rotates IPs, talk to Dr Green about IP allow-listing if/when they enforce it.
  • No customer-browser → Dr Green calls. Your backend is the proxy. CORS-allowed origins are limited; call from server-side only.
  • Outbound to FirstAML, payment processors: none. You do not call these directly. All third-party integrations are Dr Green’s domain.

Operational concerns

Rate limits

Not enforced as of 10 May 2026, but engineer politely:
  • ≤ 1 req/sec per holder for background polling
  • Cache the catalogue aggressively (5–60 min TTLs)
  • Use /dapp/orders/recent as a heartbeat across all customers rather than polling each one

Failure modes you must handle

Observability

For every Dr Green API call, log:
  • HTTP method, path, status code
  • Response time
  • Your generated correlation ID (for cross-service tracing)
  • Truncated x-auth-apikey (first 16 chars) for key-rotation diagnostics
Don’t log:
  • Full secretKey ever
  • Customer KYC fields (DOB, ID numbers, medical record content)
  • Full x-auth-signature headers (verbose; useful only for very specific debugging)

Multi-tenant store builders

If you operate stores for multiple holders (e.g. you sell a SaaS that wraps Dr Green):
  • Store each holder’s (apiKey, secretKey) pair encrypted-at-rest, indexed by your tenant ID
  • Cache the resolved nft.tokenId per tenant for routing/scoping
  • Use a separate DAPP-Green API client instance per tenant (don’t share the long-lived signing key across requests)
  • Implement bulk operations carefully — a 1000-tenant batch poll without jitter will create thundering herds

Anti-patterns to avoid


Where to next