A modern full-stack web application with Better Auth authentication, AI Chatbot powered by Groq (free!), and FastAPI backend.
This is a production-ready todo application featuring:
- π€ AI Chatbot: Manage tasks conversationally using Groq's Llama 3.3 70B (FREE!). Also Voice cmd feature enabled!
- π Better Auth + JWT: Secure authentication with token-based API access
- β Task Management: Full CRUD operations with user isolation
- π§ MCP Server: Model Context Protocol for AI tool integration
- π€ Multi-user Support: Each user has their own tasks
- π¨ Modern UI: Responsive design with Tailwind CSS and dark mode
- ποΈ PostgreSQL Database: Persistent data storage
- π Stateless Auth: Frontend and backend verify JWT tokens independently
- π§ͺ Comprehensive Tests: 15/15 backend tests passing
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
GROQ_API_KEY=gsk_your_groq_api_key_herefrontend/.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- The
BETTER_AUTH_SECRETmust be identical in both files! - Get your FREE Groq API key at https://console.groq.com (takes 2 minutes!)
# 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# Terminal 1 - Backend
cd backend
uv run uvicorn app.main:app --reload --port 8000
# Terminal 2 - Frontend
cd frontend
npm run dev- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- API Docs: http://localhost:8000/docs
- AI Chat: http://localhost:3000/chat (after login)
- GROQ_SETUP.md - How to get your free Groq API key and setup
- backend/README.md - Backend API documentation
- frontend/README.md - Frontend documentation
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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:
- User logs in β Better Auth issues JWT token (stored in HTTP-only cookie)
- Frontend makes API call β Token attached to
Authorizationheader - Backend verifies token β Uses shared secret to validate signature
- Backend identifies user β Decodes user ID from token
- Backend filters data β Returns only user's own tasks
- Framework: FastAPI
- AI Provider: Groq (Llama 3.3 70B) - FREE!
- MCP Server: Model Context Protocol SDK
- Database: PostgreSQL
- ORM: SQLAlchemy 2.0
- Migrations: Alembic
- Authentication: JWT verification with python-jose
- Password Hashing: Passlib + bcrypt
- Testing: Pytest (15/15 passing β )
- Framework: Next.js 14 (App Router)
- Language: TypeScript
- Authentication: Better Auth with JWT plugin
- Styling: Tailwind CSS
- Theme: Dark/Light mode support
- HTTP Client: Axios (auto-attaches JWT tokens)
- Testing: Jest + React Testing Library
| 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 |
cd backend
uv run pytest # Run all tests
uv run pytest --cov-report=html # With coverage reportResults: β 15/15 tests passing
- Authentication: 8/8 tests
- Task CRUD: 7/7 tests
- User isolation verified
- JWT verification working
cd frontend
npm test # Run all tests
npm run test:watch # Watch modeBackend (Alembic):
cd backend
uv run alembic revision --autogenerate -m "description"
uv run alembic upgrade head
uv run alembic downgrade -1Frontend (Better Auth):
cd frontend
npx better-auth migrateBackend:
cd backend
uv run black app tests # Format
uv run flake8 app tests # Lint
uv run mypy app # Type checkFrontend:
cd frontend
npm run lint # ESLint
npm run build # Production buildPOST /api/auth/register- Register new userPOST /api/auth/login- Login and get JWT tokenGET /api/auth/me- Get current user info
GET /api/{user_id}/tasks- List all tasksPOST /api/{user_id}/tasks- Create new taskGET /api/{user_id}/tasks/{task_id}- Get task by IDPUT /api/{user_id}/tasks/{task_id}- Update taskDELETE /api/{user_id}/tasks/{task_id}- Delete task
POST /api/chat- Send message to AI chatbot, get responseGET /api/chat- List user's conversationsGET /api/chat/{conversation_id}- Get conversation history
All endpoints require Authorization: Bearer <token> header and enforce user ownership.
The AI chatbot can help you manage tasks conversationally:
Example Commands:
- "Create a task to buy groceries"
- "Show me all my tasks"
- "Mark task 5 as complete"
- "Update task 3 description to 'Buy milk and eggs'"
- "Delete the task about groceries"
- "Show me only incomplete tasks"
MCP Tools Available:
create_task- Create new taskslist_tasks- View all or filtered tasksget_task- Get specific task detailsupdate_task- Modify task propertiesdelete_task- Remove tasksmark_task_complete/mark_task_incomplete- Toggle completion status
All AI operations are automatically scoped to the authenticated user!
- β
Verify
BETTER_AUTH_SECRETmatches in both .env files - β Check token is being sent in request headers (DevTools β Network)
- β Try logout and login again to get fresh token
- β
Ensure
GROQ_API_KEYis set in backend/.env - β Get your free key at https://console.groq.com
- β Restart backend server after adding the key
- β Check backend logs for any API errors
- β
Ensure PostgreSQL is running:
pg_isready - β Check DATABASE_URL in .env files
- β
Verify database exists:
psql -l | grep todo_db
- β Ensure DATABASE_URL is set in frontend/.env.local
- β Check PostgreSQL permissions
- β
Try:
cd frontend && npx better-auth migrate --force
- β Verify backend ALLOWED_ORIGINS includes frontend URL
- β Check both services are running on correct ports
- β Clear browser cache and cookies
.
βββ backend/ # FastAPI backend
β βββ app/
β β βββ models/ # SQLAlchemy models (User, Task, Conversation)
β β βββ schemas/ # Pydantic schemas
β β βββ routers/ # API endpoints (auth, tasks, chat)
β β βββ services/ # JWT verification, AI agent
β β βββ mcp_server.py # MCP server for AI tools
β β βββ config.py # Settings (GROQ_API_KEY, BETTER_AUTH_SECRET)
β β βββ main.py # FastAPI app
β βββ tests/ # 15 tests (all passing)
β βββ alembic/ # Database migrations
β
βββ frontend/ # Next.js frontend
β βββ app/
β β βββ (auth)/ # Login & register pages
β β βββ dashboard/ # Task management dashboard
β β βββ chat/ # AI chatbot interface
β βββ components/ # React components (Navigation, Tasks, Theme)
β βββ contexts/ # Theme context for dark mode
β βββ 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
β
βββ GROQ_SETUP.md # Free AI setup guide
βββ README.md # This file
- 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_ORIGINSwith production domain - Set
DEBUG=Falsein backend - Run database migrations
- Test authentication flow end-to-end
Backend:
DATABASE_URL=postgresql://user:pass@host:5432/todo_db
BETTER_AUTH_SECRET=<your-production-secret>
GROQ_API_KEY=<your-groq-api-key>
ALLOWED_ORIGINS=https://yourdomain.com
DEBUG=FalseFrontend:
NEXT_PUBLIC_API_URL=https://api.yourdomain.com
BETTER_AUTH_SECRET=<same-secret-as-backend>
DATABASE_URL=postgresql://user:pass@host:5432/todo_dbThis project is built following the Spec-Kit Plus methodology.
- Follow coding standards (backend: PEP 8, frontend: ESLint)
- Write tests for new features
- Update documentation as needed
- Ensure all tests pass before committing