Skip to content

MrAfoo/todo-full-stack-web-application

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Full-Stack Todo Application

A modern full-stack web application with Better Auth (frontend) and FastAPI (backend) using shared JWT authentication.

🎯 Overview

This is a production-ready todo application featuring:

  • πŸ” Better Auth + JWT: Secure authentication with token-based API access
  • βœ… Task Management: Full CRUD operations with user isolation
  • πŸ‘€ Multi-user Support: Each user has their own tasks
  • 🎨 Modern UI: Responsive design with Tailwind CSS
  • πŸ—„οΈ PostgreSQL Database: Persistent data storage
  • πŸ”’ Stateless Auth: Frontend and backend verify JWT tokens independently
  • πŸ§ͺ Comprehensive Tests: 15/15 backend tests passing

πŸš€ Quick Start (5 Minutes)

1. Set Up Environment Variables

Create .env files with the SAME SECRET KEY in both:

backend/.env:

DATABASE_URL=postgresql://postgres:password@localhost:5432/todo_db
BETTER_AUTH_SECRET=your-secret-key-min-32-chars-long-change-in-production

frontend/.env.local:

NEXT_PUBLIC_API_URL=http://localhost:8000
BETTER_AUTH_SECRET=your-secret-key-min-32-chars-long-change-in-production
DATABASE_URL=postgresql://postgres:password@localhost:5432/todo_db

⚠️ CRITICAL: The BETTER_AUTH_SECRET must be identical in both files!

2. Set Up Database

# Create PostgreSQL database
createdb todo_db

# Run migrations
cd backend
uv sync
uv run alembic upgrade head

cd ../frontend
npm install
npx better-auth migrate

3. Start Services

# Terminal 1 - Backend
cd backend
uv run uvicorn app.main:app --reload --port 8000

# Terminal 2 - Frontend  
cd frontend
npm run dev

4. Access the Application

πŸ“– Documentation

πŸ—οΈ Architecture

How JWT Authentication Works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Frontend (Next.js)                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”‚
β”‚  β”‚ Better Auth  β”‚ ──▢  β”‚   JWT Token  β”‚                    β”‚
β”‚  β”‚   Server     β”‚      β”‚  (7 days)    β”‚                    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚
β”‚                               β”‚                             β”‚
β”‚                               β–Ό                             β”‚
β”‚                       Authorization: Bearer <token>         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                   Shared Secret: BETTER_AUTH_SECRET
                                β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                               β–Ό                             β”‚
β”‚                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                      β”‚
β”‚                       β”‚  JWT Verify  β”‚                      β”‚
β”‚                       β”‚  Middleware  β”‚                      β”‚
β”‚                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β”‚
β”‚                               β”‚                             β”‚
β”‚                               β–Ό                             β”‚
β”‚                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                      β”‚
β”‚                       β”‚  Task Routes β”‚                      β”‚
β”‚                       β”‚  (Filtered)  β”‚                      β”‚
β”‚                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β”‚
β”‚                    Backend (FastAPI)                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Flow:

  1. User logs in β†’ Better Auth issues JWT token (stored in HTTP-only cookie)
  2. Frontend makes API call β†’ Token attached to Authorization header
  3. Backend verifies token β†’ Uses shared secret to validate signature
  4. Backend identifies user β†’ Decodes user ID from token
  5. Backend filters data β†’ Returns only user's own tasks

πŸ“š Tech Stack

Backend

  • Framework: FastAPI
  • Database: PostgreSQL
  • ORM: SQLAlchemy 2.0
  • Migrations: Alembic
  • Authentication: JWT verification with python-jose
  • Password Hashing: Passlib + bcrypt
  • Testing: Pytest (15/15 passing βœ…)

Frontend

  • Framework: Next.js 14 (App Router)
  • Language: TypeScript
  • Authentication: Better Auth with JWT plugin
  • Styling: Tailwind CSS
  • HTTP Client: Axios (auto-attaches JWT tokens)
  • Testing: Jest + React Testing Library

πŸ”’ Security Features

Feature Description
User Isolation Each user only sees their own tasks
Stateless Auth Backend doesn't need to call frontend to verify users
Token Expiry JWT tokens expire after 7 days
Signature Verification Tokens can't be forged without the secret key
Password Hashing Better Auth handles secure bcrypt password storage
CORS Protection Restricted to allowed origins

πŸ§ͺ Testing

Backend Tests

cd backend
uv run pytest                    # Run all tests
uv run pytest --cov-report=html  # With coverage report

Results: βœ… 15/15 tests passing

  • Authentication: 8/8 tests
  • Task CRUD: 7/7 tests
  • User isolation verified
  • JWT verification working

Frontend Tests

cd frontend
npm test              # Run all tests
npm run test:watch    # Watch mode

πŸ› οΈ Development

Database Migrations

Backend (Alembic):

cd backend
uv run alembic revision --autogenerate -m "description"
uv run alembic upgrade head
uv run alembic downgrade -1

Frontend (Better Auth):

cd frontend
npx better-auth migrate

Code Quality

Backend:

cd backend
uv run black app tests      # Format
uv run flake8 app tests     # Lint
uv run mypy app             # Type check

Frontend:

cd frontend
npm run lint                # ESLint
npm run build               # Production build

πŸ“ API Endpoints

Authentication

  • POST /api/auth/register - Register new user
  • POST /api/auth/login - Login and get JWT token
  • GET /api/auth/me - Get current user info

Tasks (JWT Required)

  • GET /api/{user_id}/tasks - List all tasks
  • POST /api/{user_id}/tasks - Create new task
  • GET /api/{user_id}/tasks/{task_id} - Get task by ID
  • PUT /api/{user_id}/tasks/{task_id} - Update task
  • DELETE /api/{user_id}/tasks/{task_id} - Delete task

All task endpoints require Authorization: Bearer <token> header and enforce user ownership.

πŸ› Troubleshooting

401 Unauthorized Errors

  • βœ… Verify BETTER_AUTH_SECRET matches in both .env files
  • βœ… Check token is being sent in request headers (DevTools β†’ Network)
  • βœ… Try logout and login again to get fresh token

Database Connection Errors

  • βœ… Ensure PostgreSQL is running: pg_isready
  • βœ… Check DATABASE_URL in .env files
  • βœ… Verify database exists: psql -l | grep todo_db

Better Auth Migration Fails

  • βœ… Ensure DATABASE_URL is set in frontend/.env.local
  • βœ… Check PostgreSQL permissions
  • βœ… Try: cd frontend && npx better-auth migrate --force

CORS Errors

  • βœ… Verify backend ALLOWED_ORIGINS includes frontend URL
  • βœ… Check both services are running on correct ports
  • βœ… Clear browser cache and cookies

πŸ“¦ Project Structure

.
β”œβ”€β”€ backend/                    # FastAPI backend
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ models/            # SQLAlchemy models
β”‚   β”‚   β”œβ”€β”€ schemas/           # Pydantic schemas  
β”‚   β”‚   β”œβ”€β”€ routers/           # API endpoints
β”‚   β”‚   β”œβ”€β”€ services/          # JWT verification & auth
β”‚   β”‚   β”œβ”€β”€ config.py          # Settings with BETTER_AUTH_SECRET
β”‚   β”‚   └── main.py            # FastAPI app
β”‚   β”œβ”€β”€ tests/                 # 15 tests (all passing)
β”‚   └── alembic/               # Database migrations
β”‚
β”œβ”€β”€ frontend/                   # Next.js frontend
β”‚   β”œβ”€β”€ app/                   # Pages (login, register, dashboard)
β”‚   β”œβ”€β”€ components/            # React components
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”œβ”€β”€ auth-server.ts    # Better Auth config (JWT plugin)
β”‚   β”‚   β”œβ”€β”€ auth-client.ts    # Client-side auth helpers
β”‚   β”‚   └── api.ts            # Axios client (auto-attaches JWT)
β”‚   └── hooks/                # Custom React hooks
β”‚
β”œβ”€β”€ JWT-INTEGRATION-GUIDE.md   # Comprehensive JWT guide
β”œβ”€β”€ QUICK-START.md             # 5-minute setup
β”œβ”€β”€ IMPLEMENTATION-SUMMARY.md  # Detailed change summary
└── src/                       # Original CLI app (legacy)

πŸš€ Deployment

Production Checklist

  • Generate secure BETTER_AUTH_SECRET (32+ chars): openssl rand -base64 32
  • Set environment variables in production
  • Ensure secrets match in frontend and backend
  • Set up HTTPS/SSL certificates
  • Update ALLOWED_ORIGINS with production domain
  • Set DEBUG=False in backend
  • Run database migrations
  • Test authentication flow end-to-end

Environment Variables for Production

Backend:

DATABASE_URL=postgresql://user:pass@host:5432/todo_db
BETTER_AUTH_SECRET=<your-production-secret>
ALLOWED_ORIGINS=https://yourdomain.com
DEBUG=False

Frontend:

NEXT_PUBLIC_API_URL=https://api.yourdomain.com
BETTER_AUTH_SECRET=<same-secret-as-backend>
DATABASE_URL=postgresql://user:pass@host:5432/todo_db

πŸ“„ License

This project is built following the Spec-Kit Plus methodology.

🀝 Contributing

  1. Follow coding standards (backend: PEP 8, frontend: ESLint)
  2. Write tests for new features
  3. Update documentation as needed
  4. Ensure all tests pass before committing

About

πŸš€ Modern full-stack task manager with Next.js 14, FastAPI, PostgreSQL. Features Better Auth, JWT, dark mode & smooth animations. Production-ready with beautiful UI!

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors