import { Body, Controller, Get, Headers, Inject, NotFoundException, Param, Patch, Post, Query, UseGuards } from "@nestjs/common"; import { CreateMissionInput, UpdateMissionDomainInput } from "@courtmitra/contracts"; import { parseOrThrow } from "../common/zod-validation.pipe.js"; import { MissionsService } from "./missions.service.js"; import { DB } from "../db/db.module.js"; import { schema, type Database } from "@courtmitra/db"; import { eq, desc } from "drizzle-orm"; import { CurrentUser } from "../auth/current-user.decorator.js"; import { ClerkAuthGuard } from "../auth/clerk-auth.guard.js"; @UseGuards(ClerkAuthGuard) @Controller("missions") export class MissionsController { constructor( @Inject(MissionsService) private readonly missions: MissionsService, @Inject(DB) private readonly db: Database, ) {} @Post() async create( @Body() body: unknown, @CurrentUser() userId: string, @Headers("idempotency-key") idempotencyKey?: string, ) { const input = parseOrThrow(CreateMissionInput, body); return this.missions.create(userId, input, idempotencyKey); } @Get() async list(@CurrentUser() userId: string) { return this.missions.list(userId); } @Get(":id") async get(@Param("id") id: string, @CurrentUser() userId: string) { return this.missions.get(id, userId); } @Get(":id/snapshot") async snapshot(@Param("id") id: string, @CurrentUser() userId: string) { return this.missions.latestSnapshot(id, userId); } @Get(":id/timeline") async timeline(@Param("id") id: string, @CurrentUser() userId: string, @Query("cursor") cursor?: string) { return this.missions.timeline(id, userId, cursor); } @Patch(":id/domain") async updateDomain(@Param("id") id: string, @CurrentUser() userId: string, @Body() body: unknown) { const input = parseOrThrow(UpdateMissionDomainInput, body); return this.missions.updateDomain(id, userId, input); } @Get(":id/public-page") async publicPage(@Param("id") id: string, @CurrentUser() userId: string) { const [row] = await this.db .select({ slug: schema.publicCasePages.slug }) .from(schema.publicCasePages) .where(eq(schema.publicCasePages.missionId, id)) .orderBy(desc(schema.publicCasePages.createdAt)) .limit(1); if (!row) throw new NotFoundException("No public page found for this mission"); return { slug: row.slug, url: `/${row.slug}` }; } }