feat: attachments on tickets and comments
Files are uploaded over REST, stored on disk (a volume in Docker) and recorded on the ticket as events; the bytes are written first, so no attachment ever points at a missing file. Only images, video, audio, PDF and plain text are shown inline, everything with nosniff and a sandbox CSP. The web shows thumbnails, uploads by drag and drop or by pasting a screenshot, and attaches files to new comments. Also adds `nx run api:contracts`, which writes schema.gql and openapi.json without starting the API or any database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
import { DynamicModule, Module, Type } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { MulterModule } from '@nestjs/platform-express';
|
||||
import './graphql/enums';
|
||||
import { CommentResolver } from './graphql/comment.resolver';
|
||||
import { IssueResolver } from './graphql/issue.resolver';
|
||||
import { ProjectResolver } from './graphql/project.resolver';
|
||||
import { ReleaseResolver } from './graphql/release.resolver';
|
||||
import { SubscriptionResolver } from './graphql/subscription.resolver';
|
||||
import { AttachmentsController } from './http/attachments.controller';
|
||||
import { CommentsController } from './http/comments.controller';
|
||||
import { IssuesController } from './http/issues.controller';
|
||||
import { ExploreController } from './http/explore.controller';
|
||||
@@ -18,9 +21,24 @@ import { ReleasesController } from './http/releases.controller';
|
||||
* application services.
|
||||
*/
|
||||
@Module({
|
||||
imports: [
|
||||
// Uploads stay in memory until the command stores them; the size limit
|
||||
// is enforced here, before a byte reaches the application.
|
||||
MulterModule.registerAsync({
|
||||
inject: [ConfigService],
|
||||
useFactory: (config: ConfigService) => ({
|
||||
limits: {
|
||||
fileSize:
|
||||
(config.get<number>('ATTACHMENTS_MAX_MB') ?? 25) * 1024 * 1024,
|
||||
files: 1,
|
||||
},
|
||||
}),
|
||||
}),
|
||||
],
|
||||
controllers: [
|
||||
ProjectsController,
|
||||
IssuesController,
|
||||
AttachmentsController,
|
||||
CommentsController,
|
||||
ReleasesController,
|
||||
ExploreController,
|
||||
@@ -38,6 +56,9 @@ export class TrackerPresentersModule {
|
||||
static withApplication(
|
||||
applicationModule: Type | DynamicModule,
|
||||
): DynamicModule {
|
||||
return { module: TrackerPresentersModule, imports: [applicationModule] };
|
||||
return {
|
||||
module: TrackerPresentersModule,
|
||||
imports: [applicationModule],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user