feat: group activities into boards with their own stages, like sales pipelines

Existing stages and activities move into a default board per environment; new activities pick a board in the form.
This commit is contained in:
2026-10-20 17:23:27 +03:30
parent 9127fa334b
commit e6aa4c64f0
11 changed files with 769 additions and 58 deletions
@@ -27,14 +27,17 @@ import { ActivitiesExcelService } from './activities-excel.service';
import { ActivityStagesService } from './activity-stages.service';
import { ActivityTypesService } from './activity-types.service';
import {
CreateActivityBoardDto,
CreateActivityDto,
CreateActivityStageDto,
CreateActivityTypeDto,
ImportActivityRowsDto,
ListActivitiesQueryDto,
ListActivityStagesQueryDto,
MoveActivityStageDto,
ReorderActivityStagesDto,
ReorderActivityTypesDto,
UpdateActivityBoardDto,
UpdateActivityDto,
UpdateActivityStageDto,
UpdateActivityTypeDto,
@@ -65,9 +68,40 @@ export class ActivitiesController {
return this.activitiesService.summary(user.organizationId, user, scope);
}
@Get('boards')
listBoards(@CurrentUser() user: Actor) {
return this.stagesService.listBoards(user.organizationId);
}
@Post('boards')
@UseGuards(RolesGuard)
@Roles('owner', 'admin')
createBoard(@CurrentUser() user: Actor, @Body() dto: CreateActivityBoardDto) {
return this.stagesService.createBoard(user.organizationId, dto.name);
}
@Patch('boards/:id')
@UseGuards(RolesGuard)
@Roles('owner', 'admin')
updateBoard(
@CurrentUser() user: Actor,
@Param('id') id: string,
@Body() dto: UpdateActivityBoardDto,
) {
return this.stagesService.updateBoard(user.organizationId, id, dto);
}
@Delete('boards/:id')
@UseGuards(RolesGuard)
@Roles('owner', 'admin')
async removeBoard(@CurrentUser() user: Actor, @Param('id') id: string) {
await this.stagesService.removeBoard(user.organizationId, id);
return { ok: true };
}
@Get('stages')
listStages(@CurrentUser() user: Actor) {
return this.stagesService.list(user.organizationId);
listStages(@CurrentUser() user: Actor, @Query() query: ListActivityStagesQueryDto) {
return this.stagesService.list(user.organizationId, query.boardId);
}
@Post('stages')
@@ -157,6 +191,7 @@ export class ActivitiesController {
typeDefId: query.typeDefId,
status: query.status,
assigneeId: query.assigneeId,
boardId: query.boardId,
},
);
}
@@ -189,6 +224,7 @@ export class ActivitiesController {
typeDefId: query.typeDefId,
status: query.status,
assigneeId: query.assigneeId,
boardId: query.boardId,
},
query.stageId ? { stageId: query.stageId } : undefined,
);