Skip to content

Comments

feat: lead time breakdown (#71)#72

Merged
waltergalvao merged 1 commit intoproductionfrom
main
Feb 12, 2026
Merged

feat: lead time breakdown (#71)#72
waltergalvao merged 1 commit intoproductionfrom
main

Conversation

@waltergalvao
Copy link
Contributor

@waltergalvao waltergalvao commented Feb 12, 2026

Summary

  • feat: lead time breakdown

  • fix: review feedback

  • fix: failure rate schema

  • fix: period copy

  • feat: info button

  • fix: docker-compose.yml

* feat: lead time breakdown

* fix: review feedback

* fix: failure rate schema

* fix: period copy

* feat: info button

* fix: docker-compose.yml
@sweetr-dev sweetr-dev bot added the huge Huge PR - High risk of reviewer fatigue label Feb 12, 2026
@waltergalvao waltergalvao merged commit 13e8c33 into production Feb 12, 2026
11 checks passed
@coderabbitai
Copy link

coderabbitai bot commented Feb 12, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch main

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@waltergalvao waltergalvao requested a deployment to sweetr-api February 12, 2026 01:41 Abandoned
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 12, 2026

Greptile Overview

Greptile Summary

This PR adds a lead time breakdown feature that provides stage-by-stage analysis of the development pipeline (coding, review, approval, merge, deploy). The implementation includes:

  • Backend: New service, GraphQL schema, and resolver for calculating lead time metrics broken down by development stages
  • Frontend: Interactive stepper visualization showing time spent in each stage with period-over-period comparisons
  • Refactoring: Extracted getPreviousPeriod utility and added period information to all DORA metrics
  • UX improvements: Added info buttons with explanations across all metrics pages and period selection filters

Key changes:

  • New lead-time-breakdown.service.ts with stage-specific metric calculations
  • SQL queries aggregate tracking data (timeToCode, timeToFirstReview, etc.) with proper NULL handling
  • React components display breakdown as a visual stepper with tooltips and change indicators
  • Comprehensive integration tests validate calculation logic and filter behavior
  • Docker Compose configuration updates (restart policies and SSL settings)

Confidence Score: 4/5

  • Safe to merge with minor code duplication that could be refactored
  • The implementation is well-tested with comprehensive integration tests, follows existing patterns, and includes proper NULL handling. The main concern is duplicated filter logic between two services, which is a maintainability issue rather than a functional one.
  • apps/api/src/app/metrics/services/lead-time-breakdown.service.ts contains duplicated code from dora-metrics.service.ts

Important Files Changed

Filename Overview
apps/api/src/app/metrics/services/lead-time-breakdown.service.ts New service for lead time breakdown metrics with stage-by-stage analysis; includes duplicated filter logic from dora-metrics.service.ts
apps/api/src/lib/date.ts Added getPreviousPeriod utility function for calculating date ranges
apps/api/src/app/metrics/services/dora-metrics.service.ts Refactored to extract buildDeploymentFilters and use shared getPreviousPeriod function; removed isPreviousPeriod parameter
apps/web/src/app/metrics-and-insights/lead-time/components/lead-time-breakdown/step.tsx Step component for breakdown visualization with tooltips and change indicators
apps/web/src/providers/date.provider.ts Added duration formatting utilities and DateTimeRange type

Sequence Diagram

sequenceDiagram
    participant Client as Web Client
    participant GraphQL as GraphQL Resolver
    participant Service as LeadTimeBreakdown Service
    participant DB as Database
    participant Transform as Transformer

    Client->>GraphQL: Query leadTime.breakdown
    GraphQL->>Service: getLeadTimeBreakdown(filters)
    Service->>Service: getPreviousPeriod(from, to)
    Service->>Service: buildBreakdownAggregateQuery(current period)
    Service->>Service: buildBreakdownAggregateQuery(previous period)
    Service->>DB: Execute current period query
    Service->>DB: Execute previous period query
    DB-->>Service: Current results (timeToCode, timeToFirstReview, etc)
    DB-->>Service: Previous results
    Service->>Service: buildStage for each metric
    Service->>Service: calculateChange(current, previous)
    Service-->>GraphQL: LeadTimeBreakdownResult
    GraphQL->>Transform: transformLeadTimeBreakdown(result)
    Transform-->>GraphQL: Formatted breakdown with periods
    GraphQL-->>Client: LeadTimeBreakdown with stage metrics
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

32 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +113 to +177
const buildDeploymentQueryFilters = (
filters: DoraMetricsFilters,
alias: string
) => {
const joins: Prisma.Sql[] = [];
const conditions: Prisma.Sql[] = [];

conditions.push(
Prisma.sql`${Prisma.raw(alias)}."workspaceId" = ${filters.workspaceId}`
);

if (filters.environmentIds && filters.environmentIds.length > 0) {
conditions.push(
Prisma.sql`${Prisma.raw(alias)}."environmentId" = ANY(ARRAY[${Prisma.join(
filters.environmentIds.map((id) => Prisma.sql`${id}`),
", "
)}])`
);
} else {
joins.push(
Prisma.sql`INNER JOIN "Environment" e ON e."id" = ${Prisma.raw(alias)}."environmentId" AND e."workspaceId" = ${Prisma.raw(alias)}."workspaceId"`
);
conditions.push(
Prisma.sql`e."isProduction" = true AND e."archivedAt" IS NULL`
);
}

if (filters.applicationIds && filters.applicationIds.length > 0) {
conditions.push(
Prisma.sql`${Prisma.raw(alias)}."applicationId" = ANY(ARRAY[${Prisma.join(
filters.applicationIds.map((id) => Prisma.sql`${id}`),
", "
)}])`
);
}

const needsApplicationJoin =
(filters.teamIds && filters.teamIds.length > 0) ||
(filters.repositoryIds && filters.repositoryIds.length > 0);

if (needsApplicationJoin) {
joins.push(
Prisma.sql`INNER JOIN "Application" a ON a."id" = ${Prisma.raw(alias)}."applicationId" AND a."workspaceId" = ${Prisma.raw(alias)}."workspaceId" AND a."archivedAt" IS NULL`
);

if (filters.teamIds && filters.teamIds.length > 0) {
conditions.push(
Prisma.sql`a."teamId" = ANY(ARRAY[${Prisma.join(
filters.teamIds.map((id) => Prisma.sql`${id}`),
", "
)}])`
);
}

if (filters.repositoryIds && filters.repositoryIds.length > 0) {
conditions.push(
Prisma.sql`a."repositoryId" = ANY(ARRAY[${Prisma.join(
filters.repositoryIds.map((id) => Prisma.sql`${id}`),
", "
)}])`
);
}
}

return { joins, conditions };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The buildDeploymentQueryFilters function is duplicated from dora-metrics.service.ts (where it's named buildDeploymentFilters). Consider extracting this shared logic to a common utility file to avoid code duplication and ensure consistency.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 32 files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

huge Huge PR - High risk of reviewer fatigue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant