feat: complete TASK-WP2-03 project lifecycle
This commit is contained in:
@@ -45,6 +45,9 @@ import {
|
||||
ProjectRatioSchema,
|
||||
ProjectRenameRequestSchema,
|
||||
ProjectRenameResponseSchema,
|
||||
ProjectRestoreResponseSchema,
|
||||
ProjectPurgeResponseSchema,
|
||||
ProjectTrashResponseSchema,
|
||||
ProjectStateConflictResponseSchema,
|
||||
ProjectStateSaveHeadersSchema,
|
||||
ProjectStateSaveResponseSchema,
|
||||
@@ -370,6 +373,9 @@ export async function createApp(options: CreateAppOptions = {}) {
|
||||
ProjectEditableStateSchema,
|
||||
ProjectRenameRequestSchema,
|
||||
ProjectRenameResponseSchema,
|
||||
ProjectTrashResponseSchema,
|
||||
ProjectRestoreResponseSchema,
|
||||
ProjectPurgeResponseSchema,
|
||||
ProjectStateSaveHeadersSchema,
|
||||
ProjectStateSaveResponseSchema,
|
||||
ProjectStateConflictResponseSchema,
|
||||
@@ -1247,6 +1253,67 @@ export async function createApp(options: CreateAppOptions = {}) {
|
||||
},
|
||||
);
|
||||
|
||||
const projectLifecycle = (
|
||||
action: "trash" | "restore" | "purge",
|
||||
operationId: string,
|
||||
responseSchema: typeof ProjectTrashResponseSchema | typeof ProjectRestoreResponseSchema | typeof ProjectPurgeResponseSchema,
|
||||
) => {
|
||||
app.post(
|
||||
`/api/v1/projects/:projectId/${action}`,
|
||||
{
|
||||
attachValidation: true,
|
||||
schema: {
|
||||
headers: Type.Ref(CsrfHeadersSchema),
|
||||
operationId,
|
||||
params: Type.Ref(ProjectParamsSchema),
|
||||
response: {
|
||||
200: Type.Ref(responseSchema),
|
||||
400: Type.Null(),
|
||||
401: Type.Ref(ErrorEnvelopeSchema),
|
||||
403: Type.Ref(ErrorEnvelopeSchema),
|
||||
404: Type.Null(),
|
||||
409: Type.Null(),
|
||||
503: Type.Ref(ErrorEnvelopeSchema),
|
||||
},
|
||||
tags: ["Projects"],
|
||||
},
|
||||
},
|
||||
async (request, reply) => {
|
||||
if (request.validationError) return reply.code(400).send(null);
|
||||
if (!options.registration || !options.projects) {
|
||||
return reply.code(503).send(createErrorEnvelope({ code: "AUTH_SERVICE_UNAVAILABLE", correlationId: request.id }));
|
||||
}
|
||||
const token = cookieValue(headerValue(request.headers.cookie), userSessionCookieName);
|
||||
const csrfToken = headerValue(request.headers["x-csrf-token"]);
|
||||
if (!token || !csrfToken) {
|
||||
return reply.code(401).send(createErrorEnvelope({ code: "AUTH_SESSION_INVALID", correlationId: request.id }));
|
||||
}
|
||||
try {
|
||||
const owner = options.registration.authorizeUserMutation({ csrfToken, sessionToken: token });
|
||||
const projectId = (request.params as ProjectParams).projectId;
|
||||
if (action === "trash") {
|
||||
const project = options.projects.trashProject(owner.userId, projectId);
|
||||
return { deleted_at: project.deletedAt, project_id: projectId, purge_at: project.purgeAt, status: "trashed" as const };
|
||||
}
|
||||
if (action === "restore") {
|
||||
options.projects.restoreProject(owner.userId, projectId);
|
||||
return { deleted_at: null, project_id: projectId, purge_at: null, status: "active" as const };
|
||||
}
|
||||
options.projects.purgeProject(owner.userId, projectId);
|
||||
return { project_id: projectId, status: "purged" as const };
|
||||
} catch (error) {
|
||||
return error instanceof RegistrationError
|
||||
? registrationFailure(reply, request.id, error)
|
||||
: projectFailure(reply, request.id, error);
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
projectLifecycle("trash", "trashProject", ProjectTrashResponseSchema);
|
||||
projectLifecycle("restore", "restoreProject", ProjectRestoreResponseSchema);
|
||||
projectLifecycle("purge", "purgeProject", ProjectPurgeResponseSchema);
|
||||
|
||||
app.post(
|
||||
"/api/v1/support/check",
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user