package models import ( "time" "gorm.io/gorm" ) // Request status shared by leave/overtime approval workflows. const ( StatusPending = "pending" StatusApproved = "approved" StatusRejected = "rejected" StatusCanceled = "canceled" ) // Leave types (한국 근로기준법 기준). 연차 draws down the annual balance; the rest // are 인정/무급 categories that still count toward worked time where applicable. const ( LeaveAnnual = "annual" // 연차 LeaveHalfAM = "half_am" // 오전 반차 LeaveHalfPM = "half_pm" // 오후 반차 LeavePublic = "public" // 공가 LeaveSick = "sick" // 병가 LeaveFamily = "family" // 경조사 LeaveUnpaid = "unpaid" // 무급 ) // Attendance is one day's clock record for a member (date is YYYY-MM-DD in KST). type Attendance struct { Base MemberEmail string `gorm:"index" json:"memberEmail"` Date string `gorm:"index" json:"date"` // YYYY-MM-DD ClockIn *time.Time `json:"clockIn"` ClockOut *time.Time `json:"clockOut"` WorkMinutes int `json:"workMinutes"` // computed net worked minutes Source string `json:"source"` // web | admin | auto Note string `json:"note"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } func (m *Attendance) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil } // LeaveRequest is a member-submitted leave application. Members may only create; // admins approve/reject. Days is fractional to support 반차 (0.5). type LeaveRequest struct { Base MemberEmail string `gorm:"index" json:"memberEmail"` Type string `json:"type"` StartDate string `json:"startDate"` // YYYY-MM-DD EndDate string `json:"endDate"` Days float64 `json:"days"` Reason string `json:"reason"` Status string `gorm:"index" json:"status"` Approver string `json:"approver"` DecidedAt *time.Time `json:"decidedAt"` DecisionMemo string `json:"decisionMemo"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } func (m *LeaveRequest) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil } // OvertimeRequest is a member-submitted overtime application (관리자만 확인/승인). type OvertimeRequest struct { Base MemberEmail string `gorm:"index" json:"memberEmail"` Date string `json:"date"` Minutes int `json:"minutes"` Reason string `json:"reason"` Status string `gorm:"index" json:"status"` Approver string `json:"approver"` DecidedAt *time.Time `json:"decidedAt"` DecisionMemo string `json:"decisionMemo"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } func (m *OvertimeRequest) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil } // WorkPolicy is the company-wide work-hours policy used by the monthly timesheet // roll-up. Singleton-ish (one active row); admin editable. type WorkPolicy struct { Base Name string `json:"name"` WeeklyHours float64 `json:"weeklyHours"` // 주 소정근로시간 (기본 40) DailyStandardMin int `json:"dailyStandardMin"` // 일 소정근로분 (기본 480) CoreStart string `json:"coreStart"` // "09:00" CoreEnd string `json:"coreEnd"` // "18:00" LunchMinutes int `json:"lunchMinutes"` // 휴게(기본 60) AnnualLeaveBase float64 `json:"annualLeaveBase"` // 1년 미만/이상 기준 부여일 Active bool `json:"active"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } func (m *WorkPolicy) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil } // LeaveBalance tracks per-member annual leave usage for a given year. type LeaveBalance struct { Base MemberEmail string `gorm:"index" json:"memberEmail"` Year int `gorm:"index" json:"year"` Granted float64 `json:"granted"` Used float64 `json:"used"` } func (m *LeaveBalance) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil }