Skip to content

feat: implement concert and ticket type management modules with role-… - #4

Merged
USThienPhu merged 1 commit into
developfrom
feat/module-concert
Jun 2, 2026
Merged

feat: implement concert and ticket type management modules with role-…#4
USThienPhu merged 1 commit into
developfrom
feat/module-concert

Conversation

@USThienPhu

Copy link
Copy Markdown
Collaborator

…based access control

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new Concert module (concert + ticket type management) into the NestJS API and wires in role-based access control and Redis-backed caching to support high-read endpoints.

Changes:

  • Add Concert + TicketType controllers/services/repos (Prisma) with organizer-only create/update routes.
  • Add Zod DTO schemas for concert and ticket type validation.
  • Introduce cookie parsing middleware and extend Redis module exports to support caching.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/ticketbox/apps/api/src/modules/redis/redis.module.ts Exports REDIS_CLIENT token and RedisService for downstream caching.
src/ticketbox/apps/api/src/modules/concert/presentation/ticket-type.controller.ts Adds public ticket-type listing and organizer-only create/update endpoints.
src/ticketbox/apps/api/src/modules/concert/presentation/dto/ticket-type.zod.ts Defines Zod validation for ticket-type create/update payloads.
src/ticketbox/apps/api/src/modules/concert/presentation/dto/concert.zod.ts Defines Zod validation for concert query/create/update payloads.
src/ticketbox/apps/api/src/modules/concert/presentation/concert.controller.ts Adds public concert read endpoints and organizer-only create/update endpoints.
src/ticketbox/apps/api/src/modules/concert/infrastructure/repository/ticket-type.repository.ts Implements Prisma-based ticket type persistence and DTO mapping.
src/ticketbox/apps/api/src/modules/concert/infrastructure/repository/concert.repository.ts Implements Prisma-based concert persistence and DTO mapping (homepage/list/detail).
src/ticketbox/apps/api/src/modules/concert/domain/ticket-type.type.ts Introduces TicketType domain/DTO types.
src/ticketbox/apps/api/src/modules/concert/domain/concert.type.ts Introduces Concert domain/DTO types (including detail DTO).
src/ticketbox/apps/api/src/modules/concert/concert.module.ts Wires controllers/services/repos and imports Redis/Auth/Session modules.
src/ticketbox/apps/api/src/modules/concert/application/service/ticket-type.service.ts Adds ticket-type business logic with Redis cache-aside + invalidation.
src/ticketbox/apps/api/src/modules/concert/application/service/concert.service.ts Adds concert business logic (homepage/list/detail + publish gating).
src/ticketbox/apps/api/src/modules/concert/application/port/service/ticket-type.service.port.ts Adds ticket-type service port + DI token.
src/ticketbox/apps/api/src/modules/concert/application/port/service/concert.service.port.ts Adds concert service port + DI token.
src/ticketbox/apps/api/src/modules/concert/application/port/repository/ticket-type.repository.port.ts Adds ticket-type repository port + DI token.
src/ticketbox/apps/api/src/modules/concert/application/port/repository/concert.repository.port.ts Adds concert repository port + DI token.
src/ticketbox/apps/api/src/app.module.ts Registers ConcertModule and applies cookie parsing middleware globally.
src/ticketbox/apps/api/common/middleware/cookie-parser.middleware.ts Adds cookie parsing middleware used by auth/public endpoints.
src/ticketbox/apps/api/common/guard/roles.guard.ts Adds RolesGuard enforcing role metadata.
src/ticketbox/apps/api/common/decorator/roles.decorator.ts Adds @Roles(...) decorator for role metadata.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +15 to +16
startAt: z.string().datetime('startAt must be a valid ISO datetime string').transform((val) => new Date(val)),
endAt: z.string().datetime('endAt must be a valid ISO datetime string').transform((val) => new Date(val)),
Comment on lines +11 to +12
saleStartAt: z.string().datetime('saleStartAt must be a valid ISO datetime string').transform((val) => new Date(val)),
saleEndAt: z.string().datetime('saleEndAt must be a valid ISO datetime string').transform((val) => new Date(val)),
Comment on lines +63 to +65
items: result.items,
meta: result.meta,
};
Comment on lines +50 to +54
if (body.saleStartAt >= body.saleEndAt) {
throw new BadRequestException('saleStartAt must be before saleEndAt');
}

const data = await this.ticketTypeService.createTicketType(concertId, body);
Comment on lines +68 to +72
if (body.saleStartAt && body.saleEndAt && body.saleStartAt >= body.saleEndAt) {
throw new BadRequestException('saleStartAt must be before saleEndAt');
}

const data = await this.ticketTypeService.updateTicketType(ticketTypeId, body);
Comment on lines +95 to +99
if (body.startAt >= body.endAt) {
throw new BadRequestException('CONCERT_INVALID_DATE_RANGE');
}

const data = await this.concertService.createConcert(body);
Comment on lines +115 to +119
if (body.startAt && body.endAt && body.startAt >= body.endAt) {
throw new BadRequestException('CONCERT_INVALID_DATE_RANGE');
}

const data = await this.concertService.updateConcert(id, body);
Comment on lines +48 to +52
await this.redisService.set({
key: cacheKey,
value: list as any,
ttlSeconds: 300, // 5 minutes TTL
});
Comment on lines +75 to +83
if (accessToken) {
try {
const payload = await this.tokenService.verifyAccessToken(accessToken);
if (payload && payload.role === RoleName.ORGANIZER) {
isOrganizer = true;
}
} catch (err) {
// Invalid token, treat as public/audience
}
@USThienPhu
USThienPhu merged commit 773a540 into develop Jun 2, 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.

2 participants