Features¶
This lists what the code actually implements today. AIM GOLD is mid-build: account, browsing, product (physical-jewellery) orders, and SIP creation are wired end-to-end; digital gold buy/sell settlement is gated off across all clients, and KYC has no live provider. Each section says what works and what is a stub.
Terminology: "gated" = hidden behind a feature flag that is currently off; "stub" = a screen/endpoint that exists but does nothing real yet.
Customer backend (aim-digigold-real/apps/api)¶
Live, JWT-protected REST API under /v1. Full endpoint list in the
API Reference. Working capability groups:
- Auth — phone OTP login (SMS via alots.in), JWT access + rotating refresh
tokens (
sessionstable), server-side MPIN, device-bound biometric tokens, session list/revoke. - Users — profile get/update, account-deletion request/confirm/status (OTP-confirmed, real soft-delete).
- Price — public live gold price (
GET /v1/price/current) + socket.io/pricebroadcast. - Portfolio — holdings summary and paginated history (passbook/statement endpoints return 501, not built).
- Orders — digital-gold buy/sell/SIP order creation with idempotency, SafeGold verify/confirm, Razorpay payment intents, webhook confirmation. SIP creation is fully live; one-off buy is wired but depends on Razorpay keys being configured.
- Products / product-orders — jewellery catalogue and Cash-on-Delivery orders (this is the shopping path that fully works today).
- Transactions, notifications, referrals — unified transaction feed, notification records (delivery handoff is a TODO), referral codes.
- KYC — submit + status with encrypted PII; Aadhaar-OTP endpoints return 501; webhook receiver verifies HMAC but does not yet parse events.
- Payments / payouts — Razorpay + RazorpayX with HMAC-verified webhooks.
Admin backend (aim-digigold-real/apps/admin-api)¶
Live REST API under /v1, global JWT + role guard (SUPER_ADMIN > ADMIN >
SUPPORT). Modules: dashboard, users, KYC review, orders, product-orders,
products, payouts, price config/override, reports, config (feature flags,
limits, CMS banners — stored in Redis), audit log, transactions, and
devops (Build Tools — see below). Full list in the
API Reference. Seed the first admin with
npm run seed:admin.
Admin portal (digigold-admin)¶
Next.js app at admin.aimgold.org. Role-gated sidebar
(lib/permissions.ts); browser never holds the API token — server routes
proxy and inject it (app/api/proxy/[...path]/route.ts).
- Dashboard — AUM/GMV/user-growth metrics and a live price ticker; header buttons for View Monitoring (opens Grafana) and Build Tools.
- Operational pages — users, KYC queue, orders, product-orders, products, transactions, payouts, price, reports, config, audit (each backed by the matching admin-api module).
- Build Tools (
/build-tools) — lists recent GitHub Actions runs per target (backend/website/admin-portal/monitoring), polling every 10 s, with Deploy buttons (SUPER_ADMIN only) that callPOST /v1/devops/deploy. This is how a deploy is triggered from the UI. - View Monitoring — external link to
monitor.aimgold.org(Grafana).
Website (aimgold-website)¶
React SPA at aimgold.org, guest-browsable (no route requires login; pages
needing data just fail for guests). Route table in src/App.tsx.
Working: home dashboard, onboarding, OTP+MPIN auth (MPIN verified
client-side against a stored hash), live gold rate, SIP creation
(POST /v1/gold/sip), transactions/passbook, full shop (catalogue,
product detail, cart, COD checkout, my orders), profile + edit
(name/email persist), referral code display, legal/policy pages, contact
(mailto), an offline FAQ chatbot.
Stubs / gated (feature flags in src/config/company.ts, all off):
digital-gold payment (Quick Savings' final "Continue" is a coming-soon
toast), sell/redeem (coming-soon page), silver (disabled), KYC (placeholder
screens), server-side account deletion (local wipe + emailed request),
biometric (native-only), bank accounts, notifications, historical price
charts. The code has an explicit "no fabricated data" convention — Home and
Portfolio show ₹— placeholders instead of fake balances because no
holdings endpoint is called.
Unused in the shipped build: src/pages/SplashPage.tsx,
src/components/LineChart.tsx.
Mobile app (aimgold_app)¶
Flutter app, three flavors (development/staging/production →
lib/flavor_config.dart), go_router navigation, fully server-backed auth
(OTP → tokens, MPIN set/verified server-side, optional biometric via a
server-issued token). API base is host-root; DioClient appends /v1.
Working: OTP sign-in (with Play Services phone hint), MPIN setup/unlock,
biometric enrollment/unlock, complete-profile step, home dashboard, live
price, portfolio (server truth, zero renders honestly), passbook,
transactions, shop + cart + COD checkout, my-orders, KYC status (read),
profile + account edit, support tickets (/v1/support/tickets),
manage devices / sessions, Google-Play-compliant account deletion
(OTP + typed "DELETE", server-confirmed), legal pages.
Gated / stub: buy/sell/SIP are behind the compile-time
FeatureFlags.digiGoldTransactionsEnabled (--dart-define, defaults false
so shipped builds are safe) — blocked at both UI and repository layers;
price-trend charts use hardcoded series (only the headline rate is live);
/price socket screen, notifications, bank accounts, referral, and the KYC
capture steps are placeholders.
Notable gaps to know: socket_io_client and Firebase
(firebase_core/messaging/analytics) are declared in pubspec.yaml but
no Dart code imports them — the live-socket price feed and push
notifications are not wired (price is HTTP polling). The SIP data source in
DI is an offline mock, but it is unreachable because the feature flag
fail-closes before it. Startup gates on server /v1/config + /v1/features
(maintenance / min-version / server banner) exist, but screens still gate on
the compile-time flag rather than the runtime digigold_transactions_effective
value. Contract tests (test/integration/nestjs_contract_test.dart and
siblings) pin client models to the NestJS API shapes.
Deploy & CI/CD (deploy/, .github/workflows/)¶
Push to main → GitHub Actions build → GHCR → SSH pull-deploy to the VPS,
with a pg_dump backup and TypeORM migrations on backend deploys. Triggerable
from the admin portal's Build Tools page. Details in
Architecture.
Monitoring (monitoring/)¶
Grafana + Prometheus + Loki + Tempo + Alloy on the VPS at
monitor.aimgold.org. Prometheus scrapes both NestJS apps' /v1/metrics;
Alloy ships all container logs to Loki. Dashboards are provisioned from git.
Parked: Go backend (aim-gold-backend) — NOT deployed¶
A complete, well-tested Go 1.25 + Fiber re-implementation of the backend
(auth, users, KYC, orders, payments, payouts, quotes, immutable ledger, admin
RBAC, provider abstraction, background workers, embedded migrations, ~45 test
files). It is provider-independent and fail-closed: every money-moving
endpoint returns FEATURE_NOT_ENABLED until DIGIGOLD_TRANSACTIONS_ENABLED
is set and a real provider is configured. Nothing in deploy/ or CI
references it. It mirrors the NestJS consumer API's module set and folds the
admin API into /api/v1/admin/*. See ADR
0012 and its own 11 topic docs.