Extracted from zoo monorepo for independent deployment. Domain: computer.zoo.ngo Deployment: GitHub Pages (GitHub Actions) App Directory: computer
14 KiB
Hanzo.Computer - Leasing Platform MVP Implementation Plan
Overview
Transform Hanzo.Computer from a simple ecommerce site into a complete GPU leasing platform with:
- Customer self-service portal
- Admin order management system
- Request for Quote (RFQ) workflow
- Stripe subscription billing
- Dashboard for tracking orders, quotes, and usage
Phase 1: Legal & Foundation (Completed ✅)
1.1 Legal Pages
- Terms of Service (
/terms) - Privacy Policy (
/privacy) - Integration points: Footer links, checkout flow
Phase 2: Backend API (Core Infrastructure)
2.1 Database Schema
-- Users (extends existing if any)
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
company VARCHAR(255),
stripe_customer_id VARCHAR(255),
role VARCHAR(50) DEFAULT 'customer', -- 'customer', 'admin'
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Request for Quotes
CREATE TABLE rfqs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
company VARCHAR(255),
email VARCHAR(255) NOT NULL,
phone VARCHAR(50),
gpu_type VARCHAR(100), -- 'B300', 'B200', 'H200', 'H100', 'Custom'
quantity INTEGER NOT NULL,
duration_months INTEGER, -- null for one-time purchase
use_case TEXT,
budget_range VARCHAR(100),
additional_requirements TEXT,
status VARCHAR(50) DEFAULT 'pending', -- 'pending', 'reviewing', 'quoted', 'accepted', 'rejected'
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Quotes (sent by admin in response to RFQ)
CREATE TABLE quotes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
rfq_id UUID REFERENCES rfqs(id),
user_id UUID REFERENCES users(id),
quote_number VARCHAR(100) UNIQUE NOT NULL, -- 'Q-2025-001'
items JSONB NOT NULL, -- [{name, description, quantity, unit_price, total}]
subtotal DECIMAL(10,2) NOT NULL,
tax DECIMAL(10,2) DEFAULT 0,
total DECIMAL(10,2) NOT NULL,
payment_terms VARCHAR(255), -- 'Monthly subscription', 'Annual prepaid', etc.
valid_until DATE,
notes TEXT,
status VARCHAR(50) DEFAULT 'sent', -- 'sent', 'viewed', 'accepted', 'expired', 'rejected'
created_at TIMESTAMP DEFAULT NOW(),
accepted_at TIMESTAMP
);
-- Orders (from accepted quotes or direct purchases)
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
order_number VARCHAR(100) UNIQUE NOT NULL, -- 'ORD-2025-001'
user_id UUID REFERENCES users(id),
quote_id UUID REFERENCES quotes(id), -- null for direct purchases
stripe_payment_intent_id VARCHAR(255),
stripe_subscription_id VARCHAR(255), -- for recurring billing
items JSONB NOT NULL,
subtotal DECIMAL(10,2) NOT NULL,
tax DECIMAL(10,2) DEFAULT 0,
total DECIMAL(10,2) NOT NULL,
status VARCHAR(50) DEFAULT 'pending', -- 'pending', 'paid', 'provisioning', 'active', 'cancelled'
payment_method VARCHAR(50), -- 'stripe_card', 'stripe_ach', 'wire_transfer'
billing_cycle VARCHAR(50), -- 'one_time', 'monthly', '6_month', 'annual'
created_at TIMESTAMP DEFAULT NOW(),
paid_at TIMESTAMP,
provisioned_at TIMESTAMP
);
-- Subscriptions (for GPU leasing)
CREATE TABLE subscriptions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
order_id UUID REFERENCES orders(id),
stripe_subscription_id VARCHAR(255) UNIQUE NOT NULL,
stripe_product_id VARCHAR(255),
stripe_price_id VARCHAR(255),
gpu_type VARCHAR(100),
quantity INTEGER,
status VARCHAR(50) DEFAULT 'active', -- 'active', 'cancelled', 'past_due', 'paused'
current_period_start TIMESTAMP,
current_period_end TIMESTAMP,
cancel_at_period_end BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW(),
cancelled_at TIMESTAMP
);
-- Invoices (generated by Stripe or manually)
CREATE TABLE invoices (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
invoice_number VARCHAR(100) UNIQUE NOT NULL, -- 'INV-2025-001'
user_id UUID REFERENCES users(id),
order_id UUID REFERENCES orders(id),
subscription_id UUID REFERENCES subscriptions(id),
stripe_invoice_id VARCHAR(255),
amount_due DECIMAL(10,2) NOT NULL,
amount_paid DECIMAL(10,2) DEFAULT 0,
status VARCHAR(50) DEFAULT 'draft', -- 'draft', 'open', 'paid', 'void', 'uncollectible'
due_date DATE,
paid_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
-- GPU Reservations (what customer actually gets)
CREATE TABLE gpu_reservations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
order_id UUID REFERENCES orders(id),
subscription_id UUID REFERENCES subscriptions(id),
gpu_type VARCHAR(100),
quantity INTEGER,
instance_ids JSONB, -- array of actual server/instance IDs
access_credentials JSONB, -- encrypted connection details
status VARCHAR(50) DEFAULT 'provisioning', -- 'provisioning', 'active', 'suspended', 'terminated'
provisioned_at TIMESTAMP,
expires_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
-- Usage Tracking
CREATE TABLE usage_records (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
gpu_reservation_id UUID REFERENCES gpu_reservations(id),
hours_used DECIMAL(10,2),
compute_units DECIMAL(10,2),
recorded_at TIMESTAMP DEFAULT NOW()
);
-- Admin Actions Log
CREATE TABLE admin_actions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
admin_id UUID REFERENCES users(id),
action VARCHAR(100), -- 'quote_sent', 'order_approved', 'subscription_cancelled', etc.
entity_type VARCHAR(50), -- 'rfq', 'quote', 'order', 'subscription'
entity_id UUID,
notes TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
2.2 API Endpoints
Customer-facing:
POST /api/rfq - Submit request for quote
GET /api/rfq/:id - Get single RFQ
GET /api/rfqs - List user's RFQs
GET /api/quotes - List user's quotes
GET /api/quotes/:id - Get single quote
POST /api/quotes/:id/accept - Accept a quote → create order
GET /api/orders - List user's orders
GET /api/orders/:id - Get single order
POST /api/orders/:id/pay - Pay for order (Stripe)
GET /api/subscriptions - List user's subscriptions
GET /api/subscriptions/:id - Get subscription details
POST /api/subscriptions/:id/cancel - Cancel subscription
GET /api/invoices - List user's invoices
GET /api/invoices/:id/pdf - Download invoice PDF
GET /api/gpu-reservations - List user's GPU reservations
GET /api/usage - Get usage statistics
Admin-only:
GET /api/admin/rfqs - List all RFQs
GET /api/admin/rfqs/:id - Get RFQ with full details
PATCH /api/admin/rfqs/:id - Update RFQ status
POST /api/admin/quotes - Create and send quote
PATCH /api/admin/quotes/:id - Update quote
GET /api/admin/orders - List all orders
PATCH /api/admin/orders/:id - Update order status
POST /api/admin/orders/:id/provision - Provision GPU resources
GET /api/admin/subscriptions - List all subscriptions
POST /api/admin/invoices - Create manual invoice
GET /api/admin/stats - Dashboard statistics
2.3 Stripe Integration
Products to create in Stripe:
// GPU Leasing Products
const products = [
{ name: '8-GPU NVIDIA B300', prices: { monthly: 'contact', annual: 'contact' } },
{ name: '8-GPU NVIDIA B200', prices: { monthly: 34999, annual: 27999 } },
{ name: '8-GPU NVIDIA H200', prices: { monthly: 26499, annual: 21199 } },
{ name: '8-GPU NVIDIA H100', prices: { monthly: 24999, annual: 19999 } },
{ name: 'DGX Spark', prices: { one_time: 4000 } }
];
Stripe Webhooks:
/api/webhooks/stripe
- payment_intent.succeeded
- invoice.paid
- invoice.payment_failed
- customer.subscription.created
- customer.subscription.updated
- customer.subscription.deleted
Phase 3: Customer Portal
3.1 Dashboard Page (/dashboard)
Components:
- Overview cards: Active subscriptions, pending quotes, total spend
- Quick actions: Request quote, view orders, manage subscriptions
- Recent activity timeline
File: src/pages/Dashboard.tsx
3.2 RFQ Submission (/request-quote)
Form Fields:
- Company information (name, email, phone)
- GPU requirements (type, quantity)
- Duration (one-time, monthly, 6-month, annual)
- Use case description
- Budget range (optional)
- Additional requirements
File: src/pages/RequestQuote.tsx
3.3 Quotes List (/dashboard/quotes)
Features:
- List all received quotes
- View quote details
- Accept/reject quote
- Download quote PDF
File: src/pages/customer/Quotes.tsx
3.4 Orders List (/dashboard/orders)
Features:
- List all orders
- Order status tracking
- Download invoices
- View provisioning details
File: src/pages/customer/Orders.tsx
3.5 Subscriptions (/dashboard/subscriptions)
Features:
- Active subscriptions
- Usage statistics
- Cancel subscription
- Update payment method
File: src/pages/customer/Subscriptions.tsx
3.6 Invoices (/dashboard/invoices)
Features:
- List all invoices
- Download PDF
- Payment status
- Pay outstanding invoices
File: src/pages/customer/Invoices.tsx
3.7 GPU Reservations (/dashboard/gpus)
Features:
- Active GPU instances
- Connection details
- Usage metrics
- Start/stop controls (if applicable)
File: src/pages/customer/GPUs.tsx
Phase 4: Admin Dashboard
4.1 Admin Dashboard (/admin)
Overview:
- Pending RFQs count
- Active orders count
- Total revenue (monthly, annual)
- New customers this month
File: src/pages/admin/Dashboard.tsx
4.2 RFQ Management (/admin/rfqs)
Features:
- List all RFQs with filtering (pending, reviewing, quoted)
- View RFQ details
- Update status
- Send quote
File: src/pages/admin/RFQs.tsx
4.3 Quote Builder (/admin/quotes/new)
Features:
- Select RFQ to quote
- Add line items
- Calculate totals
- Set payment terms
- Preview and send
- Stripe product/price selection
File: src/pages/admin/QuoteBuilder.tsx
4.4 Orders Management (/admin/orders)
Features:
- List all orders with filtering
- Order details
- Approve/provision orders
- Update status
- Manual invoice creation
File: src/pages/admin/Orders.tsx
4.5 Subscriptions Management (/admin/subscriptions)
Features:
- Active subscriptions
- Pause/resume subscription
- Cancel subscription
- View payment history
File: src/pages/admin/Subscriptions.tsx
4.6 Customers (/admin/customers)
Features:
- Customer list
- Customer details
- Order history
- Subscription history
- Stripe customer portal link
File: src/pages/admin/Customers.tsx
Phase 5: Email Notifications
Transactional Emails:
- RFQ received confirmation (to customer)
- New RFQ notification (to admin)
- Quote sent (to customer)
- Quote accepted notification (to admin)
- Order confirmation (to customer)
- GPU provisioned (to customer with credentials)
- Invoice due reminder
- Payment successful
- Subscription renewal reminder
- Subscription cancelled confirmation
Email Service: SendGrid or AWS SES
Phase 6: PDF Generation
Documents to generate:
- Quotes (professional PDF with branding)
- Invoices (Stripe-compatible format)
- Order confirmations
Library: pdfkit or react-pdf
Phase 7: Security & Auth
7.1 Authentication
- Email/password with JWT
- OAuth (Google, GitHub) optional
- Password reset flow
7.2 Authorization
- Customer role: Access own data only
- Admin role: Access all data
- API route protection with middleware
7.3 Data Protection
- Encrypted connection credentials in database
- Rate limiting on API endpoints
- Input validation and sanitization
Implementation Priority
Week 1: Foundation
- ✅ Terms of Service
- Privacy Policy
- Database schema setup
- Basic API structure
Week 2: Customer Flow
- RFQ submission form
- Customer dashboard
- Quotes viewing
- Order viewing
Week 3: Admin Flow
- Admin dashboard
- RFQ management
- Quote builder
- Order approval
Week 4: Payment & Provisioning
- Stripe subscription integration
- Payment processing
- GPU provisioning (mock)
- Email notifications
Week 5: Polish
- PDF generation
- Testing
- Deployment
- Documentation
Technology Stack
Frontend:
- React 19 + TypeScript
- React Router for navigation
- Tailwind CSS for styling
- React Query for API state management
- Stripe React SDK for payments
Backend:
- Node.js + Express (or Rust + Axum)
- PostgreSQL for database
- Redis for sessions/cache
- Stripe API for billing
- SendGrid for emails
Deployment:
- Frontend: GitHub Pages (or Vercel)
- Backend: DigitalOcean (or AWS)
- Database: DigitalOcean Managed PostgreSQL
MVP Feature Set (Bare Minimum)
Customer:
- Submit RFQ
- View quotes
- Accept quote
- View orders
- Pay via Stripe
Admin:
- View RFQs
- Send quotes
- View orders
- Approve orders
- Track payments
Nice-to-have (Post-MVP):
- Usage dashboards
- GPU instance management
- Automated provisioning
- Advanced analytics
- Mobile app
- Multi-language support
Next Steps
- Create Privacy Policy page
- Set up backend API skeleton
- Create database migrations
- Build RFQ form
- Build admin RFQ viewer
- Build quote builder
- Integrate Stripe
Estimated Timeline: 4-5 weeks for full MVP Current Status: Week 1, Day 1 (Legal pages started)