Skip to content
This repository was archived by the owner on Jun 16, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
278 changes: 278 additions & 0 deletions internal/view/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,9 @@ var builtinViews = map[string]map[string]ViewConfig{
},

"forum": {
// ── Topics ──────────────────────────────────────────────────────────
"topics/list": {
RootField: "topic_list.topics",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "title", Label: "Title", Truncate: 60, Width: 62},
Expand All @@ -242,6 +244,35 @@ var builtinViews = map[string]map[string]ViewConfig{
{Field: "category_id", Label: "Category"},
},
},
"topics/list-top": {
RootField: "topic_list.topics",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "title", Label: "Title", Truncate: 60, Width: 62},
{Field: "posts_count", Label: "Posts", Width: 8},
{Field: "reply_count", Label: "Replies", Width: 8},
{Field: "created_at", Label: "Created", Format: FormatDate, Width: 12},
},
},
"topics/get-post": {
RootField: "post_stream.posts",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "username", Label: "Author", Width: 18},
{Field: "cooked", Label: "Content", Format: FormatMultiline, Truncate: 200, Width: 60},
{Field: "created_at", Label: "Created", Format: FormatDate, Width: 12},
},
},
"topics/get-external-id": {
Columns: []ViewColumn{
{Field: "id", Label: "ID"},
{Field: "title", Label: "Title"},
{Field: "posts_count", Label: "Posts"},
{Field: "created_at", Label: "Created", Format: FormatDate},
},
},

// ── Posts ───────────────────────────────────────────────────────────
"posts/list": {
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
Expand All @@ -250,6 +281,253 @@ var builtinViews = map[string]map[string]ViewConfig{
{Field: "created_at", Label: "Created", Format: FormatDate, Width: 12},
},
},
"posts/get": {
Columns: []ViewColumn{
{Field: "id", Label: "ID"},
{Field: "username", Label: "Author", Width: 18},
{Field: "cooked", Label: "Content", Format: FormatMultiline, Truncate: 300},
{Field: "post_number", Label: "No."},
{Field: "reply_count", Label: "Replies"},
{Field: "created_at", Label: "Created", Format: FormatDate},
{Field: "updated_at", Label: "Updated", Format: FormatDate},
},
},
"posts/replies": {
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "username", Label: "Author", Width: 18},
{Field: "cooked", Label: "Content", Format: FormatMultiline, Truncate: 160, Width: 56},
{Field: "post_number", Label: "No.", Width: 6},
{Field: "created_at", Label: "Created", Format: FormatDate, Width: 12},
},
},

// ── Categories ──────────────────────────────────────────────────────
"categories/get": {
Columns: []ViewColumn{
{Field: "category.id", Label: "ID"},
{Field: "category.name", Label: "Name"},
{Field: "category.slug", Label: "Slug"},
{Field: "category.topic_count", Label: "Topics"},
{Field: "category.post_count", Label: "Posts"},
{Field: "category.color", Label: "Color"},
},
},
"categories/list": {
RootField: "topic_list.topics",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "title", Label: "Title", Truncate: 60, Width: 62},
{Field: "posts_count", Label: "Posts", Width: 8},
{Field: "reply_count", Label: "Replies", Width: 8},
{Field: "created_at", Label: "Created", Format: FormatDate, Width: 12},
},
},
"categories/list-categorie": {
RootField: "category_list.categories",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "name", Label: "Name", Width: 28},
{Field: "slug", Label: "Slug", Width: 28},
{Field: "topic_count", Label: "Topics", Width: 8},
{Field: "post_count", Label: "Posts", Width: 8},
},
},

// ── Groups ──────────────────────────────────────────────────────────
"groups/get": {
Columns: []ViewColumn{
{Field: "group.id", Label: "ID"},
{Field: "group.name", Label: "Name"},
{Field: "group.display_name", Label: "Display"},
{Field: "group.user_count", Label: "Members"},
{Field: "group.automatic", Label: "Auto"},
{Field: "group.primary_group", Label: "Primary"},
},
},
"groups/get-group": {
Columns: []ViewColumn{
{Field: "group.id", Label: "ID"},
{Field: "group.name", Label: "Name"},
{Field: "group.display_name", Label: "Display"},
{Field: "group.user_count", Label: "Members"},
{Field: "group.automatic", Label: "Auto"},
{Field: "group.primary_group", Label: "Primary"},
},
},
"groups/list": {
RootField: "groups",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "name", Label: "Name", Width: 28},
{Field: "display_name", Label: "Display", Truncate: 24, Width: 24},
{Field: "user_count", Label: "Members", Width: 8},
{Field: "automatic", Label: "Auto", Width: 6},
{Field: "primary_group", Label: "Primary", Width: 8},
},
},
"groups/list-group": {
RootField: "members",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "username", Label: "Username", Width: 20},
{Field: "name", Label: "Name", Width: 20},
{Field: "title", Label: "Title", Width: 18},
{Field: "last_seen_at", Label: "Last Seen", Format: FormatDate, Width: 12},
{Field: "added_at", Label: "Added", Format: FormatDate, Width: 12},
},
},

// ── Badges ──────────────────────────────────────────────────────────
"badges/list": {
RootField: "badges",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "name", Label: "Name", Width: 28},
{Field: "description", Label: "Description", Truncate: 40, Width: 42},
{Field: "grant_count", Label: "Grants", Width: 8},
{Field: "enabled", Label: "Enabled", Width: 8},
},
},
"badges/list-user-badge": {
RootField: "badges",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "name", Label: "Name", Width: 28},
{Field: "description", Label: "Description", Truncate: 40, Width: 42},
{Field: "grant_count", Label: "Grants", Width: 8},
},
},

// ── Tags ────────────────────────────────────────────────────────────
"tags/get": {
RootField: "topic_list.topics",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "title", Label: "Title", Truncate: 60, Width: 62},
{Field: "posts_count", Label: "Posts", Width: 8},
{Field: "created_at", Label: "Created", Format: FormatDate, Width: 12},
},
},
"tags/get-tag-group": {
Columns: []ViewColumn{
{Field: "tag_group.id", Label: "ID"},
{Field: "tag_group.name", Label: "Name"},
{Field: "tag_group.one_per_topic", Label: "One Per Topic"},
},
},
"tags/list": {
RootField: "tags",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "name", Label: "Name", Width: 28},
{Field: "text", Label: "Text", Width: 28},
{Field: "count", Label: "Topics", Width: 8},
{Field: "pm_count", Label: "PMs", Width: 8},
},
},
"tags/list-tag-group": {
RootField: "tag_groups",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "name", Label: "Name", Width: 28},
{Field: "parent_tag", Label: "Parent Tag", Width: 20},
{Field: "one_per_topic", Label: "One Per Topic", Width: 12},
},
},

// ── Users ───────────────────────────────────────────────────────────
"users/get": {
Columns: []ViewColumn{
{Field: "user.id", Label: "ID"},
{Field: "user.username", Label: "Username"},
{Field: "user.name", Label: "Name"},
{Field: "user.created_at", Label: "Joined", Format: FormatDate},
{Field: "user.trust_level", Label: "Trust"},
{Field: "user.admin", Label: "Admin"},
{Field: "user.moderator", Label: "Mod"},
},
},
"users/get-admin": {
Columns: []ViewColumn{
{Field: "id", Label: "ID"},
{Field: "username", Label: "Username"},
{Field: "name", Label: "Name"},
{Field: "active", Label: "Active"},
{Field: "admin", Label: "Admin"},
{Field: "moderator", Label: "Mod"},
{Field: "trust_level", Label: "Trust"},
{Field: "created_at", Label: "Joined", Format: FormatDate},
{Field: "last_seen_at", Label: "Last Seen", Format: FormatDate},
},
},
"users/get-admin-list": {
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "username", Label: "Username", Width: 20},
{Field: "name", Label: "Name", Width: 20},
{Field: "active", Label: "Active", Width: 7},
{Field: "admin", Label: "Admin", Width: 6},
{Field: "created_at", Label: "Joined", Format: FormatDate, Width: 12},
},
},
"users/get-by-external": {
Columns: []ViewColumn{
{Field: "user.id", Label: "ID"},
{Field: "user.username", Label: "Username"},
{Field: "user.name", Label: "Name"},
{Field: "user.created_at", Label: "Joined", Format: FormatDate},
{Field: "user.trust_level", Label: "Trust"},
},
},
"users/get-by-external-by-external": {
Columns: []ViewColumn{
{Field: "user.id", Label: "ID"},
{Field: "user.username", Label: "Username"},
{Field: "user.name", Label: "Name"},
{Field: "user.created_at", Label: "Joined", Format: FormatDate},
{Field: "user.trust_level", Label: "Trust"},
},
},
"users/get-email": {
Columns: []ViewColumn{
{Field: "email", Label: "Email"},
{Field: "secondary_emails", Label: "Secondary", Format: FormatJSON},
{Field: "unconfirmed_emails", Label: "Unconfirmed", Format: FormatJSON},
},
},
"users/list": {
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "username", Label: "Username", Width: 20},
{Field: "name", Label: "Name", Width: 20},
{Field: "active", Label: "Active", Width: 7},
{Field: "admin", Label: "Admin", Width: 6},
{Field: "created_at", Label: "Joined", Format: FormatDate, Width: 12},
},
},
"users/list-directory-item": {
RootField: "directory_items",
Columns: []ViewColumn{
{Field: "id", Label: "ID", Width: 8},
{Field: "user.username", Label: "Username", Width: 20},
{Field: "likes_received", Label: "Likes Rcvd", Width: 10},
{Field: "likes_given", Label: "Likes Given", Width: 10},
{Field: "topic_count", Label: "Topics", Width: 8},
{Field: "post_count", Label: "Posts", Width: 8},
{Field: "days_visited", Label: "Days", Width: 8},
},
},
"users/list-user-action": {
RootField: "user_actions",
Columns: []ViewColumn{
{Field: "action_type", Label: "Action", Width: 10},
{Field: "username", Label: "User", Width: 18},
{Field: "excerpt", Label: "Excerpt", Format: FormatMultiline, Truncate: 120, Width: 50},
{Field: "target_name", Label: "Target", Width: 18},
{Field: "created_at", Label: "When", Format: FormatDate, Width: 12},
},
},
},

"etherpad": {
Expand Down
5 changes: 3 additions & 2 deletions internal/view/extract.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,11 @@ func DetectItems(raw []byte, cfg *ViewConfig) ([]map[string]interface{}, map[str
return nil, nil
}

// Apply explicit root_field.
// Apply explicit root_field. Supports dot-separated nested paths
// (e.g. "topic_list.topics").
if cfg != nil && cfg.RootField != "" {
if obj, ok := v.(map[string]interface{}); ok {
v = obj[cfg.RootField]
v = ExtractField(obj, cfg.RootField)
}
}

Expand Down
19 changes: 19 additions & 0 deletions scenarios/forum/badges-list-user-badge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: "forum/badges-list-user-badge"
skip: true
skip_reason: "Forum instance IP whitelist not configured for CI runner — enable when network access is granted"
service: forum
args:
- "badges"
- "list-user-badge"
- "--username"
- "system"
format: table
timeout_ms: 10000
assertions:
- type: exit_code
value: 0
- type: response_time_lt
value: 8000
- type: stdout_not_empty
- type: stderr_not_contains
value: "ERROR"
17 changes: 17 additions & 0 deletions scenarios/forum/badges-list.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: "forum/badges-list"
skip: true
skip_reason: "Forum instance IP whitelist not configured for CI runner — enable when network access is granted"
service: forum
args:
- "badges"
- "list"
format: table
timeout_ms: 10000
assertions:
- type: exit_code
value: 0
- type: response_time_lt
value: 8000
- type: stdout_not_empty
- type: stderr_not_contains
value: "ERROR"
18 changes: 18 additions & 0 deletions scenarios/forum/categories-get.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: "forum/categories-get"
skip: true
skip_reason: "Forum instance IP whitelist not configured for CI runner — enable when network access is granted"
service: forum
args:
- "categories"
- "get"
- "--id"
- "1"
format: json
timeout_ms: 10000
assertions:
- type: exit_code
value: 0
- type: json_has_keys
values: ["category"]
- type: json_key_not_empty
key: "category"
17 changes: 17 additions & 0 deletions scenarios/forum/categories-list-categorie.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: "forum/categories-list-categorie"
skip: true
skip_reason: "Forum instance IP whitelist not configured for CI runner — enable when network access is granted"
service: forum
args:
- "categories"
- "list-categorie"
format: table
timeout_ms: 10000
assertions:
- type: exit_code
value: 0
- type: response_time_lt
value: 8000
- type: stdout_not_empty
- type: stderr_not_contains
value: "ERROR"
Loading
Loading