Scaffolds and wires a new NestJS service/module for the Video Search & Summarization sample app's pipeline-manager using the repo's real conventions. Use when asked to add a new service/module to pipeline-manager, extend the VSS orchestrator, add a new endpoint/queue/event to pipeline-manager, or scaffold a NestJS module the repo way for the video-search-and-summarization sample app.
Scaffolds and wires a new NestJS service/module for the Video Search & Summarization sample app's pipeline-manager using the repo's real conventions. Use when asked to add a new service/module to pipeline-manager, extend the VSS orchestrator, add a new endpoint/queue/event to pipeline-manager, or scaffold a NestJS module the repo way for the video-search-and-summarization sample app.
Add a VSS pipeline-manager NestJS module
Use this when adding a new pipeline-manager/src/<feature>/ capability. First read nearby modules again (summary, search, video-upload, state-manager) because this repo has concrete patterns that matter more than generic NestJS advice.
Environment setup (run first)
This skill drives the Video Search & Summarization app through its real source
files, so the VSS application must be present and you must run commands from its
app root. Do this before anything else, and it works whether or not the VSS
source is already in your workspace.
Run the bundled bootstrap. It first tries to find an existing VSS checkout -
walking up from the current directory and inspecting the enclosing git repo - and
reuses it without ever re-cloning. Only when no checkout is found does it do a
shallow, single-branch, sparse checkout of just
sample-applications/video-search-and-summarization from main. It prints the
resolved app root on stdout:
# SKILL_DIR is THIS skill's own directory (shown to you when the skill loads);# in-repo it is .github/skills/vss-add-nest-module. Works the same if the skill is installed standalone.
SKILL_DIR=".github/skills/vss-add-nest-module"
APP_ROOT="$(bash "/scripts/vss-bootstrap.sh")"
$SKILL_DIR
cd
"$APP_ROOT"
Every command below assumes the working directory is this APP_ROOT. To pull
from a fork/branch or reuse a specific checkout dir, override VSS_REPO_URL,
VSS_REPO_BRANCH, or VSS_CLONE_DIR before running it.
1. Match the repo layout
Most feature modules use this shape:
src/<feature>/
<feature>.module.ts
controllers/<feature>.controller.ts
services/<feature>.service.ts
services/<feature>-db.service.ts # only when TypeORM-backed
queues/<feature>-queue.service.ts # only when tick/event queued
models/<feature>.model.ts
models/<feature>.entity.ts # only when persisted
Why: controllers stay thin, services hold orchestration, *-db.service.ts isolates TypeORM repository access, queues are event-driven processors, and models/ keeps DTO/interfaces/entities close to the feature.
Use interfaces for internal shapes and Swagger classes for request/response documentation, as in summary/models/summary-pipeline.model.ts and search/model/search.model.ts.
Root app.module.ts: add NewEntity to TypeOrmModule.forRoot({ entities: [...] }).
Why: forFeature enables repository injection in the feature; the root entity list lets TypeORM create/sync the table.
4. Keep controllers thin and Swagger-tagged
Controllers inject services using the repo's $name property style and expose REST routes with @ApiTags, @ApiOperation, @ApiBody, @ApiParam, and response decorators.
If another module must inject your service, add it to exports.
Why: Nest resolves providers only across module boundaries through imports/exports.
6. Add events using the central enums
Define new event names in src/events/Pipeline.events.ts, src/events/app.events.ts, or src/events/socket.events.ts. Use dot-delimited names because root wiring uses:
Pipeline examples include pipeline.summary.start, pipeline.chunking.complete, and pipeline.summary.stream. App tick events are emitted by AppService and consumed by queues.
Why: event enums prevent string drift and decouple controllers/services/queues/gateways.
7. Use the repo queue pattern for background work
Queue processors are injectable services under state-manager/queues or a feature queues/ folder. They keep in-memory waiting/processing state, enqueue on a domain event, process on AppEvents.FAST_TICK, emit progress/completion events, and remove stale work on AppEvents.SUMMARY_REMOVED.
Why: long-running work is throttled centrally and does not block HTTP requests.
8. Send UI updates through SocketEvent + EventsGateway
Add socket event enum values to src/events/socket.events.ts, emit them from state/services, and add @OnEvent(...) handlers in sockets/events.gateway.ts.
Place EventEmitterModule.forRoot(...) once only; do not add another root event emitter.
11. Validate
From pipeline-manager/, run existing checks only:
npm run build
npm test -- --runInBand
npm run lint
If changing only docs or templates, no app build is required. If adding entities, verify migrations/sync behavior is acceptable for this sample (synchronize: true, migrationsRun: true are already set).