Skip to content

feat(backend): add static asset serving support (closes #217)#281

Merged
Nabeelahh merged 3 commits into
BlockDash-Studios:mainfrom
otobongdev:add-static-asset
Jun 30, 2026
Merged

feat(backend): add static asset serving support (closes #217)#281
Nabeelahh merged 3 commits into
BlockDash-Studios:mainfrom
otobongdev:add-static-asset

Conversation

@otobongdev

Copy link
Copy Markdown
Contributor

Summary

Adds backend support for serving static and uploaded assets via a new NestJS AssetsModule, plus a read-only static asset directory mounted from disk. Closes #217.

What's new

  • New AssetsModule under BackendAcademy/src/assets/:
    • assets.module.ts, assets.controller.ts, assets.service.ts
    • interfaces/asset.interface.ts (Asset, AssetListResponse, AssetSortOrder)
    • dto/upload-asset.dto.ts (UploadAssetDto with optional name and description text fields validated alongside the multipart upload)
    • Specs: assets.controller.spec.ts, assets.service.spec.ts
  • Wiring:
    • app.module.ts registers AssetsModule
    • main.ts is now typed as NestExpressApplication and mounts ASSETS_STATIC_DIR (default ./public) under the URL prefix /static/ via useStaticAssets, with mkdirSync fallback so a fresh clone boots.
    • config/config.module.ts adds Joi-validated env vars: ASSETS_UPLOAD_DIR, ASSETS_MAX_SIZE_MB, ASSETS_BASE_URL, ASSETS_STATIC_DIR.
    • .env.example documents the new env vars.
  • Dependencies:
    • multer ^1.4.5-lts.1 (now a direct dep so import { memoryStorage } from 'multer' resolves under pnpm strict mode)
    • @types/multer ^1.4.12 and typescript-eslint ^7.18.0 under devDependencies
  • Misc:
    • Removed an extra trailing } in BackendAcademy/src/social/social.service.ts that was blocking TypeScript compilation.

REST surface (URI prefix /api/v1/ thanks to global versioning)

Method Path Description
GET /assets List assets (?sort=newest|oldest|name, default newest)
GET /assets/:id Fetch asset metadata
GET /assets/:id/download Stream content back to client with stored Content-Type, length, and Content-Disposition
POST /assets Multipart upload (field file); optional name/description validated against UploadAssetDto
DELETE /assets/:id Remove asset metadata and the underlying file

Read-only prebuilt static files under ASSETS_STATIC_DIR are served at /static/*.

Behavior

  • Metadata is held in an in-memory Map<id, Asset>; the file body is persisted at ASSETS_UPLOAD_DIR (default ./data/uploads).
  • Upload guard rails: size cap (default 10 MB, configurable via ASSETS_MAX_SIZE_MB), MIME allowlist (image/*, video/*, audio/*, application/pdf, text/*).
  • Filenames in the upload directory embed the asset UUID and are sanitised so the resolved path cannot escape ASSETS_UPLOAD_DIR.
  • Orphan files in the upload directory are pruned on graceful shutdown via OnModuleDestroy.
  • Swagger annotations on every endpoint so the change shows up in /api/docs.

Tests

  • pnpm test in BackendAcademy reports 113 of 117 tests passing.
  • The 4 failures (src/rewards/rewards.service.spec.ts \u2014 nested test definition; src/rewards/streak.service.spec.ts \u2014 stale getStreak / checkIn assertions) are pre-existing on origin/main and unrelated to this change. They are documented here for transparency; fixing them is out of scope for issue Add static asset serving support #217.
  • pnpm build (nest build) compiles cleanly.
  • Note: pnpm lint currently fails on origin/main because the repo uses eslint.config.ts (flat config) with eslint@^8.0.0 declared in devDependencies. Flat config is supported by eslint 9 or by eslint 8 with ESLINT_USE_FLAT_CONFIG=true; align versions in a follow-up PR.

Configuration

# Static & uploaded assets
ASSETS_UPLOAD_DIR=./data/uploads
ASSETS_MAX_SIZE_MB=10
ASSETS_BASE_URL=/api/v1/assets
ASSETS_STATIC_DIR=./public

Closes #217

…dios#217)

Add a NestJS AssetsModule exposing CRUD endpoints for uploaded assets and mount a read-only static asset directory at /static/.

New module:\n- BackendAcademy/src/assets/{assets.module.ts,assets.controller.ts,assets.service.ts,interfaces/asset.interface.ts,dto/upload-asset.dto.ts}\n- BackendAcademy/src/assets/assets.controller.spec.ts\n- BackendAcademy/src/assets/assets.service.spec.ts

Wiring:\n- BackendAcademy/src/app.module.ts: register AssetsModule\n- BackendAcademy/src/main.ts: useStaticAssets at /static/, typed as NestExpressApplication\n- BackendAcademy/src/config/config.module.ts: Joi schema adds ASSETS_UPLOAD_DIR, ASSETS_MAX_SIZE_MB, ASSETS_BASE_URL, ASSETS_STATIC_DIR\n- BackendAcademy/.env.example: documents the new env vars

API surface (URI version /api/v1/):\n- GET    /assets              list asset metadata (newest|oldest|name)\n- GET    /assets/:id          fetch asset metadata\n- GET    /assets/:id/download stream content with stored MIME type\n- POST   /assets              multipart upload (multer memoryStorage + UploadAssetDto)\n- DELETE /assets/:id          remove asset metadata and underlying file

Behavior:\n- In-memory metadata registry mirrored to filesystem at ASSETS_UPLOAD_DIR\n- MIME allowlist: image/*, video/*, audio/*, application/pdf, text/*\n- Sanitized filenames embedding the asset UUID\n- Soft validation on missing on-disk files; orphan tmp files pruned at shutdown

Test status:\n- BackendAcademy nest build passes\n- Jest suite: 113 / 117 tests pass (4 pre-existing failures remain in src/rewards/* and are unrelated to this change; verified pre-existing on origin/main)

Dependencies:\n- multer ^1.4.5-lts.1 added under dependencies\n- @types/multer ^1.4.12 and typescript-eslint ^7.18.0 added under devDependencies

Misc:\n- Removed an extra trailing closing brace in BackendAcademy/src/social/social.service.ts that was blocking TS compilation
@drips-wave

drips-wave Bot commented Jun 30, 2026

Copy link
Copy Markdown

@otobongdev Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Nabeelahh Nabeelahh merged commit 70e6f33 into BlockDash-Studios:main Jun 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add static asset serving support

2 participants