mirror of
http://172.20.10.11:3000/gitadmin/INSIGHT-MVP.git
synced 2026-06-25 01:36:39 +02:00
feat(crm): add PATCH endpoint for pipeline stages + HTTPS router
- New PATCH /pipelines/:id/stages/:stageId endpoint to update stage name, color, and sortOrder - Added HTTPS (websecure) Traefik router for CRM service - Both requested by frontend developer via INSIGHT-CRM.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f62d032480
commit
c9e2c4a44c
4 changed files with 83 additions and 0 deletions
|
|
@ -39,6 +39,13 @@ services:
|
|||
- "traefik.http.routers.crm.entrypoints=web"
|
||||
- "traefik.http.services.crm.loadbalancer.server.port=3100"
|
||||
- "traefik.http.routers.crm.middlewares=cors-api@file,security-headers@file"
|
||||
# HTTPS Router
|
||||
- "traefik.http.routers.crm-secure.rule=Host(`172.20.10.59`) && PathPrefix(`/api/v1/crm`)"
|
||||
- "traefik.http.routers.crm-secure.priority=100"
|
||||
- "traefik.http.routers.crm-secure.entrypoints=websecure"
|
||||
- "traefik.http.routers.crm-secure.tls=true"
|
||||
- "traefik.http.routers.crm-secure.service=crm"
|
||||
- "traefik.http.routers.crm-secure.middlewares=cors-api@file,security-headers@file"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3100/health"]
|
||||
interval: 30s
|
||||
|
|
|
|||
29
packages/crm-service/src/pipelines/dto/update-stage.dto.ts
Normal file
29
packages/crm-service/src/pipelines/dto/update-stage.dto.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import {
|
||||
IsString,
|
||||
IsOptional,
|
||||
IsInt,
|
||||
Min,
|
||||
MaxLength,
|
||||
Matches,
|
||||
} from 'class-validator';
|
||||
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||
|
||||
export class UpdateStageDto {
|
||||
@ApiPropertyOptional({ maxLength: 200 })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(200)
|
||||
name?: string;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
@Min(0)
|
||||
sortOrder?: number;
|
||||
|
||||
@ApiPropertyOptional({ description: 'Hex-Farbcode, z.B. #3B82F6' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Matches(/^#[0-9A-Fa-f]{6}$/)
|
||||
color?: string;
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import {
|
|||
import { PipelinesService } from './pipelines.service';
|
||||
import { CreatePipelineDto, CreatePipelineStageDto } from './dto/create-pipeline.dto';
|
||||
import { UpdatePipelineDto } from './dto/update-pipeline.dto';
|
||||
import { UpdateStageDto } from './dto/update-stage.dto';
|
||||
import { CurrentUser, JwtPayload } from '../common/decorators';
|
||||
import { TenantGuard } from '../auth/guards/tenant.guard';
|
||||
import { singleResponse } from '../common/dto/pagination.dto';
|
||||
|
|
@ -116,6 +117,25 @@ export class PipelinesController {
|
|||
return singleResponse(stage);
|
||||
}
|
||||
|
||||
@Patch(':id/stages/:stageId')
|
||||
@ApiOperation({ summary: 'Stufe aktualisieren (Name, Farbe, Reihenfolge)' })
|
||||
@ApiParam({ name: 'id', type: 'string', format: 'uuid' })
|
||||
@ApiParam({ name: 'stageId', type: 'string', format: 'uuid' })
|
||||
async updateStage(
|
||||
@CurrentUser() user: JwtPayload,
|
||||
@Param('id', ParseUUIDPipe) pipelineId: string,
|
||||
@Param('stageId', ParseUUIDPipe) stageId: string,
|
||||
@Body() dto: UpdateStageDto,
|
||||
) {
|
||||
const stage = await this.pipelinesService.updateStage(
|
||||
user.tenantId!,
|
||||
pipelineId,
|
||||
stageId,
|
||||
dto,
|
||||
);
|
||||
return singleResponse(stage);
|
||||
}
|
||||
|
||||
@Delete(':id/stages/:stageId')
|
||||
@ApiOperation({ summary: 'Stufe aus Pipeline entfernen' })
|
||||
@ApiParam({ name: 'id', type: 'string', format: 'uuid' })
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { Injectable, NotFoundException } from '@nestjs/common';
|
|||
import { CrmPrismaService } from '../prisma/crm-prisma.service';
|
||||
import { CreatePipelineDto } from './dto/create-pipeline.dto';
|
||||
import { UpdatePipelineDto } from './dto/update-pipeline.dto';
|
||||
import { UpdateStageDto } from './dto/update-stage.dto';
|
||||
|
||||
@Injectable()
|
||||
export class PipelinesService {
|
||||
|
|
@ -98,6 +99,32 @@ export class PipelinesService {
|
|||
});
|
||||
}
|
||||
|
||||
async updateStage(
|
||||
tenantId: string,
|
||||
pipelineId: string,
|
||||
stageId: string,
|
||||
dto: UpdateStageDto,
|
||||
) {
|
||||
await this.findOne(tenantId, pipelineId);
|
||||
|
||||
const stage = await this.prisma.pipelineStage.findFirst({
|
||||
where: { id: stageId, pipelineId },
|
||||
});
|
||||
|
||||
if (!stage) {
|
||||
throw new NotFoundException('Pipeline-Stufe nicht gefunden');
|
||||
}
|
||||
|
||||
return this.prisma.pipelineStage.update({
|
||||
where: { id: stageId },
|
||||
data: {
|
||||
...(dto.name !== undefined && { name: dto.name }),
|
||||
...(dto.sortOrder !== undefined && { sortOrder: dto.sortOrder }),
|
||||
...(dto.color !== undefined && { color: dto.color }),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async removeStage(tenantId: string, pipelineId: string, stageId: string) {
|
||||
await this.findOne(tenantId, pipelineId);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue