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:
2026-10-08 08:35:33 +02:00
parent 80d9bee6e0
commit 0b65c1c912
72 changed files with 6766 additions and 4297 deletions

View File

@@ -4,6 +4,7 @@ import {
} from '@angular/core';
import {
ActivityGateway,
AttachmentsGateway,
CommentsGateway,
IssuesGateway,
ProjectsGateway,
@@ -18,10 +19,11 @@ import {
GraphqlUsersGateway,
} from './adapters/graphql-collaboration.gateways';
import { GraphqlIssuesGateway } from './adapters/graphql-issues.gateway';
import { HttpAttachmentsGateway } from './adapters/http-attachments.gateway';
import { GraphqlProjectsGateway } from './adapters/graphql-projects.gateway';
import { GraphqlRealtimeGateway } from './adapters/graphql-realtime.gateway';
/** Ports → GraphQL adapters. */
/** Ports → GraphQL adapters (and REST for files). */
export function provideTrackerInfrastructure(): EnvironmentProviders {
return makeEnvironmentProviders([
{ provide: ProjectsGateway, useClass: GraphqlProjectsGateway },
@@ -29,6 +31,7 @@ export function provideTrackerInfrastructure(): EnvironmentProviders {
{ provide: CommentsGateway, useClass: GraphqlCommentsGateway },
{ provide: ReleasesGateway, useClass: GraphqlReleasesGateway },
{ provide: ActivityGateway, useClass: GraphqlActivityGateway },
{ provide: AttachmentsGateway, useClass: HttpAttachmentsGateway },
{ provide: UsersGateway, useClass: GraphqlUsersGateway },
{ provide: TrackerRealtimeGateway, useClass: GraphqlRealtimeGateway },
]);