A backend API for managing employee time tracking, attendance, shifts, time-off requests, notifications, and user access control.
This project is built with Java, Spring Boot, Spring Security, Spring Data JPA, JWT authentication, and Microsoft SQL Server. It exposes RESTful endpoints and includes Swagger/OpenAPI documentation for testing and exploration.
The Time Tracker API is designed as a SaaS-style workforce management backend that helps organizations:
- register and manage users
- authenticate users with JWT
- track employee clock-in and clock-out activity
- manage shifts and publishing workflow
- handle time-off requests and approvals
- manage notifications
- organize users under organizations and roles
- user registration
- login with JWT
- refresh token flow
- forgot password / reset password
- change password
- email verification and resend verification
- logout endpoint
- create and manage users
- assign and remove roles
- fetch user roles
- organize users by organization
- clock in
- clock out
- fetch attendance history by user
- create shifts
- publish shifts
- fetch user shifts
- delete shifts
- submit time-off requests
- approve or reject requests
- fetch user requests
- fetch pending requests
- fetch all notifications for a user
- fetch unread notifications
- count unread notifications
- mark notifications as read
- create organization
- list organizations
- get organization by ID
- update organization
- delete organization
- Java 17
- Spring Boot
- Spring Security
- Spring Data JPA
- Hibernate
- Microsoft SQL Server
- JWT (jjwt)
- Swagger / OpenAPI
- Lombok
- Maven
src/main/java/com/kingalex/timetracker
├── config
├── controller
├── domain/entity
├── dto
├── repository
├── security
├── service
└── TimetrackerApplication.java
The API uses JWT-based stateless authentication.
/api/auth/**/swagger-ui/**/swagger-ui.html/v3/api-docs/**
- ADMIN
/api/organizations/**
- ADMIN / MANAGER
/api/shifts/**/api/reports/**/api/time-off/pending
- Authenticated users
- all remaining protected endpoints
The application uses Microsoft SQL Server with JPA/Hibernate.
- Organization
- User
- Role
- UserRole
- AttendanceRecord
- Shift
- TimeOffRequest
- Notification
- Project
- ProjectMember
- ProjectTimeLog
- AuditLog
https://dbdiagram.io/d/timetracker-655e6cb03be14957878b4975
The current database design is shown below.

Use environment variables for sensitive values instead of committing secrets into source control.
Example configuration:
spring.datasource.url=${DB_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
app.jwt.secret=${JWT_SECRET}
app.jwt.expiration=${JWT_EXPIRATION:86400000}Example values for local development:
DB_URL=jdbc:sqlserver://localhost:1433;databaseName=timetracker;encrypt=true;trustServerCertificate=true
DB_USERNAME=sa
DB_PASSWORD=your_password
JWT_SECRET=your_very_long_secret_key
JWT_EXPIRATION=86400000
git clone https://github.com/davefurn/timetracker.git
cd timetrackerSet the following environment variables in your IDE or terminal:
DB_URLDB_USERNAMEDB_PASSWORDJWT_SECRETJWT_EXPIRATION
Make sure your SQL Server instance is running and the target database exists.
Example database name:
timetracker
Using Maven wrapper:
./mvnw spring-boot:runOr on Windows:
mvnw.cmd spring-boot:run- API base URL:
http://localhost:8080 - Swagger UI:
http://localhost:8080/swagger-ui/index.html - OpenAPI docs:
http://localhost:8080/v3/api-docs
POST /api/auth/registerPOST /api/auth/loginPOST /api/auth/forgot-passwordPOST /api/auth/reset-passwordPOST /api/auth/change-passwordGET /api/auth/verify-emailPOST /api/auth/resend-verificationPOST /api/auth/refresh-tokenPOST /api/auth/logout
POST /api/usersGET /api/usersGET /api/users/{id}GET /api/users/organization/{organizationId}PUT /api/users/{id}DELETE /api/users/{id}POST /api/users/{userId}/roles/{roleName}DELETE /api/users/{userId}/roles/{roleName}GET /api/users/{userId}/roles
POST /api/organizationsGET /api/organizationsGET /api/organizations/{id}PUT /api/organizations/{id}DELETE /api/organizations/{id}
POST /api/attendance/clock-inPOST /api/attendance/clock-outGET /api/attendance/user/{userId}
POST /api/shiftsPUT /api/shifts/{id}/publishGET /api/shifts/user/{userId}DELETE /api/shifts/{id}
POST /api/time-offPUT /api/time-off/{id}/approvePUT /api/time-off/{id}/rejectGET /api/time-off/user/{userId}GET /api/time-off/pending
GET /api/notifications/user/{userId}GET /api/notifications/user/{userId}/unreadGET /api/notifications/user/{userId}/unread/countPUT /api/notifications/{id}/read
For a cleaner REST API setup, consider these properties in development:
spring.jpa.open-in-view=falseIf Hibernate auto-detects SQL Server correctly, you can remove an explicit dialect property.
Before pushing publicly:
- do not commit secrets
- ignore
target/,.idea/, local config files, and OS-generated files - use environment variables for sensitive settings
Recommended next steps for tests:
- service layer unit tests with JUnit 5 and Mockito
- controller tests with MockMvc
- integration tests for persistence and security flows
High-value starting points:
AttendanceServiceUserServiceAuthService
To move this project closer to production standard:
- replace generic
RuntimeExceptionwith custom exceptions - add a global exception handler
- move secrets fully to environment variables
- switch from
ddl-auto=updateto Flyway or Liquibase - add unit and integration tests
- add request/response examples to Swagger
- introduce audit logging for sensitive admin actions
- review authorization checks around organization boundaries
- clean up test dependencies in
pom.xml
Okoh David
Swagger contact currently set to:
- Okoh David
davidokoh2000@gmail.com