Add customer-facing features: customer accounts, order history, email verification, MFA, and invoice generation for tax deduction.
Separate from User (restaurant owners). Customers are end-users who place orders.
Fields:
id(Primary Key)email(Unique, indexed)hashed_passwordfull_namebusiness_name(Optional - for invoice generation)tax_id/vat_number(Optional - for invoice generation)address(Optional - for invoice generation)phone(Optional)email_verified(Boolean, default=False)email_verification_token(UUID, nullable)email_verification_sent_at(DateTime, nullable)mfa_enabled(Boolean, default=False)mfa_secret(String, nullable - TOTP secret)mfa_backup_codes(JSON array, nullable - backup codes)created_at(DateTime)updated_at(DateTime)
Add optional customer link (backward compatible with table-only orders).
New Fields:
customer_id(Foreign Key to Customer, nullable, indexed)- Keep existing
table_id(for backward compatibility)
For generated invoices.
Fields:
id(Primary Key)customer_id(Foreign Key to Customer)order_id(Foreign Key to Order)invoice_number(String, unique - e.g., "INV-2026-001")issue_date(DateTime)due_date(DateTime, nullable)subtotal_cents(Integer)tax_cents(Integer)total_cents(Integer)currency(String)status(Enum: draft, sent, paid, cancelled)pdf_filename(String, nullable - stored file)notes(Text, nullable)created_at(DateTime)
Or use simple token in Customer model (simpler approach chosen above).
POST /customer/register- Email, password, full_name
- Send verification email
- Return: customer_id, email (unverified status)
-
GET /customer/verify-email?token={verification_token}- Verify token and mark email as verified
- Return success/error
-
POST /customer/resend-verification- Resend verification email (rate limited)
POST /customer/token(separate from restaurant owner login)- Email + password
- Check email_verified (optional - can allow unverified login with warning)
- Return JWT token with customer_id (not tenant_id)
-
POST /customer/mfa/setup- Generate TOTP secret
- Return QR code data URL and backup codes
- Mark MFA as enabled after verification
-
POST /customer/mfa/verify- Verify TOTP code during login
- Return new token if verified
-
POST /customer/mfa/disable- Disable MFA (requires password confirmation)
-
POST /customer/mfa/backup-codes- Regenerate backup codes
get_current_customer()dependency- Similar to
get_current_user()but for customers - JWT contains customer_id instead of tenant_id
- Similar to
- Update
POST /menu/{table_token}/orderto optionally accept customer token - If customer is logged in, link order to customer
- Maintain backward compatibility (table-only orders still work)
-
GET /customer/orders- List all orders for authenticated customer
- Filter by status, date range
- Include order details, items, totals
-
GET /customer/orders/{order_id}- Get specific order details
POST /customer/orders/{order_id}/invoice- Generate invoice for a paid order
- Create Invoice record
- Generate PDF invoice
- Store PDF in uploads/customers/{customer_id}/invoices/
- Return invoice details + download URL
-
GET /customer/invoices- List all invoices for customer
- Filter by date, status
-
GET /customer/invoices/{invoice_id}- Get invoice details
-
GET /customer/invoices/{invoice_id}/download- Download PDF invoice
- Use library like
reportlaborweasyprint - Include:
- Invoice number
- Customer business details (if provided)
- Order details (items, quantities, prices)
- Tax breakdown
- Total amount
- Issue date
- Restaurant/business details (from Tenant)
- Add email service (SMTP or service like SendGrid/Mailgun)
- Configuration in
config.env:SMTP_HOSTSMTP_PORTSMTP_USERSMTP_PASSWORDEMAIL_FROM
- Email verification
- MFA setup confirmation
- Invoice ready notification
- New routes:
/customer/register,/customer/login - Separate from restaurant owner auth
- Order history
- Invoice list
- MFA settings
- Profile settings (business info for invoices)
- Invoice detail page
- PDF viewer/download
# MFA/TOTP
pyotp>=2.9.0
qrcode[pil]>=7.4.2
# PDF Generation
reportlab>=4.0.0
# OR
weasyprint>=60.0
# Email
aiosmtplib>=3.0.0 # For async email
# OR use external service SDK- Create migration for Customer table
- Add
customer_idto Order table (nullable) - Create Invoice table
- Run migration
- Customer models and authentication
- Email verification
- MFA setup
- Order linking
- Invoice generation
- Customer auth pages
- Customer dashboard
- Invoice management
- Test customer registration/login
- Test email verification
- Test MFA
- Test order linking
- Test invoice generation
- Email Verification: Required before sensitive operations (invoice generation)
- MFA: Optional but recommended
- Rate Limiting: On registration, login, email resend
- Password Requirements: Minimum 8 characters, complexity rules
- JWT Expiration: Shorter for customers (15-30 minutes)
- Invoice Access: Only customer who owns the order can generate invoice
- Data Privacy: Customer data separate from restaurant data
POST /customer/register- Register new customerPOST /customer/token- Customer loginGET /customer/verify-email?token={token}- Verify emailPOST /customer/resend-verification- Resend verification emailPOST /customer/forgot-password- Request password resetPOST /customer/reset-password- Reset password with token
POST /customer/mfa/setup- Setup MFAPOST /customer/mfa/verify- Verify MFA codePOST /customer/mfa/disable- Disable MFAPOST /customer/mfa/backup-codes- Regenerate backup codes
GET /customer/profile- Get customer profilePUT /customer/profile- Update customer profile
GET /customer/orders- List customer ordersGET /customer/orders/{order_id}- Get order details
POST /customer/orders/{order_id}/invoice- Generate invoiceGET /customer/invoices- List invoicesGET /customer/invoices/{invoice_id}- Get invoice detailsGET /customer/invoices/{invoice_id}/download- Download PDF
# Email Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASSWORD=your-app-password
EMAIL_FROM=noreply@yourdomain.com
# Invoice Settings
INVOICE_PREFIX=INV
INVOICE_NUMBER_FORMAT=INV-{year}-{number:04d}- Email Verification: Should customers be able to place orders before email verification, or should it be required?
- MFA: Should MFA be mandatory or optional?
- Invoice Requirements: What information is required for invoices (tax ID, business name, address)?
- Order Linking: Should customers be able to link existing orders (placed before login) to their account?
- Invoice Format: Any specific invoice format requirements or templates?
- Email Service: Prefer SMTP or external service (SendGrid, Mailgun, etc.)?
- PDF Library: Prefer reportlab or weasyprint for PDF generation?
- ✅ Database migrations (Customer, Invoice tables, Order.customer_id)
- ✅ Customer model and authentication endpoints
- ✅ Email verification
- ✅ MFA setup and verification
- ✅ Order linking (optional customer_id)
- ✅ Invoice generation
- ✅ Frontend customer pages
- ✅ Testing
Ready for your review and confirmation before implementation.