203 lines
8.3 KiB
Go
203 lines
8.3 KiB
Go
package model
|
|
|
|
import (
|
|
"encoding/json"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
RoleAdmin = "ADMIN"
|
|
RoleStaff = "STAFF"
|
|
// SuperAdminUsername identifies the permanent production owner account.
|
|
SuperAdminUsername = "xqkwljtadmin"
|
|
// PublicVisitorUsername is a non-login system actor used for anonymous
|
|
// visitor-created tickets so existing foreign keys and idempotency records
|
|
// remain attributable without borrowing a real staff account.
|
|
PublicVisitorUsername = "public-visitor"
|
|
|
|
ProjectNotOpen = "NOT_OPEN"
|
|
ProjectRunning = "RUNNING"
|
|
ProjectPaused = "PAUSED"
|
|
ProjectEnded = "ENDED"
|
|
|
|
ETAFixedBatch = "FIXED_BATCH"
|
|
ETAContinuous = "CONTINUOUS"
|
|
|
|
CallModeTicket = "TICKET"
|
|
CallModePeople = "PEOPLE"
|
|
CallModeBoth = "BOTH"
|
|
|
|
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:"column:call_batch_size;not null"`
|
|
CallMode string `gorm:"column:call_mode;size:16;not null;default:BOTH"`
|
|
MaxCallTicketCount int `gorm:"column:max_call_ticket_count;not null;default:100"`
|
|
DefaultCallPeopleCount int `gorm:"column:default_call_people_count;not null;default:1"`
|
|
MaxCallPeopleCount int `gorm:"column:max_call_people_count;not null;default:100"`
|
|
MinPartySize int `gorm:"column:min_party_size;not null;default:1"`
|
|
MaxPartySize int `gorm:"column:max_party_size;not null;default:10"`
|
|
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"`
|
|
ExperiencedPeopleStart int `gorm:"column:experienced_people_start;not null;default:0"`
|
|
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"`
|
|
PartySize int `gorm:"column:party_size;not null;default:1"`
|
|
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"`
|
|
CallMode string `gorm:"column:call_mode;size:16;not null;default:TICKET"`
|
|
RequestedCount int `gorm:"column:requested_count;not null;default:1"`
|
|
TicketCount int `gorm:"column:ticket_count;not null;default:1"`
|
|
PeopleCount int `gorm:"column:people_count;not null;default:1"`
|
|
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
|
|
}
|