Back to .md Directory

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.

May 2, 2026
0 downloads
1 views
ai rag prompt gemini
View source

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

Node.jsGoogle Gemini APISupabaseVercel Serverless FunctionsJavaScriptJekyll

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-flash model).

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

  1. User Upload: User selects a file on the frontend.
  2. Storage: Frontend uploads the file directly to Supabase Storage bucket term-sheet-uploads.
  3. Trigger: Frontend calls the backend API /api/analyze with the uploaded filename.
  4. Processing:
    • Backend downloads the file from Supabase.
    • Extracts text using mammoth (DOCX) or pdf-parse (PDF).
    • Loads static case context from context.json.
  5. AI Analysis: Backend sends the Case Context + Term Sheet Text + Prompt to Gemini.
  6. 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.
    • POST request to /api/analyze with { 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.json for 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-flash for 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

  1. 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 negotiations table.
    • Returns sessionId.
  2. Negotiation Loop:
    • User sends message to /api/negotiate (Action: send_message) with sessionId.
    • 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.

3.2. Database Schema (Supabase)

Table: negotiations

ColumnTypeDescription
idUUIDPrimary Key (Session ID)
created_atTimestampCreation time
user_roleText'NewCo' or 'BigTech'
ai_roleTextOpposite of user_role
original_term_sheetTextExtracted text from uploaded file
historyJSONBArray of message objects: `[{ "speaker": "user
statusText'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/negotiate with file & role.
    • sendMessage(): POST (JSON) to /api/negotiate with sessionId & 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 handle multipart/form-data manually via formidable.
  • 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...
      

4. Configuration & Environment Variables

To recreate this system, the following environment variables are required:

VariableDescription
GEMINI_API_KEYGoogle AI Studio API Key
SUPABASE_URLURL of the Supabase project
SUPABASE_SERVICE_KEYService role key (backend only) for DB access
SUPABASE_ANON_KEYAnonymous 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 the getGenerativeModel call.
  • Security: Ensure SUPABASE_SERVICE_KEY is never exposed to the client. The frontend only uses the SUPABASE_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/CS01 with your own repository name
  • Replace docs/api/context.json and docs/api/negotiation-context.json with your own context files
  • Replace gemini-2.5-flash with your chosen model name
  • Replace term-sheet-uploads with 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