A conversational AI tool that conducts structured product interviews and generates software specifications.
Live Demo: specz.jasencarroll.com
| Layer | Technologies |
|---|---|
| Frontend | React 19, React Router v7, Tailwind CSS v4, shadcn/ui |
| Backend | FastAPI, SQLAlchemy, PostgreSQL |
| AI | Mistral API (devstral-small-latest), SSE streaming |
| Auth | Custom magic link implementation via Resend |
| Tooling | uv, Ruff, Bun, Biome |
| CI/CD | GitHub Actions (lint, test, build), Railway (Dockerfile) |
- Specz Mode -- AI-driven interview that asks targeted questions about your project, then generates a structured software specification from the conversation
- SpeczCheck Mode -- Paste an existing spec and receive AI-powered analysis with actionable feedback
- Magic Link Auth -- Passwordless authentication via email; tokens are SHA-256 hashed with 15-minute expiry
- Streaming Chat -- Real-time SSE streaming from Mistral AI with incremental UI rendering
- Spec Management -- List, view, copy, and download generated specifications as Markdown
User starts a new spec
|
v
Select mode: specz or speczcheck
|
+--> specz: AI conducts a product interview
| |
| v
| AI signals READY_TO_GENERATE
| |
| v
| POST /api/generate --> structured spec
|
+--> speczcheck: User pastes existing spec
|
v
AI analyzes and returns feedback
FastAPI serves both the REST API and the built React frontend in production. Key routes:
POST /api/auth/send-magic-link-- send login email via ResendGET /api/auth/verify-- validate token, create session, set cookiePOST /api/chat-- SSE streaming chat with Mistral AIPOST /api/generate-- generate a complete spec from conversation historyGET /api/specs-- list and retrieve saved specificationsGET /api/health-- health check for Railway
Single-page React app with client-side routing. The chat component reads SSE streams and renders Markdown incrementally. Protected routes require an active session.
Four tables: user, session, magic_link, and spec. Sessions have 30-day expiry with automatic renewal. Specs store the full conversation as JSON alongside the generated output.
- Python 3.13+ with uv
- Bun
- PostgreSQL
- Mistral API key
- Resend API key (for magic link emails)
# Clone
git clone https://github.com/jasencarroll/specz.git
cd specz
# Backend
cd backend
uv sync
cp .env.example .env # then fill in your keys
# Frontend
cd ../frontend
bun installCreate backend/.env:
DATABASE_URL=postgresql://localhost/specz
MISTRAL_API_KEY=your_mistral_key
RESEND_API_KEY=your_resend_key
Run both servers in separate terminals:
# Terminal 1 -- Backend (port 8000)
cd backend
uv run uvicorn app.main:app --reload --port 8000
# Terminal 2 -- Frontend (port 5173, proxies /api to backend)
cd frontend
bun run dev# Backend
cd backend
uv run ruff check . # lint
uv run ruff format . # format
uv run pytest # tests (requires PostgreSQL)
# Frontend
cd frontend
bun run lint # Biome lint
bun run build # type-check + buildThe app deploys to Railway using a multi-stage Dockerfile:
- Stage 1 --
oven/bunimage builds the React frontend - Stage 2 --
ghcr.io/astral-sh/uvimage installs backend dependencies and serves both the API and static frontend
Railway configuration is defined in railway.json with a health check at /api/health.
specz/
├── backend/
│ └── app/
│ ├── main.py # FastAPI app, CORS, static file serving
│ ├── config.py # Pydantic Settings
│ ├── database.py # SQLAlchemy engine + session
│ ├── models.py # ORM models
│ ├── schemas.py # Request/response schemas
│ ├── dependencies.py # Auth dependencies
│ ├── routes/ # auth, chat, generate, specs, health
│ ├── lib/ # auth, magic_link, email utilities
│ └── prompts/ # Mistral system prompts (specz, generate, check)
├── frontend/
│ └── src/
│ ├── App.tsx # Route definitions
│ ├── components/ # Chat, Header, SpecView, ProtectedRoute, ui/
│ ├── pages/ # Home, Auth, SpecList, SpecDetail, SpeczCheck
│ ├── hooks/ # useAuth context
│ └── lib/ # API helpers, cn() utility
├── Dockerfile # Multi-stage production build
├── railway.json # Railway deployment config
└── .github/workflows/ci.yml # CI pipeline
See LICENSE.txt.