A modern, scalable time tracking application built for performance and enterprise-grade deployment. Features a dynamic React TypeScript frontend and a robust, stateless Java Vert.x backend with comprehensive testing and containerization.
- Stateless Architecture: Horizontally scalable design enabling unlimited scaling behind load balancers (AWS ALB)
- Cloud-Native: Fully containerized with Docker, ready for Kubernetes/EKS deployment
- CI/CD Pipeline: AWS CodeBuild integration with automated Docker image builds and ECR deployment
- Secure Authentication: AWS Cognito with JWT token-based authentication and role-based access control
- High-Performance Database: AWS DynamoDB for massive scalability and low-latency operations
- Comprehensive Testing: 17 Java unit tests (JUnit 5 + Mockito) with 100% pass rate
- Modern Stack: Java 25 with Vert.x 5.0, React 18 with TypeScript, Material-UI
- Small Footprint: Java Vert.x framework optimized for minimal memory usage and fast performance
The application follows a modern microservices architecture with complete separation of concerns:
- Frontend: React 18 + TypeScript + Material-UI, served via Nginx in production
- Backend: Java 25 + Vert.x (non-blocking, event-driven), packaged as executable JAR
- Authentication: AWS Cognito User Pools with JWT validation
- Database: AWS DynamoDB with SDK v2
- Containerization: Multi-stage Docker builds for optimized image sizes
- Deployment: AWS EKS with Pod Identity for secure credential management
# Clone the repository
git clone <repository-url>
cd scalableReacJavaFullStackApp
# Start local DynamoDB
docker run -d -p 8000:8000 amazon/dynamodb-local
# Create Tasks table
cd react_timetracking && node createTasksTable.js && cd ..
# Configure environment (edit env_dev with your AWS Cognito details)
# Then use VSCode "Run and Debug" or:
# Terminal 1: Start Java backend
cd java_timetracking
./gradlew run
# Terminal 2: Start React frontend
cd react_timetracking
npm install
npm start
# Access the application at http://localhost:3000- Development Setup
- Docker & Containerization
- CI/CD Pipeline
- Kubernetes Deployment
- Testing
- React Frontend
- Java Backend
- Local DynamoDB Setup
.vscode/launch.json- Pre-configured to start both frontend and backendCaddyfile- Included to simulate production environment locallyenv_dev- Development environment variables
Both applications use optimized multi-stage Docker builds:
Java Backend:
- Build stage: Gradle with JDK 25
- Runtime stage: Amazon Corretto 25 (minimal JRE)
- Final image: ~200MB with executable JAR
React Frontend:
- Build stage: Node.js 22 for npm build
- Runtime stage: Nginx Alpine (minimal web server)
- Final image: ~50MB with static assets
# Build Java backend
cd java_timetracking
docker build -t java_timetracking:latest .
# Build React frontend
cd react_timetracking
docker build -t react_timetracking:latest .# Run Java backend (development with local DynamoDB)
docker run -p 8888:8888 \
-e DYNAMODB_ENDPOINT=http://host.docker.internal:8000 \
-e AWS_ACCESS_KEY_ID=fake \
-e AWS_SECRET_ACCESS_KEY=fake \
java_timetracking
# Run React frontend
docker run -p 80:80 react_timetrackingThe project includes buildspec.yml for automated builds:
- Pre-build: ECR login and commit hash tagging
- Build: Docker image creation for both applications
- Post-build: Push to ECR with
latestand commit hash tags - Artifacts: Generate
imagedefinitions.jsonfor deployment
# Automated workflow:
Git Push → CodeBuild → Docker Build → ECR Push → EKS Deploymentlatest: Always points to the most recent build<commit-hash>: Specific version for rollback capability
- Namespace:
development(configurable) - Pod Identity: Secure AWS credential injection without static keys
- Ingress: AWS ALB Controller with Cognito authentication
- Auto-scaling: Horizontal Pod Autoscaler (HPA) configured
- Service Mesh: Internal service-to-service communication
- Service Accounts with IAM role associations
- ConfigMaps for environment configuration
- Secrets for sensitive data
- HPA for automatic scaling based on CPU/memory
Test Coverage: 17 unit tests, 100% pass rate
cd java_timetracking
./gradlew testTest Suites:
-
AuthMiddlewareTest (8 tests)
- Token validation and authentication flows
- Role-based access control
- Development mode authentication bypass
-
TaskServiceTest (6 tests)
- CRUD operations with DynamoDB
- Task retrieval and listing
- Error handling for missing items
-
TaskTest (3 tests)
- Model validation
- Constructor and getter/setter tests
Technologies: JUnit 5, Mockito, Vert.x JUnit 5 integration
cd react_timetracking
npm testTest Framework: Jest + React Testing Library
A modern, responsive time tracking application built with React, TypeScript, and Material-UI. Users can track their daily work by project and task, with comprehensive reporting and analytics.
- User Authentication: Secure login/signup with AWS Cognito
- Task Management: Add, edit, and delete time tracking entries
- Project Organization: Group tasks by project for better organization
- Monthly Reports: Comprehensive analytics and reporting
- Responsive Design: Works on desktop and mobile devices
- Modern UI: Beautiful Material-UI interface
This app uses AWS Cognito for user authentication, providing:
- User registration and login
- Email verification
- Password reset functionality
- Secure session management
- User profile management
- Node.js (v14 or higher)
- npm or yarn
- AWS Account (for Cognito setup)
-
Clone the repository:
git clone <repository-url> cd react_timetracking
-
Install dependencies:
npm install
-
Set up AWS Cognito:
- Follow the instructions in AWS_COGNITO_SETUP.md
- Create a User Pool and App Client in AWS Cognito
- Get your User Pool ID and App Client ID
-
Configure environment variables:
Edit
env_devorreact_timetracking/.envand add your AWS Cognito configuration:REACT_APP_AWS_REGION=eu-north-1 REACT_APP_COGNITO_USER_POOL_ID=your-user-pool-id REACT_APP_COGNITO_CLIENT_ID=your-app-client-id
-
Start the development server:
- In VSCode use "Run and Debug".
.vscode/launch.json->env_dev. - Command line loads environment variables from
react_timetracking/.envfile.
npm start
- In VSCode use "Run and Debug".
-
Open your browser: Navigate to http://localhost:3000
- Create an account: Click "Sign Up" and enter your details
- Verify your email: Check your email for a confirmation code
- Sign in: Use your username/email and password to log in
-
Add Tasks: Click "Add Task" to log your work
- Enter project name
- Describe the task
- Set the date
- Specify hours worked
-
View Reports: Click "Monthly Report" to see analytics
- Total hours worked
- Hours by project
- Task count and project count
-
Manage Tasks: Edit or delete existing tasks as needed
-
Sign Out: Use the "Sign Out" button to securely log out
├── components/ # Reusable UI components (Login, SignUp, etc.)
├── contexts/ # React contexts (e.g., AuthContext)
├── services/ # External service integrations
│ ├── api.ts # Functions for calling the backend API
│ └── cognito.ts # Cognito/Amplify configuration and services
├── App.tsx # Main application component
└── index.tsx # Application entry point
The app uses the following environment variables:
REACT_APP_AWS_REGION: AWS region (e.g., eu-north-1)REACT_APP_COGNITO_USER_POOL_ID: Cognito User Pool IDREACT_APP_COGNITO_CLIENT_ID: Cognito App Client ID
For detailed instructions on setting up AWS Cognito, see AWS_COGNITO_SETUP.md.
npm start: Start development servernpm build: Build for productionnpm test: Run testsnpm eject: Eject from Create React App
- New Components: Add to
src/components/ - API Functions: Add to
src/api.ts - Authentication: Use the
useAuthhook fromsrc/contexts/AuthContext.tsx
npm run buildFor production deployment:
- Update the
react_timetracking/public/app-config.js - Configure CORS settings in AWS Cognito
- Set up proper environment variables
- Use HTTPS in production
- Authentication errors: Check your AWS Cognito configuration
- Build errors: Ensure all dependencies are installed
- CORS errors: Configure allowed origins in Cognito
Enable debug logging by adding to src/aws-config.ts:
const awsConfig = {
Auth: {
// ... existing config
},
Logging: {
level: 'DEBUG'
}
};For issues and questions:
- Check the AWS_COGNITO_SETUP.md for authentication setup
- Review the troubleshooting section above
- Create an issue in the repository
- All authentication is handled securely through AWS Cognito
- Passwords are never stored locally
- Sessions are managed securely
- HTTPS is required in production
For more security information, see the AWS Cognito documentation.
This is a Java Vert.x server application that provides a REST API for task management with AWS DynamoDB storage and AWS Cognito User Pools authentication.
- REST API for CRUD operations on tasks
- AWS DynamoDB integration for data persistence
- AWS Cognito User Pools authentication
- JWT token validation
- Role-based access control
- Executable JAR with all dependencies included
- Java 25 or higher
- AWS account with DynamoDB and Cognito User Pools configured
- AWS credentials configured (via AWS CLI, environment variables, or IAM roles)
The application uses the following environment variables from env_dev for AWS Cognito configuration:
-
COGNITO_USER_POOL_ID: Your AWS Cognito User Pool ID -
COGNITO_CLIENT_ID: Your AWS Cognito App Client ID -
AWS_REGION: AWS region (e.g., eu-north-1) -
DYNAMODB_ENDPOINT=http://localhost:8000DynamoDB endpoint for dev env -
dev=trueDisables auhtentification for development in backend -
port=8888Vert.x server port and host -
host=localhost
./gradlew shadowJarThis creates an executable JAR file at build/libs/java_timetracking-1.0.0.jar
If you set dev=true environment variable, the backend will run without authentication:
java -jar build/libs/java_timetracking-1.0.0.jarSet the required environment variables and run: NB: in EC2 instance DYNAMODB_ENDPOINT not needed. Instance should have IAM role for DynamoDB access.
export COGNITO_USER_POOL_ID="your-user-pool-id"
export COGNITO_CLIENT_ID="your-client-id"
export AWS_REGION="eu-north-1"
export DYNAMODB_ENDPOINT=http://localhost:8000
export port=80
export host=127.0.0.1
java -jar build/libs/java_timetracking-1.0.0.jarAll API endpoints are prefixed with /api.
POST /api/auth/login- Authenticate user with username and password{ "username": "user@example.com", "password": "password" }
GET /api/tasks- List all tasksGET /api/tasks/:id- Get task by IDPOST /api/tasks- Create new taskPUT /api/tasks/:id- Update taskDELETE /api/tasks/:id- Delete task
{
"id": 1234567890,
"date": "2025-07-05",
"project": "Project Name",
"hours": 8,
"task": "Task description"
}- Login: Use the
/api/auth/loginendpoint with username and password - Get Token: The response includes an
idToken(JWT) - API Calls: Include the token in the Authorization header:
Authorization: Bearer <your-jwt-token>
- Create a Cognito User Pool in AWS Console
- Create an App Client in the User Pool
- Configure the App Client to allow USER_PASSWORD_AUTH
- Note down the User Pool ID and App Client ID
- Set up users in the User Pool
401 Unauthorized: Missing or invalid authentication token403 Forbidden: Insufficient permissions503 Service Unavailable: Authentication service not configured
./gradlew testTest Results: 17 tests across 3 test suites
- ✅ AuthMiddlewareTest: 8 tests
- ✅ TaskServiceTest: 6 tests
- ✅ TaskTest: 3 tests
./gradlew shadowJar -x test# Build Docker image
docker build -t java_timetracking:latest .
# Run with local DynamoDB
docker run -p 8888:8888 \
-e DYNAMODB_ENDPOINT=http://host.docker.internal:8000 \
-e AWS_ACCESS_KEY_ID=fake \
-e AWS_SECRET_ACCESS_KEY=fake \
java_timetracking- MainVerticle: Main application entry point and HTTP server setup
- TaskService: Business logic for task operations with DynamoDB
- CognitoAuthService: AWS Cognito authentication and JWT validation
- AuthMiddleware: HTTP middleware for authentication and authorization
- DynamoDBClientProvider: AWS DynamoDB client configuration
- Java: 25 (LTS)
- Framework: Vert.x 5.0 (non-blocking, event-driven)
- Build Tool: Gradle 9.0 with Shadow plugin for fat JAR
- AWS SDK: 2.40 (DynamoDB, Cognito)
- Authentication: Auth0 JWT 4.4.0 + JWKS RSA 0.22.1
- JSON Processing: Jackson 2.17.1
- Logging: SLF4J 2.0.13 + Logback 1.5.19
- Testing: JUnit 5.10.2, Mockito 5.11.0
- React: 18.3.1
- TypeScript: 4.9.5
- UI Framework: Material-UI 5.15.21
- State Management: React Context API
- Authentication: amazon-cognito-identity-js 6.3.15
- AWS SDK: @aws-sdk/client-dynamodb 3.840.0
- Build Tool: react-scripts 5.0.1
- Testing: Jest, React Testing Library
- Containerization: Docker (multi-stage builds)
- Container Registry: AWS ECR
- Orchestration: AWS EKS (Kubernetes)
- Load Balancer: AWS ALB with Cognito integration
- Database: AWS DynamoDB
- CI/CD: AWS CodeBuild
- Authentication: AWS Cognito User Pools
- IAM: EKS Pod Identity for secure credential injection
- Vert.x Core and Web for HTTP server
- AWS SDK for DynamoDB and Cognito
- Auth0 JWT library for token validation
- Jackson for JSON processing
- JUnit 5 for testing
For development, it's recommended to use local DynamoDB to avoid AWS costs and enable offline development.
# Run DynamoDB Local in Docker
docker run -p 8000:8000 amazon/dynamodb-local
# Verify it's running
curl http://localhost:8000Download from: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html
The application requires a Tasks table with primary key id (Number).
# Using AWS CLI with local endpoint
aws dynamodb create-table \
--table-name Tasks \
--attribute-definitions AttributeName=id,AttributeType=N \
--key-schema AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--endpoint-url http://localhost:8000
# Or use the provided script
cd react_timetracking
node createTasksTable.jsSet DYNAMODB_ENDPOINT=http://localhost:8000 in your environment to use local DynamoDB.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
My Slack: friendly-solutions
MIT License Free to use unless reference to my homepage https://friendly-solution.com/ not removed ;)