A full-stack todo list application with JWT authentication, built with AngularJS frontend, AdonisJS backend, and PostgreSQL database, all containerized with Docker.
- π JWT Authentication: Secure register, login, and logout functionality
- π CRUD Operations: Create, read, update, and delete todos
- β‘ Real-time Updates: Update todos with optimistic UI feedback
- π Search & Filter: Search todos and filter by completion status
- π Statistics: View total, completed, and pending todo counts
- π± Responsive Design: Modern UI with Bootstrap 5
- π³ Docker Ready: Complete containerization setup
- πΎ Database Persistence: PostgreSQL with proper migrations
- π‘οΈ Route Protection: Secure frontend routing with authentication guards
- β° Timestamps: Display creation and update times for todos
- AngularJS 1.8.3: Single-page application framework
- Bootstrap 5: Responsive UI framework
- Font Awesome: Icons
- Nginx: Web server for production
- JWT Authentication: Secure token-based authentication
- AdonisJS 6: Node.js web framework
- TypeScript: Type-safe JavaScript
- Lucid ORM: Database ORM
- JWT Authentication: Secure token-based authentication
- Custom JWT Middleware: Token validation and user context
- PostgreSQL 15: Relational database
- Migrations: Database schema management
- Docker: Containerization
- Docker Compose: Multi-container orchestration
todo_list_angular/
βββ backend/ # AdonisJS backend
β βββ app/
β β βββ controllers/ # API controllers (Auth, Todos)
β β βββ models/ # Database models (User, Todo)
β β βββ middleware/ # Custom middleware (JWT, Auth)
β β βββ services/ # Business logic (JWT Service)
β β βββ validators/ # Request validators
β βββ config/ # Configuration files
β βββ database/
β β βββ migrations/ # Database migrations
β βββ start/
β β βββ routes.ts # API routes
β β βββ kernel.ts # Middleware configuration
β βββ Dockerfile
βββ frontend/ # AngularJS frontend
β βββ app/
β β βββ views/ # HTML templates (Login, Register, Todos)
β βββ js/
β β βββ controllers/ # AngularJS controllers
β β βββ services/ # API services (Auth, Todo, Test)
β βββ css/ # Custom styles
β βββ index.html # Main application entry point
β βββ Dockerfile
βββ docker-compose.yml # Docker orchestration
βββ docker-compose.prod.yml # Production Docker configuration
βββ docker-restart.bat # Windows Docker restart script
βββ docker-restart.sh # Linux/Mac Docker restart script
βββ start.bat # Windows startup script
βββ start.sh # Linux/Mac startup script
βββ README.md
- Docker and Docker Compose installed
- Git
-
Clone the repository
git clone <repository-url> cd todo_list_angular
-
Start the application
# Windows start.bat # Linux/Mac ./start.sh # Or manually docker-compose up --build
-
Access the application
- Frontend: http://localhost:8080
- Backend API: http://localhost:3333
- Database: localhost:5432
- Register a new account at http://localhost:8080/register
- Login with your credentials
- Start creating todos!
-
Navigate to backend directory
cd backend -
Install dependencies
npm install
-
Set up environment
cp .env.example .env # Edit .env with your database credentials -
Generate APP_KEY (if not already done)
node ace generate:key
-
Run migrations
node ace migration:run
-
Start development server
npm run dev
node ace migration:run- Run pending migrationsnode ace migration:rollback- Rollback last migrationnode ace migration:status- Check migration statusnode ace make:controller <name>- Create new controllernode ace make:model <name>- Create new modelnode ace make:migration <name>- Create new migrationnode ace make:validator <name>- Create new validatornpm run dev- Start development server with hot reloadnpm run build- Build for production
-
Navigate to frontend directory
cd frontend -
Install dependencies
npm install
-
Start development server
npm start
POST /api/auth/register- Register new userPOST /api/auth/login- Login user (returns JWT token)POST /api/auth/logout- Logout userGET /api/auth/me- Get current user info
GET /api/todos- Get all todos for authenticated userPOST /api/todos- Create new todoGET /api/todos/:id- Get specific todoPUT /api/todos/:id- Update todoDELETE /api/todos/:id- Delete todo
GET /- API health checkGET /api/test- Backend connectivity test
id(Primary Key)fullName(String)email(String, Unique)password(String, Hashed)created_at(Timestamp)updated_at(Timestamp)
id(Primary Key)title(String)description(Text, Optional)completed(Boolean)user_id(Foreign Key to Users)created_at(Timestamp)updated_at(Timestamp)
- Docker Desktop (Windows/Mac) or Docker Engine (Linux)
- Docker Compose
- Node.js 20+ (for local development)
Windows:
# Start development environment
docker-setup.bat dev
# Start production environment
docker-setup.bat prod
# Stop all containers
docker-setup.bat stop
# View logs
docker-setup.bat logs
# Run database migrations
docker-setup.bat migrate
# Clean up everything
docker-setup.bat cleanupLinux/Mac:
# Make script executable (first time only)
chmod +x docker-setup.sh
# Start development environment
./docker-setup.sh dev
# Start production environment
./docker-setup.sh prod
# Stop all containers
./docker-setup.sh stop
# View logs
./docker-setup.sh logs
# Run database migrations
./docker-setup.sh migrate
# Clean up everything
./docker-setup.sh cleanupDevelopment Environment:
# Start all services
docker-compose up --build -d
# View logs
docker-compose logs -f
# Stop services
docker-compose downProduction Environment:
# Start production services
docker-compose -f docker-compose.prod.yml up --build -d
# View logs
docker-compose -f docker-compose.prod.yml logs -f
# Stop services
docker-compose -f docker-compose.prod.yml down- Frontend: http://localhost:8080 (Nginx)
- Backend API: http://localhost:3333 (AdonisJS)
- Database: localhost:5432 (PostgreSQL)
- Application: http://localhost (Nginx)
- Backend API: Internal (via Nginx proxy)
- Database: Internal (PostgreSQL)
-
Backend Environment: Copy
backend/.env.exampletobackend/.envand update the values:cp backend/.env.example backend/.env
-
Important: Update the
APP_KEYinbackend/.envwith a secure random string:# Generate a secure key node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
The database will be automatically created and migrations will run on first startup. The Docker containers now include automatic migration execution:
# Automatic migrations (recommended)
# Migrations run automatically when containers start
# Manual migration execution (if needed)
# Development
docker-compose exec backend node ace migration:run
# Production
docker-compose -f docker-compose.prod.yml exec backend node ace migration:run
# Force rebuild with fresh migrations
docker-restart.bat # Windows
./docker-restart.sh # Linux/MacAll services include health checks:
- PostgreSQL: Checks database connectivity
- Backend: Checks AdonisJS health endpoint
- Frontend: Checks Nginx response
-
Database Migration Issues: If you see "relation does not exist" errors:
# Use the restart script to rebuild with migrations docker-restart.bat # Windows ./docker-restart.sh # Linux/Mac # Or manually rebuild docker-compose down docker-compose build --no-cache docker-compose up -d
-
Port Conflicts: If ports 80, 8080, 3333, or 5432 are in use, modify the port mappings in
docker-compose.yml -
Database Connection Issues: Ensure PostgreSQL is healthy before starting the backend:
docker-compose ps
-
Build Issues: Clean up and rebuild:
docker-compose down -v docker system prune -f docker-compose up --build
-
View Service Logs:
# All services docker-compose logs -f # Specific service docker-compose logs -f backend docker-compose logs -f frontend docker-compose logs -f postgres
-
Node.js Version Issues: If you see "Invalid regular expression flags" errors:
# Ensure you're using Node.js 20+ node --version # The Docker setup uses Node.js 20 automatically # For local development, upgrade to Node.js 20+
- Registration/Login β Backend validates credentials
- JWT Token Generated β Secure token with user info
- Token Stored β Frontend stores token in cookies
- API Requests β Token sent in Authorization header
- Middleware Validation β Backend validates token on protected routes
- User Context β Authenticated user available in controllers
PORT=3333
HOST=0.0.0.0
NODE_ENV=development
DB_CONNECTION=pg
DB_HOST=postgres
DB_PORT=5432
DB_USER=todo_user
DB_PASSWORD=todo_password
DB_DATABASE=todo_db
APP_KEY=your-secret-app-key-here
SESSION_DRIVER=cookie-
Update environment variables for production
-
Build and start containers
docker-compose -f docker-compose.yml up --build -d
-
Set up reverse proxy (Nginx/Apache) for SSL and domain routing
-
Database connection errors
- Ensure PostgreSQL container is running:
docker-compose up postgres -d - Check database credentials in .env file
- Verify database exists:
docker-compose exec postgres psql -U todo_user -d todo_db
- Ensure PostgreSQL container is running:
-
Migration errors
- Make sure database is running first
- Check if migrations are pending:
node ace migration:status - Run migrations:
node ace migration:run
-
Frontend not loading
- Verify backend API is accessible at http://localhost:3333
- Check browser console for errors
- Ensure CORS is properly configured
-
Authentication issues
- Clear browser cookies
- Check JWT token in browser dev tools
- Verify APP_KEY is set in .env file
- Check backend console for JWT middleware logs
-
401 Unauthorized errors
- Verify JWT token is being sent in Authorization header
- Check if token is expired
- Ensure user exists in database
- Check backend JWT middleware logs
-
Time not displaying
- Check browser console for date formatting errors
- Verify todo data structure in network tab
- Check if created_at field is present in API response
# View all logs
docker-compose logs
# View specific service logs
docker-compose logs backend
docker-compose logs frontend
docker-compose logs postgres
# Follow logs in real-time
docker-compose logs -f backendcd backend
npm testcd frontend
npm test-
Authentication Flow
- Register new user
- Login with credentials
- Verify JWT token is stored
- Test logout functionality
-
Todo Operations
- Create new todos
- Edit existing todos
- Update todo completion status
- Delete todos
- Test search and filtering
-
Route Protection
- Try accessing todos without authentication
- Verify redirect to login page
- Test authenticated access to todos
- Optimistic Updates: Immediate UI feedback for better UX
- JWT Token Caching: Efficient authentication state management
- Database Indexing: Optimized queries for user-specific todos
- Responsive Design: Works on all device sizes
- Error Handling: Comprehensive error management and user feedback
- JWT Authentication: Secure token-based authentication
- Password Hashing: Bcrypt password encryption
- Route Protection: Frontend and backend route guards
- CORS Configuration: Proper cross-origin resource sharing
- Input Validation: Request validation on all endpoints
- SQL Injection Protection: ORM-based database queries
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
This project is licensed under the ISC License - see the LICENSE file for details.
For support and questions, please open an issue in the repository.
- β Fixed JWT authentication flow
- β Resolved 401 Unauthorized errors
- β Fixed "Loading application..." issue
- β Implemented proper time display
- β Added comprehensive error handling
- β Improved route protection
- β Enhanced debugging and logging
- β Optimized authentication state management
- β Fixed Docker database migration issues
- β Added automatic migration execution on container startup
- β Created Docker restart scripts for easier troubleshooting
- β Removed checkbox UI element from todo items
- β Streamlined todo completion status management