NG Chat Backend
Auth, credits and chat history for NG Assistant
Backend architecture for the chatbot: a Go gateway for auth, rate limits and credits; FastAPI only answers and stores history; Supabase Postgres split into per-service schemas. Unregistered guests can chat within limits.
- Role
- Founder – system architecture, database design
- Year
- 2026
- Status
- In progress
Source lives in the ngaiplatform GitHub organisation (private).

01The idea
Problem
The chatbot serves registered users, web guests and people messaging via Facebook, Zalo and Telegram – it needs fair, abuse-resistant limits without double charging.
Insight
Everyone who chats is an 'account', registered or not; signing up only upgrades the plan without losing history.
Solution
A unified accounts table for all three user types, a daily-plus-balance credit wallet, a ledger preventing double charges by request_id, and SQL functions that consume/refund safely under concurrency.
Built for
- NG Assistant users
- The NG engineering team
Goals
- Guests: 10 credits/day; registered: 50; Pro: 1,000.
- Each service sees only its own data.
- No negative balances, no double charges.
02Features
- 01
Unified accounts
registered, guest (anonymous sign-in), channel (Facebook, Zalo, Telegram) in one table.
- 02
Credit wallet and ledger
Vietnam-day quota + purchased balance; pricing by message type: text 1, image 3, video 10.
- 03
Per-service privileges
svc_gateway uses only core, svc_chat only chat; the frontend has no direct access.
- 04
Chat history
Conversations, messages and attachments in a private bucket; new messages bubble conversations to the top.
03Design & decisions
Go for the gateway, Python for AI
Why: Go is light and handles high concurrency for auth and limits; AI libraries live almost entirely in Python.
One database, many schemas
Why: Chat history needs foreign keys to accounts; one database, separate schemas and database roles per service.
Split by environment, not service
Why: Two Supabase projects: dev and prod; the develop branch deploys to dev, main to prod.
04Architecture
01
Entry
- Web/app (Supabase JWT), Facebook/Zalo/Telegram webhooks
02
Go gateway
- Auth, rate limiting (Redis), credits, request_id
03
FastAPI
- Answers and stores history only – not public
04
Supabase
- auth · core · chat · storage
05Tech stack
Services
- Go
- Python · FastAPI
- Redis
Data
- Supabase Postgres
- PL/pgSQL
- Supabase Auth (anonymous, email, Google)
- Supabase Storage
Infrastructure
- Google Cloud Run
- Cloud SQL (so sánh)
- Vercel
- Cloudflare
06Research
Node.js or Go
Business APIs suit TypeScript shared with the front-end; IoT and high-connection gateways suit Go; AI stays in Python.
Storing sensor data
Cloud SQL doesn't support TimescaleDB – use time-partitioned tables and push to BigQuery for heavy analytics.
Data residency
Decree 53/2022 and Law 91/2025 regulate storing and transferring user data – legal advice needed; Supabase can be self-hosted on a Vietnamese cloud if required.
07Results
- tables across 2 schemas
- 11
- business SQL functions
- 4
- concurrent requests → exactly 10 charged
- 30 → 10
- double charges on retry
- 0
- Tested on real PostgreSQL: daily quotas, day rollover, refunds, guest → registered keeping history, two-service privileges.
08Demo & gallery
Demo video coming soon
09Lessons
Lessons
- “Double-charge protection belongs in the database (unique request_id, wallet row locks) – never trust the client.”
- “Getting the data model right early saves more than any later optimisation.”
Next steps
- Write the Go gateway and FastAPI service.
- Zalo OA and Telegram bot channels.
- Credit purchases.