Documentation
¶
Index ¶
- Constants
- Variables
- func ParseBearerToken(raw string, maxLen int) string
- type ApiKeyResult
- type Datastore
- type ListTicketsFilter
- type Mysql
- func (ds Mysql) FindAllPositionGroups() ([]*proto.PositionGroup, error)
- func (ds Mysql) FindAllRanks() ([]*proto.RankExpanded, error)
- func (ds Mysql) FindAwol() ([]*proto.Awol, error)
- func (ds Mysql) FindLiteRosterByType(rosterType proto.RosterType) (*proto.LiteRoster, error)
- func (ds Mysql) FindProfileByDiscordID(discordId string) (*proto.Profile, error)
- func (ds Mysql) FindProfileByGamertag(gamertag string) (*proto.Profile, error)
- func (ds Mysql) FindProfileByKeycloakID(keycloakId string) (*proto.Profile, error)
- func (ds Mysql) FindProfilesById(userIds ...uint64) ([]*proto.Profile, error)
- func (ds Mysql) FindProfilesByPosition(positionQuery string) (*proto.LiteRoster, error)
- func (ds Mysql) FindProfilesByUsername(username string) ([]*proto.Profile, error)
- func (ds Mysql) FindRosterByType(rosterType proto.RosterType) (*proto.Roster, error)
- func (ds Mysql) FindS1UniformsRosterByType(rosterType proto.RosterType) (*proto.S1UniformsRoster, error)
- func (ds *Mysql) GetTicket(ctx context.Context, rc TicketReferenceCache, ticketID uint32, ...) (*proto.Ticket, error)
- func (ds *Mysql) GetTicketByRef(ctx context.Context, rc TicketReferenceCache, ref string, forumBase string) (*proto.Ticket, error)
- func (ds *Mysql) GetTicketFirstMessages(ctx context.Context, ticketID uint32, n int, includeHidden bool) ([]*proto.Message, uint32, error)
- func (ds *Mysql) ListCategories(ctx context.Context, rc TicketReferenceCache) ([]*proto.Category, error)
- func (ds *Mysql) ListTicketMessages(ctx context.Context, ticketID uint32, afterCursor string, perPage uint32, ...) ([]*proto.Message, string, bool, error)
- func (ds *Mysql) ListTickets(ctx context.Context, rc TicketReferenceCache, f *ListTicketsFilter) ([]*proto.Ticket, string, bool, error)
- func (ds *Mysql) LoadCategories(ctx context.Context) ([]*referencecache.CategoryRecord, error)
- func (ds *Mysql) LoadPrefixNames(ctx context.Context) (map[uint32]string, error)
- func (ds *Mysql) LoadPriorityNames(ctx context.Context) (map[uint32]string, error)
- func (ds *Mysql) LoadStatusNames(ctx context.Context) (map[uint32]string, error)
- func (ds Mysql) ValidateApiKey(rawKey string) (*ApiKeyResult, error)
- type TicketReferenceCache
Constants ¶
const ( // HotLastPostAggregation feeds getLatestForumPostDates (the // last-forum-post column on lite rosters and full profiles). With // the user_id_post_date composite it plans a loose index scan. HotLastPostAggregation = "SELECT user_id, MAX(post_date) as date FROM xf_post GROUP BY user_id" // AwolLastPostAggregation feeds FindAwol. The extra MAX(post_id) // disqualifies the loose scan; the same composite instead serves a // covering index scan. AwolLastPostAggregation = "SELECT user_id, MAX(post_date) as date, MAX(post_id) as post_id FROM xf_post GROUP BY user_id" )
HotLastPostAggregation and AwolLastPostAggregation are the derived-table bodies of the two xf_post GROUP BY hotspots (PRD #112). They are exported so the EXPLAIN-plan tests in testdb/indexes_test.go pin the exact strings production executes — editing a query here re-points the corresponding test automatically instead of leaving it green against a stale copy. The SQL is frozen per PRD #112: index, don't refactor.
Variables ¶
var ( Info = log.New(os.Stdout, "INFO: ", log.LstdFlags) Warn = log.New(os.Stdout, "WARNING: ", log.LstdFlags) Error = log.New(os.Stdout, "ERROR: ", log.LstdFlags) )
var ErrInvalidCursor = errors.New("invalid cursor")
ErrInvalidCursor signals a malformed cursor string. Handlers should map errors wrapping this sentinel to codes.InvalidArgument → HTTP 400.
Functions ¶
func ParseBearerToken ¶
ParseBearerToken extracts the raw API token from an Authorization header value. Returns "" if no Bearer scheme is present, the token is empty, or the result exceeds maxLen. Scheme name is matched case-insensitively per RFC 7235.
Types ¶
type ApiKeyResult ¶
func (*ApiKeyResult) HasScope ¶
func (r *ApiKeyResult) HasScope(name string) bool
HasScope reports whether the API key has been granted the named scope.
type Datastore ¶
type Datastore interface {
// FindProfilesById and FindProfilesByUsername return a NON-EMPTY slice of
// non-nil profiles on a nil error — no-match is gorm.ErrRecordNotFound,
// never an empty slice. Handlers index [0] under this invariant (with a
// defensive 500 guard for implementations that break it).
FindProfilesById(userId ...uint64) ([]*proto.Profile, error)
FindProfilesByUsername(username string) ([]*proto.Profile, error)
FindRosterByType(rosterType proto.RosterType) (*proto.Roster, error)
FindLiteRosterByType(rosterType proto.RosterType) (*proto.LiteRoster, error)
FindProfileByKeycloakID(keycloakId string) (*proto.Profile, error)
FindProfileByDiscordID(discordId string) (*proto.Profile, error)
FindProfilesByPosition(positionQuery string) (*proto.LiteRoster, error)
FindS1UniformsRosterByType(rosterType proto.RosterType) (*proto.S1UniformsRoster, error)
FindAllRanks() ([]*proto.RankExpanded, error)
FindAllPositionGroups() ([]*proto.PositionGroup, error)
FindAwol() ([]*proto.Awol, error)
FindProfileByGamertag(gamertag string) (*proto.Profile, error)
ValidateApiKey(rawKey string) (*ApiKeyResult, error)
// Tickets
ListTickets(ctx context.Context, rc TicketReferenceCache, filter *ListTicketsFilter) (tickets []*proto.Ticket, nextCursor string, hasMore bool, err error)
GetTicket(ctx context.Context, rc TicketReferenceCache, ticketID uint32, forumBaseURL string) (*proto.Ticket, error)
GetTicketByRef(ctx context.Context, rc TicketReferenceCache, ref string, forumBaseURL string) (*proto.Ticket, error)
GetTicketFirstMessages(ctx context.Context, ticketID uint32, n int, includeHidden bool) (msgs []*proto.Message, totalCount uint32, err error)
ListTicketMessages(ctx context.Context, ticketID uint32, afterCursor string, perPage uint32, includeHidden bool) (msgs []*proto.Message, nextCursor string, hasMore bool, err error)
ListCategories(ctx context.Context, rc TicketReferenceCache) ([]*proto.Category, error)
}
type ListTicketsFilter ¶
type ListTicketsFilter struct {
CategoryIDs []uint32
ExcludeSubcategories bool
TicketStates []string
StatusIDs []uint32
PrefixIDs []uint32
AssignedUserIDs []uint32
StarterUserIDs []uint32
ModifiedSince uint32
IncludeHidden bool
PerPage uint32
AfterCursor string
}
ListTicketsFilter carries the conjunctive filter knobs supported by ListTickets. Empty slices and zero-valued scalars mean "no filter."
type Mysql ¶
func (Mysql) FindAllPositionGroups ¶
func (ds Mysql) FindAllPositionGroups() ([]*proto.PositionGroup, error)
func (Mysql) FindAllRanks ¶
func (ds Mysql) FindAllRanks() ([]*proto.RankExpanded, error)
func (Mysql) FindLiteRosterByType ¶
func (ds Mysql) FindLiteRosterByType(rosterType proto.RosterType) (*proto.LiteRoster, error)
func (Mysql) FindProfileByDiscordID ¶
func (Mysql) FindProfileByGamertag ¶
func (Mysql) FindProfileByKeycloakID ¶
func (Mysql) FindProfilesById ¶
func (Mysql) FindProfilesByPosition ¶
func (ds Mysql) FindProfilesByPosition(positionQuery string) (*proto.LiteRoster, error)
func (Mysql) FindProfilesByUsername ¶
func (Mysql) FindRosterByType ¶
func (Mysql) FindS1UniformsRosterByType ¶
func (ds Mysql) FindS1UniformsRosterByType(rosterType proto.RosterType) (*proto.S1UniformsRoster, error)
func (*Mysql) GetTicketByRef ¶
func (*Mysql) GetTicketFirstMessages ¶
func (*Mysql) ListCategories ¶
func (*Mysql) ListTicketMessages ¶
func (*Mysql) ListTickets ¶
func (ds *Mysql) ListTickets(ctx context.Context, rc TicketReferenceCache, f *ListTicketsFilter) ([]*proto.Ticket, string, bool, error)
func (*Mysql) LoadCategories ¶
func (ds *Mysql) LoadCategories(ctx context.Context) ([]*referencecache.CategoryRecord, error)
func (*Mysql) LoadPrefixNames ¶
func (*Mysql) LoadPriorityNames ¶
func (*Mysql) LoadStatusNames ¶
func (Mysql) ValidateApiKey ¶
func (ds Mysql) ValidateApiKey(rawKey string) (*ApiKeyResult, error)
type TicketReferenceCache ¶
type TicketReferenceCache interface {
StatusName(id uint32) string
PriorityName(id uint32) string
PrefixName(id uint32) string
Category(id uint32) *referencecache.CategoryRecord
CategoryAncestors(id uint32) []uint32
CategoryTree() []*referencecache.CategoryRecord
ExpandSubtree(ids []uint32) []uint32
}
TicketReferenceCache is the slice of referencecache.ReferenceCache that tickets datastore methods need. Defined here (not pulled in via dependency) so the Datastore interface stays self-describing and easy to mock in tests.