feat: dashboard maps the activity, follows a ticket's way and the proposals
Three more blocks on the project dashboard, also by REST, GraphQL and MCP: - Activity: what moved each day of the last 12 weeks, in a heatmap, with the busiest weekday and the longest lull. - A ticket's way: for the tickets done in the last 90 days, where the time from created to done went, status by status (waiting included), and how much of it was work (flow efficiency). - The public's proposals: received, waiting, under way, done and discarded, and the most voted still unanswered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,8 @@ import {
|
||||
ProjectInsightsReadModel,
|
||||
SprintStatus,
|
||||
} from '@task-stream/api/tracker/domain';
|
||||
import { computeInsights } from '../analytics/insights';
|
||||
import { computeInsights, heatmapStart } from '../analytics/insights';
|
||||
import { FindActivityRepository } from '../ports/find-activity.repository';
|
||||
import { FindIssuesRepository } from '../ports/find-issues.repository';
|
||||
import { FindProjectsRepository } from '../ports/find-projects.repository';
|
||||
import { FindReleasesRepository } from '../ports/find-releases.repository';
|
||||
@@ -27,13 +28,15 @@ export class GetProjectInsightsQueryHandler
|
||||
private readonly findSprints: FindSprintsRepository,
|
||||
private readonly findReleases: FindReleasesRepository,
|
||||
private readonly notifications: NotificationsRepository,
|
||||
private readonly findActivity: FindActivityRepository,
|
||||
) {}
|
||||
|
||||
async execute(
|
||||
query: GetProjectInsightsQuery,
|
||||
): Promise<ProjectInsightsReadModel> {
|
||||
await this.access.assertSeesWholeProject(query.projectId, query.viewerId);
|
||||
const [project, issues, timeline, sprints, releases, mentions] =
|
||||
const now = new Date();
|
||||
const [project, issues, timeline, sprints, releases, mentions, activity] =
|
||||
await Promise.all([
|
||||
this.findProjects.findById(query.projectId),
|
||||
this.findIssues.findByProject(query.projectId),
|
||||
@@ -41,6 +44,10 @@ export class GetProjectInsightsQueryHandler
|
||||
this.findSprints.findByProject(query.projectId),
|
||||
this.findReleases.findByProject(query.projectId),
|
||||
this.mentionsSince(query),
|
||||
this.findActivity.dailyCounts(
|
||||
[query.projectId],
|
||||
heatmapStart(now.getTime()),
|
||||
),
|
||||
]);
|
||||
return computeInsights({
|
||||
issues,
|
||||
@@ -53,7 +60,8 @@ export class GetProjectInsightsQueryHandler
|
||||
members: project?.members ?? [],
|
||||
since: query.since,
|
||||
mentions,
|
||||
now: new Date(),
|
||||
activity,
|
||||
now,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user