A full-stack task management application built with Next.js, Express, PostgreSQL, and Google Gemini AI. Designed to feel like a modern SaaS product — clean, fast, and production-ready.
- Full Task CRUD — Create, read, update, delete tasks with title, description, due date, priority, and status
- AI Suggest — Enter a rough title and let Gemini generate a professional description and suggested priority
- Filters — Filter tasks by status and priority with responsive dropdowns
- Statistics Dashboard — Live stat cards for total, in-progress, done, and high-priority tasks
- Dark Mode — Smooth light/dark theme with persisted preference
- Responsive — Works cleanly on mobile, tablet, and desktop
- Animations — Framer Motion transitions throughout — subtle, not excessive
- Error handling — Loading states, empty states, toast notifications, validation
| Tool | Purpose |
|---|---|
| Next.js 14 (App Router) | React framework |
| TypeScript | Type safety |
| Tailwind CSS | Utility-first styling |
| shadcn/ui | Accessible UI primitives |
| Framer Motion | Animations |
| React Hook Form + Zod | Form handling and validation |
| TanStack Query | Server state management |
| Axios | HTTP client |
| Tool | Purpose |
|---|---|
| Node.js + Express | REST API server |
| TypeScript | Type safety |
| Prisma ORM | Database access layer |
| PostgreSQL | Relational database |
| express-validator | Request validation |
| helmet + cors | Security middleware |
| express-rate-limit | Rate limiting |
| Tool | Purpose |
|---|---|
| Google Gemini 1.5 Flash | AI task suggestions |
taskflow/
├── backend/
│ ├── prisma/
│ │ └── schema.prisma # Database schema
│ ├── src/
│ │ ├── config/
│ │ │ └── index.ts # Environment config
│ │ ├── controllers/
│ │ │ └── task.controller.ts # Route handlers
│ │ ├── lib/
│ │ │ └── prisma.ts # Prisma client singleton
│ │ ├── middleware/
│ │ │ ├── errorHandler.ts # Global error handling
│ │ │ └── validation.ts # express-validator rules
│ │ ├── routes/
│ │ │ └── task.routes.ts # Express routes
│ │ ├── services/
│ │ │ ├── ai.service.ts # Gemini AI integration
│ │ │ └── task.service.ts # Business logic
│ │ ├── types/
│ │ │ └── task.types.ts # TypeScript interfaces
│ │ └── index.ts # Express app entry point
│ ├── .env.example
│ ├── package.json
│ └── tsconfig.json
│
└── frontend/
├── src/
│ ├── app/
│ │ ├── globals.css # Global styles + CSS variables
│ │ ├── layout.tsx # Root layout
│ │ └── page.tsx # Dashboard page
│ ├── components/
│ │ ├── layout/
│ │ │ ├── Header.tsx
│ │ │ ├── QueryProvider.tsx
│ │ │ └── ThemeProvider.tsx
│ │ ├── tasks/
│ │ │ ├── DeleteConfirmDialog.tsx
│ │ │ ├── StatsGrid.tsx
│ │ │ ├── TaskFilters.tsx
│ │ │ ├── TaskFormModal.tsx
│ │ │ └── TaskTable.tsx
│ │ └── ui/
│ │ ├── badge.tsx
│ │ ├── button.tsx
│ │ ├── dialog.tsx
│ │ ├── input.tsx
│ │ ├── label.tsx
│ │ ├── select.tsx
│ │ ├── textarea.tsx
│ │ ├── toast.tsx
│ │ └── toaster.tsx
│ ├── hooks/
│ │ ├── useTasks.ts # TanStack Query hooks
│ │ └── useToast.ts # Toast notification hook
│ ├── lib/
│ │ ├── api-client.ts # Axios instance
│ │ ├── utils.ts # cn(), formatDate(), config maps
│ │ └── validations.ts # Zod schemas
│ ├── services/
│ │ └── task.service.ts # API service layer
│ └── types/
│ └── task.ts # Shared TypeScript types
├── .env.example
├── next.config.js
├── package.json
├── postcss.config.js
├── tailwind.config.js
└── tsconfig.json
- Node.js 18+
- PostgreSQL 14+
- A Google Gemini API key (get one here)
git clone https://github.com/your-username/taskflow.git
cd taskflowcd backend
npm installCopy the environment file and fill in your values:
cp .env.example .envEdit backend/.env:
DATABASE_URL="postgresql://your_user:your_password@localhost:5432/taskflow_db"
PORT=4000
NODE_ENV=development
GEMINI_API_KEY=your_gemini_api_key_here
FRONTEND_URL=http://localhost:3000Run Prisma migrations to create the database tables:
npx prisma migrate dev --name init
npx prisma generatecd ../frontend
npm installCopy the environment file:
cp .env.example .env.localEdit frontend/.env.local:
NEXT_PUBLIC_API_URL=http://localhost:4000cd backend
npm run devThe API will be available at http://localhost:4000.
Health check: http://localhost:4000/health
cd frontend
npm run devThe app will be available at http://localhost:3000.
| Variable | Description | Example |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | postgresql://user:pass@localhost:5432/taskflow_db |
PORT |
API server port | 4000 |
NODE_ENV |
Environment | development |
GEMINI_API_KEY |
Google Gemini API key | AIza... |
FRONTEND_URL |
Frontend origin for CORS | http://localhost:3000 |
| Variable | Description | Example |
|---|---|---|
NEXT_PUBLIC_API_URL |
Backend API base URL | http://localhost:4000 |
Base URL: http://localhost:4000/api
| Method | Endpoint | Description |
|---|---|---|
GET |
/tasks |
List all tasks (supports ?status= and ?priority= filters) |
GET |
/tasks/stats |
Get dashboard statistics |
GET |
/tasks/:id |
Get a single task |
POST |
/tasks |
Create a new task |
PUT |
/tasks/:id |
Update a task |
DELETE |
/tasks/:id |
Delete a task |
POST |
/tasks/ai-suggest |
Get AI-generated description and priority |
{
"title": "Fix authentication bug",
"description": "Optional description",
"dueDate": "2025-12-31",
"priority": "HIGH",
"status": "TODO"
}{
"title": "Fix login bug"
}{
"success": true,
"data": {
"description": "Investigate and resolve the authentication failure affecting user login. Review session handling, token expiration logic, and error responses.",
"priority": "HIGH"
}
}LOW | MEDIUM | HIGH
TODO | IN_PROGRESS | DONE
200— Success201— Created400— Validation error404— Not found429— Rate limited500— Server error
The AI Suggest feature uses Google Gemini 1.5 Flash via the @google/generative-ai SDK.
Flow:
- User enters a rough task title (e.g. "Fix login bug")
- User clicks the AI Suggest button in the task form
- Frontend sends
POST /api/tasks/ai-suggestwith the title - Backend sends the title to Gemini with a structured prompt
- Gemini returns a JSON object with
descriptionandpriority - The form fields are automatically populated
- User can edit before saving
Security: The Gemini API key lives only in the backend .env file and is never exposed to the client.
- Push your backend folder to a GitHub repository
- Create a new service on Railway or Render
- Add a PostgreSQL plugin/database
- Set the environment variables (
DATABASE_URL,PORT,GEMINI_API_KEY,FRONTEND_URL,NODE_ENV=production) - Set the build command:
npm install && npx prisma generate && npm run build - Set the start command:
npm start
- Push your frontend folder to a GitHub repository
- Import the project on Vercel
- Set the environment variable:
NEXT_PUBLIC_API_URL=https://your-backend-url.railway.app - Deploy
- Task search — Full-text search across title and description
- Drag-and-drop board view — Kanban-style column layout
- Due date reminders — Email or browser notifications
- Task tags/labels — Custom categorization
- User authentication — Multi-user support with workspaces
- Activity log — History of changes per task
- Bulk actions — Select and update/delete multiple tasks
- Export — Download tasks as CSV or PDF
- Recurring tasks — Daily, weekly, monthly recurrence
MIT