Initial commit: Memind H5 portal with MindSpace, Plaza, and agent jobs.
Track application source and tests; exclude local env, user workspaces, and runtime data via .gitignore. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,502 @@
|
||||
export function plazaOpenApiExtensions() {
|
||||
const dataResponse = (description) => ({
|
||||
description,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/DataEnvelope' },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const errorResponse = (description) => ({
|
||||
description,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/ErrorResponse' },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
tags: [{ name: 'Plaza' }, { name: 'Plaza Ops' }],
|
||||
paths: {
|
||||
'/plaza/v1/feed': {
|
||||
get: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Get plaza feed (hot or new)',
|
||||
parameters: [
|
||||
{ name: 'sort', in: 'query', schema: { type: 'string', enum: ['hot', 'new'] } },
|
||||
{ name: 'category', in: 'query', schema: { type: 'string' } },
|
||||
{ name: 'cursor', in: 'query', schema: { type: 'string' } },
|
||||
{ name: 'limit', in: 'query', schema: { type: 'integer', maximum: 50 } },
|
||||
],
|
||||
responses: { 200: dataResponse('Feed page') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/categories': {
|
||||
get: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'List plaza categories',
|
||||
responses: { 200: dataResponse('Category list') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/posts/{postId}': {
|
||||
get: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Get published plaza post',
|
||||
parameters: [{ $ref: '#/components/parameters/PostId' }],
|
||||
responses: {
|
||||
200: dataResponse('Post detail'),
|
||||
404: errorResponse('Post not found or hidden'),
|
||||
},
|
||||
},
|
||||
patch: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Update own plaza post metadata',
|
||||
parameters: [{ $ref: '#/components/parameters/PostId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/UpdatePlazaPostRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 200: dataResponse('Updated post') },
|
||||
},
|
||||
delete: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Hide own plaza post',
|
||||
parameters: [{ $ref: '#/components/parameters/PostId' }],
|
||||
responses: { 200: dataResponse('Hidden post') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/posts': {
|
||||
post: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Publish an online MindSpace publication to plaza',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/CreatePlazaPostRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
201: dataResponse('Created plaza post'),
|
||||
409: errorResponse('Already published to plaza'),
|
||||
},
|
||||
},
|
||||
},
|
||||
'/plaza/v1/posts/{postId}/reactions': {
|
||||
post: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Add like, collect, or share reaction',
|
||||
parameters: [{ $ref: '#/components/parameters/PostId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/PlazaReactionRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 200: dataResponse('Reaction applied') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/posts/{postId}/reactions/{type}': {
|
||||
delete: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Remove like or collect reaction',
|
||||
parameters: [
|
||||
{ $ref: '#/components/parameters/PostId' },
|
||||
{ $ref: '#/components/parameters/ReactionType' },
|
||||
],
|
||||
responses: { 200: dataResponse('Reaction removed') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/posts/{postId}/comments': {
|
||||
get: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'List post comments',
|
||||
parameters: [
|
||||
{ $ref: '#/components/parameters/PostId' },
|
||||
{ name: 'parent_id', in: 'query', schema: { type: 'string' } },
|
||||
{ name: 'cursor', in: 'query', schema: { type: 'string' } },
|
||||
],
|
||||
responses: { 200: dataResponse('Comment page') },
|
||||
},
|
||||
post: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Create comment or reply',
|
||||
parameters: [{ $ref: '#/components/parameters/PostId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/CreatePlazaCommentRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 201: dataResponse('Created comment') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/comments/{commentId}': {
|
||||
delete: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Soft-delete own comment',
|
||||
parameters: [{ $ref: '#/components/parameters/CommentId' }],
|
||||
responses: { 200: dataResponse('Deleted comment') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/comments/{commentId}/reactions': {
|
||||
post: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Like or unlike a comment',
|
||||
parameters: [{ $ref: '#/components/parameters/CommentId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['liked'],
|
||||
properties: { liked: { type: 'boolean' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 200: dataResponse('Comment reaction') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/posts/{postId}/reports': {
|
||||
post: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Report a plaza post',
|
||||
parameters: [{ $ref: '#/components/parameters/PostId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/PlazaReportRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 201: dataResponse('Report created') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/comments/{commentId}/reports': {
|
||||
post: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Report a plaza comment',
|
||||
parameters: [{ $ref: '#/components/parameters/CommentId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/PlazaReportRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 201: dataResponse('Report created') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/users/{slug}': {
|
||||
get: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Get plaza user profile',
|
||||
parameters: [{ $ref: '#/components/parameters/UserSlug' }],
|
||||
responses: { 200: dataResponse('User profile') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/users/{slug}/posts': {
|
||||
get: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'List user published plaza posts',
|
||||
parameters: [
|
||||
{ $ref: '#/components/parameters/UserSlug' },
|
||||
{ name: 'cursor', in: 'query', schema: { type: 'string' } },
|
||||
],
|
||||
responses: { 200: dataResponse('User posts') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/users/{slug}/follow': {
|
||||
post: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Follow user',
|
||||
parameters: [{ $ref: '#/components/parameters/UserSlug' }],
|
||||
responses: { 200: dataResponse('Following') },
|
||||
},
|
||||
delete: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Unfollow user',
|
||||
parameters: [{ $ref: '#/components/parameters/UserSlug' }],
|
||||
responses: { 200: dataResponse('Unfollowed') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/seo/sitemap': {
|
||||
get: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Sitemap data for Next.js',
|
||||
responses: { 200: dataResponse('Sitemap entries') },
|
||||
},
|
||||
},
|
||||
'/plaza/v1/attribution/events': {
|
||||
post: {
|
||||
tags: ['Plaza'],
|
||||
summary: 'Record UTM attribution event',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/PlazaAttributionRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 201: dataResponse('Attribution recorded') },
|
||||
},
|
||||
},
|
||||
'/ops/v1/review/queue': {
|
||||
get: {
|
||||
tags: ['Plaza Ops'],
|
||||
summary: 'List posts in review queue',
|
||||
parameters: [
|
||||
{ name: 'status', in: 'query', schema: { type: 'string' } },
|
||||
{ name: 'cursor', in: 'query', schema: { type: 'string' } },
|
||||
],
|
||||
responses: { 200: dataResponse('Review queue') },
|
||||
},
|
||||
},
|
||||
'/ops/v1/review/posts/{postId}': {
|
||||
post: {
|
||||
tags: ['Plaza Ops'],
|
||||
summary: 'Review a single plaza post',
|
||||
parameters: [{ $ref: '#/components/parameters/PostId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/OpsReviewRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 200: dataResponse('Review result') },
|
||||
},
|
||||
},
|
||||
'/ops/v1/review/batch': {
|
||||
post: {
|
||||
tags: ['Plaza Ops'],
|
||||
summary: 'Batch review plaza posts (editor+)',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/OpsBatchReviewRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 200: dataResponse('Batch review result') },
|
||||
},
|
||||
},
|
||||
'/ops/v1/reports': {
|
||||
get: {
|
||||
tags: ['Plaza Ops'],
|
||||
summary: 'List pending reports',
|
||||
responses: { 200: dataResponse('Reports') },
|
||||
},
|
||||
},
|
||||
'/ops/v1/reports/{reportId}/process': {
|
||||
post: {
|
||||
tags: ['Plaza Ops'],
|
||||
summary: 'Process a report',
|
||||
parameters: [{ $ref: '#/components/parameters/ReportId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/OpsProcessReportRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 200: dataResponse('Processed report') },
|
||||
},
|
||||
},
|
||||
'/ops/v1/featured': {
|
||||
get: {
|
||||
tags: ['Plaza Ops'],
|
||||
summary: 'List featured placements',
|
||||
responses: { 200: dataResponse('Featured list') },
|
||||
},
|
||||
post: {
|
||||
tags: ['Plaza Ops'],
|
||||
summary: 'Set featured placement',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/OpsFeaturedRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 201: dataResponse('Featured created') },
|
||||
},
|
||||
},
|
||||
'/ops/v1/featured/{featuredId}': {
|
||||
delete: {
|
||||
tags: ['Plaza Ops'],
|
||||
summary: 'Remove featured placement',
|
||||
parameters: [{ $ref: '#/components/parameters/FeaturedId' }],
|
||||
responses: { 200: dataResponse('Featured removed') },
|
||||
},
|
||||
},
|
||||
'/ops/v1/analytics/overview': {
|
||||
get: {
|
||||
tags: ['Plaza Ops'],
|
||||
summary: 'Plaza analytics overview',
|
||||
responses: { 200: dataResponse('Analytics overview') },
|
||||
},
|
||||
},
|
||||
'/ops/v1/creators': {
|
||||
get: {
|
||||
tags: ['Plaza Ops'],
|
||||
summary: 'List plaza creators',
|
||||
parameters: [{ name: 'keyword', in: 'query', schema: { type: 'string' } }],
|
||||
responses: { 200: dataResponse('Creators') },
|
||||
},
|
||||
},
|
||||
'/ops/v1/creators/{userId}': {
|
||||
patch: {
|
||||
tags: ['Plaza Ops'],
|
||||
summary: 'Update creator moderation flags',
|
||||
parameters: [{ $ref: '#/components/parameters/OpsUserId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/OpsCreatorPatchRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { 200: dataResponse('Creator updated') },
|
||||
},
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
PostId: { name: 'postId', in: 'path', required: true, schema: { type: 'string' } },
|
||||
CommentId: { name: 'commentId', in: 'path', required: true, schema: { type: 'string' } },
|
||||
UserSlug: { name: 'slug', in: 'path', required: true, schema: { type: 'string' } },
|
||||
ReactionType: {
|
||||
name: 'type',
|
||||
in: 'path',
|
||||
required: true,
|
||||
schema: { type: 'string', enum: ['like', 'collect'] },
|
||||
},
|
||||
ReportId: { name: 'reportId', in: 'path', required: true, schema: { type: 'string' } },
|
||||
FeaturedId: { name: 'featuredId', in: 'path', required: true, schema: { type: 'string' } },
|
||||
OpsUserId: { name: 'userId', in: 'path', required: true, schema: { type: 'string' } },
|
||||
},
|
||||
schemas: {
|
||||
CreatePlazaPostRequest: {
|
||||
type: 'object',
|
||||
required: ['publication_id', 'category_id'],
|
||||
properties: {
|
||||
publication_id: { type: 'string' },
|
||||
category_id: { type: 'string' },
|
||||
category_slug: { type: 'string' },
|
||||
tags: { type: 'array', items: { type: 'string' } },
|
||||
cover_url: { type: 'string' },
|
||||
allow_comment: { type: 'boolean' },
|
||||
},
|
||||
},
|
||||
UpdatePlazaPostRequest: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
tags: { type: 'array', items: { type: 'string' } },
|
||||
cover_url: { type: 'string' },
|
||||
allow_comment: { type: 'boolean' },
|
||||
},
|
||||
},
|
||||
PlazaReactionRequest: {
|
||||
type: 'object',
|
||||
required: ['type'],
|
||||
properties: {
|
||||
type: { type: 'string', enum: ['like', 'collect', 'share'] },
|
||||
},
|
||||
},
|
||||
CreatePlazaCommentRequest: {
|
||||
type: 'object',
|
||||
required: ['content'],
|
||||
properties: {
|
||||
content: { type: 'string', maxLength: 500 },
|
||||
parent_id: { type: ['string', 'null'] },
|
||||
},
|
||||
},
|
||||
PlazaReportRequest: {
|
||||
type: 'object',
|
||||
required: ['reason'],
|
||||
properties: {
|
||||
reason: {
|
||||
type: 'string',
|
||||
enum: ['spam', 'violence', 'porn', 'political', 'privacy', 'other'],
|
||||
},
|
||||
detail: { type: 'string', maxLength: 500 },
|
||||
},
|
||||
},
|
||||
PlazaAttributionRequest: {
|
||||
type: 'object',
|
||||
required: ['event_type', 'utm_source'],
|
||||
properties: {
|
||||
event_type: { type: 'string', enum: ['landing', 'signup'] },
|
||||
utm_source: { type: 'string' },
|
||||
utm_medium: { type: 'string' },
|
||||
utm_campaign: { type: 'string' },
|
||||
ref_id: { type: 'string' },
|
||||
},
|
||||
},
|
||||
OpsReviewRequest: {
|
||||
type: 'object',
|
||||
required: ['action'],
|
||||
properties: {
|
||||
action: { type: 'string', enum: ['approve', 'reject', 'hide'] },
|
||||
reason: { type: 'string' },
|
||||
},
|
||||
},
|
||||
OpsBatchReviewRequest: {
|
||||
type: 'object',
|
||||
required: ['post_ids', 'action'],
|
||||
properties: {
|
||||
post_ids: { type: 'array', items: { type: 'string' }, maxItems: 50 },
|
||||
action: { type: 'string', enum: ['approve', 'reject', 'hide'] },
|
||||
reason: { type: 'string' },
|
||||
},
|
||||
},
|
||||
OpsProcessReportRequest: {
|
||||
type: 'object',
|
||||
required: ['action'],
|
||||
properties: {
|
||||
action: { type: 'string', enum: ['dismiss', 'hide_post'] },
|
||||
action_taken: { type: 'string' },
|
||||
},
|
||||
},
|
||||
OpsFeaturedRequest: {
|
||||
type: 'object',
|
||||
required: ['post_id', 'position'],
|
||||
properties: {
|
||||
post_id: { type: 'string' },
|
||||
position: { type: 'string', enum: ['homepage_banner', 'category_top', 'trending'] },
|
||||
sort_order: { type: 'integer' },
|
||||
expires_at: { type: ['string', 'null'], format: 'date-time' },
|
||||
},
|
||||
},
|
||||
OpsCreatorPatchRequest: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
verified: { type: 'boolean' },
|
||||
post_banned: { type: 'boolean' },
|
||||
comment_banned: { type: 'boolean' },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user