Collaborative project with Canadian Museums · Summer 2025
A full-stack web platform that brings museum collections to life through an AI chatbot named "Eve" — with tiered subscriptions, invite-only access, and a multilingual interface across 15 languages.
🔗 Live: Deployed on Render | Chatbot backend: Deployed on Hugging Face Spaces (NitinMoturu/maiseumsChat)
Note: Source code is in a private organizational repository. Code available upon request.
mAIseums gives museum visitors a conversational AI guide — "Eve" — that can answer questions about artworks and collections from the Prado, National Gallery of Art, and Art of Genome datasets. Visitors access Eve through a tiered subscription model, with usage limits enforced per tier. Museum administrators control access through an invite-only approval flow.
I built the entire web platform (Node.js backend, frontend, and all integrations). My teammate built the RAG chatbot backend independently, which I integrated via the Gradio API.
Backend architecture
- Designed and built the full Node.js + Express server from scratch
- Implemented all routes: auth, subscription management, chat, admin, invite flow
- Built session management using Firebase Auth + secure HTTP-only session cookies
- Enforced daily prompt limits per subscription tier in server-side middleware
- Connected to the RAG chatbot by integrating the
@gradio/clientlibrary to call the Hugging Face Space API on each chat request
Payments
- Integrated Stripe Checkout for subscription purchases across all three paid tiers
- Integrated Stripe Customer Portal for self-serve subscription management and cancellations
- Handled Stripe webhooks to sync subscription state back to Firestore
Access control & email
- Built the invite-only access system: request form → admin approval → invite email sent via Nodemailer
- Implemented the full email flow: invite emails, welcome emails, and account notifications
Frontend
- Built all EJS templates: landing page, dashboard, chat UI, admin panel, pricing page
- Implemented multilingual UI using i18next across 15 languages
- Designed the 4-tier subscription UX (Explorer → Curator → Visionary → Platinum)
Infrastructure
- Deployed the full platform on Render
- Configured Firestore collections for users, conversations, invites, and subscription state
┌─────────────────────────────────────────────────────────┐
│ VISITOR BROWSER │
│ EJS Templates + i18next (15 languages) │
│ │
│ Landing · Chat UI · Dashboard · Pricing · Admin Panel │
└──────────────────────┬──────────────────────────────────┘
│ HTTP + Session Cookie (Firebase Auth)
▼
┌─────────────────────────────────────────────────────────┐
│ NODE.JS + EXPRESS SERVER │
│ (Render) │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ MIDDLEWARE │ │
│ │ Firebase Auth verification · Tier enforcement │ │
│ │ Daily prompt limit check · Session handling │ │
│ └────────────────────┬────────────────────────────┘ │
│ │ │
│ ┌────────────────────▼────────────────────────────┐ │
│ │ ROUTES │ │
│ │ /auth /chat /subscribe /admin /invite │ │
│ └────┬──────────┬─────────────┬───────────────────┘ │
└───────┼──────────┼─────────────┼────────────────────────┘
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────┐ ┌──────────────────────────────┐
│ Firestore │ │ Stripe │ │ Hugging Face Space │
│ │ │ │ │ (Teammate's RAG pipeline) │
│ users │ │Checkout│ │ │
│ convos │ │Portal │ │ ChromaDB + Sentence- │
│ invites │ │Webhooks│ │ Transformers + DeepSeek v3 │
│ sub state │ │ │ │ via @gradio/client │
└────────────┘ └────────┘ └──────────────────────────────┘
▲
Gradio API call
(query + conversation context)
| Tier | Price | Daily Prompts | Notes |
|---|---|---|---|
| Explorer | Free | 5 | Guest access, no account required |
| Curator | $8/mo | 20 | Basic subscription |
| Visionary | $59/mo | 35 | Advanced access |
| Platinum | $175/mo | 50 | Full access |
Limits are enforced server-side on every chat request — not just in the UI.
| Layer | Technologies |
|---|---|
| Backend | Node.js, Express |
| Frontend | EJS templating, CSS |
| Database | Firestore (Google Cloud) |
| Auth | Firebase Authentication + session cookies |
| Payments | Stripe Checkout + Customer Portal + Webhooks |
| Nodemailer (invite flow, notifications) | |
| i18n | i18next (15 languages) |
| AI Integration | @gradio/client → Hugging Face Space |
| Deployment | Render (web platform), Hugging Face Spaces (chatbot) |
The AI chatbot "Eve" is powered by a separate RAG pipeline built and deployed by my teammate on Hugging Face Spaces.
Pipeline:
- Loads ~130MB of museum data (Prado, National Gallery of Art, Art of Genome)
- Embeds documents using
all-MiniLM-L6-v2(384-dimensional vectors) into ChromaDB - On each query: retrieves the top-5 semantically similar documents
- Sends query + context to DeepSeek Chat v3 (via OpenRouter API) with a persona prompt defining Eve
- Returns grounded, context-aware responses
My backend calls this pipeline via the Gradio API on every chat request, passing the user's message and receiving Eve's response to display in the chat UI.
- Firebase Auth + server-side session cookies over client-side token storage — more secure for a subscription product where access control matters
- Stripe webhooks for subscription sync — subscription state in Firestore is updated via webhook events, not just at checkout, so cancellations and failures are handled correctly
- Server-side prompt limit enforcement — daily limits are checked in middleware before the Gradio API call, preventing tier bypass through direct API requests
- Gradio API abstraction — the chatbot integration is isolated in a single service module, making it easy to swap the underlying AI backend without touching the rest of the application
Visitor requests access
│
▼
Admin receives notification
│
Approve / Deny
│
▼ (approved)
Nodemailer sends invite link
│
▼
Visitor creates account via Firebase Auth
│
▼
Session cookie issued → access granted
Source code available upon request.