theorose49 f83724b995
All checks were successful
build-and-push / build (push) Successful in 39s
feat: spin 백엔드 전체 구현 (근무·프로젝트·인센티브·회계)
- config/db/storage/auth/router/perms: eQMS 규약 미러링, 권한 2-tier
  (관리자 전체 / 구성원 본인·신청만), oauth2-proxy 헤더 인증 + DEV_AUTH mock
- 모델: 구성원/부서, 근무(출퇴근·휴가·공가·초과), 프로젝트(회사/제품/버전·
  작업자portion·담당자·태스크·계약·첨부·분할입금), 인센티브(설정·단계·
  유저배분·분기정산), 회계(거래·세금)
- internal/worktime: 근로기준법 월 집계 엔진
- internal/incentive: BE/non-BE × 계약금/중도금/잔금 3단계 계산 + 시뮬레이션
- 시드 데이터, Go 멀티스테이지 Dockerfile
- ADMIN_GROUPS 기본값 'admin' (전 내부 앱 공통 그룹)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 08:57:35 +09:00

64 lines
2.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package models
import (
"time"
"gorm.io/gorm"
)
// Transaction kinds for the ledger. 인센티브 지급 links the accounting side to the
// incentive engine so the "가상 포인트 vs 실제 현금" gap can be reconciled.
const (
TxnIncome = "income" // 수입 (계약 입금 등)
TxnExpense = "expense" // 비용
TxnTax = "tax" // 세금
TxnPayroll = "payroll" // 급여
TxnIncentive = "incentive" // 인센티브 지급
)
// Account is a chart-of-accounts entry (계정과목).
type Account struct {
Base
Code string `json:"code"`
Name string `json:"name"`
Type string `json:"type"` // income | expense | tax | asset | liability
CreatedAt time.Time `json:"createdAt"`
}
func (m *Account) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil }
// Transaction is a single ledger line. Optional ProjectID / MemberEmail tie it to
// project profitability and per-member incentive payouts.
type Transaction struct {
Base
Date string `gorm:"index" json:"date"` // YYYY-MM-DD
Kind string `gorm:"index" json:"kind"`
AccountID *string `json:"accountId"`
Amount float64 `json:"amount"` // signed (income +, expense/tax/payroll )
ProjectID *string `gorm:"index" json:"projectId"`
MemberEmail *string `json:"memberEmail"`
Counterparty string `json:"counterparty"`
Memo string `json:"memo"`
CreatedBy string `json:"createdBy"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
func (m *Transaction) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil }
// TaxRecord captures periodic tax obligations (부가세/원천세 등) for the dashboard.
type TaxRecord struct {
Base
Period string `json:"period"` // YYYY-MM or YYYY-Q
Type string `json:"type"`
Base_ float64 `gorm:"column:base" json:"base"`
Amount float64 `json:"amount"`
DueDate string `json:"dueDate"`
Paid bool `json:"paid"`
Memo string `json:"memo"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
func (m *TaxRecord) BeforeCreate(*gorm.DB) error { m.ensureID(); return nil }