Files
computer/LEASING_PLATFORM_PLAN.md
zeekay 6d6cdb2483 feat: Extract zoo.computer from monorepo
Extracted from zoo monorepo for independent deployment.

Domain: computer.zoo.ngo
Deployment: GitHub Pages (GitHub Actions)
App Directory: computer
2025-11-02 10:41:38 -08:00

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

  • 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:

  1. RFQ received confirmation (to customer)
  2. New RFQ notification (to admin)
  3. Quote sent (to customer)
  4. Quote accepted notification (to admin)
  5. Order confirmation (to customer)
  6. GPU provisioned (to customer with credentials)
  7. Invoice due reminder
  8. Payment successful
  9. Subscription renewal reminder
  10. 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

  1. ✅ Terms of Service
  2. Privacy Policy
  3. Database schema setup
  4. Basic API structure

Week 2: Customer Flow

  1. RFQ submission form
  2. Customer dashboard
  3. Quotes viewing
  4. Order viewing

Week 3: Admin Flow

  1. Admin dashboard
  2. RFQ management
  3. Quote builder
  4. Order approval

Week 4: Payment & Provisioning

  1. Stripe subscription integration
  2. Payment processing
  3. GPU provisioning (mock)
  4. Email notifications

Week 5: Polish

  1. PDF generation
  2. Testing
  3. Deployment
  4. 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:

  1. Submit RFQ
  2. View quotes
  3. Accept quote
  4. View orders
  5. Pay via Stripe

Admin:

  1. View RFQs
  2. Send quotes
  3. View orders
  4. Approve orders
  5. Track payments

Nice-to-have (Post-MVP):

  • Usage dashboards
  • GPU instance management
  • Automated provisioning
  • Advanced analytics
  • Mobile app
  • Multi-language support

Next Steps

  1. Create Privacy Policy page
  2. Set up backend API skeleton
  3. Create database migrations
  4. Build RFQ form
  5. Build admin RFQ viewer
  6. Build quote builder
  7. Integrate Stripe

Estimated Timeline: 4-5 weeks for full MVP Current Status: Week 1, Day 1 (Legal pages started)