conceptadev / conceptadev/rockets
feat(core): first-class file upload on operationResource (multipart, storage-adapter seam)
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 2
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 23
Description
## Problem
File upload (`multipart/form-data`) has no first-class surface in Rockets. Every app that needs one leaves the generated paths and hand-writes a controller with `@UseInterceptors(FileInterceptor(...))` — which is:
- **Express/Multer-specific** (breaks the adapter-agnostic discipline; Fastify needs a different stack);
- **outside every Rockets guarantee** — no generated validation, no OpenAPI `multipart` documentation, no `routePolicy` visibility beyond auth metadata, and exposed to the hand-written traps already filed as #83;
- **another reason the hand-written surface exists at all**, alongside streaming/SSE (#52). Same family: transport shapes `operationResource` v1 does not speak.
## Ask
A generic upload primitive that follows the house patterns:
- Declared on the resource like any operation (e.g. an `op.upload(...)` shape on `operationResource`), with typed limits (size, count, accepted mime types) validated at the boundary and failing with the standard error envelope.
- **Storage behind an adapter seam**, like persistence already is (`RepositoryInterface`) and entity compilation already is (`SchemaEntityCompiler`): local disk / S3 / GCS are configuration, not code. Core stays free of any concrete storage SDK.
- Generated OpenAPI: `multipart/form-data` request body with the file field and any declared metadata fields, so clients and codegen see the truth.
- Composes with everything a generated route already has: auth, `acl`, `transactional` metadata handling, and the #77 route audit.
## Non-goals (follow-ups)
- Download/streaming of stored files — that is #52's Range/stream territory; this issue is the inbound half.
- Image processing, virus scanning, resumable/chunked uploads — adapter or app concerns; the seam should not preclude them.
Related: #52 (streaming/SSE — the outbound half of the same gap), #83 (the traps waiting for whoever hand-writes these routes today), #46 (field report documenting how much surface stays hand-written).
Contributor guide
Research direction
Start by reading the operationResource, RepositoryInterface, and SchemaEntityCompiler patterns, then review related issues #52, #77, and #83 to understand the existing route and transport boundaries. Confirm the adapter and operation design with maintainers before implementation. Done means typed multipart limits, adapter-backed storage, generated OpenAPI, standard errors, and composition with auth, acl, and transactional metadata.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 28/100