feat(teams): Teams as a platform primitive — MODULE_API 1.6.0 (Teams cutover 4/6) #161

Merged
whitlocktech merged 45 commits from edge into main 2026-08-19 08:57:13 +00:00
3 changed files with 349 additions and 5 deletions
Showing only changes of commit 203ce9c654 - Show all commits

View File

@@ -1731,10 +1731,20 @@
},
{
"method": "GET",
"path": "/api/v1/public/teams/:slug/members",
"handlers": 2,
"path": "/api/v1/public/teams/:slug/activity",
"handlers": 3,
"gates": [
"siteMode"
"siteMode",
"optionalAuth"
]
},
{
"method": "GET",
"path": "/api/v1/public/teams/:slug/members",
"handlers": 3,
"gates": [
"siteMode",
"optionalAuth"
]
},
{

View File

@@ -705,6 +705,10 @@
"method": "GET",
"path": "/api/v1/public/teams/:slug"
},
{
"method": "GET",
"path": "/api/v1/public/teams/:slug/activity"
},
{
"method": "GET",
"path": "/api/v1/public/teams/:slug/members"

View File

@@ -10527,13 +10527,85 @@
}
}
},
"/api/v1/public/teams/{slug}/activity": {
"get": {
"tags": [
"Public · Teams"
],
"summary": "A Teams activity feed, filtered to what the caller may see",
"description": "Items are `public` or `members`. Anyone who can see the Team gets the public ones; members and forum-granted users also get the members-only ones, and the response says which via `scope` so a client can render \"some items are hidden\" rather than presenting a filtered feed as the whole one. Sending a session is optional.",
"parameters": [
{
"name": "slug",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "The Team slug."
},
{
"name": "limit",
"in": "query",
"required": false,
"schema": {
"type": "integer"
},
"description": "Page size, max 100 (default 50)."
},
{
"name": "offset",
"in": "query",
"required": false,
"schema": {
"type": "integer"
},
"description": "Rows to skip (default 0)."
}
],
"responses": {
"200": {
"description": "One page of the feed",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PublicTeamActivity"
}
}
}
},
"404": {
"description": "No such Team, or it is hidden from this caller",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"503": {
"description": "Service Unavailable"
}
},
"security": [
{},
{
"cookieAuth": []
},
{
"bearerAuth": []
}
]
}
},
"/api/v1/public/teams/{slug}/members": {
"get": {
"tags": [
"Public · Teams"
],
"summary": "Get a Team roster",
"description": "In-game display names only. A member key is a game-internal identifier and a user id names a site account; neither is published. `linked` answers whether a character has an account behind it without saying which.",
"description": "In-game display names only. A member key is a game-internal identifier and a user id names a site account; neither is published, whatever the modules projection answers. `linked` answers whether a character has an account behind it without saying which. WHICH rows appear is the modules audience projection; sending a session is optional and may widen it.",
"parameters": [
{
"name": "slug",
@@ -10569,7 +10641,16 @@
"503": {
"description": "Service Unavailable"
}
}
},
"security": [
{},
{
"cookieAuth": []
},
{
"bearerAuth": []
}
]
}
},
"/api/v1/public/version": {
@@ -17081,6 +17162,23 @@
"example": 12
}
}
},
"enabled": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "boolean"
},
"description": {
"type": "string",
"example": "Whether this deployment has Teams at all — a provider is registered, or Teams exist from one that since went away. The `teams` nav feature flag resolves from this; false means bare core, where a Teams link would lead to a permanently empty page."
},
"example": {
"type": "boolean",
"example": true
}
}
}
}
}
@@ -17225,6 +17323,238 @@
"example": true
}
}
},
"projected": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "boolean"
},
"description": {
"type": "string",
"example": "Whether the module applied its own audience projection to this roster. False means the module declined or does not project, and the roster was served at cores public shape — never the full one."
},
"example": {
"type": "boolean",
"example": true
}
}
}
}
}
}
},
"PublicTeamActivityItem": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "object"
},
"description": {
"type": "string",
"example": "`summary` is already-rendered text supplied by whoever pushed the item; core never composes one. `kind` and `payload` are opaque to core — only the modules `team.overview` slot renders anything richer than the text."
},
"properties": {
"type": "object",
"properties": {
"id": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "integer"
},
"example": {
"type": "number",
"example": 4821
}
}
},
"source": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"description": {
"type": "string",
"example": "`core` or a module id."
},
"example": {
"type": "string",
"example": "uo"
}
}
},
"kind": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"example": {
"type": "string",
"example": "uo.champion.completed"
}
}
},
"summary": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"example": {
"type": "string",
"example": "Completed Champion Neira"
}
}
},
"visibility": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"enum": {
"type": "array",
"example": [
"public",
"members"
],
"items": {
"type": "string"
}
}
}
},
"occurredAt": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"format": {
"type": "string",
"example": "date-time"
}
}
},
"payload": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "object"
},
"nullable": {
"type": "boolean",
"example": true
},
"additionalProperties": {
"type": "boolean",
"example": true
}
}
}
}
}
}
},
"PublicTeamActivity": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "object"
},
"properties": {
"type": "object",
"properties": {
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "array"
},
"items": {
"$ref": "#/components/schemas/PublicTeamActivityItem"
}
}
},
"total": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "integer"
},
"description": {
"type": "string",
"example": "Matching rows for THIS callers visibility, so paging is honest."
},
"example": {
"type": "number",
"example": 137
}
}
},
"limit": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "integer"
},
"example": {
"type": "number",
"example": 50
}
}
},
"offset": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "integer"
},
"example": {
"type": "number",
"example": 0
}
}
},
"scope": {
"type": "object",
"properties": {
"type": {
"type": "string",
"example": "string"
},
"enum": {
"type": "array",
"example": [
"public",
"members"
],
"items": {
"type": "string"
}
},
"description": {
"type": "string",
"example": "Which visibilities this caller received. `public` means members-only items were withheld — render that fact rather than presenting a filtered feed as the whole one."
}
}
}
}
}