feat(iios): media sharing — presigned storage port + attachments on messages
Media the industry way: the DB stores a reference, bytes live behind a storage port. - StoragePort + LocalDiskStorage (dev). MediaService presigns short-lived signed upload/download URLs (HS256 tokens) pointing at IIOS's own endpoints; the bytes never touch the kernel. Prod swaps STORAGE_PORT to S3/Supabase — same as auth. - MediaController: presign-upload / PUT upload/:token (raw stream) / GET blob/:token / presign-download. Uploads are OPA-governed (iios.media.upload: 25 MB cap + image/video/audio/pdf/office allowlist); downloads are tenant-fenced by object key. - send() + MessageDto carry an attachment (contentRef/mimeType/sizeBytes → generic MEDIA_REF/VOICE_REF/FILE_REF part; DTO exposes kind image|video|audio|file). Tests: media.service.spec (6) — round-trip, oversize/type denied, oversized PUT refused, tampered token rejected, tenant fence. Full suite 192 green. Verified live: presign→upload→send→history→signed download round-trips the exact bytes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PlatformModule } from '../platform/platform.module';
|
||||
import { IdentityModule } from '../identity/identity.module';
|
||||
import { MediaController } from './media.controller';
|
||||
import { MediaService } from './media.service';
|
||||
import { LocalDiskStorage } from './local-disk.storage';
|
||||
import { STORAGE_PORT } from './storage.port';
|
||||
|
||||
@Module({
|
||||
imports: [PlatformModule, IdentityModule],
|
||||
controllers: [MediaController],
|
||||
// Dev binds local disk; prod swaps STORAGE_PORT to an S3/Supabase adapter.
|
||||
providers: [MediaService, { provide: STORAGE_PORT, useClass: LocalDiskStorage }],
|
||||
})
|
||||
export class MediaModule {}
|
||||
Reference in New Issue
Block a user