AI Implementation Guide: CS01 Case Study
Documents how two AI features, Term Sheet Analyzer and DealCraft Negotiation, are built with Gemini, Supabase, and Vercel serverless functions.
What this file does
Documents how two AI features, Term Sheet Analyzer and DealCraft Negotiation, are built with Gemini, Supabase, and Vercel serverless functions.
When to use it
- Recreating or migrating the CS01 case study's AI features
- Building a serverless AI pipeline with file upload and chat history
- Learning how to structure a multi-step AI workflow with Supabase persistence
- Understanding prompt engineering for role-based negotiation simulations
Assumes this stack
AI Implementation Guide: CS01 Case Study
This document details the implementation of the two AI-powered features in the CS01 Case Study: the Term Sheet Analyzer and the DealCraft Negotiation simulation. It is intended to guide developers in recreating or migrating these features to a new system.
1. System Overview
Both features utilize a Client-Server-Database architecture:
- Frontend: Standard HTML/JS running in a browser (Jekyll site).
- Backend: Node.js Serverless Functions (Vercel).
- Database & Storage: Supabase (PostgreSQL for data, Supabase Storage for files).
- AI Engine: Google Gemini API (
gemini-2.5-flashmodel).
2. Term Sheet Analyzer
Location: Module 3 (docs/03-the-exercise.md)
Objective: Analyze a user-uploaded term sheet (PDF/DOCX) against the case study context and provide negotiation advice.
2.1. Architecture & Data Flow
- User Upload: User selects a file on the frontend.
- Storage: Frontend uploads the file directly to Supabase Storage bucket
term-sheet-uploads. - Trigger: Frontend calls the backend API
/api/analyzewith the uploaded filename. - Processing:
- Backend downloads the file from Supabase.
- Extracts text using
mammoth(DOCX) orpdf-parse(PDF). - Loads static case context from
context.json.
- AI Analysis: Backend sends the Case Context + Term Sheet Text + Prompt to Gemini.
- Response: Gemini returns text analysis; Backend sends it to Frontend for display.
2.2. Component Details
Frontend (docs/assets/js/term-sheet-analyzer.js)
- Dependencies:
@supabase/supabase-js(via CDN). - Key Logic:
- Initializes Supabase client.
- Handles file selection and upload to Supabase Storage.
POSTrequest to/api/analyzewith{ fileName }.- Renders the returned Markdown/Text response.
Backend (docs/api/analyze.js)
- Runtime: Node.js.
- Dependencies:
@google/generative-ai,@supabase/supabase-js,mammoth,pdf-parse. - Key Logic:
getFileText(buffer, type): Helper to parse PDF/DOCX buffers into raw text.- Retrieves file from Supabase using the filename.
- Reads
docs/api/context.jsonfor grounding the AI. - Prompt Construction:
**Case Study Context:** [Content of context.json] **User's Term Sheet:** [Extracted Text] **Analysis Task:** As an expert... analyze the user's redlined term sheet... - Model: Uses
gemini-2.5-flashfor high-speed, cost-effective text generation.
3. DealCraft Negotiation (Chat)
Location: Module 3 (docs/03-the-exercise.md)
Objective: Interactive chat where users negotiate with an AI opponent (playing the opposite role).
3.1. Architecture & Data Flow
- Session Creation:
- User uploads term sheet & selects role (NewCo vs BigTech).
- Frontend sends file + role to
/api/negotiate(Action:create). - Backend extracts text, determines AI persona, and creates a session row in Supabase
negotiationstable. - Returns
sessionId.
- Negotiation Loop:
- User sends message to
/api/negotiate(Action:send_message) withsessionId. - Backend fetches session history & context from Supabase.
- Backend calls Gemini with full context (Persona + Case Data + History + New Message).
- Backend appends User & AI messages to Supabase history.
- Returns AI response to Frontend.
- User sends message to
3.2. Database Schema (Supabase)
Table: negotiations
| Column | Type | Description |
|---|---|---|
id | UUID | Primary Key (Session ID) |
created_at | Timestamp | Creation time |
user_role | Text | 'NewCo' or 'BigTech' |
ai_role | Text | Opposite of user_role |
original_term_sheet | Text | Extracted text from uploaded file |
history | JSONB | Array of message objects: `[{ "speaker": "user |
status | Text | 'initializing', 'active', etc. |
3.3. Component Details
Frontend (docs/assets/js/dealcraft.js)
- State: Manages
sessionId, loading states, and chat UI. - Actions:
startNegotiation():POST(multipart/form-data) to/api/negotiatewith file & role.sendMessage():POST(JSON) to/api/negotiatewithsessionId& message text.addMessageToHistory(): Updates the DOM with new messages.
Backend (docs/api/negotiate.js)
- Runtime: Node.js (Vercel Serverless).
- Configuration: Disables default body parser (
export const config = { api: { bodyParser: false } }) to handlemultipart/form-datamanually viaformidable. - Context Files:
context.json: General facts about the case.negotiation-context.json: Specific personas/objectives for "NewCo" and "BigTech".
- Prompt Engineering:
- Dynamically loads the persona based on
ai_role. - Injects the entire conversation history into the prompt to maintain context (stateless API).
- Prompt Structure:
**Case Context:** [context.json] **Your Persona:** [negotiation-context.json for AI Role] **Negotiation History:** [Previous turns] **User's Latest Message:** [Input] **Your Task:** concise and strategic response...
- Dynamically loads the persona based on
4. Configuration & Environment Variables
To recreate this system, the following environment variables are required:
| Variable | Description |
|---|---|
GEMINI_API_KEY | Google AI Studio API Key |
SUPABASE_URL | URL of the Supabase project |
SUPABASE_SERVICE_KEY | Service role key (backend only) for DB access |
SUPABASE_ANON_KEY | Anonymous key (frontend) for Storage upload |
5. File Structure Reference
- Frontend Logic:
docs/assets/js/ - Backend Logic:
docs/api/ - Context Data:
docs/api/*.json - Storage: Supabase Bucket
term-sheet-uploads
6. Migration Notes
- State Management: The current implementation relies on Supabase to persist chat history because Vercel functions are stateless. If migrating to a stateful server (e.g., Express.js on a VM), in-memory session stores could be used, but database persistence is recommended for reliability.
- Model Selection: The code uses
gemini-2.5-flash. If upgrading, ensure the model name is updated in thegetGenerativeModelcall. - Security: Ensure
SUPABASE_SERVICE_KEYis never exposed to the client. The frontend only uses theSUPABASE_ANON_KEY.
What's inside
6 sections covering architecture, data flow, component details, database schema, environment variables, and migration notes
Change this for your project
- Replace
jglazer75/CS01with your own repository name - Replace
docs/api/context.jsonanddocs/api/negotiation-context.jsonwith your own context files - Replace
gemini-2.5-flashwith your chosen model name - Replace
term-sheet-uploadswith your own Supabase Storage bucket name
Where it goes
Save in docs/ or the repository root. Gives agents and new contributors a map of the codebase.
Worth borrowing
- Stateless serverless functions that persist conversation history in a database, enabling multi-turn chat without server memory
- Prompt construction that injects case context, persona, and full history into each API call for coherent role-play
- Separate context JSON files for case facts and negotiation personas, keeping prompts modular and maintainable
Related Documents
PCB Design Sources for Industry-Scale Testing
Lists GitHub repos and communities where you can download real PCB designs for testing optimization at scale.
Design Document: BharatSeva AI
Describes a 10-agent AWS system that helps India's informal workers access government schemes via voice-first, serverless architecture.
OpenClaw Enterprise Transformation Plan
Transforms a single-user AI agent into a dual-mode platform supporting both viral open-source and Fortune 500 enterprise deployments through phased security, IAM, audit, multi-tenancy, and Kubernetes features.
Qwen Image and Edit: Open-sourcing and Local GGUF Generations with Lightning
Documents the Qwen-Image and Qwen-Image-Edit models, covering architecture, training, benchmarks, ComfyUI setup, and prompting techniques for local GGUF deployment.