Skip to content

feat: add get project endpoint under v1-alpha - #2231

Merged
epipav merged 7 commits into
mainfrom
feat/IN-1345-project-endpoint
Sep 21, 2026
Merged

epipav merged 7 commits into
mainfrom
feat/IN-1345-project-endpoint

Conversation

@epipav

@epipav epipav commented Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds the first route in the public API, GET /v1-alpha/projects/{slug}, and turns on the /v1-alpha version it lives under. Development callers use it to learn which values to pass in repos and platform.

{
  "slug": "kubernetes",
  "name": "Kubernetes",
  "repositories": [{ "url": "https://github.com/kubernetes/kubernetes" }],
  "connectedPlatforms": ["github", "git"]
}
  • api/src/versions/registry.ts and api/src/versions/v1-alpha/index.ts: register /v1-alpha. Its spec is served at /v1-alpha/openapi.json as 1.0.0-alpha. The docs reference page still renders only /v1, so alpha routes stay unannounced until the closed-alpha allowlist lands.
  • api/src/versions/v1-alpha/projects.ts: the route. It makes one projects_list call (slug, details=true), the same call as the Nuxt handler.
  • api/src/lib/errors.ts: NotFoundError (404 not_found) and UpstreamUnavailableError (503 upstream_unavailable), in the same style as InvalidDateRangeError. It also takes notFoundHandler from feat: version deprecation and sunset headers #2224's src/errors/not-found.ts, which is deleted: each branch had created a home for error code without seeing the other, and one file gives the error envelope and the promotion-time GoneError a single place to land. The version-bump playbook now points there (review on #2224).
  • api/tests/version-lifecycle.test.ts (from feat: version deprecation and sunset headers #2224): the registry case pinned /v1 as the only version. It now expects ['/v1', '/v1-alpha'], neither with lifecycle metadata.

Decisions worth a look

  • repositories is a list of { url } objects. The Overviews group will add repo fields here, and objects keep that additive.
  • Platform keys drop the -nango suffix and any resulting duplicates, the same way the UI does. Every value is then one a caller can pass straight into platform.
  • An unknown slug returns 404. The epic's "unknown slug returns empty data" rule fits the metric endpoints, where an empty series is a valid answer.
  • Every Tinybird failure returns 503 upstream_unavailable, and the original error is logged. Without this, Fastify would pass Tinybird's own status to the caller, so a Tinybird 401 would read as the caller's auth failure.
  • One onRequest hook in the alpha plugin sets Cache-Control: private, max-age=0 on every /v1-alpha response, errors included (ADR-0013). api/ has no Redis response cache yet. When it lands, this endpoint belongs in the 24h tier.
  • Error bodies use Fastify's default shape, with code set, until the error envelope lands.

Testing

  • api/tests/project-endpoint.test.ts: runs the real app and Tinybird client, with fetch stubbed at the HTTP boundary. It covers the response body, the pipe call, platform and repo edge cases, the 404, Tinybird 500/401/429, network and non-JSON failures mapping to 503, the cache header on successes and errors, and the /v1-alpha spec (version, Projects tag, field descriptions, kept out of /v1).
  • api/tests/openapi-versions.test.ts: the registry now lists ['/v1', '/v1-alpha'].

References

Signed-off-by: anilb <epipav@gmail.com>
Signed-off-by: anilb <epipav@gmail.com>
Signed-off-by: anilb <epipav@gmail.com>
Copilot AI balanced review requested due to automatic review settings September 18, 2026 17:19
@epipav epipav self-assigned this Sep 18, 2026

Copilot AI left a comment

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.

🟡 Changes recommended

The route lacks required authentication and allowlist enforcement, while malformed upstream responses and the alpha specification violate documented response contracts.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds the first /v1-alpha public API endpoint for retrieving project metadata.

Changes:

  • Registers /v1-alpha and its OpenAPI specification.
  • Adds project lookup, normalization, and upstream error handling.
  • Adds comprehensive endpoint and version-registry tests.
File summaries
File Description
api/src/lib/errors.ts Adds 404 and 503 API errors.
api/src/versions/registry.ts Registers /v1-alpha.
api/src/versions/v1-alpha/index.ts Configures alpha routes and caching headers.
api/src/versions/v1-alpha/projects.ts Implements project lookup.
api/tests/openapi-versions.test.ts Updates version registry expectations.
api/tests/project-endpoint.test.ts Tests endpoint behavior and specification.
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread api/src/versions/v1-alpha/index.ts
Comment thread api/src/versions/v1-alpha/index.ts
Comment thread api/src/versions/v1-alpha/projects.ts
Base automatically changed from feat/IN-1330-development-shared-schemas to main September 21, 2026 08:40

Copilot AI left a comment

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.

Copilot review overview

🟢 Approval recommended

The endpoint implementation, version isolation, error mapping, caching behavior, and tests are consistent and complete for the stated scope.

Review effort: Balanced
Findings: None

Resolved since last review (3)

The lifecycle test from IN-1139 pinned the registry to /v1 alone; this branch adds
/v1-alpha, so the case now expects both while still asserting neither carries
lifecycle metadata.

Signed-off-by: anilb <epipav@gmail.com>
Fold notFoundHandler from src/errors/not-found.ts into src/lib/errors.ts next to
NotFoundError and UpstreamUnavailableError, so error code has one home before the
error envelope lands. The version-bump playbook now names that file for GoneError.

Signed-off-by: anilb <epipav@gmail.com>
Copilot AI review requested due to automatic review settings September 21, 2026 10:26

Copilot AI left a comment

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.

Copilot review overview

🟢 Approval recommended

The implementation matches its stated scope, has comprehensive tests, and all relevant checks pass.

Review effort: Balanced
Findings: None

@gaspergrom gaspergrom left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Traced this against the Nuxt handler (frontend/server/api/project/[slug]/index.ts): same projects_list call, same -nango suffix stripping. Confirmed the deleted not-found.ts has no leftover references and the registry tests match the new /v1-alpha entry. Solid edge case coverage on the error mapping. LGTM.

Signed-off-by: anilb <epipav@gmail.com>
Copilot AI review requested due to automatic review settings September 21, 2026 11:24

Copilot AI left a comment

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.

Copilot review overview

🔵 Needs a closer look

Unmatched /v1-alpha 404 responses bypass the scoped cache-header hook.

Review effort: Balanced
Findings: None

Previously missed (1)

In code that hasn't changed since last review

Medium severity Scoped unmatched paths miss required cache header

api/​src/​versions/​v1-alpha/​index.ts:11

Unmatched paths such as /v1-alpha/does-not-exist bypass this plugin's scoped hook and use the root 404 handler, so they lack the cache header required for every response by ADR-0013. Register the shared not-found handler in this scope, as applyLifecycle does for scoped headers, and add an unmatched-path assertion.

@epipav
epipav merged commit ef31c9e into main Sep 21, 2026
11 checks passed
@epipav
epipav deleted the feat/IN-1345-project-endpoint branch September 21, 2026 12:26
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.

3 participants