theorose49 a904cbf9b9
All checks were successful
build-and-push / build (push) Successful in 33s
feat: 메일함·근무상태 기록·프로필 사진·자동 프로비저닝 + 인센티브 유저 노출 제한
- 알림(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>
2026-06-28 09:38:33 +09:00

40 lines
1.3 KiB
Go

// Package models defines the GORM models for spin. Each domain slice adds its
// own file (member.go, attendance.go, project.go, incentive.go, accounting.go);
// this file holds the shared Base type and the AutoMigrate registry.
package models
import (
"github.com/google/uuid"
"gorm.io/gorm"
)
// Base provides a string UUID primary key populated in a BeforeCreate hook.
type Base struct {
ID string `gorm:"primaryKey" json:"id"`
}
func (b *Base) ensureID() {
if b.ID == "" {
b.ID = uuid.NewString()
}
}
// All returns every model for AutoMigrate. Each slice appends its models here.
func All() []interface{} {
return []interface{}{
// slice 1 — members / org
&Member{}, &Department{}, &AuditLog{}, &Notification{}, &WorkStatusEvent{},
// slice 2 — attendance / leave
&Attendance{}, &LeaveRequest{}, &OvertimeRequest{}, &WorkPolicy{}, &LeaveBalance{},
// slice 3 — projects
&Company{}, &Product{}, &Version{}, &Project{}, &ProjectMember{},
&ClientContact{}, &ProjectTask{}, &Contract{}, &ContractFile{}, &PaymentSplit{},
// slice 4 — incentive
&IncentiveConfig{}, &PaymentStage{}, &UserIncentive{}, &QuarterlySettlement{},
// slice 5 — accounting
&Account{}, &Transaction{}, &TaxRecord{},
}
}
var _ = gorm.ErrRecordNotFound // keep gorm imported for slice files