feat: templates per ticket type

Each ticket type can carry a starting description and a checklist, edited
in the project settings. New tickets of that type get the description
when they come without one and always get the checklist; the new ticket
form says what the template will add.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 15:58:37 +02:00
parent 8994590b54
commit 5863d773be
23 changed files with 565 additions and 9 deletions

View File

@@ -165,6 +165,21 @@ export class StatusTransitionsBodyDto {
to!: string[];
}
export class IssueTemplateBodyDto {
@ApiPropertyOptional({ type: String, nullable: true, maxLength: 5000 })
@IsOptional()
@IsString()
@MaxLength(5000)
description?: string | null;
@ApiPropertyOptional({ type: [String], maxItems: 20 })
@IsOptional()
@IsArray()
@ArrayMaxSize(20)
@IsString({ each: true })
@MaxLength(300, { each: true })
checklist?: string[];
}
export class IssueTypeOptionBodyDto {
@ApiProperty({ example: 'SPIKE' }) @Matches(SETTING_ID) id!: string;
@ApiProperty({ example: 'Spike', maxLength: 40 })
@@ -182,6 +197,15 @@ export class IssueTypeOptionBodyDto {
@IsOptional()
@IsBoolean()
archived = false;
@ApiPropertyOptional({
type: IssueTemplateBodyDto,
nullable: true,
description: 'What a new ticket of the type starts with',
})
@IsOptional()
@ValidateNested()
@Type(() => IssueTemplateBodyDto)
template?: IssueTemplateBodyDto | null;
}
export class AreaOptionBodyDto {

View File

@@ -53,6 +53,11 @@ export class StatusTransitionsDto {
to!: string[];
}
export class IssueTemplateDto {
@ApiProperty({ type: String, nullable: true }) description!: string | null;
@ApiProperty({ type: [String] }) checklist!: string[];
}
export class IssueTypeOptionDto {
@ApiProperty({ example: 'BUG' }) id!: string;
@ApiProperty({ example: 'Bug' }) name!: string;
@@ -60,6 +65,11 @@ export class IssueTypeOptionDto {
@ApiProperty({ enum: SETTING_COLORS, enumName: 'SettingColor' })
color!: string;
@ApiProperty() archived!: boolean;
@ApiPropertyOptional({
type: IssueTemplateDto,
description: 'What a new ticket of the type starts with',
})
template?: IssueTemplateDto;
}
export class AreaOptionDto {