Files
boc/backend/service/hr.go
T
Bernt e5623d2f84 feat: integrate Grafana dashboards into BOC DashboardPage
- Add Infrastructure Health section with CPU/Memory/Disk panels
- Add Service Status section with PM2/Docker panels
- Create GrafanaPanel component for iframe embedding
- Build passes successfully
2026-07-29 19:03:06 +00:00

93 lines
2.3 KiB
Go

package service
import (
"context"
"database/sql"
"fmt"
"boc/repository"
)
// HRService handles business logic for HR operations
type HRService struct {
repo *repository.HRRepository
db *sql.DB
}
func NewHRService(db *sql.DB) *HRService {
return &HRService{
repo: repository.NewHRRepository(db),
db: db,
}
}
// ListEmployees returns all employees
func (s *HRService) ListEmployees(ctx context.Context) ([]repository.Employee, error) {
return s.repo.ListEmployees(ctx)
}
// GetEmployee returns a single employee by ID
func (s *HRService) GetEmployee(ctx context.Context, id string) (*repository.Employee, error) {
return s.repo.GetEmployee(ctx, id)
}
// CreateEmployee creates a new employee with validation
func (s *HRService) CreateEmployee(ctx context.Context, e *repository.Employee) error {
if e.Name == "" {
return fmt.Errorf("employee name is required")
}
if e.Email == "" {
return fmt.Errorf("employee email is required")
}
if e.Status == "" {
e.Status = "active"
}
return s.repo.CreateEmployee(ctx, e)
}
// UpdateEmployee updates an existing employee
func (s *HRService) UpdateEmployee(ctx context.Context, id string, e *repository.Employee) error {
if e.Name == "" {
return fmt.Errorf("employee name is required")
}
return s.repo.UpdateEmployee(ctx, id, e)
}
// ListLeaves returns all leave requests
func (s *HRService) ListLeaves(ctx context.Context) ([]repository.Leave, error) {
return s.repo.ListLeaves(ctx)
}
// CreateLeave creates a new leave request with validation
func (s *HRService) CreateLeave(ctx context.Context, l *repository.Leave) error {
if l.EmployeeID == "" {
return fmt.Errorf("employee ID is required")
}
if l.Type == "" {
return fmt.Errorf("leave type is required")
}
if l.Status == "" {
l.Status = "pending"
}
return s.repo.CreateLeave(ctx, l)
}
// ListTimesheets returns all timesheet entries
func (s *HRService) ListTimesheets(ctx context.Context) ([]repository.Timesheet, error) {
return s.repo.ListTimesheets(ctx)
}
// CreateTimesheet creates a new timesheet entry with validation
func (s *HRService) CreateTimesheet(ctx context.Context, t *repository.Timesheet) error {
if t.EmployeeID == "" {
return fmt.Errorf("employee ID is required")
}
if t.Hours <= 0 {
return fmt.Errorf("hours must be positive")
}
if t.Status == "" {
t.Status = "pending"
}
return s.repo.CreateTimesheet(ctx, t)
}