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