Skip to content

Features

This lists what the code actually implements today, and — just as importantly — what is gated on configuration. The backend is feature-complete for its route surface; several money- and identity-touching paths deliberately return errors until their external provider is configured, rather than pretending to work.

Terminology: "gated" = the code path exists but refuses to operate until a credential/config is present; it fails closed, never open.

Backend (aim-backend)

Live, dual-auth REST API under /api/v1. Full endpoint list in the API Reference. Working capability groups:

  • Auth — password register/login, SMS OTP login (auto-creates user + wallet), token refresh, server-side logout/revocation, admin password login (POST /auth/admin/login, rate-limited, uniform 401), OTP email verification (/me/email/send-otp + verify-otp, see the gate below), and an optional reviewer login — a fixed OTP for exactly one configured number (REVIEWER_LOGIN_PHONE / REVIEWER_LOGIN_OTP) so payment-gateway and app-store reviewers can sign in without our SMS; only delivery changes, every gate and limit still applies, and admin accounts are excluded.
  • Referrals — per-user share codes (GET /referrals/my-code), the public /r/:code click-logging Play Store redirect, and attribution-only signup tracking (users.referred_by + referral_attributions; explicit code first, IP-match fallback). No wallet rewards — see ADR 0012.
  • Storefront — public products/categories, server-authoritative quote → order → cancel, paid from the shopping-credits wallet. Products carry an ordered image gallery alongside the single cover image — see ADR 0013. Catalogue images are either uploaded (POST /api/v1/admin/uploads/image, stored content-addressed and served at GET /media/:key) or referenced by URL.
  • Wallet — balance, transactions, claims, daily spin, and the verified top-up flow (see the gate below).
  • Fantasy — Entity Sport sync, contests + templates, teams, live scoring, Redis leaderboards, finalize/void with wallet payouts, pick-one-player sets.
  • Predictions — admin-synced markets plus the user-facing orderbook (place/cancel orders, book, activity, positions).
  • Account deletion — Google-Play-compliant: an unauthenticated OTP-proven web flow and an authenticated in-app flow with eligibility, status, and cancel.
  • Support tickets — user + admin sides; email notification via SMTP when configured.
  • Affiliates — application, KYC upload, stats/earnings, click tracking, admin approval + payouts.
  • Admin — the whole /api/v1/admin/* back office (fantasy ops, catalogue + catalogue-image uploads, gateways, users, orders/refunds/reconciliation, tickets, affiliates, predictions, Entity proxy).
  • Observability/health, Prometheus /metrics (fiberprometheus), OTLP-HTTP traces (otelfiber) when OTEL_EXPORTER_OTLP_ENDPOINT is set.

What is gated, and on what

Capability Gate Behaviour until configured
Website checkout / top-up pages CCAVENUE_* + PHONEPE_* on the payment server payment endpoints return 503; storefront browsing still works (server/index.js logs a warning at boot)
Backend top-up initiate TOPUP_PAGE_BASE_URL POST /wallet/topup-initiate returns 503 — it never routes users to an unconfigured/retired merchant page
Backend top-up credit callback STORE_WEBHOOK_SECRET POST /wallet/topup-credit returns 503 ("callback verification not configured") — credits are impossible without HMAC verification
Top-up status self-heal PHONEPE_CLIENT_ID/SECRET GET /wallet/topup-status/:token can't verify with PhonePe and leaves the top-up pending
OTP login SMS provider (SMS_* vars, alots.in gateway in pkg/sms) OTP send fails with a generic error and the stored OTP is deleted; password auth still works
Fantasy + predictions (whole process) ENTITY_ACCESS_TOKEN the backend exits at boot (mustGetEnv in config/config.go) — this is a hard requirement, not a soft feature flag
Firebase bearer auth FIREBASE_SERVICE_ACCOUNT_PATH only the custom-JWT header works
Ticket emails SMTP_* tickets work; notification emails are skipped
Email verification SMTP_* POST /me/email/send-otp returns 503 {"error":"email_disabled"}; accounts simply stay unverified (email_verified: false)
Referral attribution nothing — always on n/a: share links, click logging, and signup attribution need no external provider (share hosts come from PLAY_STORE_URL / REFERRAL_SHARE_BASE_URL, which have working defaults)
Traces OTEL_EXPORTER_OTLP_ENDPOINT no traces exported; metrics/logs unaffected

Wallet top-up is gateway-verified only — by design

The legacy POST /wallet/topup route credited shopping_credits with no payment, so any logged-in user could mint store currency. The route is intentionally unrouted in routes.go (the handler survives only because the verified gateway callbacks reuse the repo method). Money enters exclusively via topup-initiate → hosted gateway page → verified topup-credit / topup-status. Do not re-add the direct route.

Website (aim-store-website)

React 19 + Vite SPA at aimstoreorg.com, with an Express server (server/index.js, :3001) that serves the built SPA in production and fronts the payment gateways:

  • Storefront — catalogue, search, wishlist, cart, checkout, policies (refund/return/shipping/terms), account deletion page. Product pages show the full image gallery (arrows, thumbnails, arrow-key navigation).
  • Payment plumbing — CCAvenue encrypt/redirect + response handling, PhonePe OAuth + checkout + webhook, and the wallet top-up variants of both, which call the backend's HMAC-verified topup-credit. Deep-links back into the app via the aimstore scheme.
  • GET /api/health reports {status, payments} so you can see the gate state at a glance.

Mobile app (aim-store-app)

Expo SDK 54 / React Native app (expo-router): OTP sign-in, storefront (home, categories, product pages with a swipeable image gallery, cart, checkout), orders + order status, wallet credits + transactions + top-up (via the website's hosted page), rewards/daily spin, gift cards & e-vouchers screens, saved addresses, support, legal pages, and the full Google-Play account-deletion flow. Env files select dev/staging/prod hosts; release builds refuse localhost/HTTP values.

Admin portal (aim-store-admin)

Next.js 14 App Router portal at admin.aimstoreorg.com, port 3002. NextAuth credentials login against the backend's POST /api/v1/auth/admin/login; the browser never holds the API token — server-side routes proxy requests and inject x-sdk-access-token. Operational pages map onto the /api/v1/admin/* modules (dashboard, users, orders/refunds, products, gateways, fantasy ops, tickets, affiliates, predictions), plus a link out to Grafana (NEXT_PUBLIC_MONITORING_URL).

Deploy & CI/CD (deploy/, .github/workflows/)

Push to main → GitHub Actions build → GHCR → SSH pull-deploy to the VPS, with pg_dump + mongodump backups and SQL migrations on backend deploys, and pinned curl --resolve health verification. The Expo app is the exception: it releases through EAS Workflows (aim-store-app/.eas/workflows/), which build and submit to Google Play automatically on merge. Details in Deployment.

Monitoring (monitoring/)

Grafana + Prometheus + Loki + Tempo + Alloy at monitor.aimstoreorg.com. Prometheus scrapes the backend's /metrics; Alloy ships container logs to Loki; Tempo receives the backend's OTLP traces. Dashboards and alert rules are provisioned from git (see ADR 0007).