-
Notifications
You must be signed in to change notification settings - Fork 607
fix: projects hook violation #3982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,68 @@ | ||
| import { db } from "@/lib/db"; | ||
| import type { Deployment } from "@/lib/collections/deploy/deployments"; | ||
| import type { Project } from "@/lib/collections/deploy/projects"; | ||
| import { db, sql } from "@/lib/db"; | ||
| import { ratelimit, requireUser, requireWorkspace, t, withRatelimit } from "@/lib/trpc/trpc"; | ||
| import { TRPCError } from "@trpc/server"; | ||
| import { deployments, domains, projects } from "@unkey/db/src/schema"; | ||
|
|
||
| type ProjectRow = { | ||
| id: string; | ||
| name: string; | ||
| slug: string; | ||
| updated_at: number | null; | ||
| git_repository_url: string | null; | ||
| live_deployment_id: string | null; | ||
| git_commit_message: string | null; | ||
| git_branch: string | null; | ||
| git_commit_author_name: string | null; | ||
| git_commit_timestamp: number | null; | ||
| runtime_config: Deployment["runtimeConfig"] | null; | ||
| domain: string | null; | ||
| }; | ||
|
|
||
| export const listProjects = t.procedure | ||
| .use(requireUser) | ||
| .use(requireWorkspace) | ||
| .use(withRatelimit(ratelimit.read)) | ||
| .query(async ({ ctx }) => { | ||
| return await db.query.projects | ||
| .findMany({ | ||
| where: (table, { eq }) => eq(table.workspaceId, ctx.workspace.id), | ||
| columns: { | ||
| id: true, | ||
| name: true, | ||
| slug: true, | ||
| updatedAt: true, | ||
| gitRepositoryUrl: true, | ||
| liveDeploymentId: true, | ||
| }, | ||
| }) | ||
| .catch((error) => { | ||
| console.error("Error querying projects:", error); | ||
| throw new TRPCError({ | ||
| code: "INTERNAL_SERVER_ERROR", | ||
| message: | ||
| "Failed to retrieve projects due to an error. If this issue persists, please contact support.", | ||
| }); | ||
| }); | ||
| const result = await db.execute(sql` | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's the benefit of doing a raw sql, rather than a nice-to-read drizzle query?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| SELECT | ||
| ${projects.id}, | ||
| ${projects.name}, | ||
| ${projects.slug}, | ||
| ${projects.updatedAt}, | ||
| ${projects.gitRepositoryUrl}, | ||
| ${projects.liveDeploymentId}, | ||
| ${deployments.gitCommitMessage}, | ||
| ${deployments.gitBranch}, | ||
| ${deployments.gitCommitAuthorName}, | ||
| ${deployments.gitCommitTimestamp}, | ||
| ${deployments.runtimeConfig}, | ||
| ${domains.domain} | ||
| FROM ${projects} | ||
| LEFT JOIN ${deployments} | ||
| ON ${projects.liveDeploymentId} = ${deployments.id} | ||
| AND ${deployments.workspaceId} = ${ctx.workspace.id} | ||
| LEFT JOIN ${domains} | ||
| ON ${projects.id} = ${domains.projectId} | ||
| AND ${domains.workspaceId} = ${ctx.workspace.id} | ||
|
Comment on lines
+45
to
+47
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Domain join can duplicate rows and pick a non‑active domain Joining domains by projectId returns 1+ rows per project (multiple domains) and selects an arbitrary domain. Join by live deployment to get the “active” domain; consider a deterministic tie‑break (e.g., prefer custom over wildcard, newest first). - LEFT JOIN ${domains}
- ON ${projects.id} = ${domains.projectId}
- AND ${domains.workspaceId} = ${ctx.workspace.id}
+ LEFT JOIN ${domains}
+ ON ${deployments.id} IS NOT NULL
+ AND ${domains.deploymentId} = ${deployments.id}
+ AND ${domains.workspaceId} = ${ctx.workspace.id}If you must support project‑level domains as a fallback, pull one deterministically via a subquery (ORDER BY type='custom' DESC, updated_at DESC LIMIT 1). I can draft that if desired.
🤖 Prompt for AI Agents |
||
| WHERE ${projects.workspaceId} = ${ctx.workspace.id} | ||
| ORDER BY ${projects.updatedAt} DESC | ||
| `); | ||
|
|
||
| return (result.rows as ProjectRow[]).map( | ||
| (row): Project => ({ | ||
| id: row.id, | ||
| name: row.name, | ||
| slug: row.slug, | ||
| updatedAt: row.updated_at, | ||
| gitRepositoryUrl: row.git_repository_url, | ||
| liveDeploymentId: row.live_deployment_id, | ||
| commitTitle: row.git_commit_message ?? "[DUMMY] Initial commit", | ||
| branch: row.git_branch ?? "main", | ||
| author: row.git_commit_author_name ?? "[DUMMY] Unknown Author", | ||
| commitTimestamp: row.git_commit_timestamp ?? Date.now() - 86400000, | ||
| regions: row.runtime_config?.regions?.map((r) => r.region) ?? ["us-east-1"], | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is bad, the default should absolutely not be some random region. The control plane already create a proper
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the control plane sets the region correctly though, there is no need for default here |
||
| domain: row.domain ?? "project-temp.unkey.app", | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is flat out broken and no longer supports multiple domains per deployment
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For projects listing we only require 1 domain similar to Vercel. If you are saying we should return all the associated data and filter it on the frontend that we can do.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for projects listing maybe, but then you need a different trpc route to get more details about the deployment or whatever if we just return dumb lists and join on the frontend, we can reuse the data on many pages |
||
| }), | ||
| ); | ||
| }); | ||
Uh oh!
There was an error while loading. Please reload this page.