Context
Porting sharity-api (Express + Mongoose, ~23k LoC) to Perry. Two
adjacent gaps block every upload flow: server-side multipart parsing
and AWS S3.
Multipart / form-data on fastify
The Fastify server in perry-ext-fastify handles JSON bodies, but every
upload route in the target app is multipart/form-data — avatars, cover
photos, item images. Need a multer-equivalent or fastify-multipart-style
plugin with:
- Disk and memory storage modes
- File size limits (
limits: { fileSize: 5 * 1024 * 1024 })
- MIME filter (
fileFilter: (file) => /^image\//.test(file.mimetype))
- Multiple field names (
avatar, image, cover-photo)
- Generated filenames (UUID + original extension)
- Stream the file body without buffering the whole multipart payload in
memory
AWS S3
Sharity-api uses S3 as the canonical image store. Local disk fallback
exists but isn't viable in production. Surface needed:
@aws-sdk/client-s3: PutObjectCommand, GetObjectCommand,
DeleteObjectCommand, HeadObjectCommand
@aws-sdk/s3-request-presigner: getSignedUrl(command, {expiresIn})
- Region + credential resolution from env (
AWS_REGION,
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_S3_BUCKET_NAME)
- ACL support (
public-read is what the existing app uses)
Acceptance
A fastify route that accepts a multipart upload, streams it to S3 with
PutObjectCommand, and returns a presigned GET URL for the uploaded key.
Compiles and runs against real S3 (or LocalStack) under perry run.
Why both in one issue
The two together are how every upload endpoint in a typical Node API is
wired. Splitting them lets the multipart side ship without S3 (still
useful for disk-only setups), but the issue tracks both because
sharity-api needs both.
Context
Porting sharity-api (Express + Mongoose, ~23k LoC) to Perry. Two
adjacent gaps block every upload flow: server-side multipart parsing
and AWS S3.
Multipart / form-data on fastify
The Fastify server in perry-ext-fastify handles JSON bodies, but every
upload route in the target app is
multipart/form-data— avatars, coverphotos, item images. Need a multer-equivalent or fastify-multipart-style
plugin with:
limits: { fileSize: 5 * 1024 * 1024 })fileFilter: (file) => /^image\//.test(file.mimetype))avatar,image,cover-photo)memory
AWS S3
Sharity-api uses S3 as the canonical image store. Local disk fallback
exists but isn't viable in production. Surface needed:
@aws-sdk/client-s3:PutObjectCommand,GetObjectCommand,DeleteObjectCommand,HeadObjectCommand@aws-sdk/s3-request-presigner:getSignedUrl(command, {expiresIn})AWS_REGION,AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_S3_BUCKET_NAME)public-readis what the existing app uses)Acceptance
A fastify route that accepts a multipart upload, streams it to S3 with
PutObjectCommand, and returns a presigned GET URL for the uploaded key.
Compiles and runs against real S3 (or LocalStack) under
perry run.Why both in one issue
The two together are how every upload endpoint in a typical Node API is
wired. Splitting them lets the multipart side ship without S3 (still
useful for disk-only setups), but the issue tracks both because
sharity-api needs both.