feat(guild): file upload/retention + channel canvas
Files: - StoredFile entity + FilesModule: multipart upload (configurable FABRIC_BACKEND_GUILD_FILE_MAX_BYTES, default 100MB; no type limit), authenticated download (Bearer or ?access_token=), hourly + on-boot retention sweep (FABRIC_BACKEND_GUILD_FILE_TTL_DAYS, default 7). - ApiKeyGuard also accepts ?access_token= (browser <img>/<a>). Canvas: - ChannelCanvas entity (one active per channel) + CanvasModule: GET / PUT|POST (share-replace, caller becomes sharer) / PATCH (sharer-only in-place update, version++) / DELETE (sharer-only). Emits canvas.updated / canvas.removed to the channel room. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
58
src/canvas/canvas.controller.ts
Normal file
58
src/canvas/canvas.controller.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
Post,
|
||||
Put,
|
||||
Patch,
|
||||
Req,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { CanvasService } from './canvas.service.js';
|
||||
|
||||
type AuthedRequest = { userId?: string };
|
||||
type CanvasBody = { title?: string; format?: string; source?: string };
|
||||
|
||||
@Controller('channels/:id/canvas')
|
||||
export class CanvasController {
|
||||
constructor(private readonly canvas: CanvasService) {}
|
||||
|
||||
private uid(req: AuthedRequest): string {
|
||||
const userId = req.userId ?? '';
|
||||
if (!userId) throw new UnauthorizedException('missing user');
|
||||
return userId;
|
||||
}
|
||||
|
||||
@Get()
|
||||
get(@Req() req: AuthedRequest, @Param('id') channelId: string) {
|
||||
return this.canvas.get(channelId, this.uid(req));
|
||||
}
|
||||
|
||||
// share / replace (caller becomes the sharer)
|
||||
@Put()
|
||||
@Post()
|
||||
share(
|
||||
@Req() req: AuthedRequest,
|
||||
@Param('id') channelId: string,
|
||||
@Body() body: CanvasBody,
|
||||
) {
|
||||
return this.canvas.share(channelId, this.uid(req), body ?? {});
|
||||
}
|
||||
|
||||
// update in place (original sharer only)
|
||||
@Patch()
|
||||
update(
|
||||
@Req() req: AuthedRequest,
|
||||
@Param('id') channelId: string,
|
||||
@Body() body: CanvasBody,
|
||||
) {
|
||||
return this.canvas.update(channelId, this.uid(req), body ?? {});
|
||||
}
|
||||
|
||||
@Delete()
|
||||
remove(@Req() req: AuthedRequest, @Param('id') channelId: string) {
|
||||
return this.canvas.remove(channelId, this.uid(req));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user