Food carts are a beloved part of local communities, but they suffer from one major problem: discoverability. Because they move around, customers never know exactly where they are or if they are open.
CartKoi solves this by providing a premium, centralized platform where:
- π§βπΌ Food Cart Owners can instantly update their live location, status, rich menu descriptions, and receive Mistral AI-powered business analytics.
- π§βπ³ Employees can securely log in to help manage stock and location without needing owner credentials.
- π Customers can explore a live, interactive map to discover nearby food carts, view menus, see operating hours, calculate exact distances, and read AI-generated review summaries.
- Live Interactive Map: Find open food carts near you instantly using Leaflet.js.
- Real-Time Distance Calculation: CartKoi uses the Haversine formula to compute exactly how far away a food cart is based on your device's GPS.
- π€ AI Review Summaries (Mistral AI): Automated qualitative synthesis of customer reviews (stratified sample across high/mid/low ratings) to provide an unbiased 3-4 sentence food critic summary.
- Advanced Filtering & Search: Client-side, ultra-fast search functionality to filter carts by name or "Open Now" status.
- Reviews & Ratings System: Leave star ratings with comments, protected by anti-abuse policies and server-side cache invalidation.
- Native Sharing & Socials: One-click Web Share API integration to easily send cart locations, plus direct links to Foodpanda, Facebook, and Instagram.
- Role-Based Access Control (RBAC): Secure Supabase Auth ensures owners have full control over their business and team permissions.
- π AI Sales & Profitability Insights (Mistral AI): Intelligent location-based revenue analysis that identifies top-performing spots, weakest spots, best operating windows, and actionable expansion recommendations.
- Dynamic Dashboard: Update menus, add food descriptions, toggle availability, manage gallery images, and set daily operating hours effortlessly.
- Client-Side Image Compression: Zero-dependency, hardware-accelerated image compression (via HTML5 Canvas) squashes 5MB photo uploads to ~100KB before uploading to Supabase Storage.
- Secure Join System: Employees join a cart's operational team via a secure 6-character Invite Code generated by the owner.
- Operational Control: Employees update live GPS locations and mark items as "Sold Out" on the fly without accessing financial settings.
CartKoi integrates Mistral AI (mistral-small-latest) across two key features:
-
AI Review Summarizer (
/api/cart/[id]/summary)- Synthesizes balanced feedback by taking 5 high (4-5β ), 5 medium (3β ), and 5 low (1-2β ) rating comments.
- Evaluates a smart DB caching policy (
last_summarized_review_count), triggering re-generation only when at least 2 new text reviews accumulate.
-
AI Sales & Location Profitability (
/api/cart/[id]/sales-insights)- Processes historical sales logs (timestamp, geo-coordinates, revenue per spot).
- Generates structured JSON output with metrics:
top_location,secondary_location,weakest_location,best_time, andrecommendation.
- Frontend: Next.js 14+ (App Router), React 19, TypeScript, Tailwind CSS, Framer Motion, Lucide Icons
- AI Integration: Mistral AI API (
mistral-small-latestchat completions with JSON schema enforcement) - Backend / Database: Supabase (PostgreSQL with RLS policies & SQL Triggers)
- Authentication: Supabase Auth (Email/Password, Magic Links, Role Metadata)
- Storage: Supabase Storage (Buckets:
menu-items,cart-images,profiles) - Mapping: React-Leaflet (Leaflet.js)
CartKoi/
βββ client/ # Next.js Frontend App Router Root
β βββ src/
β β βββ app/ # Next.js App Router Pages & API Endpoints
β β β βββ api/
β β β β βββ cart/[id]/
β β β β βββ sales-insights/route.ts # Mistral AI Profitability Analysis
β β β β βββ summary/route.ts # Mistral AI Review Summarizer
β β β βββ cart/[id]/page.tsx # Public Cart Profile & Review UI
β β β βββ employees/ # Employee Login & Operational Dashboard
β β β βββ explore/page.tsx # Interactive Map & Search Discovery Page
β β β βββ owners/ # Owner Auth & Full Business Dashboard
β β β βββ profile/page.tsx # Customer/User Profile Settings
β β β βββ layout.tsx # App Root Layout with TopBar & Auth Context
β β βββ components/ # Reusable UI & Business Domain Components
β β β βββ MapComponent.tsx # Interactive Leaflet Map Wrapper
β β β βββ LocationUpdater.tsx # Live GPS Tracker component
β β β βββ NavBar.tsx & TopBar.tsx # Navigation Header Components
β β β βββ ui/ # Atomic UI Primitives (Button, Skeleton, EmptyState)
β β βββ hooks/
β β β βββ useAuth.ts # Supabase Auth state hook & session tracking
β β βββ utils/ # Modular pure helper functions
β β βββ distance.ts # Geolocation & Haversine distance calculations
β β βββ hours.ts # Operating hour parse & "Open Now" evaluator
β β βββ imageCompression.ts # Client-side HTML5 Canvas Image Squasher
β β βββ supabase/ # Supabase Browser, Server, & Middleware clients
β βββ package.json
βββ docs/ # Database Schemas & Migration Scripts
βββ database_schema.sql # Core Schema Definitions (Tables, Keys, RLS)
βββ auth_trigger.sql # Trigger for automatically creating profiles on Signup
βββ migrations/ # SQL Patch files (01..09)
CartKoi is architected following clean software design principles to maximize modularity and reusability:
-
Pure Utility Modules (
client/src/utils/):distance.ts: Exports pure functions (calculateDistance,formatDistance) decoupled from React state, making geo-calculations reusable across client rendering or server pre-computation.hours.ts: Standalone parser verifying whether a business is currently open against dynamic schedule strings.imageCompression.ts: Framework-agnostic browser canvas module. Can be reused in any frontend project needing client-side image optimization.
-
Decoupled API Contracts (
/api/cart/[id]/*):- Serverless route handlers act as isolated proxy bridges between Supabase DB and Mistral AI API, preventing leak of service role keys and AI credentials to the client.
-
Atomic UI Component Architecture:
- Shared atomic primitives in
src/components/ui/(Skeleton,EmptyState,Button) decoupled from business domain logic.
- Shared atomic primitives in
flowchart TD
A["Customer Views Cart Page"] --> B{"Check DB Cache: ai_summary exists?"}
B -- Yes --> C{"New text reviews >= 2 since last summary?"}
C -- No --> D["Return Cached AI Summary"]
C -- Yes --> E["Fetch Reviews Stratified: 5 High, 5 Mid, 5 Low"]
B -- No --> E
E --> F["Send Prompt to Mistral AI (mistral-small-latest)"]
F --> G["Receive Clean Summary Paragraph"]
G --> H["Update DB Cache in carts table"]
H --> I["Render AI Summary on UI"]
flowchart TD
Owner["Cart Owner Request Insights"] --> API["/api/cart/id/sales-insights"]
API --> DB[("Query sales_logs table")]
DB --> Format["Format Logs: Lat/Lng, Location Name, Revenue, Timestamp"]
Format --> Prompt["Construct System Prompt with JSON Schema"]
Prompt --> Mistral["Call Mistral AI API"]
Mistral --> Parse["Receive Structured JSON: Top/Weak Locations, Best Time, Recommendation"]
Parse --> CacheDB[("Cache JSON in carts.ai_sales_insight")]
CacheDB --> Render["Render Profitability Cards on Owner Dashboard"]
erDiagram
PROFILES ||--o| CARTS : "owns (for owner role)"
PROFILES ||--o{ EMPLOYEES : "belongs to (for employee role)"
CARTS ||--o{ EMPLOYEES : "employs"
CARTS ||--o{ MENU_ITEMS : "has"
CARTS ||--o{ REVIEWS : "receives"
CARTS ||--o{ SALES_LOGS : "records"
PROFILES ||--o{ REVIEWS : "writes"
PROFILES {
uuid id PK
string email
string full_name
string role "owner | employee | customer"
string phone_number
timestamp created_at
}
CARTS {
uuid id PK
uuid owner_id FK
string name
string description
string address
float lat
float lng
boolean is_open
string opening_hours
string invite_code
text ai_summary
int last_summarized_review_count
jsonb ai_sales_insight
}
EMPLOYEES {
uuid id PK
uuid cart_id FK
uuid user_id FK
timestamp created_at
}
MENU_ITEMS {
uuid id PK
uuid cart_id FK
string name
float price
boolean is_available
string image_url
}
REVIEWS {
uuid id PK
uuid cart_id FK
uuid user_id FK
int rating
text comment
timestamp created_at
}
SALES_LOGS {
uuid id PK
uuid cart_id FK
float amount
string location_name
float lat
float lng
timestamp created_at
}
-
Clone the repository
git clone https://github.com/yourusername/cartkoi.git cd cartkoi/client -
Install dependencies
npm install
-
Set up Environment Variables Create a
.env.localfile in theclientdirectory:NEXT_PUBLIC_SUPABASE_URL=your_supabase_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key MISTRAL_API_KEY=your_mistral_ai_api_key
-
Run Database Migrations Execute SQL files located under
docs/database_schema.sqlanddocs/migrations/*.sqlin your Supabase SQL Editor. -
Run the development server
npm run dev
Open http://localhost:3000 with your browser to view CartKoi.
This project is licensed under the MIT License - see the LICENSE file for details.