A full-stack todo application built with Next.js 16+, FastAPI, SQLModel, and Neon PostgreSQL following Spec-Driven Development practices using Claude Code and Spec-Kit Plus.
| Layer | Technology |
|---|---|
| Frontend | Next.js 16+ (App Router), TypeScript, Tailwind CSS |
| Backend | Python FastAPI |
| ORM | SQLModel |
| Database | Neon Serverless PostgreSQL |
| Authentication | Better Auth (JWT tokens) |
| Development | Claude Code + Spec-Kit Plus |
hackathon-todo/
├── frontend/ # Next.js application
│ ├── app/ # App Router pages
│ │ ├── (auth)/ # Authentication pages
│ │ ├── (dashboard)/ # Protected dashboard pages
│ │ ├── layout.tsx
│ │ └── page.tsx
│ ├── components/ # Reusable UI components
│ ├── lib/ # Utilities and API client
│ ├── package.json
│ └── .env.local.example
│
├── backend/ # FastAPI application
│ ├── app/
│ │ ├── models/ # SQLModel database models
│ │ ├── routes/ # API route handlers
│ │ ├── schemas/ # Pydantic schemas
│ │ ├── middleware/ # Auth middleware
│ │ ├── config.py # Configuration
│ │ ├── db.py # Database connection
│ │ └── main.py # FastAPI entry point
│ ├── requirements.txt
│ └── .env.example
│
├── specs/ # Spec-Kit Plus specifications
│ ├── features/ # Feature specifications
│ ├── api/ # API endpoint specs
│ ├── database/ # Database schema specs
│ └── ui/ # UI component specs
│
├── .spec-kit/ # Spec-Kit configuration
├── CLAUDE.md # Root navigation guide
└── README.md # This file
git clone <repository-url>
cd hackathon-todo
postgresql://user:password@host/database)# Navigate to backend directory
cd backend
# Create virtual environment
python -m venv venv
# Activate virtual environment
# On Windows:
venv\Scripts\activate
# On macOS/Linux:
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Create .env file from example
cp .env.example .env
# Edit .env and add your configuration:
# - DATABASE_URL (your Neon connection string)
# - JWT_SECRET (generate a secure random string, min 32 chars)
Example .env file:
DATABASE_URL=postgresql://user:password@ep-xxx.us-east-1.aws.neon.tech/neondb?sslmode=require
JWT_SECRET=your-super-secret-key-min-32-characters-long-please
ENVIRONMENT=development
CORS_ORIGINS=http://localhost:3000
API_HOST=0.0.0.0
API_PORT=8000
Start the backend server:
# Run with auto-reload
uvicorn app.main:app --reload
# Server will start at http://localhost:8000
# API docs available at http://localhost:8000/docs
# Navigate to frontend directory (from project root)
cd frontend
# Install dependencies
npm install
# Create .env.local file from example
cp .env.local.example .env.local
# Edit .env.local and add your configuration:
# - NEXT_PUBLIC_API_URL (backend URL)
# - BETTER_AUTH_SECRET (same as backend JWT_SECRET)
# - DATABASE_URL (same Neon connection string)
Example .env.local file:
NEXT_PUBLIC_API_URL=http://localhost:8000
BETTER_AUTH_SECRET=your-super-secret-key-min-32-characters-long-please
BETTER_AUTH_URL=http://localhost:3000
DATABASE_URL=postgresql://user:password@ep-xxx.us-east-1.aws.neon.tech/neondb?sslmode=require
Start the frontend server:
# Run development server
npm run dev
# Application will start at http://localhost:3000
http://localhost:3000Once the backend is running, access the interactive API documentation:
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/signup |
Register new user |
| POST | /api/auth/signin |
Login user |
| GET | /api/auth/me |
Get current user |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/{user_id}/tasks |
List all user tasks |
| POST | /api/{user_id}/tasks |
Create new task |
| GET | /api/{user_id}/tasks/{id} |
Get task details |
| PUT | /api/{user_id}/tasks/{id} |
Update task |
| DELETE | /api/{user_id}/tasks/{id} |
Delete task |
| PATCH | /api/{user_id}/tasks/{id}/complete |
Toggle completion |
All task endpoints require authentication via JWT token in the Authorization: Bearer <token> header.
id (UUID): Primary keyemail (VARCHAR): Unique user emailpassword_hash (VARCHAR): Bcrypt hashed passwordname (VARCHAR): User display namecreated_at (TIMESTAMP): Account creation timeid (INTEGER): Primary key (auto-increment)user_id (UUID): Foreign key to userstitle (VARCHAR): Task titledescription (TEXT): Task description (optional)completed (BOOLEAN): Completion statuscreated_at (TIMESTAMP): Creation timeupdated_at (TIMESTAMP): Last update timeThis project follows Spec-Driven Development using Claude Code and Spec-Kit Plus:
/specsbackend/CLAUDE.mdfrontend/CLAUDE.md# View feature spec
cat specs/features/task-crud.md
# View API spec
cat specs/api/rest-endpoints.md
# View database schema
cat specs/database/schema.md
cd backend
pytest
cd frontend
npm test
# Build and run with Docker Compose
docker-compose up --build
# Frontend: http://localhost:3000
# Backend: http://localhost:8000
pip install -r requirements.txtgunicorn app.main:app --workers 4 --worker-class uvicorn.workers.UvicornWorkernpm run buildnpm startOr deploy to Vercel (recommended for Next.js):
npm install -g vercel
vercel
Database Connection Error:
?sslmode=requireJWT Token Error:
JWT_SECRET is at least 32 charactersAPI Connection Error:
NEXT_PUBLIC_API_URL in .env.localAuthentication Error:
BETTER_AUTH_SECRET matches JWT_SECRETThis is a hackathon project. To contribute:
/specsCLAUDE.md filesThis project is created for the Hackathon Phase II challenge.
For questions or issues:
/specs documentationCLAUDE.md files for guidance/docsBuilt with Claude Code and Spec-Kit Plus 🚀