Skip to content

feat(web): add GET /api/diff endpoint#1063

Open
brendan-kellam wants to merge 4 commits intomainfrom
brendan/feat-diff-api-SOU-833
Open

feat(web): add GET /api/diff endpoint#1063
brendan-kellam wants to merge 4 commits intomainfrom
brendan/feat-diff-api-SOU-833

Conversation

@brendan-kellam
Copy link
Copy Markdown
Contributor

@brendan-kellam brendan-kellam commented Mar 31, 2026

Summary

  • Adds GET /api/diff?repo=...&base=...&head=... endpoint that returns a structured diff between two git refs using a two-dot comparison
  • Diff response includes per-file oldPath/newPath and structured hunks with oldRange, newRange, heading, and body
  • Adds OpenAPI documentation with descriptions for all request and response fields under a new Git tag

Test plan

  • Call GET /api/diff?repo=<repo>&base=<ref>&head=<ref> and verify structured response
  • Verify invalid refs return a 400 error
  • Verify unknown repo returns a 404 error
  • Check /api/openapi.json includes the new endpoint with descriptions

Closes SOU-833

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added GET /api/diff endpoint returning structured diffs between two git refs: files with old/new paths, hunks (ranges, optional heading, and diff body).
  • Documentation

    • Public API docs updated with a new "Git" tag and request/response schemas for the diff endpoint.
    • CHANGELOG updated under Unreleased.

Adds a new public API endpoint for retrieving structured diffs between two git refs. Includes OpenAPI documentation with descriptions for all request/response fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@mintlify
Copy link
Copy Markdown

mintlify bot commented Mar 31, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
sourcebot 🟢 Ready View Preview Mar 31, 2026, 12:40 AM

@github-actions

This comment has been minimized.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c35ac5db-6159-47c1-9c82-abc687be14a1

📥 Commits

Reviewing files that changed from the base of the PR and between 81388ac and 38a49bc.

📒 Files selected for processing (1)
  • docs/api-reference/sourcebot-public.openapi.json

Walkthrough

Adds a new public GET /api/diff endpoint with OpenAPI docs, Zod request/response schemas, a Next.js API route, a service implementation that runs git diff + parses output into structured file/hunk objects, and a changelog entry. (28 words)

Changes

Cohort / File(s) Summary
Docs & OpenAPI
CHANGELOG.md, docs/api-reference/sourcebot-public.openapi.json
Changelog entry and OpenAPI spec additions: new Git tag and GET /api/diff path with repo, base, head query params and PublicGetDiffResponse schema describing files → hunks.
API Route
packages/web/src/app/api/(server)/diff/route.ts
New Next.js route exporting GET handler that validates query params and delegates to getDiff, returning JSON or service error responses.
Service Implementation
packages/web/src/features/git/getDiffApi.ts
New getDiff function: validates refs, resolves repo, runs git diff in repo cwd, maps git errors to service errors, parses raw diff with parse-diff into typed file/hunk structures.
Schemas
packages/web/src/features/git/schemas.ts
Added Zod request/response schemas (getDiffRequestSchema, getDiffResponseSchema) describing repo/base/head and files→hunks structure.
OpenAPI wrappers & registry
packages/web/src/openapi/publicApiSchemas.ts, packages/web/src/openapi/publicApiDocument.ts
Added OpenAPI-wrapped request/response schemas and registered the new Git tag + GET /api/diff operation in the public API document.
Module export
packages/web/src/features/git/index.ts
Re-exported new getDiff API surface from the git barrel module.

Sequence Diagram

sequenceDiagram
    participant Client
    participant RouteHandler as API Route Handler
    participant ServiceLayer as getDiff Service
    participant Database as Database
    participant Git as Git Process
    participant Parser as parse-diff

    Client->>RouteHandler: GET /api/diff?repo=R&base=B&head=H
    RouteHandler->>RouteHandler: Validate query (Zod)
    alt invalid params
        RouteHandler->>Client: 400 ServiceError
    else params valid
        RouteHandler->>ServiceLayer: getDiff({repo:R, base:B, head:H})
        ServiceLayer->>ServiceLayer: Validate refs
        alt invalid refs
            ServiceLayer->>RouteHandler: invalidGitRef error
            RouteHandler->>Client: 400 ServiceError
        else refs valid
            ServiceLayer->>Database: find repo by name/org
            alt repo not found
                ServiceLayer->>RouteHandler: notFound error
                RouteHandler->>Client: 404 ServiceError
            else repo found
                ServiceLayer->>Git: git diff B H (cwd repo)
                Git->>ServiceLayer: raw diff text / error
                alt git error (bad/unknown rev)
                    ServiceLayer->>RouteHandler: invalidGitRef error
                    RouteHandler->>Client: 400 ServiceError
                else raw diff
                    ServiceLayer->>Parser: parse raw diff
                    Parser->>ServiceLayer: structured files & hunks
                    ServiceLayer->>RouteHandler: GetDiffResult
                    RouteHandler->>Client: 200 JSON(GetDiffResult)
                end
            end
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(web): add GET /api/diff endpoint' accurately and concisely describes the main change—adding a new GET /api/diff endpoint.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brendan/feat-diff-api-SOU-833

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.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

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

🧹 Nitpick comments (1)
packages/web/src/app/api/(server)/diff/route.ts (1)

8-12: Consider reusing the existing request schema.

This local schema duplicates getDiffRequestSchema from @/features/git/schemas.ts. Reusing the existing schema would ensure consistency and reduce maintenance burden.

♻️ Proposed refactor
-import { z } from "zod";
+import { getDiffRequestSchema } from "@/features/git/schemas";

-const getDiffQueryParamsSchema = z.object({
-    repo: z.string(),
-    base: z.string(),
-    head: z.string(),
-});
+const getDiffQueryParamsSchema = getDiffRequestSchema;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/app/api/`(server)/diff/route.ts around lines 8 - 12, The
local duplicate schema getDiffQueryParamsSchema should be removed and the
existing getDiffRequestSchema reused: import getDiffRequestSchema from the
module that defines it, replace usages of getDiffQueryParamsSchema with
getDiffRequestSchema (or derive from it if you only need a subset), and update
any parsing/validation calls to call getDiffRequestSchema.parse(...) (or
.partial/.pick if needed) so the code uses the single shared schema rather than
duplicating validation logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/web/src/app/api/`(server)/diff/route.ts:
- Around line 8-12: The local duplicate schema getDiffQueryParamsSchema should
be removed and the existing getDiffRequestSchema reused: import
getDiffRequestSchema from the module that defines it, replace usages of
getDiffQueryParamsSchema with getDiffRequestSchema (or derive from it if you
only need a subset), and update any parsing/validation calls to call
getDiffRequestSchema.parse(...) (or .partial/.pick if needed) so the code uses
the single shared schema rather than duplicating validation logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 14fe17ce-9836-47ea-8387-f376e74fea20

📥 Commits

Reviewing files that changed from the base of the PR and between 2fa86ff and 60ba90e.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • docs/api-reference/sourcebot-public.openapi.json
  • packages/web/src/app/api/(server)/diff/route.ts
  • packages/web/src/features/git/getDiffApi.ts
  • packages/web/src/features/git/index.ts
  • packages/web/src/features/git/schemas.ts
  • packages/web/src/openapi/publicApiDocument.ts
  • packages/web/src/openapi/publicApiSchemas.ts

Copy link
Copy Markdown
Contributor

@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: 1

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

Inline comments:
In `@packages/web/src/openapi/publicApiDocument.ts`:
- Around line 247-265: The new OpenAPI path registered via registry.registerPath
for path '/api/diff' is missing an operationId; add a unique operationId (e.g.,
'getDiff' or 'getDiffBetweenCommits') to the object passed into
registry.registerPath so it matches other endpoints and enables codegen and
clearer docs—update the registration for the '/api/diff' endpoint to include
operationId alongside method, path, tags, summary, request, and responses.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 23d0f39d-5ed4-4c5a-b5a8-08854f01a31d

📥 Commits

Reviewing files that changed from the base of the PR and between 60ba90e and 81388ac.

📒 Files selected for processing (3)
  • docs/api-reference/sourcebot-public.openapi.json
  • packages/web/src/openapi/publicApiDocument.ts
  • packages/web/src/openapi/publicApiSchemas.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/api-reference/sourcebot-public.openapi.json

Comment on lines +247 to +265
registry.registerPath({
method: 'get',
path: '/api/diff',
tags: [gitTag.name],
summary: 'Get diff between two commits',
description: 'Returns a structured diff between two git refs (branches, tags, or commit SHAs) using a two-dot comparison. See [git-diff](https://git-scm.com/docs/git-diff) for details.',
request: {
query: publicGetDiffRequestSchema,
},
responses: {
200: {
description: 'Structured diff between the two refs.',
content: jsonContent(publicGetDiffResponseSchema),
},
400: errorJson('Invalid query parameters or git ref.'),
404: errorJson('Repository not found.'),
500: errorJson('Unexpected diff failure.'),
},
});
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.

⚠️ Potential issue | 🟡 Minor

Missing operationId for the new endpoint.

All other endpoints in this file define an operationId (e.g., 'search', 'getFileSource', 'listFiles'), but this new endpoint is missing it. The operationId is important for OpenAPI code generation tools and improves API documentation clarity.

🔧 Proposed fix
     registry.registerPath({
         method: 'get',
         path: '/api/diff',
+        operationId: 'getDiff',
         tags: [gitTag.name],
         summary: 'Get diff between two commits',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
registry.registerPath({
method: 'get',
path: '/api/diff',
tags: [gitTag.name],
summary: 'Get diff between two commits',
description: 'Returns a structured diff between two git refs (branches, tags, or commit SHAs) using a two-dot comparison. See [git-diff](https://git-scm.com/docs/git-diff) for details.',
request: {
query: publicGetDiffRequestSchema,
},
responses: {
200: {
description: 'Structured diff between the two refs.',
content: jsonContent(publicGetDiffResponseSchema),
},
400: errorJson('Invalid query parameters or git ref.'),
404: errorJson('Repository not found.'),
500: errorJson('Unexpected diff failure.'),
},
});
registry.registerPath({
method: 'get',
path: '/api/diff',
operationId: 'getDiff',
tags: [gitTag.name],
summary: 'Get diff between two commits',
description: 'Returns a structured diff between two git refs (branches, tags, or commit SHAs) using a two-dot comparison. See [git-diff](https://git-scm.com/docs/git-diff) for details.',
request: {
query: publicGetDiffRequestSchema,
},
responses: {
200: {
description: 'Structured diff between the two refs.',
content: jsonContent(publicGetDiffResponseSchema),
},
400: errorJson('Invalid query parameters or git ref.'),
404: errorJson('Repository not found.'),
500: errorJson('Unexpected diff failure.'),
},
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/openapi/publicApiDocument.ts` around lines 247 - 265, The
new OpenAPI path registered via registry.registerPath for path '/api/diff' is
missing an operationId; add a unique operationId (e.g., 'getDiff' or
'getDiffBetweenCommits') to the object passed into registry.registerPath so it
matches other endpoints and enables codegen and clearer docs—update the
registration for the '/api/diff' endpoint to include operationId alongside
method, path, tags, summary, request, and responses.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant