Stage 17 round 6 (#18, PR D): admin Messages moderation section
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 11s
CI / ui (pull_request) Successful in 32s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m14s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 11s
CI / ui (pull_request) Successful in 32s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m14s
A new /_gm/messages console page lists posted chat messages (nudges excluded) newest-first — time, source (guest/robot/oldest identity kind), sender (linked to the user card), IP, body, game (linked to the game card) — searchable by sender name / external-id glob masks and pinnable to one game (?game=) or sender (?user=), linked from the game and user cards. The list query lives in social (raw SQL, kind='message', source via a SQL CASE), reusing the now-exported account.LikePattern. Server-rendered adminconsole MessagesView + messages.gohtml, 50/page via the shared pager. Tests: adminconsole render case; backend integration AdminListMessages (real Postgres) — nudge exclusion, game/sender pins, glob masks, source. Docs: ARCHITECTURE section 8 chat moderation, PLAN round-6.
This commit is contained in:
@@ -51,11 +51,11 @@ func (s *Store) IsRobot(ctx context.Context, accountID uuid.UUID) (bool, error)
|
||||
func userListWhere(f UserFilter) (string, []any) {
|
||||
args := []any{f.Robots}
|
||||
where := robotExists + ` = $1`
|
||||
if name := likePattern(f.NameMask); name != "" {
|
||||
if name := LikePattern(f.NameMask); name != "" {
|
||||
args = append(args, name)
|
||||
where += fmt.Sprintf(` AND a.display_name ILIKE $%d ESCAPE '\'`, len(args))
|
||||
}
|
||||
if ext := likePattern(f.ExternalIDMask); ext != "" {
|
||||
if ext := LikePattern(f.ExternalIDMask); ext != "" {
|
||||
args = append(args, ext)
|
||||
where += fmt.Sprintf(` AND EXISTS (SELECT 1 FROM backend.identities i WHERE i.account_id = a.account_id AND i.external_id ILIKE $%d ESCAPE '\')`, len(args))
|
||||
}
|
||||
@@ -95,9 +95,9 @@ func (s *Store) CountUsers(ctx context.Context, f UserFilter) (int, error) {
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// likePattern converts a glob mask ('*' any run, '?' one char) to an ILIKE pattern,
|
||||
// LikePattern converts a glob mask ('*' any run, '?' one char) to an ILIKE pattern,
|
||||
// escaping the SQL wildcards already in the input first. An empty/blank mask returns "".
|
||||
func likePattern(mask string) string {
|
||||
func LikePattern(mask string) string {
|
||||
mask = strings.TrimSpace(mask)
|
||||
if mask == "" {
|
||||
return ""
|
||||
|
||||
Reference in New Issue
Block a user