Skip to content

fix: dora team filter#78

Merged
waltergalvao merged 2 commits intomainfrom
fix/dora-team-filter
Feb 19, 2026
Merged

fix: dora team filter#78
waltergalvao merged 2 commits intomainfrom
fix/dora-team-filter

Conversation

@waltergalvao
Copy link
Copy Markdown
Contributor

@waltergalvao waltergalvao commented Feb 19, 2026

Greptile Summary

This PR changes DORA metrics team filtering from application ownership to deployment author team membership. Previously, filtering by teamIds matched deployments whose applications were owned by those teams. Now it matches deployments whose authors are members of those teams via the TeamMember table.

Key Changes:

  • Replaced Application.teamId join with TeamMember EXISTS subquery in both buildDeploymentFilters and buildIncidentFilters
  • Incidents now filter by deployment author's team membership (via causeDeployment.authorId) instead of Incident.teamId or Application.teamId
  • Added comprehensive test coverage including new test cases that verify filtering matches author team, not app owner team
  • Added seedTeamMember helper to properly set up team memberships in tests
  • Added rimraf dev dependency (likely for test cleanup utilities)

Impact:
This is a behavioral change that aligns team metrics with who actually performed deployments rather than which team owns the application. Existing tests were updated to maintain the same assertions by properly creating team memberships.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are well-structured with comprehensive test coverage. All existing tests were updated to work with the new filtering logic, and new test cases were added to verify the distinction between app ownership and author membership. The SQL logic is clean and uses proper EXISTS subqueries with appropriate workspace scoping.
  • No files require special attention

Important Files Changed

Filename Overview
apps/api/src/app/metrics/services/dora-metrics.service.ts Refactored team filtering to use deployment author's team membership via EXISTS subquery instead of application's teamId
apps/api/src/app/metrics/services/dora-metrics.integration.test.ts Added comprehensive test coverage for new team filtering behavior with seedTeamMember calls and new test cases
apps/api/test/seed/index.ts Added seedTeamMember helper function to create team member relationships in tests

Entity Relationship Diagram

%%{init: {'theme': 'neutral'}}%%
erDiagram
    Team ||--o{ TeamMember : has
    GitProfile ||--o{ TeamMember : member-of
    GitProfile ||--o{ Deployment : authors
    Deployment }o--|| Application : deployed-to
    Application }o--|| Team : owned-by
    Deployment ||--o{ Incident : causes

    Team {
        int id PK
        string name
        int workspaceId FK
    }
    
    TeamMember {
        int id PK
        int teamId FK
        int gitProfileId FK
        string role
    }
    
    GitProfile {
        int id PK
        string handle
    }
    
    Deployment {
        int id PK
        int applicationId FK
        int authorId FK "nullable"
        int environmentId FK
        datetime deployedAt
    }
    
    Application {
        int id PK
        string name
        int teamId FK "nullable"
        int repositoryId FK
    }
    
    Incident {
        int id PK
        int causeDeploymentId FK
        int teamId FK "nullable"
        datetime detectedAt
    }
Loading

Last reviewed commit: b7c515d

@sweetr-dev sweetr-dev Bot added the large Large PR - Consider splitting up into smaller PRs to reduce risk and review time label Feb 19, 2026
Copy link
Copy Markdown
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.

3 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +171 to 183
if (filters.teamIds && filters.teamIds.length > 0) {
conditions.push(
Prisma.sql`EXISTS (
SELECT 1 FROM "TeamMember" tm
WHERE tm."gitProfileId" = ${Prisma.raw(alias)}."authorId"
AND tm."workspaceId" = ${Prisma.raw(alias)}."workspaceId"
AND tm."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}`),
", "
)}])`
);
}
)}])
)`
);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

EXISTS subquery doesn't handle NULL authorId. Deployments without an author will be excluded when filtering by teamIds since NULL = anything is false in SQL. Add ${Prisma.raw(alias)}."authorId" IS NOT NULL AND before the EXISTS clause to explicitly handle this edge case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

When filtering by teams, it shouldn't bring data about deployments that has no author. The behaviour is correct.

Comment thread apps/api/src/app/metrics/services/dora-metrics.service.ts
Comment thread apps/api/src/app/metrics/services/dora-metrics.integration.test.ts
Copy link
Copy Markdown
Contributor

@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.

2 issues found across 3 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/api/src/app/metrics/services/dora-metrics.service.ts">

<violation number="1" location="apps/api/src/app/metrics/services/dora-metrics.service.ts:175">
P2: The EXISTS subquery doesn't explicitly handle NULL `authorId` values. In SQL, `NULL = anything` evaluates to UNKNOWN (not true), so deployments without an author will be silently excluded when filtering by `teamIds`. Consider adding an explicit NULL check or documenting this as expected behavior.</violation>

<violation number="2" location="apps/api/src/app/metrics/services/dora-metrics.service.ts:533">
P2: Same NULL `authorId` handling issue exists in this EXISTS subquery. When `cd.authorId` is NULL, the comparison will evaluate to UNKNOWN in SQL, causing incidents linked to deployments without authors to be excluded when filtering by `teamIds`.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread apps/api/src/app/metrics/services/dora-metrics.service.ts
Comment thread apps/api/src/app/metrics/services/dora-metrics.service.ts
coderabbitai[bot]
coderabbitai Bot previously approved these changes Feb 19, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 19, 2026

Walkthrough

The changes implement team-member-based filtering for DORA metrics by replacing application-owner-based filtering with deployment-author membership checks. This includes refactoring the metric service's filter logic to use EXISTS subqueries for team verification, adding a new seed helper function to establish team-member relationships, and updating integration tests to propagate author information through test data.

Changes

Cohort / File(s) Summary
Metric Service Refactoring
apps/api/src/app/metrics/services/dora-metrics.service.ts
Changed filter construction for deployments and incidents to replace direct teamId filtering on Application with EXISTS subqueries on TeamMember table. Conditional logic now separately handles repositoryIds (via Application join) and teamIds (via membership verification).
Integration Tests
apps/api/src/app/metrics/services/dora-metrics.integration.test.ts
Expanded test coverage for team-member-based DORA metric filtering. Introduced multiple git profiles per team scenario, wired team membership associations into tests via seedTeamMember, and added assertions for deployment author-based visibility across single and multi-app deployments with combined filters.
Test Seed Infrastructure
apps/api/test/seed/index.ts
Added new public seed helper seedTeamMember() to create team member entries with configurable roles (defaults to ENGINEER). Extended imports to include TeamMemberRole from Prisma client.
Dependencies
apps/api/package.json
Added rimraf ^6.1.3 as a dependency.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: dora team filter' directly summarizes the main change: fixing the team filtering logic in DORA metrics from application ownership to deployment author team membership.
Description check ✅ Passed The description is directly related to the changeset, explaining the behavioral change from application-ownership-based filtering to deployment-author-based team membership filtering with detailed examples and test coverage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/dora-team-filter

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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/api/src/app/metrics/services/dora-metrics.integration.test.ts`:
- Around line 508-559: Add a new integration test in
dora-metrics.integration.test.ts that verifies deployments with a NULL authorId
are included when filtering by teamIds: create context via
createTestContextWithGitProfile(), seedGitProfile(), seedRepository(),
seedTeam() and seedTeamMember() to attach the git profile to the team,
seedApplication(), seedEnvironment({ isProduction: true }), seedPullRequest()
(with createdAt), then call seedDeployment() without supplying authorId (so it
is NULL) and link it via seedDeploymentPullRequest(); finally call
getDeploymentFrequencyMetric({ workspaceId, dateRange, period: Period.DAILY,
teamIds: [team.teamId] }) and assert result.currentAmount equals BigInt(1).
Ensure the test name clearly states it “includes deployments with null authorId
when filtering by teamIds.”

In `@apps/api/src/app/metrics/services/dora-metrics.service.ts`:
- Around line 171-183: In buildDeploymentFilters, the EXISTS subquery currently
drops rows when ${Prisma.raw(alias)}."authorId" is NULL; update the WHERE clause
inside the EXISTS (the subquery referencing tm."gitProfileId" and
${Prisma.raw(alias)}."authorId") to treat NULL authorId as a match so authorless
deployments are included for any team filter (e.g., change the predicate to
check tm."gitProfileId" = alias."authorId" OR alias."authorId" IS NULL);
alternatively, if you intend to exclude authorless deployments, add an explicit
AND ${Prisma.raw(alias)}."authorId" IS NOT NULL guard before the EXISTS—adjust
the condition in buildDeploymentFilters accordingly.
- Around line 529-541: In buildIncidentFilters the EXISTS clause `WHERE
tm."gitProfileId" = cd."authorId"` causes incidents to be excluded when
cd."authorId" is NULL; change the condition to allow NULL authorIds by making
the filter accept rows where cd."authorId" IS NULL OR the EXISTS(...) matches a
TeamMember — i.e., wrap the EXISTS check with `cd."authorId" IS NULL OR
EXISTS(...)` (keeping the same INNER EXISTS body matching tm."gitProfileId" =
cd."authorId", tm."workspaceId" = cd."workspaceId" and teamId ANY of
filters.teamIds) so that incidents with no cause author are not silently dropped
when filters.teamIds is applied.

Comment thread apps/api/src/app/metrics/services/dora-metrics.integration.test.ts
Comment thread apps/api/src/app/metrics/services/dora-metrics.service.ts
Comment thread apps/api/src/app/metrics/services/dora-metrics.service.ts
Copy link
Copy Markdown
Contributor

@sweetrdev sweetrdev left a comment

Choose a reason for hiding this comment

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

Many hallucinations

@waltergalvao waltergalvao merged commit 86b01ef into main Feb 19, 2026
10 checks passed
@waltergalvao waltergalvao deleted the fix/dora-team-filter branch March 15, 2026 01:31
@coderabbitai coderabbitai Bot mentioned this pull request Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

large Large PR - Consider splitting up into smaller PRs to reduce risk and review time

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants