Files
XQKqueue/server/internal/model/models.go
2026-07-12 15:53:24 +08:00

183 lines
6.9 KiB
Go

package model
import (
"encoding/json"
"time"
)
const (
RoleAdmin = "ADMIN"
RoleStaff = "STAFF"
// SuperAdminUsername identifies the permanent production owner account.
SuperAdminUsername = "xqkwljtadmin"
ProjectNotOpen = "NOT_OPEN"
ProjectRunning = "RUNNING"
ProjectPaused = "PAUSED"
ProjectEnded = "ENDED"
ETAFixedBatch = "FIXED_BATCH"
ETAContinuous = "CONTINUOUS"
TicketWaiting = "WAITING"
TicketCalled = "CALLED"
TicketArrived = "ARRIVED"
TicketCompleted = "COMPLETED"
TicketMissed = "MISSED"
TicketCanceled = "CANCELED"
DefaultVisitorNotice = "请您在景区附近等候,注意听从工作人员指引。"
)
type User struct {
ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()"`
Username string `gorm:"size:80;not null;uniqueIndex"`
PasswordHash string `gorm:"not null"`
Role string `gorm:"size:16;not null"`
Active bool `gorm:"not null"`
CreatedAt time.Time
UpdatedAt time.Time
}
type Project struct {
ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()"`
Code string `gorm:"size:24;not null;uniqueIndex"`
Name string `gorm:"size:120;not null"`
Status string `gorm:"size:16;not null"`
Timezone string `gorm:"size:64;not null"`
TicketPrefix string `gorm:"size:8;not null"`
CallBatchSize int `gorm:"not null"`
GracePeriodMinutes int `gorm:"not null"`
ETAMode string `gorm:"column:eta_mode;size:24;not null"`
AverageBatchIntervalSeconds int `gorm:"not null"`
ContinuousRatePerMinute float64 `gorm:"type:numeric(10,2);not null"`
ETABufferMinutes int `gorm:"column:eta_buffer_minutes;not null"`
ETAIntervalSeconds int `gorm:"column:eta_interval_seconds;not null;default:60"`
VisitorNotice string `gorm:"column:visitor_notice;size:240;not null"`
DisplayTokenHash *string `gorm:"type:char(64)"`
DeviceSimulationMode string `gorm:"size:16;not null"`
CreatedAt time.Time
UpdatedAt time.Time
}
type UserProject struct {
UserID string `gorm:"type:uuid;primaryKey"`
ProjectID string `gorm:"type:uuid;primaryKey"`
CreatedAt time.Time
}
type AuthSession struct {
ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()"`
UserID string `gorm:"type:uuid;not null;index"`
TokenHash string `gorm:"type:char(64);not null;uniqueIndex"`
ExpiresAt time.Time `gorm:"not null"`
LastSeenAt time.Time `gorm:"not null"`
RevokedAt *time.Time
CreatedIP *string `gorm:"type:inet"`
UserAgent string `gorm:"size:512;not null"`
CreatedAt time.Time
User User `gorm:"foreignKey:UserID"`
}
type QueueSession struct {
ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()"`
ProjectID string `gorm:"type:uuid;not null;index"`
BusinessDate time.Time `gorm:"type:date;not null"`
Status string `gorm:"size:16;not null"`
NextTicketNumber int `gorm:"not null"`
Revision int64 `gorm:"not null"`
OpenedAt time.Time `gorm:"not null"`
ClosedAt *time.Time
CreatedAt time.Time
UpdatedAt time.Time
}
type QueueTicket struct {
ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()"`
ProjectID string `gorm:"type:uuid;not null;index"`
QueueSessionID string `gorm:"type:uuid;not null;index"`
ReissuedFromTicketID *string `gorm:"type:uuid;uniqueIndex"`
TicketNumber int `gorm:"not null"`
DisplayNumber string `gorm:"size:24;not null"`
PublicTokenHash string `gorm:"type:char(64);not null;uniqueIndex"`
PhoneCiphertext []byte `gorm:"type:bytea"`
PhoneNonce []byte `gorm:"type:bytea"`
PhoneHMAC *string `gorm:"type:char(64);index"`
LastNameCiphertext []byte
LastNameNonce []byte
Honorific string `gorm:"size:16;not null"`
Status string `gorm:"size:16;not null;index"`
JoinedAt time.Time `gorm:"not null"`
CalledAt *time.Time
ArrivedAt *time.Time
CompletedAt *time.Time
MissedAt *time.Time
PersonalDataPurgedAt *time.Time
PersonalDataPurgeAt time.Time `gorm:"not null"`
CreatedBy string `gorm:"type:uuid;not null"`
CreatedAt time.Time
UpdatedAt time.Time
}
type CallBatch struct {
ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()"`
ProjectID string `gorm:"type:uuid;not null;index"`
QueueSessionID string `gorm:"type:uuid;not null;index"`
BatchSequence int `gorm:"not null"`
Revision int64 `gorm:"not null"`
Status string `gorm:"size:16;not null"`
RequestedBy string `gorm:"type:uuid;not null"`
CalledAt time.Time `gorm:"not null"`
CompletedAt *time.Time
CreatedAt time.Time
}
type CallBatchTicket struct {
CallBatchID string `gorm:"type:uuid;primaryKey"`
TicketID string `gorm:"type:uuid;primaryKey"`
ProjectID string `gorm:"type:uuid;not null"`
Position int `gorm:"not null"`
CreatedAt time.Time
}
type AuditEntry struct {
ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()"`
ProjectID *string `gorm:"type:uuid;index"`
ActorUserID *string `gorm:"type:uuid;index"`
Action string `gorm:"size:64;not null"`
EntityType string `gorm:"size:64;not null"`
EntityID *string `gorm:"type:uuid"`
Details json.RawMessage `gorm:"type:jsonb;not null"`
RequestID string `gorm:"size:80;not null"`
IPAddress *string `gorm:"type:inet"`
UserAgent string `gorm:"size:512;not null"`
RetainUntil time.Time `gorm:"not null"`
CreatedAt time.Time
}
type IdempotencyKey struct {
ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()"`
ProjectID string `gorm:"type:uuid;not null"`
UserID string `gorm:"type:uuid;not null"`
Scope string `gorm:"size:40;not null"`
Key string `gorm:"size:128;not null"`
RequestHash string `gorm:"type:char(64);not null"`
ResponseCode int `gorm:"not null"`
ResponseBody json.RawMessage `gorm:"type:jsonb;not null"`
ResourceID *string `gorm:"type:uuid"`
ExpiresAt time.Time `gorm:"not null"`
CreatedAt time.Time
}
type DeviceSimulation struct {
ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()"`
ProjectID string `gorm:"type:uuid;not null;index"`
CallBatchID string `gorm:"type:uuid;not null;uniqueIndex"`
Adapter string `gorm:"size:40;not null"`
Outcome string `gorm:"size:16;not null"`
Detail string `gorm:"size:500;not null"`
AttemptedAt time.Time `gorm:"not null"`
CompletedAt time.Time `gorm:"not null"`
CreatedAt time.Time
}