mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 17:08:18 +00:00
feat: WIP Contnet managemtn
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import { CurrentUser } from "@edr/api-common";
|
||||
import { SUPPORT_MEDIA_MAX_BYTES } from "@edr/types";
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Get,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Patch,
|
||||
Post,
|
||||
Query,
|
||||
UploadedFile,
|
||||
UseInterceptors,
|
||||
} from "@nestjs/common";
|
||||
import { FileInterceptor } from "@nestjs/platform-express";
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
ApiConsumes,
|
||||
ApiOperation,
|
||||
ApiQuery,
|
||||
ApiTags,
|
||||
} from "@nestjs/swagger";
|
||||
import type { TCurrentUser } from "@tria-plc/api-common/modules/auth/types/current-user.type";
|
||||
|
||||
import { BookingStaff } from "../../common/booking-guards";
|
||||
import { FREIGHT_PERMS } from "../../seed/freight-permissions.registry";
|
||||
import { UpdateSupportDocumentDto } from "./dto/support-content.dto";
|
||||
import { SupportContentService } from "./support-content.service";
|
||||
|
||||
const READ = [
|
||||
FREIGHT_PERMS.settings.supportContent.view,
|
||||
FREIGHT_PERMS.settings.supportContent.manage,
|
||||
FREIGHT_PERMS.admin,
|
||||
];
|
||||
|
||||
const WRITE = [
|
||||
FREIGHT_PERMS.settings.supportContent.manage,
|
||||
FREIGHT_PERMS.admin,
|
||||
];
|
||||
|
||||
@ApiTags("support-content")
|
||||
@ApiBearerAuth()
|
||||
@Controller("support-content")
|
||||
export class SupportContentController {
|
||||
constructor(private readonly service: SupportContentService) {}
|
||||
|
||||
/**
|
||||
* Stores a help-page image or video and returns its object key. The editor
|
||||
* saves the key, not the returned URL — see `SupportContentService.uploadMedia`.
|
||||
*
|
||||
* The Multer limit duplicates the service-side type check on purpose: it
|
||||
* stops reading the socket once the part is oversized instead of buffering
|
||||
* the whole thing into memory first.
|
||||
*/
|
||||
@Post("media")
|
||||
@BookingStaff(WRITE)
|
||||
@UseInterceptors(
|
||||
FileInterceptor("file", { limits: { fileSize: SUPPORT_MEDIA_MAX_BYTES } }),
|
||||
)
|
||||
@ApiConsumes("multipart/form-data")
|
||||
@ApiOperation({ summary: "Upload an image or video for a help section" })
|
||||
uploadMedia(@UploadedFile() file: Express.Multer.File) {
|
||||
return this.service.uploadMedia(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs one stored key so the editor can preview an already-saved image.
|
||||
* The editor stores `minio:<key>`, never a signed URL, so it needs somewhere
|
||||
* to resolve those refs for display — this is it.
|
||||
*/
|
||||
@Get("media-url")
|
||||
@BookingStaff(READ)
|
||||
@ApiQuery({ name: "key", description: "MinIO object key" })
|
||||
@ApiOperation({ summary: "Presigned URL for one stored media key" })
|
||||
mediaUrl(@Query("key") key: string) {
|
||||
return this.service.mediaUrl(key);
|
||||
}
|
||||
|
||||
@Get("documents")
|
||||
@BookingStaff(READ)
|
||||
@ApiOperation({ summary: "List the five portal content documents (no payloads)" })
|
||||
list() {
|
||||
return this.service.list();
|
||||
}
|
||||
|
||||
@Get("documents/:slug")
|
||||
@BookingStaff(READ)
|
||||
@ApiOperation({ summary: "Get one document with its payload" })
|
||||
getBySlug(@Param("slug") slug: string) {
|
||||
return this.service.getBySlug(slug);
|
||||
}
|
||||
|
||||
@Patch("documents/:slug")
|
||||
@BookingStaff(WRITE)
|
||||
@ApiOperation({
|
||||
summary: "Replace a document's payload, recording a new version",
|
||||
})
|
||||
update(
|
||||
@Param("slug") slug: string,
|
||||
@Body() dto: UpdateSupportDocumentDto,
|
||||
@CurrentUser() user: TCurrentUser,
|
||||
) {
|
||||
return this.service.update(slug, dto, user?.id ?? null);
|
||||
}
|
||||
|
||||
@Get("documents/:slug/versions")
|
||||
@BookingStaff(READ)
|
||||
@ApiOperation({ summary: "Version history, newest first (no payloads)" })
|
||||
listVersions(@Param("slug") slug: string) {
|
||||
return this.service.listVersions(slug);
|
||||
}
|
||||
|
||||
@Get("documents/:slug/versions/:version")
|
||||
@BookingStaff(READ)
|
||||
@ApiOperation({ summary: "One historical version, with its payload" })
|
||||
getVersion(
|
||||
@Param("slug") slug: string,
|
||||
@Param("version", ParseIntPipe) version: number,
|
||||
) {
|
||||
return this.service.getVersion(slug, version);
|
||||
}
|
||||
|
||||
@Post("documents/:slug/versions/:version/restore")
|
||||
@BookingStaff(WRITE)
|
||||
@ApiOperation({
|
||||
summary: "Restore a version — re-saves it as a new version, never destructive",
|
||||
})
|
||||
restore(
|
||||
@Param("slug") slug: string,
|
||||
@Param("version", ParseIntPipe) version: number,
|
||||
@CurrentUser() user: TCurrentUser,
|
||||
) {
|
||||
return this.service.restore(slug, version, user?.id ?? null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user