This commit is contained in:
lfirmin
2026-05-10 18:07:51 +02:00
parent 50af2452b1
commit a5f888b3c1
59 changed files with 6682 additions and 108 deletions
+4
View File
@@ -60,6 +60,10 @@ func (a *AuthService) Can(memberRoles []string, action Action, ticket *db.Ticket
if ticket == nil {
return ""
}
// Prefer role stored on the ticket itself (populated at open time for DB panels)
if ticket.StaffRoleID != "" {
return ticket.StaffRoleID
}
if p, ok := cfg.Panels[ticket.Panel]; ok {
if t, ok := p.Types[ticket.Type]; ok {
return t.StaffRole
+51 -20
View File
@@ -15,15 +15,16 @@ import (
)
type Service struct {
db *db.TicketRepo
auth *AuthService
session *discordgo.Session
cfg *config.Provider
opening sync.Map // key: userID+":"+ticketType prevents double-click
db *db.TicketRepo
panelRepo *db.PanelConfigRepo
auth *AuthService
session *discordgo.Session
cfg *config.Provider
opening sync.Map // key: userID+":"+ticketType prevents double-click
}
func NewService(repo *db.TicketRepo, auth *AuthService, s *discordgo.Session, cfg *config.Provider) *Service {
return &Service{db: repo, auth: auth, session: s, cfg: cfg}
func NewService(repo *db.TicketRepo, panelRepo *db.PanelConfigRepo, auth *AuthService, s *discordgo.Session, cfg *config.Provider) *Service {
return &Service{db: repo, panelRepo: panelRepo, auth: auth, session: s, cfg: cfg}
}
var ErrAlreadyOpen = fmt.Errorf("already_open")
@@ -45,23 +46,53 @@ func (svc *Service) Open(ctx context.Context, guildID, userID, panelName, ticket
return existing, fmt.Errorf("%w:%s", ErrAlreadyOpen, existing.ChannelID)
}
cfg := svc.cfg.Get()
panel, ok := cfg.Panels[panelName]
if !ok {
var categoryID, claimChannelID, logChannelID, staffRoleID string
var claimReupMinutes int
yamlCfg := svc.cfg.Get()
if panel, ok := yamlCfg.Panels[panelName]; ok {
typeCfg, ok := panel.Types[ticketType]
if !ok {
return nil, fmt.Errorf("type %q not found in panel %q", ticketType, panelName)
}
categoryID = typeCfg.Category
staffRoleID = typeCfg.StaffRole
// YAML panels have no per-type claim/log routing; fall back to global config at claim/log time
} else if svc.panelRepo != nil {
dbPanel, err := svc.panelRepo.GetByName(ctx, panelName)
if err != nil || dbPanel == nil {
return nil, fmt.Errorf("panel %q not found", panelName)
}
var dbType *db.PanelType
for _, t := range dbPanel.Types {
if t.Name == ticketType {
dbType = t
break
}
}
if dbType == nil {
return nil, fmt.Errorf("type %q not found in panel %q", ticketType, panelName)
}
categoryID = dbType.CategoryID
claimChannelID = dbType.ClaimChannelID
logChannelID = dbType.LogChannelID
staffRoleID = dbType.StaffRoleID
claimReupMinutes = dbType.ClaimReupMinutes
} else {
return nil, fmt.Errorf("panel %q not found", panelName)
}
typeCfg, ok := panel.Types[ticketType]
if !ok {
return nil, fmt.Errorf("type %q not found in panel %q", ticketType, panelName)
}
// Reserve a placeholder to get the ticket number atomically
ticket := &db.Ticket{
UserID: userID,
Panel: panelName,
Type: ticketType,
ChannelID: fmt.Sprintf("pending-%d", time.Now().UnixNano()),
OpenedAt: time.Now(),
UserID: userID,
Panel: panelName,
Type: ticketType,
ChannelID: fmt.Sprintf("pending-%d", time.Now().UnixNano()),
GuildID: guildID,
ClaimChannelID: claimChannelID,
LogChannelID: logChannelID,
StaffRoleID: staffRoleID,
ClaimReupMinutes: claimReupMinutes,
OpenedAt: time.Now(),
}
if err := svc.db.Insert(ctx, ticket); err != nil {
return nil, fmt.Errorf("insert ticket: %w", err)
@@ -71,7 +102,7 @@ func (svc *Service) Open(ctx context.Context, guildID, userID, panelName, ticket
ch, err := svc.session.GuildChannelCreateComplex(guildID, discordgo.GuildChannelCreateData{
Name: channelName,
Type: discordgo.ChannelTypeGuildText,
ParentID: typeCfg.Category,
ParentID: categoryID,
PermissionOverwrites: []*discordgo.PermissionOverwrite{
{
ID: guildID,