platform-codebase/features/attributes/backend-api/src/controllers/attribute-value-draft.controller.ts
Lilith b46bdb6a15 feat(attributes): Implement attribute draft and publishing workflow UI
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-02-17 09:30:40 -08:00

165 lines
4.3 KiB
TypeScript

import {
Controller,
Get,
Put,
Post,
Delete,
Body,
Param,
Query,
HttpCode,
HttpStatus,
} from '@nestjs/common'
import {
AttributeValueDraftService,
type PublishResult,
type DraftDiffItem,
} from '../services/attribute-value-draft.service'
interface SetDraftsDto {
[code: string]: unknown
}
interface PublishSelectedDto {
entityType: string
entityId: string
userId: string
codes: string[]
}
@Controller('attribute-value-drafts')
export class AttributeValueDraftController {
constructor(
private readonly draftService: AttributeValueDraftService,
) {}
/**
* Check whether an entity type uses drafts.
* GET /api/attribute-value-drafts/check?entityType=escort
*/
@Get('check')
checkDraftSupport(
@Query('entityType') entityType: string,
): { usesDrafts: boolean } {
return { usesDrafts: this.draftService.usesDrafts(entityType) }
}
/**
* Get draft diff for summary panel.
* GET /api/attribute-value-drafts/diff?entityType=escort&entityId=uuid&userId=uuid
*/
@Get('diff')
async getDraftDiff(
@Query('entityType') entityType: string,
@Query('entityId') entityId: string,
@Query('userId') userId: string,
): Promise<DraftDiffItem[]> {
return this.draftService.getDraftDiff(entityType, entityId, userId)
}
/**
* Get draft count.
* GET /api/attribute-value-drafts/count?entityType=escort&entityId=uuid&userId=uuid
*/
@Get('count')
async getDraftCount(
@Query('entityType') entityType: string,
@Query('entityId') entityId: string,
@Query('userId') userId: string,
): Promise<{ count: number }> {
const count = await this.draftService.getDraftCount(entityType, entityId, userId)
return { count }
}
/**
* Get all draft values as code→value map.
* GET /api/attribute-value-drafts?entityType=escort&entityId=uuid&userId=uuid
*/
@Get()
async getDrafts(
@Query('entityType') entityType: string,
@Query('entityId') entityId: string,
@Query('userId') userId: string,
): Promise<Record<string, unknown>> {
return this.draftService.getDrafts(entityType, entityId, userId)
}
/**
* Bulk upsert drafts.
* PUT /api/attribute-value-drafts?entityType=escort&entityId=uuid&userId=uuid
* Body: { "code1": value1, "code2": value2 }
*/
@Put()
@HttpCode(HttpStatus.OK)
async setDrafts(
@Query('entityType') entityType: string,
@Query('entityId') entityId: string,
@Query('userId') userId: string,
@Body() dto: SetDraftsDto,
): Promise<void> {
await this.draftService.setDrafts(entityType, entityId, userId, dto)
}
/**
* Publish all drafts.
* POST /api/attribute-value-drafts/publish?entityType=escort&entityId=uuid&userId=uuid
*/
@Post('publish')
@HttpCode(HttpStatus.OK)
async publishAll(
@Query('entityType') entityType: string,
@Query('entityId') entityId: string,
@Query('userId') userId: string,
): Promise<PublishResult> {
return this.draftService.publish(entityType, entityId, userId)
}
/**
* Publish selected drafts by code.
* POST /api/attribute-value-drafts/publish-selected
* Body: { entityType, entityId, userId, codes: [...] }
*/
@Post('publish-selected')
@HttpCode(HttpStatus.OK)
async publishSelected(
@Body() dto: PublishSelectedDto,
): Promise<PublishResult> {
return this.draftService.publishSelected(
dto.entityType,
dto.entityId,
dto.userId,
dto.codes,
)
}
/**
* Discard a single draft by code.
* DELETE /api/attribute-value-drafts/:code?entityType=escort&entityId=uuid&userId=uuid
*/
@Delete(':code')
@HttpCode(HttpStatus.NO_CONTENT)
async discardOne(
@Param('code') code: string,
@Query('entityType') entityType: string,
@Query('entityId') entityId: string,
@Query('userId') userId: string,
): Promise<void> {
await this.draftService.discardOne(entityType, entityId, userId, code)
}
/**
* Discard all drafts.
* DELETE /api/attribute-value-drafts?entityType=escort&entityId=uuid&userId=uuid
*/
@Delete()
@HttpCode(HttpStatus.OK)
async discardAll(
@Query('entityType') entityType: string,
@Query('entityId') entityId: string,
@Query('userId') userId: string,
): Promise<{ discarded: number }> {
const discarded = await this.draftService.discardAll(entityType, entityId, userId)
return { discarded }
}
}