- Go 1.24 or higher
- GVM (optional, for managing Go versions)
-
Clone the repository:
git clone https://github.com/WangWilly/labs-hr-go.git cd labs-hr-go -
Install dependencies:
go mod download
-
Run the development server:
./scripts/dev.sh
-
Build the Docker image using the provided build script:
./scripts/build.sh
This will create a Docker image named
labs-hr-go:latest. -
Run the service using Docker Compose:
cd deployments docker compose up -dThis will start the service in detached mode, listening on port 8080.
-
To stop the service:
docker compose down
-
Monitor logs:
docker compose logs -f
- Docker and Docker Compose for local database setup
Set up the local database environment using the provided script:
./scripts/local_setup.shThis script will:
- Navigate to the deployment directory
- Verify Docker is running
- Check if Docker Compose is installed
- Start the required database containers
-
Create a new migration file in the
database/migrationsdirectory following the naming conventionNNNNN_description.go, whereNNNNNis a sequential number.Example structure (see example):
package migrations import ( "context" "github.com/WangWilly/labs-hr-go/pkgs/models" "github.com/WangWilly/labs-hr-go/pkgs/utils" ) // UpNNNNNDescription runs the "up" migration func UpNNNNNDescription(ctx context.Context) error { // Migration logic to apply changes return nil } // DownNNNNNDescription runs the "down" migration func DownNNNNNDescription(ctx context.Context) error { // Migration logic to revert changes return nil }
-
In the
Upfunction, implement the changes you want to apply to the database (create tables, add columns, etc.). -
In the
Downfunction, implement the logic to revert those changes (drop tables, remove columns, etc.).
Execute migrations using the migration command:
go run database/cmd/main.go- Always create both
UpandDownfunctions for each migration - Test migrations in development before applying to production
- Keep migrations idempotent when possible
- Use transactions for complex migrations to ensure atomicity
If you encounter issues with migrations:
- Check the database connection settings
- Verify that the migration files are properly formatted
- Look for error messages in the application logs
- Reset the database if needed during development
- Gormigrate Documentation
- Goose Documentation
- GORM Migrations
- Stack Overflow: GORM Migration with golang-migrate
The HR management system provides RESTful APIs for managing employees and attendance records. All requests and responses use JSON format.
Creates a new employee record with their position information.
curl --location 'http://localhost:8080/employee' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Will",
"age": 39,
"address": "united states",
"phone": "654321232",
"email": "[email protected]",
"position": "tester",
"department": "tech",
"salary": 4000,
"start_date": 1746365072
}'Response (200 OK):
{
"employee_id": 1,
"position_id": 1
}Request Parameters:
name(string, required): Employee's full nameage(integer, required): Employee's ageaddress(string, required): Employee's addressphone(string, required): Contact phone numberemail(string, required): Contact email addressposition(string, required): Job position titledepartment(string, required): Department namesalary(number, required): Monthly salary amountstart_date(unix timestamp, required): Employment start date
Error Responses:
- 400 Bad Request: Invalid request format or missing required fields
- 500 Internal Server Error: Server-side processing error
Retrieves detailed information about an employee by ID.
curl --location 'http://localhost:8080/employee/1'Response (200 OK):
{
"employee_id": 1,
"name": "Will",
"age": 39,
"phone": "654321232",
"email": "[email protected]",
"address": "united states",
"created_at": "2025-05-04 13:26:51",
"updated_at": "2025-05-04 13:26:51",
"position_id": 1,
"position": "tester",
"department": "tech",
"salary": 4000,
"start_date": "2025-05-04 00:00:00"
}Error Responses:
- 400 Bad Request: Invalid ID format
- 404 Not Found: Employee not found
Updates an existing employee's information. All fields are optional - only include fields you want to update.
curl --location --request PUT 'http://localhost:8080/employee/1' \
--header 'Content-Type: application/json' \
--data '{
"address": "taiwan"
}'Response (200 OK):
{
"id": 1,
"name": "Will",
"age": 39,
"address": "taiwan",
"phone": "654321232",
"email": "[email protected]"
}Request Parameters:
name(string, optional): Updated employee nameage(integer, optional): Updated employee ageaddress(string, optional): Updated addressphone(string, optional): Updated phone numberemail(string, optional): Updated email address
Error Responses:
- 400 Bad Request: Invalid ID format or request body
- 404 Not Found: Employee not found
- 500 Internal Server Error: Update operation failed
Updates an employee's position, department, or salary information.
curl --location 'http://localhost:8080/promote/1' \
--header 'Content-Type: application/json' \
--data '{
"position": "tester2",
"department": "tech",
"salary": 5000,
"start_date": 1747365072
}'Response (200 OK):
{
"position_id": 5,
"start_date": "2025-05-16 11:11:12"
}Request Parameters:
position(string, required): New position titledepartment(string, required): New department namesalary(number, required): New salary amountstart_date(unix timestamp, required): When the promotion takes effect
Error Responses:
- 400 Bad Request: Invalid request format or missing required fields
- 404 Not Found: Employee not found
- 500 Internal Server Error: Promotion operation failed
Records an attendance entry when an employee starts work.
curl --location 'http://localhost:8080/attendance' \
--header 'Content-Type: application/json' \
--data '{
"employee_id": 1
}'Response (200 OK):
{
"attendance_id": 1,
"position_id": 3,
"clock_in_time": "2025-05-04 13:41:15",
"clock_out_time": ""
}Request Parameters:
employee_id(integer, required): ID of the employee clocking in
Error Responses:
- 400 Bad Request: Invalid employee ID or already clocked in
- 404 Not Found: Employee not found
- 500 Internal Server Error: Clock-in operation failed
Records when an employee ends their workday.
curl --location --request PUT 'http://localhost:8080/attendance/1' \
--header 'Content-Type: application/json'Response (200 OK):
{
"attendance_id": 1,
"position_id": 3,
"clock_in_time": "2025-05-04 13:41:15",
"clock_out_time": "2025-05-04 17:30:22"
}Error Responses:
- 400 Bad Request: Invalid ID format or already clocked out
- 404 Not Found: Attendance record not found
- 500 Internal Server Error: Clock-out operation failed
Retrieves an attendance record by ID.
curl --location 'http://localhost:8080/attendance/1'Response (200 OK):
{
"attendance_id": 1,
"position_id": 3,
"clock_in_time": "2025-05-04 13:41:15",
"clock_out_time": "2025-05-04 17:30:22"
}Error Responses:
- 400 Bad Request: Invalid ID format
- 404 Not Found: Attendance record not found
| Name | Description | Default |
|---|---|---|
| PORT | The port on which the service listens | 8080 |
| HOST | The host address for the service | 0.0.0.0 |
| Name | Description | Default |
|---|---|---|
| DB_HOST | Database server hostname | - |
| DB_PORT | Database server port | 3306 |
| DB_USER | Database username | - |
| DB_PASSWORD | Database password | - |
| DB_DATABASE | Database name | - |
| Name | Description | Default |
|---|---|---|
| DB_SEED | Whether to seed the database with sample data | false |
# Run with database seeding enabled
DB_SEED=true go run cmd/main.go
# Custom database connection
DB_HOST=localhost DB_PORT=3306 DB_USER=myuser DB_PASSWORD=mypass DB_DATABASE=mydb go run cmd/main.goWhen using Docker Compose, configure these variables in the deployments/docker-compose.yml file.