- 알림(Notification) 모델/이벤트 발행(프로젝트 추가·휴가/초과근무 승인·인센티브 반영/지급·정산 확정) + 메일함 API - 근무상태 기록(WorkStatusEvent: 출근/퇴근/휴식/미팅/이동), 출퇴근은 Attendance도 갱신 - 남은 연차(소수점) 엔드포인트, 관리자 근무관리용 집계/로그 조회 - 프로필 사진(Member.AvatarKey) 업로드/스트리밍 - Keycloak 최초 로그인 자동 Member 프로비저닝(ensureMember, rank/부서 nullable) - 프로젝트 scope=mine(나의 업무는 관리자도 본인 참여분만), nav에 메일함·근무관리·프로젝트관리·내프로필 추가 - 운영 안전: SEED 기본값 false(로컬만 SEED=true), ADMIN_GROUPS 기본 'admin' Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
f83724b995
commit
a904cbf9b9
@@ -39,10 +39,14 @@ type Member struct {
|
||||
Status string `json:"status"` // active | inactive
|
||||
JoinDate *time.Time `json:"joinDate"`
|
||||
AnnualLeave float64 `json:"annualLeave"` // granted 연차 days for the year
|
||||
AvatarKey string `json:"avatarKey"` // S3 key of profile photo (empty = none)
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
// HasAvatar reports whether a profile photo is set.
|
||||
func (m *Member) HasAvatar() bool { return m.AvatarKey != "" }
|
||||
|
||||
func (m *Member) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil }
|
||||
|
||||
// Department is an org unit. Lightweight; the lead is a Member email.
|
||||
@@ -68,3 +72,30 @@ type AuditLog struct {
|
||||
}
|
||||
|
||||
func (m *AuditLog) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil }
|
||||
|
||||
// Notification is a per-member inbox event (프로젝트 추가·휴가 승인·인센티브 반영 등).
|
||||
type Notification struct {
|
||||
Base
|
||||
Recipient string `gorm:"index" json:"recipient"` // member email
|
||||
Type string `json:"type"` // project | leave | overtime | incentive | settlement
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body"`
|
||||
Link string `json:"link"` // in-app path, e.g. /projects/{id}
|
||||
Read bool `gorm:"index" json:"read"`
|
||||
CreatedAt time.Time `gorm:"index" json:"createdAt"`
|
||||
}
|
||||
|
||||
func (m *Notification) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil }
|
||||
|
||||
// WorkStatusEvent logs a member's presence change (출근/퇴근/휴식/미팅/이동) for the
|
||||
// admin work-management timeline. 출근/퇴근 additionally update the Attendance row.
|
||||
type WorkStatusEvent struct {
|
||||
Base
|
||||
MemberEmail string `gorm:"index" json:"memberEmail"`
|
||||
Date string `gorm:"index" json:"date"` // YYYY-MM-DD (KST)
|
||||
Status string `json:"status"` // in|out|break|meeting|move
|
||||
At time.Time `json:"at"`
|
||||
Note string `json:"note"`
|
||||
}
|
||||
|
||||
func (m *WorkStatusEvent) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil }
|
||||
|
||||
@@ -23,7 +23,7 @@ func (b *Base) ensureID() {
|
||||
func All() []interface{} {
|
||||
return []interface{}{
|
||||
// slice 1 — members / org
|
||||
&Member{}, &Department{}, &AuditLog{},
|
||||
&Member{}, &Department{}, &AuditLog{}, &Notification{}, &WorkStatusEvent{},
|
||||
// slice 2 — attendance / leave
|
||||
&Attendance{}, &LeaveRequest{}, &OvertimeRequest{}, &WorkPolicy{}, &LeaveBalance{},
|
||||
// slice 3 — projects
|
||||
|
||||
Reference in New Issue
Block a user