Executive Summary
Cost, timeline, and expected return — everything Brendon needs for a go/no-go decision.
| Phase | What's Delivered | Human Hours | AI Inference | Timeline |
|---|---|---|---|---|
| Phase 1 — MVP | Admin portal, customer ordering, guest orders w/ PDF, QuickBooks automation, packing sheets, standing orders | 35h | ~$2,000 | 6-8 weeks |
| Phase 2 — Self-Service | Customer self-management, order analytics, delivery tracking, mobile optimization | 12h | ~$650 | 3-4 weeks |
| Phase 3 — Email Intake | AI-powered email-to-order parsing for clients who prefer email | 10h | ~$650 | 2-3 weeks |
| Total | 57h | ~$3,300 | 12-16 weeks |
This project uses AI-accelerated development with Claude Opus 4.7. The AI agent handles the bulk of code generation, testing, and iteration — Brendon pays only for human expert hours (architecture, code review, QuickBooks setup, UAT support) and AI inference costs. A comparable system built by a traditional agency would cost $40,000-80,000+ and take 4-6 months. Phase 1 alone eliminates ~$27-31K/year in manual processing labor — the investment pays for itself within the first two months.
Pricing Model
Human expert hours billed at agreed rate. AI inference billed at cost. No markup on AI time — the AI agent's labor is included at no charge.
vs. Traditional Agency
$40-80K+ and 4-6 months at a traditional agency. Our approach: ~$3,300 inference + 57h human across all 3 phases.
Phase Independence
Each phase delivers standalone value. Brendon can stop after Phase 1 and still have a fully functional system. Phases 2 & 3 are optional enhancements.
Monthly Operational Cost After Launch
| Service | Tier | Monthly Cost | Notes |
|---|---|---|---|
| Supabase (DB + Auth + Storage) | Free | $0 | 50K MAU, 500MB DB, 1GB storage — more than sufficient |
| Cloudflare Workers (Frontend) | Free | $0 | 100K requests/day |
| QuickBooks Online API | Builder (Free) | $0 | 500K reads/month |
| Resend (Transactional Email) | Free | $0 | 3,000 emails/month — sufficient for 70 clients |
| Total | $0/month | All services within free tiers for this volume |
The Problem & Our Solution
A thriving 70+ client agricultural operation bottlenecked by manual email ordering and paper processes.
Mari's Gardens is Hawaii's largest aquaponics farm — 18 acres in Mililani, run by the Lau family across 4 entities with 100+ employees. They supply 70+ B2B clients including top restaurants (MW Restaurant, Pai Honolulu, Halekulani Hotel, Roy's Ko'olina), major retailers (Safeway, Foodland), and even formerly supplied all McDonald's Hawaii. The farm itself is highly automated: Autogrow systems for nutrients, Link4 for greenhouse climate, tested IDEC Japanese oxygen technology. The bottleneck isn't production — it's the order-to-invoice pipeline.
The Problem — Six Pain Points
Unstructured Email Orders
70+ clients each send orders in their own format — lists, paragraphs, replies. No validation, no standardization. "3 cases romaine" vs "the usual."
~24h/Week Manual Processing
One staff member spends ~4h/day reading, interpreting, and transcribing emails into orders. ~$27-31K/year pure labor cost for data entry.
Paper Packing Sheets
Orders printed, physically handed to packing crew. Lost paper = lost order. No digital trail, no status tracking.
Late Shortage Discovery
Stock shortages only discovered during packing in the field. Client notified after the fact — no time for proactive substitutions.
Standing Orders Re-Entered
~10 clients with identical weekly orders. Each re-entered manually every cycle. No templates, no automation.
Manual QB Invoicing
Every order re-keyed into QuickBooks. Double entry = errors, missed invoices, delayed billing, revenue leakage.
Our Solution — B2B Ordering Portal
A purpose-built ordering portal (not a payment portal) with two interfaces sharing one backend. The Admin Portal is Brendon's command center — products, customers, orders, packing, QuickBooks. The Customer Portal is where restaurants and retailers place orders in under 60 seconds. We also include guest ordering so new potential clients can order without an account — a natural acquisition funnel.
Key design decision: this is ordering, not payment. Brendon's B2B clients have existing payment terms. We create the order and the QuickBooks invoice — payment flows through existing channels. This eliminates PCI compliance requirements and payment processor complexity entirely.
Admin Portal
Product catalog with multi-image + carousel, customer management with invite-based onboarding, order processing, packing sheets, standing orders, QuickBooks sync. Role-based: Owner (full) vs Staff (limited).
Customer Portal (Authenticated)
Visual catalog with real-time availability, image carousels, one-click ordering, order history, standing order management. Pre-populated account from admin invite — zero friction.
Guest Ordering
New clients browse and order without login. Form checkout generates PDF for records. Admin converts guests to registered customers with one click.
B2B Customer Journeys
Four distinct journeys mapped end-to-end: the current manual process, the new authenticated flow, the guest flow, and the standing order cycle.
We mapped every touchpoint from the client's perspective and Brendon's operations. The current flow has seven manual steps with five failure points. The new flow eliminates all five failure points and reduces manual touchpoints to two: the client submitting and Brendon confirming. Everything else is automated. We've defined four distinct journeys because different customer types interact with the system differently.
❌ Journey A — Current Process (Manual)
This is how every order flows today, for all 70+ clients.
Client Composes Email Order
Restaurant manager writes email with product names, quantities, delivery date — in whatever format they prefer. No template, no structure.
Staff Opens, Reads, Interprets Each Email
One team member opens each email, mentally deciphers the request, maps to products. ~4 hours/day, 5 days/week.
Order Printed & Delivered to Packing Crew
Interpreted order formatted, printed on paper, physically brought to the packing area.
Crew Picks Products in Field
Packing crew takes paper to greenhouse/field, picks items. Only NOW do they discover if quantity is sufficient.
Shortage → Manual Client Contact
Crew notifies Brendon. Brendon calls/emails client to negotiate substitution or partial fill. Reactive, not proactive.
Manual QuickBooks Invoice
After order ships, staff creates invoice in QBO — re-entering all line items, quantities, prices by hand.
Client Pays via Existing Terms
Check, ACH, or existing arrangement. No change proposed — this works.
✅ Journey B — Authenticated B2B Client (New Process)
The primary ordering flow for the 70+ existing clients after onboarding to the portal.
Client Receives Invitation & Activates Account
Brendon creates client profile in admin (name, contact, address, delivery schedule, tier). Client receives branded email with activation link. Clicks → sees pre-populated profile → confirms/adjusts → sets password or chooses magic link. Zero data entry by client.
Client Logs In & Browses Catalog
Visual product grid with real photos (multi-image carousel), short descriptions, prices, and real-time availability. Filter by category (Leafy Greens, Herbs, Microgreens, Root Vegetables, Fish). Search by name.
Client Builds Order (<60 seconds)
Selects products, sets quantities, sees running total. Can click "Repeat Last Order" to reload a previous order with one click. Low-stock items show warning. Out-of-stock items disabled — impossible to order unavailable product.
Client Submits → Instant Confirmation
Reviews order summary (all items, quantities, prices, estimated total, preferred delivery date). Submits. Receives immediate on-screen confirmation with order number + confirmation email.
Admin Confirms → Packing Sheet Auto-Generated
Brendon sees order in admin dashboard. One-click confirm. If quantity needs adjustment, admin modifies and system notifies client automatically. Upon confirmation: formatted packing sheet generated (digital + printable).
QuickBooks Invoice Created Automatically
On confirmation, system creates Invoice in QBO via Accounting API — correct line items, quantities, prices. Zero manual entry. Invoice number cross-referenced with portal order number.
Client Pays via Existing Terms
Same payment flow as today. Portal is ordering only — no payment disruption.
🆕 Journey C — Guest (New Client / Walk-In)
For new prospects or one-time buyers who discover Mari's Gardens. This is the acquisition funnel.
Guest Browses Catalog (No Login Required)
Full product catalog visible — images, descriptions, prices, availability. Same visual experience as authenticated clients. "Already a customer? Log in here" prompt visible.
Guest Builds Order
Same ordering flow — select products, set quantities, see totals. No restrictions vs. authenticated flow.
Guest Fills Business Form at Checkout
Required fields: business name, contact name, email, phone, delivery address, preferred delivery date. Optional: business type, delivery window, special instructions.
Order Submitted → PDF Generated
System generates formatted PDF with: Mari's Gardens branding, order details, line items, totals, guest business info, order number. PDF downloadable immediately + sent via email.
Admin Reviews Guest Order
Appears in dashboard with "Guest Order" flag. Admin can: approve and process normally, OR reject with reason. Can also convert guest to registered customer with one click — form data pre-fills the customer creation.
🔁 Journey D — Standing Order Cycle
For the ~10 clients with recurring weekly orders. Eliminates repetitive re-entry entirely.
Admin Creates Standing Order Template
Sets up for a client: specific products, quantities, and recurring schedule (e.g., "Every Tuesday"). Template saved.
System Auto-Generates Pending Order (T-48h)
48 hours before scheduled delivery, system creates a pending order from the template. Checks current availability against requested quantities.
Client Receives Notification
Email: "Your standing order for Tuesday is ready. Confirm as-is or adjust by Monday 6pm." Link to portal for one-click confirm or modification.
Client Confirms or Adjusts
One-click confirm if unchanged. Or: modify quantities, add/remove items, then confirm. If deadline passes with no action → configurable auto-confirm or expiry.
Normal Order Flow Continues
Confirmed standing order enters the same pipeline: packing sheet generated, QuickBooks invoice created, delivery processed.
Business Rules & Acceptance Criteria
The rules that govern how the system behaves, and the testable criteria that define "done" for every capability.
These rules come from three sources: (1) how Brendon's operation actually works today, (2) B2B wholesale industry norms, and (3) product decisions we made during our design sessions. Every rule is deliberate. Every acceptance criterion is testable.
BR-1: Access Control
Rules
- Three access levels: Admin (Owner + Staff), Customer (Authenticated B2B), Guest (Unauthenticated)
- Owner role: full system access — products, customers, orders, settings, QB, staff management
- Staff role: can view/update orders, update availability, generate packing sheets. Cannot: delete products, manage staff, access settings, manage QB connection
- Customer role: can browse catalog, place orders, view own order history, manage own standing orders. Cannot see other clients' data
- Guest: can browse catalog, place orders via form. No history, no standing orders, no account management
- No public self-registration. All customer accounts created by admin and activated via invite
Acceptance Criteria
- Owner logs in → sees all sidebar menu items including Settings and QuickBooks
- Staff logs in → sees limited menu (no Settings, no QuickBooks, no Staff Management)
- Staff attempts to delete product → action blocked with "Insufficient permissions" message
- Customer logs in → sees only Customer Portal navigation (Catalog, My Orders, Standing Orders, Account)
- Customer attempts to access admin URL → redirected to customer portal
- Guest accesses catalog → full product browsing works, no login required
- Guest attempts to access "/my-orders" → prompted to log in
- Deactivated customer attempts login → "Account inactive — contact Mari's Gardens" message
BR-2: Product Catalog
Rules
- Each product has: name, short description (max 120 chars), long description (rich text), category, unit (head, bunch, lb, case, tray, each), price per unit, availability quantity, status (Active/Inactive/Seasonal), up to 10 images
- First image = primary (shown in catalog grid). Images reorderable via drag-and-drop
- Product with availability = 0 shows "Out of Stock" and cannot be added to orders
- Product with status = Inactive or Seasonal does not appear in customer catalog
- Product deletion is soft — preserves order history references, removes from catalog
- Categories are admin-manageable (CRUD). A product belongs to exactly one category
Acceptance Criteria
- Admin creates product with all required fields + 4 images → product appears in customer catalog within 30 seconds
- Admin updates price → customer sees new price on next page load (no cache delay >60s)
- Admin sets availability to 0 → customer sees "Out of Stock", cannot add to order
- Admin reorders images → customer carousel reflects new order
- Admin sets status to Inactive → product disappears from customer catalog, admin still sees it with "Inactive" label
- Upload image >5MB → rejected with "Max file size: 5MB" error
- Upload non-image file → rejected with "Only JPEG, PNG, and WebP supported"
BR-3: Customer Management & Onboarding
Rules
- Customer profile: business name, contact name, email, phone, delivery address(es), delivery schedule, tier (Restaurant/Retail/Wholesale), internal notes
- Admin creates profile → sends invite → customer receives email → clicks link → sees pre-filled data → confirms → account active
- Invite link valid for 7 days (configurable). After expiry: "Link expired" with contact info
- Guest-to-customer conversion: admin clicks "Convert" on guest order → customer creation form pre-fills from guest form data
- Customer lifecycle: Invited → Active → Inactive. Deactivation revokes access, preserves history
Acceptance Criteria
- Admin creates customer with all fields → sends invite → customer receives email within 60 seconds
- Customer clicks invite → profile shows admin-entered data (business name, address, etc.) pre-filled
- Customer modifies phone number during activation → change persisted correctly
- Invite link clicked after 8 days → "Link expired" page with "Contact Mari's Gardens" CTA
- Admin resends invite → new email arrives, new link works, old link invalidated
- Admin converts guest to customer → all guest form fields pre-populate customer form
- Admin deactivates customer → customer's next login attempt shows "Account inactive" message
BR-4: Ordering
Rules
- Orders flow through statuses: New → Confirmed → Packed → Delivered
- Only admin can advance order status
- Admin can adjust quantities before confirming — triggers automatic client notification with change details
- Client can cancel order only while status = New. After Confirmed, must contact Brendon
- Availability decremented on order confirmation, not on submission (prevents phantom holds)
- "Repeat Last Order" loads previous order's items; checks current availability; flags any unavailable items
- Guest orders: same as authenticated, but status starts as "Pending Review" (requires admin approval before entering normal flow)
- Rate limit: max 5 guest orders per email address per day
Acceptance Criteria
- Client submits order → status = New → visible in admin within 5 seconds
- Admin adjusts quantity from 10 to 6 → confirms → client receives email with adjustment details
- Two clients order same product (3 available): Client A orders 2, Client B orders 2 → first confirmed gets 2, second sees updated availability (1 left)
- Client clicks "Repeat Last Order" → 2 of 6 items now OOS → loaded with 4 items, 2 flagged "Currently Unavailable"
- Guest submits → order shows as "Pending Review (Guest)" in admin
- Same email submits 6th guest order in 24h → rejected with "Order limit reached" message
BR-5: Packing Sheets
Rules
- Generated automatically on order confirmation
- Contents: product name, quantity, unit, bin/location (if configured), check-off boxes
- Can be generated per-order or batched by delivery date
- Optimized for print (A4/Letter) and tablet display
BR-6: Standing Orders
Rules
- Template: client + products + quantities + schedule (day of week + frequency)
- System generates pending order 48h before scheduled delivery
- Client has until configurable deadline (default: day before, 6pm) to confirm or adjust
- After deadline: configurable auto-confirm (default) or expiry
- If product in standing order is OOS at generation time → flagged in pending order + client notified
- Client and admin can both edit template at any time; changes apply from next cycle
BR-7: QuickBooks Integration
Rules
- Uses Accounting API only (not Payments API) — this is ordering, not payment processing
- OAuth 2.0: access token (1h), refresh token (100 days rolling). Auto-refresh on expiry
- Invoice created in QBO on order confirmation with correct line items, quantities, prices
- Customer matching: by business name. Auto-creates QBO customer if not found
- Product matching: admin maps portal products to QBO Items. Fallback: match by name
- Failed sync: retry 3x with exponential backoff. If all fail: flag in admin, allow manual retry
- Sync can be disabled per-order (for test/internal orders)
BR-8: PDF Generation (Guest Orders)
Rules
- Generated server-side on guest order submission
- Contents: Mari's Gardens branding, order number, date, guest business info, line items with qty/price/subtotal, estimated total, "This is not an invoice" disclaimer
- Available for immediate download + sent via email to guest
- Also accessible by admin from the guest order detail view
BR-9: Email Notifications
Rules
- Provider: Resend (transactional email service) via Supabase Edge Functions
- Client triggers: order submitted, order confirmed, order adjusted, shortage alert, standing order reminder, invitation
- Admin triggers: new order received, new guest order, QB sync failure
- All emails: Mari's Gardens branding, clear subject lines, unsubscribe option
User Stories & BDD Scenarios
Formal user stories using the standard As a [role], I want [feature], so that [benefit] framework, with BDD acceptance scenarios in Given/When/Then format for test direction.
These user stories define what gets built. Each is a thin vertical slice — independently deliverable, independently testable. The BDD scenarios provide precise test specifications that can be directly translated into automated tests. We've prioritized them as MUST (Phase 1 launch blocker) and SHOULD (Phase 1 target, can descope if needed).
Epic 1 — Authentication & Access Control
US-1.1: Admin Login
MustGiven I am on the admin login page
And I have valid owner credentials
When I enter my email and password and click "Log In"
Then I am redirected to the admin dashboard
And I see the full sidebar navigation including Settings and QuickBooks
Scenario: Invalid credentials
Given I am on the admin login page
When I enter incorrect credentials
Then I see "Invalid email or password" error
And my account is not locked after 1 failed attempt
US-1.2: Customer Invite & Activation
MustGiven I am logged in as admin
And I have filled in customer details: "MW Restaurant", "Michelle W.", "mw@mwrestaurant.com"
When I click "Create & Send Invite"
Then the customer appears in my customer list with status "Invited"
And Michelle receives an email with activation link within 60 seconds
Scenario: Customer activates account
Given I am Michelle and I received the invitation email
When I click the activation link
Then I see a profile page with business name, address, and contact pre-filled
And I only need to set my password to complete activation
And my status changes to "Active" in admin
US-1.3: Guest Browsing (No Auth)
MustGiven I am not logged in
When I navigate to the portal URL
Then I see the full product catalog with images, descriptions, prices, and availability
And I can add items to my order
And I see a "Already a customer? Log in" prompt
Epic 2 — Product Catalog Management
US-2.1: Product CRUD
MustGiven I am logged in as admin on the Products page
When I click "Add New Product" and fill in: name "Longan", short desc "Fresh longan fruit, sweet and fragrant", price "$6.00/lb", category "Fruit", availability "25"
Then the product appears in the admin product list
And the product is visible in the customer catalog within 30 seconds
Scenario: Update availability
Given product "Baby Romaine" has availability 5
When I set availability to 0 and save
Then the customer catalog shows "Out of Stock" for Baby Romaine
And the "Add to Order" button is disabled
US-2.2: Multi-Image Upload & Carousel
MustGiven I am editing product "Microgreens Mix"
When I upload 4 images and drag the third image to the first position
Then the third image becomes the primary image
And the customer catalog shows this image in the grid card
And the detail view carousel starts with this image
Scenario: Reject oversized upload
Given I am uploading product images
When I select a 7MB JPEG file
Then the upload is rejected with "Max file size: 5MB"
Epic 3 — Customer Management
US-3.1: Customer CRUD & Invite
MustGiven I create customer "Aloha Bistro" with contact "James K." and email "james@alohabistro.com"
When I send the invite and James activates within 7 days
Then status progresses: Invited → Active
And James can log in and place orders
Scenario: Guest-to-customer conversion
Given a guest order exists from "Aloha Bistro" with email "james@alohabistro.com"
When I click "Convert to Customer" on the guest order
Then the customer creation form pre-fills with guest data
And after saving, the guest order is linked to the new customer account
Epic 4 — Ordering
US-4.1: Place Order (Authenticated)
MustGiven I am logged in as "MW Restaurant"
And I add 2 heads Baby Romaine and 4 bunches Thai Basil to my order
When I review and click "Submit Order"
Then I see a confirmation with order number
And I receive a confirmation email
And the order appears in admin dashboard as "New"
US-4.2: Guest Order with PDF
MustGiven I am not logged in and have items in my cart
When I fill in: business name "Aloha Bistro", email "james@alohabistro.com", phone, address, delivery date
And I click "Submit Order"
Then a PDF is generated with order details, line items, totals, and my business info
And I can download the PDF immediately
And the PDF is also emailed to "james@alohabistro.com"
US-4.3: Repeat Last Order
MustGiven my last order had 6 items and 2 are now out of stock
When I click "Repeat Last Order"
Then 4 available items are loaded into my cart
And 2 items show "Currently Unavailable" warnings
And I can submit the partial order or modify it
Epic 5 — Order Management (Admin)
US-5.1: Process & Confirm Orders
MustGiven order #1047 from MW Restaurant has 10 units of Baby Romaine but only 6 available
When I adjust quantity to 6 and click "Confirm"
Then order status changes to "Confirmed"
And MW Restaurant receives email: "Order adjusted — Baby Romaine reduced from 10 to 6"
And packing sheet is generated with 6 units
And QuickBooks invoice is created with 6 units
US-5.2: Batch Packing Sheets
MustGiven 8 orders are confirmed for Tuesday AM delivery
When I click "Generate Batch Packing Sheet" for Tuesday AM
Then a single document is generated with all 8 orders
And each order lists: customer name, products, quantities, check-off boxes
And the document renders cleanly on both screen and printer
Epic 6 — Standing Orders
US-6.1: Create & Manage Standing Orders
MustGiven Safeway Mililani has a standing order: 15 items, every Tuesday
And today is Sunday (48h before Tuesday)
When the system runs the standing order scheduler
Then a pending order is created for Safeway Mililani with 15 items
And Safeway receives email: "Your standing order for Tuesday is ready — confirm by Monday 6pm"
Scenario: Standing order with OOS item
Given the standing order includes Microgreens Mix but availability is 0
When the pending order is generated
Then Microgreens Mix is flagged as "Currently Unavailable" in the pending order
And the notification email includes the shortage warning
Epic 7 — QuickBooks Integration
US-7.1: Automatic Invoice Creation
MustGiven order #1047 is confirmed with 3 line items totaling $385
When the QB sync runs
Then an Invoice is created in QBO with 3 matching line items and total $385
And the order shows "QB: Synced ✓" in admin
Scenario: QB sync failure and recovery
Given the QB access token has expired
When invoice creation fails
Then the system refreshes the token and retries
And if successful, the invoice is created
And if 3 retries fail, admin sees "QB Sync Failed — Retry"
Epic 8 — Notifications
US-8.1: Transactional Emails
ShouldGiven admin confirms my order #1047
When the confirmation is saved
Then I receive an email within 60 seconds
And the email contains: order number, items, total, estimated delivery date
And the email has Mari's Gardens branding
Delivery Slices
The feature breakdown into thin vertical slices — each independently deployable, testable, and demonstrable. This is how we build incrementally with visible progress every week.
We sliced the work into 7 deliveries. Each slice is a working increment — not a layer (backend then frontend then testing). Every slice includes its own backend, frontend, and tests. After Slice 3, Brendon can start using the admin. After Slice 5, clients can start ordering. This approach lets us validate assumptions early and course-correct before investing in later features.
🟢 Slice 1 — Foundation & Auth
Database schema, Supabase project, auth system (admin + customer + guest), basic UI shell with sidebar navigation. Role-based access control enforced.
🔵 Slice 2 — Product Catalog (Admin)
Full product CRUD with multi-image upload, carousel, drag-and-drop reordering. Supabase Storage for images with CDN delivery.
🟣 Slice 3 — Customer Management
Customer CRUD, invite management, status tracking. At this point, admin portal is fully usable for daily management.
🟠 Slice 4 — Customer Portal & Ordering
Customer-facing catalog with carousel, ordering flow, guest checkout with PDF generation, "repeat last order." This is the core value delivery.
🔴 Slice 5 — Order Management & Packing
Admin order processing: confirm, adjust, generate packing sheets. Guest-to-customer conversion.
🟡 Slice 6 — Standing Orders & QuickBooks
Recurring order automation and accounting integration. The two features that save the most time long-term.
⚪ Slice 7 — Notifications, Polish & Launch
Email notification system, edge case fixes, mobile responsiveness, UAT with Brendon, production deployment.
Technical Architecture
Modern, managed infrastructure chosen for reliability, low operational overhead, and zero server maintenance for Brendon.
Every choice here optimizes for Brendon never needing to think about infrastructure. Supabase provides database, auth, storage, and edge functions in one managed service. Cloudflare serves the frontend globally. Resend handles email. QuickBooks handles accounting. There's no server to maintain, no uptime to monitor, no security patches to apply. All services have generous free tiers that cover this project's volume comfortably — $0/month operational cost at launch.
Next.js (App Router)
React framework, server-side rendering, optimized routing
Cloudflare Workers
Frontend hosting, global CDN, zero cold-start
Supabase
PostgreSQL DB, Auth, Storage (images/PDFs), Edge Functions, RLS
QuickBooks Online API
Accounting API, OAuth 2.0, Invoice automation
Resend
Transactional email, branded templates, delivery tracking
Claude Opus 4.7
AI-accelerated development, code generation, testing
System Architecture Flow
┌─────────────────────────────────────────────────────────────────┐
│ CLOUDFLARE WORKERS │
│ (Next.js App Router SSR) │
│ ┌──────────────┐ ┌───────────────────┐ ┌──────────────┐ │
│ │ Admin Portal │ │ Customer Portal │ │ Guest Portal │ │
│ │ (Owner/Staff)│ │ (Authenticated) │ │ (No Auth) │ │
│ └──────┬───────┘ └────────┬──────────┘ └──────┬───────┘ │
└─────────┼─────────────────────┼──────────────────────┼─────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ SUPABASE │
│ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌────────────────┐ │
│ │ Auth │ │ Database │ │ Storage │ │ Edge Functions │ │
│ │ (RBAC) │ │ (Postgres)│ │ (Images) │ │ (PDF, QB Sync) │ │
│ └─────────┘ └──────────┘ └──────────┘ └───────┬────────┘ │
└────────────────────────────────────────────────────┼────────────┘
│
┌────────────────────────────────┼───────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────┐ ┌────────┐
│ QuickBooks API │ │ Resend │ │ PDF │
│ (Accounting) │ │ (Email) │ │ (Gen) │
│ OAuth 2.0 │ └──────────┘ └────────┘
│ Invoice creation│
└─────────────────┘
Database Schema (Core Tables)
| Table | Key Fields | Relationships |
|---|---|---|
| profiles | id, email, role (owner/staff/customer), business_name, contact_name, phone, tier, status, delivery_schedule, notes | 1:1 with Supabase Auth users |
| products | id, name, short_desc, long_desc, category_id, unit, price, availability, status, sort_order | → categories, → product_images |
| product_images | id, product_id, image_url, sort_order, is_primary | → products |
| categories | id, name, sort_order | → products |
| orders | id, customer_id (nullable for guests), status, guest_info (JSONB), total, delivery_date, delivery_window, notes, qb_invoice_id, qb_sync_status | → profiles, → order_items |
| order_items | id, order_id, product_id, quantity, unit_price, subtotal | → orders, → products |
| standing_orders | id, customer_id, schedule (JSONB), is_active, auto_confirm | → profiles, → standing_order_items |
| standing_order_items | id, standing_order_id, product_id, quantity | → standing_orders, → products |
| addresses | id, customer_id, street, city, zip, is_default | → profiles |
Auth Architecture
| Component | Implementation | Notes |
|---|---|---|
| Auth Provider | Supabase Auth | Email/password + Magic Link |
| Session | JWT via HttpOnly cookies (@supabase/ssr) | 30-day session, auto-refresh |
| RBAC | Custom claims in JWT + RLS policies | 4 roles: owner, staff, customer, guest |
| Invite Flow | Supabase Auth invite + custom metadata | Pre-fills profile on activation |
| Row-Level Security | PostgreSQL RLS on all tables | Customers only see own orders/data |
Email Architecture (Resend)
| Email Type | Trigger | Template |
|---|---|---|
| Invitation | Admin creates customer + clicks "Send Invite" | Branded, activation CTA, pre-fill link |
| Order Confirmation | Admin confirms order | Order #, items, total, delivery date |
| Order Adjustment | Admin modifies qty before confirming | What changed, new total |
| Standing Order Reminder | Scheduler (T-48h) | Items, confirm/adjust CTA, deadline |
| Guest Order Receipt | Guest submits order | Order details + PDF attachment |
| Shortage Alert | OOS item in standing order or admin flags | Which items affected, alternatives |
| Admin: New Order | Any order submitted | Customer, items, total — review link |
| Admin: QB Sync Fail | 3 retry failures | Order #, error, retry link |
QuickBooks Integration Detail
| Aspect | Detail |
|---|---|
| API | QuickBooks Online Accounting API (REST, JSON) — not Payments API |
| Auth | OAuth 2.0 via Intuit Developer Portal. Access token: 1h. Refresh token: 100 days (rolling) |
| Scope | com.intuit.quickbooks.accounting |
| Entities Used | Invoice (create), Customer (read/create), Item (read) |
| Rate Limits | 500 requests/min (Builder tier). ~70 orders/day = well within limits |
| Sandbox | Full sandbox available for development — US payments sandbox (Hawaii ✓) |
| Cost | $0 (Builder tier, free up to 500K reads/month) |
| Future Phase 2 | Optionally add com.intuit.quickbooks.payment scope for ACH payments (1% fee, $10 cap) |
Low-Fidelity Wireframes
Key screen layouts for validation. These define structure and flow — final visual design is applied during development.
| # | Customer | Total | Delivery | Status |
|---|---|---|---|---|
| #1047 | MW Restaurant | $385 | May 6 AM | New |
| #1046 | Pai Honolulu | $220 | May 6 AM | New |
| #1045 | Halekulani Hotel | $890 | May 6 PM | Confirmed |
| #1043 | Guest — Aloha Bistro | $145 | May 6 AM | Guest |
2 × $3.50
4 × $4.00
1 × $8.00
10lb × $7.00
What We Need from Mari's Gardens
Information and access required from Brendon and his team to execute this project.
We've designed the project to require minimal involvement from Brendon's team — but there are things only they can provide. This list is organized by when we need each item. Most of the heavy lifting is in Week 1 (data collection). After that, Brendon's involvement drops to periodic reviews and final UAT.
📋 Before Development Starts (Week 0)
| Item | Detail | Who Provides | Format |
|---|---|---|---|
| Product Catalog Data | Complete list of ~50 SKUs: name, description, unit type, price per unit, category | Brendon / team | Spreadsheet (Excel/Google Sheets) |
| Product Photos | At least 2-3 photos per product. Higher quality = better customer experience | Brendon / team | JPEG/PNG, phone camera OK |
| Customer List | List of B2B clients: business name, contact name, email, phone, delivery address, delivery schedule, tier (restaurant/retail) | Brendon | Spreadsheet |
| Standing Order Details | Which ~10 clients have recurring orders, what products, what quantities, what schedule | Brendon | Any format |
| QuickBooks Online Access | Admin access to Brendon's QBO account for OAuth app setup. We'll configure the developer app together. | Brendon | Screen-share session (30 min) |
| Brand Assets | Logo (PNG/SVG), brand colors if any. If none, we'll use a clean green/white theme inspired by the farm | Brendon | Files or "use your judgment" |
🔄 During Development (Weeks 1-7)
| Item | Detail | When | Time Required |
|---|---|---|---|
| Point of Contact | Designated person (Brendon or staff) to answer quick questions during development via Slack/email | Ongoing | ~15 min/week |
| Design Review | Review wireframes and early UI screenshots. Feedback on layout, colors, flow | Week 2-3 | 1 hour |
| Product Data Validation | Verify imported product data is correct (names, prices, units, categories) | Week 3 | 30 min |
| QB Sandbox Testing | Quick verification that sandbox invoices look correct in QBO | Week 6 | 30 min |
🚀 Before Launch (Week 7-8)
| Item | Detail | Time Required |
|---|---|---|
| UAT Session | Brendon walks through the system with us: creates products, invites a test client, places an order, generates packing sheet, verifies QB invoice. We fix any issues found. | 2-3 hours |
| Domain Decision | Custom domain (e.g., order.marisgardens.com) or use our provided URL? If custom: DNS access needed. | 5 min decision |
| Go-Live Approval | Brendon confirms system is ready for real client use after UAT | N/A |
| Client Communication | Brendon introduces portal to B2B clients (we provide email template). Phased rollout recommended: 5 clients first, then all. | 30 min |
Total time commitment from Brendon's team across the entire project: ~6-8 hours (bulk is the spreadsheet preparation and UAT). That's it. We handle everything else.
Investment & Timeline
Detailed cost breakdown by phase and delivery slice, with expected ROI.
We structured the investment in three independent phases so Brendon can evaluate real-world results after Phase 1 before committing further. Phase 1 alone delivers the complete ordering portal with QuickBooks automation. Phases 2 and 3 are enhancements — valuable, but optional. Each phase has its own deliverables, timeline, and cost. No lock-in, no upfront commitment beyond Phase 1.
Phase 1 — MVP (Core Portal)
| Delivery Slice | Features | Human Hours | AI Inference | Week |
|---|---|---|---|---|
| Slice 1: Foundation & Auth | DB schema, auth system, RBAC, UI shell | 5h | ~$300 | 1-2 |
| Slice 2: Product Catalog | Product CRUD, multi-image, carousel, categories | 5h | ~$350 | 2-3 |
| Slice 3: Customer Management | Customer CRUD, invite, onboarding, status | 4h | ~$250 | 3-4 |
| Slice 4: Customer Portal & Ordering | Catalog, cart, ordering, guest checkout, PDF | 7h | ~$400 | 4-5 |
| Slice 5: Order Management | Order processing, packing sheets, conversions | 5h | ~$250 | 5-6 |
| Slice 6: Standing Orders & QB | Recurring orders, QuickBooks integration | 5h | ~$250 | 6-7 |
| Slice 7: Notifications & Launch | Email system, polish, UAT, production deploy | 4h | ~$200 | 7-8 |
| Phase 1 Total | 35h | ~$2,000 | 6-8 wk |
Phase 2 — Self-Service Enhancements
| Feature | Human Hours | AI Inference |
|---|---|---|
| Customer self-registration (admin-approved) | 2h | ~$100 |
| Order history with analytics (spend trends, popular items) | 3h | ~$150 |
| Standing order self-management (customer edits template) | 3h | ~$150 |
| Delivery tracking (status updates for clients) | 2h | ~$100 |
| Advanced mobile optimization | 2h | ~$150 |
| Phase 2 Total | 12h | ~$650 |
Phase 3 — Smart Email Intake
| Feature | Human Hours | AI Inference |
|---|---|---|
| Email inbox monitoring (dedicated orders@ address) | 2h | ~$100 |
| AI parsing: extract products, quantities, delivery from email text | 4h | ~$350 |
| Parsed order review UI + human confirm/adjust | 2h | ~$100 |
| Confidence scoring + fallback to manual on ambiguity | 2h | ~$100 |
| Phase 3 Total | 10h | ~$650 |
ROI Analysis
Annual Savings: ~$27-31K
Eliminates ~24h/week of manual email processing labor at ~$22-25/hr. Additional savings from: fewer invoicing errors, no missed invoices (revenue leakage), reduced shortage-related client friction.
Payback: <2 Months
Total investment (all 3 phases): ~$3,300 inference + 57h human. At $27K/year annual savings, the system pays for itself within 6-8 weeks of operation.
Growth Enabler
Guest ordering creates acquisition channel. Standing order automation makes scaling to 100+ clients feasible without additional order-processing staff.
Ongoing Maintenance & Support
Keeping the system healthy, secure, and compatible — 10 hours/month of proactive human expert oversight plus AI inference for implementation.
Delivering a system without a maintenance plan is irresponsible. Technology stacks evolve constantly: Next.js ships major versions quarterly, Intuit updates the QuickBooks API, Supabase rolls out platform changes, and security vulnerabilities are discovered in dependencies. Without proactive maintenance, the portal risks becoming incompatible, insecure, or unreliable within months. This retainer ensures Brendon's system stays healthy, performant, and up-to-date — with zero effort from his team.
What's Included — Monthly
| Activity | Description | Est. Hours | Frequency |
|---|---|---|---|
| Dependency Updates | Update Next.js, Supabase SDK, Resend SDK, node-quickbooks, and all sub-dependencies. Run full test suite after each update. Deploy to production. | 3-4h | Monthly |
| Security Patches | Monitor CVE databases and npm advisories. Apply critical patches within 48h, non-critical within the monthly cycle. | Included above | As needed |
| QB API Compatibility | Monitor Intuit's API changelog and deprecation notices. Adjust integration code before deprecated endpoints are removed. Verify OAuth token refresh continues working. | 1-2h | Monthly |
| Supabase Platform Sync | Supabase Cloud applies platform updates automatically. Verify Auth, Storage, and Edge Functions remain compatible. Review RLS policy integrity. | Included in check | Monthly |
| Bug Fixes | Diagnose and fix issues reported by Brendon or his team during the month. Includes investigation, fix, testing, and deployment. | 2-3h | As reported |
| Small Enhancements | Minor UX adjustments, new fields, simple report additions, configuration changes — anything that fits within 1-2h of work. | Included above | As requested |
| Monitoring & Health Check | Review application logs, error rates, email deliverability (Resend dashboard), QB sync success rate. Flag anomalies before they become issues. | 1-2h | Monthly |
| Backup Verification | Confirm Supabase automatic backups are running. Periodic test restore to verify data integrity. | Included in check | Monthly |
| Total Monthly | ~10h |
Monthly Cost
| Component | Monthly | Annual | Notes |
|---|---|---|---|
| Human Expert Hours | 10h | 120h | Billed at agreed hourly rate |
| AI Inference (maintenance tasks) | ~$50-100 | ~$600-1,200 | Dependency updates, bug fixes, patches |
| Infrastructure (Supabase, Cloudflare, Resend, QB API) | $0 | $0 | All within free tiers at current volume |
What's NOT Included (Billed Separately)
New Feature Development
Features beyond small enhancements — e.g., Phase 2 or Phase 3 work, new integrations, major UI redesigns. Scoped and quoted separately.
Scale-Up Infrastructure
If Brendon's volume exceeds free tiers (unlikely at current scale), infrastructure costs are passed through at cost. We'll notify before any paid tier transition.
Emergency / After-Hours Support
Critical production outages outside normal business hours. Available at 1.5x rate if needed. Standard maintenance handles prevention to minimize these.
Why This Matters
Without maintenance, a typical web application degrades within 6-12 months:
• Month 3: npm audit shows 5+ vulnerabilities. Most are low-risk, but one is critical.
• Month 6: QuickBooks deprecates an endpoint. Invoices stop syncing. Brendon discovers it when a client asks about a missing invoice.
• Month 9: Supabase ships a major Auth update. Login flow breaks for 3 customers before anyone notices.
• Month 12: Next.js version is 2 major versions behind. Security patches stop. Updating now requires rewriting components.
With 10h/month of proactive maintenance, none of this happens. Updates are applied incrementally, compatibility is verified before it breaks, and issues are caught in monitoring — not by Brendon's customers.
Monthly Maintenance Report
Brendon receives a brief monthly report including:
- What was updated (packages, versions, patches applied)
- Any QB or Supabase API changes monitored
- Bugs fixed during the month
- Small enhancements delivered
- Health check results (uptime, error rate, email deliverability, QB sync rate)
- Recommendations for the next month (if any)
- Hours used vs. allocated