feat: a public notes page per release, for clients
On the releases page, «Página pública» (owners and admins) opens a
secret link to a page with the release's notes, readable without an
account, also for private projects: the notes written, or the draft
from its finished tickets while there are none (without repeating the
title the page already shows). The link can be copied, renewed (the old
one stops working) or withdrawn. Stored in Mongo (`release_note_shares`).
API: shareReleaseNotes / unshareReleaseNotes / releaseNotesShare,
publicReleaseNotes(token); GET/PUT/DELETE /api/releases/{id}/public-notes,
GET /api/shared/release-notes/{token}. Web: /notes/:token.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13702,6 +13702,316 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/releases/{release}/public-notes": {
|
||||
"get": {
|
||||
"operationId": "SharingController_releaseNotesShare",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "release",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ReleaseNotesShareDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid input",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Missing or rejected Pireon token",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Not a member of the project (or not allowed)",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"pireon-oauth": []
|
||||
},
|
||||
{
|
||||
"pireon": []
|
||||
}
|
||||
],
|
||||
"summary": "A release's public notes link, if any (owners and admins)",
|
||||
"tags": [
|
||||
"Projects"
|
||||
]
|
||||
},
|
||||
"put": {
|
||||
"description": "The page shows the notes written, or the ones drawn from its finished tickets. ?renew=true makes a new link.",
|
||||
"operationId": "SharingController_shareReleaseNotes",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "release",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "renew",
|
||||
"required": true,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ReleaseNotesShareDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid input",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Missing or rejected Pireon token",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Not a member of the project (or not allowed)",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"409": {
|
||||
"description": "Someone changed it at the same time: retry",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Business rule (e.g. a transition the workflow forbids)",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"pireon-oauth": []
|
||||
},
|
||||
{
|
||||
"pireon": []
|
||||
}
|
||||
],
|
||||
"summary": "Turn a release's public notes page on (owners and admins)",
|
||||
"tags": [
|
||||
"Projects"
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"operationId": "SharingController_unshareReleaseNotes",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "release",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": ""
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid input",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Missing or rejected Pireon token",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Not a member of the project (or not allowed)",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"409": {
|
||||
"description": "Someone changed it at the same time: retry",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Business rule (e.g. a transition the workflow forbids)",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"pireon-oauth": []
|
||||
},
|
||||
{
|
||||
"pireon": []
|
||||
}
|
||||
],
|
||||
"summary": "A release's public notes link stops working",
|
||||
"tags": [
|
||||
"Projects"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/shared/release-notes/{token}": {
|
||||
"get": {
|
||||
"operationId": "SharingController_publicReleaseNotes",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "token",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/PublicReleaseNotesDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"summary": "A release's notes, for anyone with its link",
|
||||
"tags": [
|
||||
"Projects"
|
||||
],
|
||||
"security": []
|
||||
}
|
||||
},
|
||||
"/api/shared/dashboards/{token}": {
|
||||
"get": {
|
||||
"description": "Only the chosen blocks: tickets per status, the sprint under way, release forecasts, open epics and activity per day. The others are null.",
|
||||
@@ -19804,6 +20114,81 @@
|
||||
"blocks"
|
||||
]
|
||||
},
|
||||
"ReleaseNotesShareDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"releaseId": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"token": {
|
||||
"type": "string",
|
||||
"description": "The secret of the link: /notes/{token}"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"releaseId",
|
||||
"token",
|
||||
"createdAt"
|
||||
]
|
||||
},
|
||||
"PublicReleaseNotesDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"projectName": {
|
||||
"type": "string"
|
||||
},
|
||||
"projectKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"releaseName": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"status": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ReleaseStatus"
|
||||
}
|
||||
]
|
||||
},
|
||||
"targetDate": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"releasedAt": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"format": "date-time"
|
||||
},
|
||||
"notes": {
|
||||
"type": "string",
|
||||
"description": "Markdown"
|
||||
},
|
||||
"written": {
|
||||
"type": "boolean",
|
||||
"description": "False: drawn from its finished tickets (none written yet)"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"projectName",
|
||||
"projectKey",
|
||||
"releaseName",
|
||||
"description",
|
||||
"status",
|
||||
"targetDate",
|
||||
"releasedAt",
|
||||
"notes",
|
||||
"written"
|
||||
]
|
||||
},
|
||||
"SharedFlowDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -1185,6 +1185,11 @@ type Mutation {
|
||||
"""Turn the link on or change its blocks; renew for a new secret"""
|
||||
shareDashboard(input: ShareDashboardInput!): DashboardShare!
|
||||
|
||||
"""
|
||||
Turn a release's public notes page on; renew makes a new link (the old one stops working)
|
||||
"""
|
||||
shareReleaseNotes(releaseId: ID!, renew: Boolean! = false): ReleaseNotesShare!
|
||||
|
||||
"""Start a planned sprint (only one under way per project)"""
|
||||
startSprint(sprintId: ID!): CommandResult!
|
||||
|
||||
@@ -1227,6 +1232,9 @@ type Mutation {
|
||||
"""The link stops working"""
|
||||
unshareDashboard(projectId: ID!): Boolean!
|
||||
|
||||
"""A release's public notes link stops working"""
|
||||
unshareReleaseNotes(releaseId: ID!): Boolean!
|
||||
|
||||
"""Push off on this device"""
|
||||
unsubscribePush(endpoint: String!): Boolean!
|
||||
|
||||
@@ -1637,6 +1645,23 @@ type ProposalsFunnel {
|
||||
waiting: Int!
|
||||
}
|
||||
|
||||
"""A release's notes, for anyone with its link"""
|
||||
type PublicReleaseNotes {
|
||||
description: String
|
||||
|
||||
"""Markdown"""
|
||||
notes: String!
|
||||
projectKey: String!
|
||||
projectName: String!
|
||||
releaseName: String!
|
||||
releasedAt: String
|
||||
status: ReleaseStatus!
|
||||
targetDate: String
|
||||
|
||||
"""False: drawn from its finished tickets (none written yet)"""
|
||||
written: Boolean!
|
||||
}
|
||||
|
||||
"""A browser's Web Push subscription (PushSubscription.toJSON())"""
|
||||
input PushSubscriptionInput {
|
||||
auth: String!
|
||||
@@ -1783,8 +1808,14 @@ type Query {
|
||||
|
||||
"""Projects anyone can read, also without signing in"""
|
||||
publicProjects: [Project!]!
|
||||
|
||||
"""A release's notes, for anyone with its link"""
|
||||
publicReleaseNotes(token: String!): PublicReleaseNotes
|
||||
release(id: ID!): Release!
|
||||
|
||||
"""A release's public notes link, if any (owners and admins)"""
|
||||
releaseNotesShare(releaseId: ID!): ReleaseNotesShare
|
||||
|
||||
"""My views of the project's board, then the shared ones"""
|
||||
savedFilters(projectId: ID!): [SavedFilter!]!
|
||||
|
||||
@@ -1882,6 +1913,15 @@ type ReleaseForecast {
|
||||
verdict: String!
|
||||
}
|
||||
|
||||
"""A release's public notes link (owners and admins)"""
|
||||
type ReleaseNotesShare {
|
||||
createdAt: String!
|
||||
releaseId: ID!
|
||||
|
||||
"""The secret of the link: /notes/{token}"""
|
||||
token: String!
|
||||
}
|
||||
|
||||
type ReleaseProgress {
|
||||
byStatus: [CountByStatus!]!
|
||||
finished: Int!
|
||||
|
||||
@@ -2042,6 +2042,45 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/releases/{release}/public-notes": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** A release's public notes link, if any (owners and admins) */
|
||||
get: operations["SharingController_releaseNotesShare"];
|
||||
/**
|
||||
* Turn a release's public notes page on (owners and admins)
|
||||
* @description The page shows the notes written, or the ones drawn from its finished tickets. ?renew=true makes a new link.
|
||||
*/
|
||||
put: operations["SharingController_shareReleaseNotes"];
|
||||
post?: never;
|
||||
/** A release's public notes link stops working */
|
||||
delete: operations["SharingController_unshareReleaseNotes"];
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/shared/release-notes/{token}": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** A release's notes, for anyone with its link */
|
||||
get: operations["SharingController_publicReleaseNotes"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/shared/dashboards/{token}": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -4025,6 +4064,28 @@ export interface components {
|
||||
/** @description A new secret: the old link stops working */
|
||||
renew?: boolean;
|
||||
};
|
||||
ReleaseNotesShareDto: {
|
||||
/** Format: uuid */
|
||||
releaseId: string;
|
||||
/** @description The secret of the link: /notes/{token} */
|
||||
token: string;
|
||||
/** Format: date-time */
|
||||
createdAt: string;
|
||||
};
|
||||
PublicReleaseNotesDto: {
|
||||
projectName: string;
|
||||
projectKey: string;
|
||||
releaseName: string;
|
||||
description: string | null;
|
||||
status: components["schemas"]["ReleaseStatus"];
|
||||
targetDate: string | null;
|
||||
/** Format: date-time */
|
||||
releasedAt: string | null;
|
||||
/** @description Markdown */
|
||||
notes: string;
|
||||
/** @description False: drawn from its finished tickets (none written yet) */
|
||||
written: boolean;
|
||||
};
|
||||
SharedFlowDto: {
|
||||
status: string;
|
||||
name: string;
|
||||
@@ -13705,6 +13766,234 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
SharingController_releaseNotesShare: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
release: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ReleaseNotesShareDto"];
|
||||
};
|
||||
};
|
||||
/** @description Invalid input */
|
||||
400: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Missing or rejected Pireon token */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Not a member of the project (or not allowed) */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Not found */
|
||||
404: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
SharingController_shareReleaseNotes: {
|
||||
parameters: {
|
||||
query: {
|
||||
renew: string;
|
||||
};
|
||||
header?: never;
|
||||
path: {
|
||||
release: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ReleaseNotesShareDto"];
|
||||
};
|
||||
};
|
||||
/** @description Invalid input */
|
||||
400: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Missing or rejected Pireon token */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Not a member of the project (or not allowed) */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Not found */
|
||||
404: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Someone changed it at the same time: retry */
|
||||
409: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Business rule (e.g. a transition the workflow forbids) */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
SharingController_unshareReleaseNotes: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
release: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
204: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Invalid input */
|
||||
400: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Missing or rejected Pireon token */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Not a member of the project (or not allowed) */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Not found */
|
||||
404: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Someone changed it at the same time: retry */
|
||||
409: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Business rule (e.g. a transition the workflow forbids) */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
SharingController_publicReleaseNotes: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
token: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["PublicReleaseNotesDto"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
SharingController_shared: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
||||
Reference in New Issue
Block a user