🍽️ 多租户AI餐厅系统
一个由人工智能驱动的生产就绪的多租户餐厅点餐系统,使用Next.js 16、PostgreSQL和Cerebras AI构建。
🌟 特性
- 🏢 多租户 -从一个代码库运行多个餐厅品牌
- 🤖 AI服务员 -用于菜单查询、订单和预订的智能聊天机器人
- 🎨 动态品牌 -每家餐厅都有独特的主题和个性
- 👥 并发用户 -处理无限的同时客户
- 🔐 安全认证 -基于JWT的租户隔离身份验证
- ⚙️ 可配置AI -每个餐厅都可以轻松定制AI行为
- 👨🍳 厨师代理 -通过A2A协议在5555端口上提供单独的厨房服务
- ⚡ 快速性能 -由Cerebras(骆驼3.1-8b)提供动力
______________________________________________________________________
🏗️ 建筑
技术栈
- 前端: Next.js 16,React 19,顺风CSS
- 后端: Next.js API路线
- 数据库: PostgreSQL与租户隔离
- AI提供商: 大脑AI(calla3.1-8b)
- 认证: JWT+HTTP专用Cookie
- 多租户: 基于环境+数据库
tenant_id
多租户设置
Waiter Agent (Port 4444)
├─ pistahouse.waiter.local:4444 │ chutneys.waiter.local:4444
├─ Red theme (#DC2626) │ Green theme (#16A34A)
├─ Hyderabadi cuisine │ South Indian cuisine
├─ Non-veg specialist │ Pure vegetarian
└─ Energetic tone │ Calm, friendly tone
Chef Agent (Port 5555)
├─ pistahouse.chef.local:5555 │ chutneys.chef.local:5555
└─ Kitchen Display System │ Order management______________________________________________________________________
👥 多用户并发如何工作
会话隔离
每个用户都会获得一个唯一的JWT令牌,该令牌存储在仅支持HTTP的cookie中:
User A → Cookie: "auth_token_pista-house=eyJ...ABC123"
User B → Cookie: "auth_token_pista-house=eyJ...XYZ789"
User C → Cookie: "auth_token_pista-house=eyJ...DEF456"无状态请求处理
User A sends message
↓
Next.js Server
├─ Request 1 (User A) → Validate JWT → Process → Response A
├─ Request 2 (User B) → Validate JWT → Process → Response B
└─ Request 3 (User C) → Validate JWT → Process → Response C
↓
All processed concurrently, no interference!为什么它有效
✅ 无状态设计 -每个请求都是独立的\ ✅ JWT代币 -每个用户的唯一标识符\ ✅ HTTP隔离 -请求不共享内存\ ✅ PostgreSQL -本机处理并发查询\ ✅ Next.js -专为并发请求处理而构建
是什么让它具有可扩展性
- 用户之间没有共享内存
- 服务器上没有对话状态
- 无全局变量
- 数据库自动处理并发
结果: 支持 无限并发用户 零冲突! 🚀
______________________________________________________________________
🚀 快速开始
先决条件
- Node.js 18+和pnpm
- PostgreSQL数据库
安装
# Install dependencies
pnpm install
# Set up database
psql -h localhost -U postgres -d demo -f src/lib/db/migrations/001_initial_schema.sql
# Seed data
psql -h localhost -U postgres -d demo -f src/lib/db/seed-tenants.sql
psql -h localhost -U postgres -d demo -f src/lib/db/seed-menu-items.sql
psql -h localhost -U postgres -d demo -f src/lib/db/seed-restaurant-config.sql
# Configure environment
cp env.pista-house.template .env.pista-house
cp env.chutneys.template .env.chutneys
# Add your API keys
# Edit both .env files and add:
# - CEREBRAS_API_KEY
# - GOOGLE_API_KEY (optional fallback)
# Run waiter agent
pnpm dev为多租户设置主机
增添 /etc/hosts:
127.0.0.1 pistahouse.waiter.local
127.0.0.1 chutneys.waiter.local
127.0.0.1 pistahouse.chef.local
127.0.0.1 chutneys.chef.local访问应用程序
服务员代理(4444端口):
- 违约:http://localhost:4444
- 皮斯塔之家:http://pistahouse.waiter.local:4444
- 酸辣酱:http://chutneys.waiter.local:4444
厨师代理(端口5555):
- 违约:http://localhost:5555/kitchen
- 皮斯塔之家:http://pistahouse.chef.local:5555/kitchen
- 酸辣酱:http://chutneys.chef.local:5555/kitchen
______________________________________________________________________
⚙️ 配置
餐厅设置(数据库驱动)
每个租户都可以通过设置页面自定义他们的AI:
餐厅配置:
- 餐厅描述
- 菜肴类型
- 运行时间
- AI语气/个性
- 特别说明
- 服务/功能
示例(Pista House):
Cuisine: Hyderabadi & North Indian
Tone: Warm, energetic, proud of heritage
Instructions: Always recommend Haleem if in season
Specialties: Biryani, Kebabs, Rich gravies示例(酸辣酱):
Cuisine: 100% Pure Vegetarian - South Indian
Tone: Polite, calm, family-friendly
Instructions: Never suggest meat, highlight 7 Chutneys
Specialties: Dosas, Idlis, Filter CoffeeAI提供者配置
当前: 大脑AI(calla3.1-8b)
- 超快速推理
- 慷慨的免费套餐
- 比Gemini更好的配额
退路: 谷歌双子座
- 集
AI_PROVIDER=google在.env中 - 需要
GOOGLE_API_KEY
______________________________________________________________________
📊 数据库模式
关键表
-- Multi-tenancy
tenants (id, name, slug, domain)
users (id, tenant_id, name, email, phone)
sessions (id, user_id, token, expires_at)
-- Restaurant Data
menu_items (id, tenant_id, name, price, category)
orders (id, tenant_id, table_id, items, status)
reservations (id, tenant_id, guest_name, party_size)
-- Configuration
settings (tenant_id, key, value, value_type)
menu_categories (id, tenant_id, name, display_order)租户隔离
所有查询包括 tenant_id 过滤:
await repo.getAllMenuItems(tenantId);
await repo.createOrder(tenantId, orderData);______________________________________________________________________
🤖 AI功能
菜单查询工具
Customer: "show me the menu"
AI calls: queryMenu() with no filters
Returns: Full menu grouped by category with prices智能功能:
- 无参数=完整菜单
- 可选过滤器:搜索、类别、饮食
- 为清楚起见,按类别分组
- 带有表情符号指示符号的清晰定价(🥬 蔬菜,🍖 非蔬菜)
订单管理
Customer: "I want biryani and kebab roll"
AI:
1. Calls queryMenu("biryani") → Gets item ID
2. Calls queryMenu("kebab") → Gets item ID
3. Confirms order with customer
4. Calls placeOrder(items, tableId)
5. Returns order confirmation with ETA预订系统
Customer: "Book table for 4 at 7pm"
AI:
1. Calls manageReservation(create)
2. Checks availability
3. Confirms guest details
4. Returns confirmation______________________________________________________________________
🎨 品牌和主题
动态主题
每个租户都有一个存储在数据库中的唯一颜色:
settings (tenant_id='pista-house', key='theme_color', value='#DC2626')
settings (tenant_id='chutneys', key='theme_color', value='#16A34A')通过CSS变量应用:
document.documentElement.style.setProperty('--color-primary', themeColor);所有UI组件都使用: bg-[var(--color-primary)]
______________________________________________________________________
🔒 安全
身份验证流程
1. User registers/logs in
2. Server creates JWT token with:
- user_id
- tenant_id
- expiration (7 days)
3. Token stored in HTTP-only cookie
4. All API requests validate token
5. Session checked against database租户验证
// Every API route validates tenant
const session = await validateSession(token);
if (session.tenant_id !== process.env.TENANT_ID) {
return 401 Unauthorized;
}Cookie安全
- 仅限HTTP(无JavaScript访问)
- 安全(仅在生产环境中使用HTTPS)
- SameSite=Lax(CSRF保护)
- 租户特定名称(无冲突)
______________________________________________________________________
📈 演出
优化
- 遥测跟踪 -监控AI性能
- 温度控制 -0.7用于平衡响应
- 智能缓存 -AI提供者上缓存的系统提示
- 分组查询 -高效的菜单显示
响应时间
- 菜单查询:~200ms
- 下订单:~400ms
- AI响应:~1-2s(流媒体)
______________________________________________________________________
🧪 测试
多租户测试
# Test Pista House
curl http://pistahouse.waiter.local:4444/api/menu
# Test Chutneys
curl http://chutneys.waiter.local:4444/api/menu
# Test Chef Agent
curl http://localhost:5555/api/a2a
# Verify isolation - should be different!并发用户测试
# Open 3+ browser tabs
# Login different users
# Send messages simultaneously
# All should work independently______________________________________________________________________
🚢 部署
环境变量(每个租户)
# Required
TENANT_ID=tenant-pista-house
TENANT_NAME="Pista House"
DB_HOST=localhost
DB_NAME=demo
JWT_SECRET=your-secret-key
CEREBRAS_API_KEY=your-key
# Optional
AI_PROVIDER=cerebras
AI_MODEL=llama3.1-8b
GOOGLE_API_KEY=fallback-key生产清单
- ✅ 设置唯一
JWT_SECRET每位租户 - ✅ 使用特定于环境的数据库
- ✅ 为Cookie启用HTTPS
- ✅ 设置正确的CORS标头
- ✅ 配置速率限制
- ✅ 设置监控/记录
______________________________________________________________________
📚 项目结构
src/
├── app/
│ ├── api/
│ │ ├── auth/ # Login, register, logout
│ │ ├── chat/ # AI conversation endpoint
│ │ ├── menu/ # Menu CRUD
│ │ ├── settings/ # Restaurant config
│ │ └── theme/ # Dynamic theming
│ ├── admin/ # Admin dashboard
│ └── agent/ # Customer chat interface
├── lib/
│ ├── db/
│ │ ├── postgres.ts # Database client
│ │ └── migrations/ # SQL schema files
│ ├── repository/ # Data access layer
│ │ ├── auth.ts
│ │ └── restaurant.ts
│ └── utils/ # Helper functions
└── components/ # React components
├── ai-elements/ # Chat UI
├── auth/ # Auth components
└── layout/ # Layout components______________________________________________________________________
🤝 贡献
添加新租户
- 创建环境文件:
env.new-restaurant.template - 添加数据库种子:
INSERT INTO tenants... - 种子菜单项和配置
- 更新
package.json脚本:dev:new-restaurant - 增添
dev:all并发启动脚本
______________________________________________________________________
📝 许可证
MIT许可证-有关详细信息,请参阅许可证文件
______________________________________________________________________
🙏 致谢
- AI SDK 通过Vercel
- 大脑 用于快速AI推理
- PostgreSQL 用于可靠的数据存储
- Next.js 令人惊叹的框架
______________________________________________________________________
📞 支持
对于问题或疑问,请打开GitHub问题或联系开发团队。
______________________________________________________________________
内置于❤️ 餐饮业
