Skip to content

feat: add Swagger/OpenAPI documentation to backend#118

Open
Rishavraaj wants to merge 10 commits into
mainfrom
feat/add-swagger-openapi-docs
Open

feat: add Swagger/OpenAPI documentation to backend#118
Rishavraaj wants to merge 10 commits into
mainfrom
feat/add-swagger-openapi-docs

Conversation

@Rishavraaj
Copy link
Copy Markdown
Contributor

Summary

  • Swagger UI mounted at /api/docs with Bearer auth support; OpenAPI JSON at /api/docs-json
  • CLI plugin enabled via tsPlugins in webpack.config.js to auto-infer @ApiProperty from TypeScript types, with a webpack resolve alias
    fixing bun's class-transformer/storage resolution
  • All controllers decorated with @ApiTags, @ApiBearerAuth, @ApiOperation, and typed response decorators (tasks, contacts,
    companies, deals, activities, table, agents, chats, chat, meeting, admin, metadata, app)
  • All DTOs have full class-validator + @ApiProperty annotations, including query DTOs (ContactListQueryDto, ActivityQueryDto)
  • Bug fixes bundled in:
    • TaskStatus enum corrected to uppercase values (TODO/IN_PROGRESS/DONE/CANCELLED) matching Prisma schema
    • Deal stage enum corrected to actual valid values (prospecting, qualification, proposal, negotiation, closed_won, closed_lost)
    • Task repository default filter changed from root-only (parentId: null) to all tasks so subtasks appear in GET /api/tasks
  • MeetingSwaggerDto parallel classes added for Zod-based meeting endpoints (runtime validation still uses Zod)

Test plan

  • Run backend: bunx nx serve backend
  • Open http://localhost:3001/api/docs — Swagger UI loads with all endpoint groups in the sidebar
  • Authenticate via the Authorize button with a Bearer token
  • POST /api/tasks with status: "TODO" — no Prisma validation error
  • POST /api/deals with stage: "qualification" — no invalid stage error
  • GET /api/tasks — returns all tasks including subtasks
  • GET /api/docs-json — returns valid OpenAPI JSON

Rishavraaj and others added 10 commits May 4, 2026 16:43
- Install @nestjs/swagger and swagger-ui-express; enable CLI plugin via tsPlugins in webpack.config.js so @ApiProperty decorators are auto-inferred from TypeScript types
- Mount Swagger UI at /api/docs with Bearer auth support
- Add @apitags, @ApiBearerAuth, @apioperation, and response decorators to all controllers (tasks, contacts, companies, deals, activities, table, agents, chats, chat, meeting, admin, metadata, app)
- Add full class-validator decorators to all DTOs including ContactListQueryDto and ActivityQueryDto query params
- Create MeetingSwaggerDto parallel classes for Zod-based meeting endpoints
- Fix TaskStatus enum values to uppercase (TODO/IN_PROGRESS/DONE/CANCELLED) to match Prisma schema
- Fix deal stage enum to use correct values from constants (prospecting, qualification, proposal, negotiation, closed_won, closed_lost)
- Fix task repository default filter to return all tasks instead of root-only
- Add webpack resolve alias for class-transformer/storage to fix bun module resolution

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
swagger-ui-express, swagger-ui-dist, and @types/swagger-ui-express are
not directly imported — @nestjs/swagger bundles its own asset serving.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
findAll with no parentId now returns all tasks (no filter), not just
root-level tasks. Update test description and assertion accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add --output-style=stream to the nx e2e command so Playwright's list
reporter output is piped directly to the GitHub Actions log instead of
being buffered and hidden.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The backend was only checking NEXT_PUBLIC_BETTER_AUTH_INCLUDE_EMAILS_AUTH
(a frontend env var) to enable email/password auth. In CI only the server-
side BETTER_AUTH_INCLUDE_EMAILS_AUTH var is set, so emailAndPassword was
disabled, causing the auth setup E2E test to time out on sign-in.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After removing swagger-ui-dist from package.json (unused dep), main.ts
still called createRequire('swagger-ui-dist/absolute-path.js') at startup
causing MODULE_NOT_FOUND and preventing the backend from booting.

@nestjs/swagger serves its own bundled UI assets, so the custom path is
not needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Swagger UI static assets (bun module resolution):
- swagger-ui-dist is not hoisted by bun so it can't be required at runtime
- Copy swagger-ui-dist assets into dist/swagger-ui at build time via
  webpack assets config; reference them with path.join(__dirname, 'swagger-ui')
- Use factory function pattern per NestJS docs for SwaggerModule.setup
- Add swagger-ui-express to knip ignoreDependencies (peer dep used internally
  by @nestjs/swagger, not directly imported)
- Remove .controller.ts from dtoFileNameSuffix to avoid double-processing
  manually-annotated inline DTOs

Duplicate DTO names:
- Rename AddOwnerDto → AddDealOwnerDto / AddCompanyOwnerDto
- Rename UpdateCompanyDto → UpdateDealCompanyDto (deals.controller.ts)
- Rename AddContactDto → AddDealContactDto (deals.controller.ts)
- Rename UpdateContactDto → UpdateDealContactDto (deals.controller.ts)
- Rename UpdateContactDto → UpdateCompanyContactDto (companies.controller.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
webpack.config.js calls require.resolve('swagger-ui-dist/package.json') at
load time to compute the asset copy path. This requires swagger-ui-dist to
be an explicit dependency; it is not hoisted by bun from transitive deps.

Also add swagger-ui-dist to knip ignoreDependencies since it is consumed
by webpack.config.js, not a source file that knip scans.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant