# AGENTS.md — media Media collection for uploads (images, PDFs, etc.) and media-related use cases (upload, delete, list). Provides the Media Payload collection and tRPC procedures for asset management. ## What it owns - **Entities** — Media type (filename, mimetype, size, URL), upload errors - **Use cases** — Upload media, delete media, list media, get media - **Repository interface** — `IMediaRepository` for media persistence - **Mock repository** — In-memory media store for tests - **Payload repository** — Real Payload-backed media repository (constructor-injected at boot) - **Payload collection** — Media collection definition - **tRPC router** — Procedures for upload, delete, list - **DI container** — Per-feature InversifyJS container with media symbols - **UI components** — Media upload form, media gallery ## Public exports From `package.json`: - `.` — Media type + media errors + UI components - `./api` — tRPC router (`mediaRouter`) - `./cms` — Payload Media collection - `./di/bind-production` — `bindProductionMedia()` to wire Payload repo at boot ## What it must NOT import - Any other feature package (`@repo/auth`, `@repo/blog`, etc.) - Any app package - `@repo/core-api`, `@repo/core-cms`, `@repo/core-trpc`, `@repo/core-ui` directly; only import from `@repo/core-shared` and use DI for Payload config ## Layer rules ### `src/` files use relative imports ```typescript // ✓ Correct import type { IMediaRepository } from "../repositories/media.repository.interface.js"; // ✗ Wrong import { Media } from "@/entities/media.js"; ``` ### Tests use @/ alias ```typescript // ✓ Correct import { uploadMediaUseCase } from "@/application/use-cases/upload-media.use-case.js"; ``` ### DI container is per-feature Tests rebind their own container: ```typescript import { container as mediaContainer, MEDIA_SYMBOLS } from "@/di/container.js"; import { MockMediaRepository } from "@/infrastructure/repositories/mock-media.repository.js"; beforeEach(() => { mediaContainer.unbindAll(); mediaContainer.bind(MEDIA_SYMBOLS.IMediaRepository).to(MockMediaRepository); }); ``` ## Test conventions - **Unit tests** colocated: `*.test.ts` - **Feature tests** in `tests/`: `*.feature.test.ts` - **Vitest environment** — `node` - **Alias** — `@/` resolves to `src/` - **Run** — `pnpm test --filter @repo/media` ## Structure (minimal) ``` src/ entities/ media.ts # Media schema + type errors.ts # UploadError, InvalidMimetype, etc. application/ repositories/ media.repository.interface.ts use-cases/ upload-media.use-case.ts delete-media.use-case.ts infrastructure/ repositories/ payload-media.repository.ts mock-media.repository.ts di/ symbols.ts container.ts bind-production.ts interface-adapters/ controllers/ media.controller.ts integrations/ cms/ collections/ media.ts index.ts api/ router.ts index.ts ui/ upload-form.tsx index.ts tests/ upload.feature.test.ts ```