Skip to content

timotius-devin/brew-lab

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Brew Lab ☕🍵

AI-powered coffee & matcha drink generator. Tell us your mood or flavour preference, and we'll craft something you'd see on a specialty café menu.

Disclaimer: Recipes are AI-generated. The codebase was developed with AI assistance. Always use your best judgment when preparing drinks and review the code before deploying.


Quick start

Prerequisites

1. Clone

git clone https://github.com/timotius-devin/brew-lab.git
cd brew-lab

2. Start the backend

./run-be.sh

This script will:

  • Create a conda environment named brew-lab (Python 3.12) if it doesn't exist
  • Install all Python dependencies (fastapi, anthropic, uvicorn, slowapi, etc.)
  • Start the FastAPI server on http://localhost:8002

On first run, it copies .env.example.env — edit the .env file with your Anthropic API key and re-run.

3. Start the frontend (separate terminal)

./run-fe.sh

This script will:

4. Open the app

Go to http://localhost:5173, type your mood or flavour craving, and hit Brew it.


Running tests

Backend (pytest)

cd backend
conda activate brew-lab
pytest

Tests cover: health endpoint, valid prompts, off-topic rejection, empty/long prompts, bad JSON from Claude, and CORS.

Frontend (Vitest)

cd frontend
npm run test          # run once
npm run test:watch    # watch mode

Tests cover: PromptInput component (rendering, disabled state, character count) and LoadingState component.


How topic drift is prevented

Brew Lab is strictly scoped to coffee and matcha. Topic drift is prevented at three levels:

  1. System prompt — Claude is explicitly instructed to only respond to coffee, matcha, drinks, flavours, and café culture. Off-topic inputs trigger a hard-coded rejection: {"error": "I only know coffee and matcha..."}.

  2. Backend validation — The API validates every response against a strict schema. If Claude returns anything outside the expected structure (including error keys), it's caught and returned as a 400/422 error.

  3. Input sanitisation — User input is trimmed, length-limited to 300 characters, and HTML-escaped before being sent to Claude.

The API key is stored server-side only and never exposed to the browser. The Vite dev server proxies /api requests to the FastAPI backend.


Project structure

brew-lab/
├── .gitignore
├── README.md
├── run-be.sh              # Start script — backend (conda + uvicorn)
├── run-fe.sh              # Start script — frontend (npm + vite)
├── backend/
│   ├── main.py            # FastAPI app + Claude integration + rate limiting
│   ├── requirements.txt   # Python dependencies (pinned versions)
│   ├── pytest.ini         # Pytest configuration
│   ├── .env.example
│   └── tests/
│       ├── conftest.py    # Pytest fixtures + mocks
│       └── test_drinks.py # API endpoint tests
└── frontend/
    ├── index.html
    ├── package.json
    ├── package-lock.json
    ├── tsconfig.json
    ├── vite.config.ts     # Proxies /api → localhost:8002
    ├── vitest.config.ts   # Vitest configuration
    └── src/
        ├── main.tsx
        ├── App.tsx
        ├── types.ts       # Shared TypeScript interfaces
        ├── index.css      # Specialty café aesthetic
        ├── components/
        │   ├── PromptInput.tsx
        │   ├── DrinkCard.tsx
        │   └── LoadingState.tsx
        └── tests/
            ├── setup.ts
            ├── PromptInput.test.tsx
            └── LoadingState.test.tsx

Tech stack

Layer Technology
Frontend React 18 + TypeScript + Vite
Backend Python 3.12 + FastAPI
AI Claude (claude-sonnet-4-20250514)
Rate limiting slowapi (10 req/min per IP)

Contributing

  1. Fork the repo
  2. Create a branch: git checkout -b feature/your-feature
  3. Make your changes
  4. Test both servers
  5. Open a pull request

Ideas

  • Dark/light theme toggle
  • Save favourite drinks to localStorage
  • Share drink via URL
  • Seasonal drink suggestions
  • Caffeine level indicator

License

MIT

About

AI-powered coffee & matcha drink generator. Type your mood, get a specialty café recipe. Built with FastAPI, React, and Claude — because even side projects deserve rate limiting and schema validation.

Topics

Resources

Stars

Watchers

Forks

Contributors