feat(guilds): a guild detail page, and the slot core puts the feed in
The module's half of the org lead's correction: Teams is the contract, guilds are the presentation, and the presentation is this module's. Adds `/uo/guilds/:id` — the detail view the board never had — with the roster from this module's OWN board, which is the same data it answers core's Team provider from. Reading core's projection of our own answer back would be a round trip through a staler copy of it. The page declares `uo.guild.detail` and core fills it with the Team activity feed. That is the one part of this page core cannot hand over: only core can resolve whether the viewer is inside the Team, and the public/members split on that feed is a security boundary. The guild is named in OUR terms — core maps its own Team from the module id and the external id — so this module never holds core's row id or slug. `TeamOverviewStrip` is deleted with the core Team page it filled. `team.member.row` is not declared here either: the useful thing to put in a roster row is a link to the character behind it, and nothing core could supply identifies one. `GET /public/shard/guilds/:id` backs the page, gated and projected through the same `guilds` feature as the board — so an operator who raises that audience raises this too, and the locked acct/webId fields never survive below admin. A roster is where those appear in bulk, which makes this the endpoint where getting the projection wrong would matter most. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -100,6 +100,17 @@ shardRouter.get(
|
||||
/* #swagger.responses[200] = { description: 'Guilds, ordered by name', content: { "application/json": { schema: { type: "array", items: { type: "object", additionalProperties: true } } } } } */
|
||||
shard.getGuilds,
|
||||
)
|
||||
shardRouter.get(
|
||||
'/guilds/:id',
|
||||
requireFeature('guilds'),
|
||||
// #swagger.tags = ['Public · Shard']
|
||||
// #swagger.summary = 'One guild and its roster'
|
||||
// #swagger.description = 'The detail view behind the board. Gated and projected through the same `guilds` feature, so an operator who raises that audience raises this too, and the locked acct/webId fields never survive below admin — a roster is where they appear in bulk. This page is also where core renders the Team activity feed, through the `uo.guild.detail` extension slot.'
|
||||
// #swagger.parameters['id'] = { in: 'path', required: true, schema: { type: 'string' }, description: 'The guild id.' }
|
||||
/* #swagger.responses[200] = { description: 'The guild, with its roster', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
|
||||
/* #swagger.responses[404] = { description: 'No such guild', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
|
||||
shard.getGuild,
|
||||
)
|
||||
shardRouter.get(
|
||||
'/governors',
|
||||
requireFeature('governors'),
|
||||
|
||||
Reference in New Issue
Block a user