Migrate all schema validation to zod#76
Conversation
906a010 to
d58c628
Compare
There was a problem hiding this comment.
Pull request overview
Migrates shared DTO/schema validation to a new @nbw/validation package built on Zod, updates backend request validation to use nestjs-zod/ZodValidationPipe (with Swagger/OpenAPI cleanup), and refactors frontend/backends to consume schema-backed DTOs from the shared package.
Changes:
- Added
@nbw/validationworkspace package with shared Zod schemas/types (env, auth, users, songs, pagination, forms). - Updated backend to use Zod DTOs/pipes (global + route-specific) and adjusted controllers/services/tests accordingly.
- Updated frontend imports to consume shared Zod schemas/types from
@nbw/validation, and wired build tooling to include the new package.
Reviewed changes
Copilot reviewed 105 out of 108 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Adds packages/validation to workspace references. |
| tsconfig.eslint.json | Adds packages/validation to ESLint TS references. |
| tsconfig.base.json | Updates decorator-metadata comment to reflect Nest/Mongoose usage. |
| scripts/build.ts | Ensures @nbw/validation is built early in the package build pipeline. |
| packages/validation/package.json | Defines new shared validation package (ESM output, build scripts, deps). |
| packages/validation/tsconfig.json | Base TS config for validation package output to dist/. |
| packages/validation/tsconfig.build.json | JS build config (tsc ESM output). |
| packages/validation/tsconfig.types.json | Types-only build config (emit .d.ts). |
| packages/validation/jest.config.js | Adds test config file for the validation package. |
| packages/validation/README.md | Adds package README (currently bun-init template). |
| packages/validation/src/index.ts | Barrel exports for all shared schemas/types. |
| packages/validation/src/config-shim.ts | Re-exports config for runtime resolution from validation dist. |
| packages/validation/src/config/EnvironmentVariables.dto.ts | Introduces Zod env schema + validateEnv() helper. |
| packages/validation/src/auth/DiscordStrategyConfig.dto.ts | Adds Zod schema/type for Discord strategy config. |
| packages/validation/src/common/Page.dto.ts | Adds shared Page DTO shape helper + type. |
| packages/validation/src/common/PageQuery.dto.ts | Adds shared pagination/query Zod schema + input/output types. |
| packages/validation/src/common/types.ts | Adds shared type alias wiring for page query types. |
| packages/validation/src/user/user.dto.ts | Adds shared user DTO schema/type. |
| packages/validation/src/user/CreateUser.dto.ts | Adds shared create-user schema/type. |
| packages/validation/src/user/GetUser.dto.ts | Adds shared get-user lookup schema/type. |
| packages/validation/src/user/LoginWithEmail.dto.ts | Adds shared login schema/type (with deprecated aliases). |
| packages/validation/src/user/NewEmailUser.dto.ts | Adds shared new-email-user schema/type. |
| packages/validation/src/user/SingleUsePass.dto.ts | Adds shared single-use-pass schema/type. |
| packages/validation/src/user/UpdateUsername.dto.ts | Adds shared update-username schema/type using config constants. |
| packages/validation/src/user/UserIndexQuery.dto.ts | Adds union-style query parsing for GET /user (lookup vs pagination). |
| packages/validation/src/song/types.ts | Adds shared song-related type aliases and constants-based types. |
| packages/validation/src/song/CustomInstrumentData.dto.ts | Adds shared custom-instrument data schema/type. |
| packages/validation/src/song/FeaturedSongsDto.dto.ts | Adds shared featured-songs schema/type + factory. |
| packages/validation/src/song/SongFileQuery.dto.ts | Adds shared download query schema/type. |
| packages/validation/src/song/SongForm.dto.ts | Migrates song form schemas/types to use Zod + config shim. |
| packages/validation/src/song/SongListQuery.dto.ts | Adds shared song list query schema/types (sort/order enums). |
| packages/validation/src/song/SongPage.dto.ts | Adds shared paged song schema/type. |
| packages/validation/src/song/SongPreview.dto.ts | Adds shared song preview schema/type. |
| packages/validation/src/song/SongSearchQuery.dto.ts | Adds shared search query schema/types. |
| packages/validation/src/song/SongStats.ts | Adds shared song stats schema/type. |
| packages/validation/src/song/SongView.dto.ts | Adds shared song view schema/type. |
| packages/validation/src/song/ThumbnailData.dto.ts | Adds shared thumbnail-data schema/type + example creator. |
| packages/validation/src/song/UploadSongDto.dto.ts | Adds shared upload-song body schema/type (multipart-friendly). |
| packages/validation/src/song/UploadSongResponseDto.dto.ts | Adds shared upload-song response schema/type. |
| packages/database/package.json | Adds dependency on @nbw/validation, removes class-validator deps, adjusts exports. |
| packages/database/src/index.ts | Re-exports entities + @nbw/validation as the DTO/schema source of truth. |
| packages/database/src/index.web.ts | Removes web-only barrel (DTOs now come from @nbw/validation). |
| packages/database/src/user/user.entity.ts | Adds/updates user entity definition (including social links). |
| packages/database/src/user/dto/user.dto.ts | Removes class-validator UserDto class (migrated to validation package). |
| packages/database/src/user/dto/CreateUser.dto.ts | Removes class-validator CreateUser DTO (migrated). |
| packages/database/src/user/dto/GetUser.dto.ts | Removes class-validator GetUser DTO (migrated). |
| packages/database/src/user/dto/LoginWithEmail.dto.ts | Removes class-validator login DTO (migrated). |
| packages/database/src/user/dto/Login.dto copy.ts | Removes duplicate login DTO file. |
| packages/database/src/user/dto/NewEmailUser.dto.ts | Removes class-validator new-email DTO (migrated). |
| packages/database/src/user/dto/SingleUsePass.dto.ts | Removes class-validator single-use-pass DTO (migrated). |
| packages/database/src/user/dto/UpdateUsername.dto.ts | Removes class-validator update-username DTO (migrated). |
| packages/database/src/common/dto/Page.dto.ts | Removes class-validator Page DTO (migrated). |
| packages/database/src/common/dto/PageQuery.dto.ts | Removes class-validator PageQuery DTO (migrated). |
| packages/database/src/common/dto/types.ts | Removes legacy PageQuery type alias (migrated). |
| packages/database/src/song/song.entity.ts | Switches entity typing imports to @nbw/validation types. |
| packages/database/src/song/dto/types.ts | Removes legacy song DTO type exports (migrated). |
| packages/database/src/song/dto/CustomInstrumentData.dto.ts | Removes class-validator DTO (migrated). |
| packages/database/src/song/dto/FeaturedSongsDto.dto.ts | Removes DTO class (migrated). |
| packages/database/src/song/dto/SongListQuery.dto.ts | Removes class-validator query DTO (migrated). |
| packages/database/src/song/dto/SongPage.dto.ts | Removes class-validator paged DTO (migrated). |
| packages/database/src/song/dto/SongPreview.dto.ts | Removes class-validator preview DTO (migrated). |
| packages/database/src/song/dto/SongStats.ts | Removes class-validator stats DTO (migrated). |
| packages/database/src/song/dto/SongView.dto.ts | Removes class-validator view DTO (migrated). |
| packages/database/src/song/dto/ThumbnailData.dto.ts | Removes class-validator thumbnail DTO (migrated). |
| packages/database/src/song/dto/UploadSongDto.dto.ts | Removes class-validator upload DTO (migrated). |
| packages/database/src/song/dto/UploadSongResponseDto.dto.ts | Removes class-validator response DTO (migrated). |
| bun.lock | Adds workspace + dependency locks for @nbw/validation and nestjs-zod. |
| apps/frontend/package.json | Adds @nbw/validation dependency for client usage. |
| apps/frontend/src/modules/song/components/client/ThumbnailRenderer.tsx | Switches form types import to @nbw/validation. |
| apps/frontend/src/modules/song/components/client/SongThumbnailInput.tsx | Switches form types import to @nbw/validation. |
| apps/frontend/src/modules/song-upload/components/client/context/UploadSong.context.tsx | Switches schema/types import to @nbw/validation. |
| apps/frontend/src/modules/song-edit/components/client/context/EditSong.context.tsx | Switches upload DTO + form schema/types imports to @nbw/validation. |
| apps/backend/package.json | Adds @nbw/validation + nestjs-zod, removes class-validator dep. |
| apps/backend/scripts/build.ts | Adds @nbw/validation to backend bundling externals and adjusts optional requires. |
| apps/backend/src/main.ts | Removes global class-validator ValidationPipe setup. |
| apps/backend/src/app.module.ts | Uses validateEnv from @nbw/validation and installs global ZodValidationPipe. |
| apps/backend/src/lib/initializeSwagger.ts | Adds OpenAPI cleanup via nestjs-zod + strips invalid zod markers from params. |
| apps/backend/src/lib/initializeSwagger.spec.ts | Updates test to mock cleanupOpenApiDoc. |
| apps/backend/src/config/EnvironmentVariables.ts | Removes class-validator env config (migrated). |
| apps/backend/src/zod-dto/index.ts | Adds barrel export for backend Zod DTO classes/schemas. |
| apps/backend/src/zod-dto/page-query.dto.ts | Adds Zod DTO class for common pagination query. |
| apps/backend/src/zod-dto/song-id.param.dto.ts | Adds Zod DTO class for :id route params. |
| apps/backend/src/zod-dto/song-file.query.dto.ts | Adds Zod DTO class for song download query. |
| apps/backend/src/zod-dto/song-open.headers.dto.ts | Adds Zod DTO class for headers validation on open endpoint. |
| apps/backend/src/zod-dto/song-list.query.dto.ts | Adds Zod DTO class for song list query validation. |
| apps/backend/src/zod-dto/song-search.query.dto.ts | Adds Zod DTO class for song search query validation. |
| apps/backend/src/zod-dto/update-username.body.dto.ts | Adds Zod DTO class for update-username request body. |
| apps/backend/src/zod-dto/upload-song.body.dto.ts | Adds Zod DTO class for upload-song multipart body (non-file fields). |
| apps/backend/src/zod-dto/user-index.query.dto.ts | Exposes union query schema/type for GET /user (pipe-based). |
| apps/backend/src/user/user.service.ts | Replaces class-validator calls with Zod schema parsing and typed inputs. |
| apps/backend/src/user/user.service.spec.ts | Updates service tests to use validation types and URL constraints. |
| apps/backend/src/user/user.controller.ts | Refactors GET /user to union query handling + Zod pipe; updates username patch DTO handling. |
| apps/backend/src/user/user.controller.spec.ts | Updates controller tests for new query DTO shape and response DTO construction. |
| apps/backend/src/song/song.util.ts | Replaces DTO class factories with plain typed mappers returning validation types. |
| apps/backend/src/song/song.service.ts | Updates service query parsing to Zod and uses new mapping helpers. |
| apps/backend/src/song/song.service.spec.ts | Updates tests to expect new mapper outputs and updated query validation behavior. |
| apps/backend/src/song/song.controller.ts | Updates controller signatures to Zod DTO classes for params/query/body/headers; adjusts response shaping. |
| apps/backend/src/song/song.controller.spec.ts | Updates controller tests for new DTO classes and signature changes. |
| apps/backend/src/song/song-upload/song-upload.service.ts | Switches DTO typings to @nbw/validation and minor refactors. |
| apps/backend/src/song/song-upload/song-upload.service.spec.ts | Updates upload service test imports/types to validation package. |
| apps/backend/src/song/my-songs/my-songs.controller.ts | Switches pagination query DTO to Zod DTO class and response type to validation type. |
| apps/backend/src/song/my-songs/my-songs.controller.spec.ts | Updates my-songs controller tests for new query DTO type. |
| apps/backend/src/seed/seed.service.ts | Switches type imports for upload/category/license/visibility to validation package. |
| apps/backend/src/auth/strategies/discord.strategy/Strategy.ts | Replaces class-validator config validation with Zod schema parsing. |
| apps/backend/src/auth/strategies/discord.strategy/Strategy.spec.ts | Updates tests for sync validation + oauth2 callback typing tweak. |
| apps/backend/src/auth/strategies/discord.strategy/DiscordStrategyConfig.ts | Removes class-validator config class (migrated). |
| apps/backend/src/auth/auth.service.ts | Replaces DTO construction with Zod schema parsing for user creation. |
| apps/backend/src/auth/auth.service.spec.ts | Adjusts test setup for username generation expectation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
3ce8dfa to
478ebb4
Compare
| ); | ||
|
|
||
| // Create song document | ||
| const song = await this.generateSongDocument( |
There was a problem hiding this comment.
In the refactorings, some intermediate variables ended up being merged into a straight return which returns a more complex expression. Though I find the previous, more explicit definition in steps to be clearer.
There was a problem hiding this comment.
Fixed this instance in b2d4c62, but I'm still looking for the other places
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 128 out of 132 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
apps/frontend/package.json:24
- Frontend code now imports types/schemas from
@nbw/validation, but@nbw/validationis not listed in this app's dependencies. Add it (likely as a workspace dependency) so installs/builds are reproducible and module resolution doesn't depend on hoisting/lockfile state.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ator - Add env, Discord strategy, and song form schemas to @nbw/validation - Wire ConfigModule to validateEnv; parse user/song/query payloads with Zod - Replace DTO class helpers with mappers in song.util; re-export validation from @nbw/database for consumers - Frontend: import song form schemas from @nbw/validation; remove local SongForm.zod - Remove class-validator/class-transformer and global ValidationPipe from backend - Update specs; note bun test may need workspace resolution fixes for @nbw/config
- Introduce a new jsonStringField function to validate and parse JSON strings, ensuring invalid JSON surfaces as a Zod issue. - Update thumbnailData and customInstruments fields to utilize jsonStringField for improved validation.
…instructions - Change package name to @nbw/validation and clarify its role as the source of shared Zod schemas and TypeScript types. - Add detailed layout and script sections for building, developing, testing, linting, and cleaning the package. - Include instructions for consumers on how to import and use the package after building.
- Delete jest.config.js as part of the cleanup process for the validation package.
…TO names Remove common/types.ts and song/types.ts (PageQueryDTOType and *DtoType aliases). Add song/uploadMeta.ts for VisibilityType, CategoryType, LicenseType, TimespanType. Export SongsFolder from SongPage.dto.ts next to SongPageDto. Point SongPreview/SongView/UploadSongDto at uploadMeta; update package index exports. Rename frontend imports from *DtoType to the real DTO types (via @nbw/database).
…ckage dependencies - Introduced new UI components: Button, Input, Label, and Textarea for consistent styling and functionality across the application. - Added @radix-ui/react-label dependency to package.json for label component integration. - Updated existing components to utilize the new UI components for improved user experience. - Refactored ProfileBioEditor and ProfilePublicNameEditor to use the new Input and Button components.
- Changed the order field in PageQuery DTO from a union of boolean and string to an enum with 'asc' and 'desc' options for improved clarity and validation.
…ewSource type - Updated song retrieval logic to use a more specific type for the uploader field in the song model. - Introduced the SongPreviewSource type to standardize the structure of song preview data. - Refactored songPreviewFromSongDocumentWithUser function to accept the new type for improved type safety and clarity.
- Changed various imports across the frontend application to source DTOs and types from the new @nbw/validation package instead of @nbw/database. - This refactor aims to centralize validation logic and improve type safety throughout the application.
…e SongSearchParams - Updated the SearchSongPage component to utilize the new SongSearchParams type for improved type safety. - Refactored search logic to use constants from the SEARCH_SONGS configuration for pagination and placeholder counts. - Cleaned up unused interfaces and enums, streamlining the codebase for better maintainability. - Introduced a new SongSearchParams DTO to standardize search parameters across the application.
… from @nbw/config - Removed the config-shim.ts file and updated imports in various DTOs to directly source constants from @nbw/config. - This change simplifies the import structure and enhances clarity across the validation package.
…ring - Modified the UserController to return paginated user data filtered by email, ID, or username. - Updated the UserService to handle pagination and filtering logic, ensuring consistent query handling. - Adjusted tests to reflect the new functionality and ensure proper coverage for paginated user retrieval. - Removed deprecated lookup mode handling for a more streamlined approach to user queries.
- Removed unnecessary import of UserIndexQueryDto and updated the getUserIndex method to directly use UserIndexPageQueryInput. - Streamlined the user retrieval logic for improved clarity and maintainability.
…constraints - Introduced maximum length constraints for title, originalAuthor, and description fields in the Song entity using UPLOAD_CONSTANTS. - Simplified the songPreviewFromSongDocumentWithUser function to default the description to an empty string if not provided. - Updated the SongPreview DTO to reflect the new maximum length validations for title, originalAuthor, and description fields.
…pdate package dependencies" This reverts commit fb03997.
This reverts commit 99bc5e6.
- Updated import statements across multiple DTO files to remove the '.js' extension for consistency and clarity. - This change enhances maintainability and aligns with best practices for module imports.
- Removed the mongoose dependency from the validation package to streamline dependencies. - Updated import statements in SongSearchQuery.dto.ts to reference the correct path without the file extension, enhancing consistency and maintainability.
1e7eea7 to
dd50786
Compare
| @ApiOperation({ summary: 'Edit song info by ID' }) | ||
| @ApiBody({ description: 'Upload Song', type: UploadSongResponseDto }) | ||
| @ApiBody({ description: 'Upload Song' }) | ||
| public async patchSong( | ||
| @Param('id') id: string, | ||
| @Param() params: SongIdParamDto, | ||
| @Req() req: RawBodyRequest<Request>, | ||
| @GetRequestToken() user: UserDocument | null, | ||
| ): Promise<UploadSongResponseDto> { | ||
| user = validateUser(user); | ||
| //TODO: Fix this weird type casting and raw body access | ||
| const body = req.body as unknown as UploadSongDto; | ||
| return await this.songService.patchSong(id, body, user); | ||
| return await this.songService.patchSong(params.id, body, user); | ||
| } |
| @@ -31,34 +28,7 @@ export class UserController { | |||
| @Get() | |||
| @ApiTags('user') | |||
| @ApiBearerAuth() | |||
| async getUser(@Query() query: GetUser) { | |||
| const { email, id, username } = query; | |||
|
|
|||
| if (email) { | |||
| return await this.userService.findByEmail(email); | |||
| } | |||
|
|
|||
| if (id) { | |||
| return await this.userService.findByID(id); | |||
| } | |||
|
|
|||
| if (username) { | |||
| throw new HttpException( | |||
| 'Username is not supported yet', | |||
| HttpStatus.BAD_REQUEST, | |||
| ); | |||
| } | |||
|
|
|||
| throw new HttpException( | |||
| 'You must provide an email or an id', | |||
| HttpStatus.BAD_REQUEST, | |||
| ); | |||
| } | |||
|
|
|||
| @Get() | |||
| @ApiTags('user') | |||
| @ApiBearerAuth() | |||
| async getUserPaginated(@Query() query: PageQueryDTO) { | |||
| async getUserIndex(@Query() query: UserIndexPageQueryInput) { | |||
| return await this.userService.getUserPaginated(query); | |||
| } | |||
Summary
Moves shared validation to Zod as the single source of truth, wires NestJS to validate requests with Zod (including OpenAPI/Swagger integration), and refactors controllers to rely on schema-backed DTOs instead of ad hoc parsing.
Changes
@nbw/validation): Central Zod schemas for env, auth, users, songs, pagination, uploads, etc.ZodValidationPipe,nestjs-zod/createZodDto-style wrappers where applicable, controller query/body/param/header validation aligned with those DTOs, and Swagger doc generation updated (including handling of OpenAPI parameter cleanup edge cases).distmatches"type": "module"and Next.js client bundles do not hitexports is not definedfrom accidental CommonJS output.Testing
Notes / follow-ups
packages/validationbuild before apps that depend on it.