Skip to content

chore: use makefiles#3453

Merged
chronark merged 22 commits intomainfrom
makefile
Jul 7, 2025
Merged

chore: use makefiles#3453
chronark merged 22 commits intomainfrom
makefile

Conversation

@chronark
Copy link
Collaborator

@chronark chronark commented Jul 7, 2025

chore: use makefile

What does this PR do?

This PR replaces Taskfiles with Makefiles across the project for more standardized build automation. It converts the root Taskfile.yml, apps/agent/Taskfile.yml, and go/Taskfile.yml to equivalent Makefiles while preserving all functionality.

Type of change

  • Chore (refactoring code, technical debt, workflow improvements)

How should this be tested?

  • Run make up to verify Docker containers start correctly
  • Run make migrate-clickhouse to test database migrations
  • Run make integration to verify integration tests work with the new Makefiles
  • In the agent directory, run make build and make test to verify Go build commands work
  • In the go directory, run make test-unit to verify tests run correctly

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Summary by CodeRabbit

  • Chores
    • Replaced Taskfile-based automation with Makefile-based workflows for Docker management, database migrations, testing, and code generation across the project and submodules.
    • Removed documentation files related to database migration strategies and progress for the Hydra project.
  • Refactor
    • Standardized development and automation commands using Makefiles in place of Taskfiles for more consistent task execution.

@changeset-bot
Copy link

changeset-bot bot commented Jul 7, 2025

⚠️ No Changeset found

Latest commit: 6b95dbf

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Jul 7, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
dashboard ⬜️ Ignored (Inspect) Visit Preview Jul 7, 2025 8:35pm
engineering ⬜️ Ignored (Inspect) Visit Preview Jul 7, 2025 8:35pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 7, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This change replaces all Taskfile-based automation with Makefile-based workflows across the root, apps/agent, and go directories. It introduces new Makefiles with equivalent targets for Docker management, database migrations, code generation, linting, and testing. Additionally, two Hydra migration documentation files are removed from the codebase.

Changes

File(s) Change Summary
Makefile, apps/agent/Makefile, go/Makefile Added Makefiles defining phony targets for Docker, migrations, testing, linting, and builds.
Taskfile.yml, apps/agent/Taskfile.yml, go/Taskfile.yml Deleted all Taskfile.yml files, removing Task-based automation in favor of Makefiles.
go/pkg/hydra/MIGRATION_BEST_PRACTICES.md, go/pkg/hydra/MIGRATION_PROGRESS.md Deleted Hydra migration documentation files.

Sequence Diagram(s)

sequenceDiagram
    participant Developer
    participant Makefile
    participant Docker
    participant Goose
    participant DrizzleKit
    participant App

    Developer->>Makefile: make up
    Makefile->>Docker: docker-compose down
    Makefile->>Docker: docker-compose build
    Makefile->>Docker: docker-compose up -d

    Developer->>Makefile: make migrate-clickhouse
    Makefile->>Goose: goose -dir migrations up (with env vars)

    Developer->>Makefile: make generate-sql
    Makefile->>DrizzleKit: pnpm drizzle-kit generate (MySQL)

    Developer->>Makefile: make integration
    Makefile->>Docker: Ensure containers are up
    Makefile->>App: cd apps/api && make seed && pnpm test:integration
Loading

Suggested reviewers

  • perkinsjr
  • Flo4604

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f929e8 and 6b95dbf.

📒 Files selected for processing (2)
  • go/pkg/hydra/MIGRATION_BEST_PRACTICES.md (0 hunks)
  • go/pkg/hydra/MIGRATION_PROGRESS.md (0 hunks)

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link
Contributor

github-actions bot commented Jul 7, 2025

Thank you for following the naming conventions for pull request titles! 🙏

@chronark chronark changed the title chore: use makefiles chore: use makefiles (merge after 3426) Jul 7, 2025
Copy link
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: 79

🔭 Outside diff range comments (2)
go/pkg/db/queries/build_update_status.sql (1)

6-6: Remove trailing whitespace.

There's an unnecessary blank line at the end of the file that should be removed for consistency.

WHERE id = sqlc.arg(id);
-
go/pkg/hydra/store_test.go.bak (1)

1-1: Rename or remove backup extension on store_test.go.bak

It appears that go/pkg/hydra/store_test.go.bak is the only test file in this directory—there is no store_test.go. To ensure your tests are picked up correctly:

  • If this is the intended test, rename:
    • go/pkg/hydra/store_test.go.bakgo/pkg/hydra/store_test.go
  • Remove or untrack the .bak version from source control
  • Add *.bak to your .gitignore to prevent future backup files from being committed
♻️ Duplicate comments (2)
go/pkg/hydra/simple_consistency_test.go (1)

203-214: Same performance concern as the first test.

The individual query approach here has the same performance implications as mentioned in the TestSimpleDataConsistency function above.

go/pkg/hydra/step.go (1)

139-165: Inconsistent use of raw SQL vs SQLC queries.

Similar to sleep.go, this function uses raw SQL for step creation with lease validation instead of SQLC-generated queries. This inconsistency makes the codebase harder to maintain.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3f34c92 and 7f929e8.

⛔ Files ignored due to path filters (9)
  • go/gen/proto/ctrl/v1/build.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • go/gen/proto/ctrl/v1/ctrlv1connect/build.connect.go is excluded by !**/gen/**
  • go/gen/proto/ctrl/v1/ctrlv1connect/routing.connect.go is excluded by !**/gen/**
  • go/gen/proto/ctrl/v1/ctrlv1connect/service.connect.go is excluded by !**/gen/**
  • go/gen/proto/ctrl/v1/ctrlv1connect/version.connect.go is excluded by !**/gen/**
  • go/gen/proto/ctrl/v1/routing.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • go/gen/proto/ctrl/v1/service.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • go/gen/proto/ctrl/v1/version.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • go/go.sum is excluded by !**/*.sum
📒 Files selected for processing (107)
  • Makefile (1 hunks)
  • Taskfile.yml (0 hunks)
  • apps/agent/Makefile (1 hunks)
  • apps/agent/Taskfile.yml (0 hunks)
  • apps/api/src/pkg/testutil/harness.ts (2 hunks)
  • apps/dashboard/lib/trpc/routers/workspace/create.ts (1 hunks)
  • apps/engineering/content/infrastructure/database-schema.mdx (1 hunks)
  • apps/engineering/content/infrastructure/meta.json (1 hunks)
  • deployment/Dockerfile.mysql (1 hunks)
  • deployment/docker-compose.yaml (3 hunks)
  • deployment/init-databases.sql (1 hunks)
  • go/Makefile (1 hunks)
  • go/Taskfile.yml (0 hunks)
  • go/apps/api/cancel_test.go (2 hunks)
  • go/apps/api/integration/harness.go (1 hunks)
  • go/apps/api/run.go (1 hunks)
  • go/apps/ctrl/config.go (1 hunks)
  • go/apps/ctrl/run.go (1 hunks)
  • go/apps/ctrl/services/ctrl/liveness.go (1 hunks)
  • go/apps/ctrl/services/ctrl/service.go (1 hunks)
  • go/apps/ctrl/services/version/create_version.go (1 hunks)
  • go/apps/ctrl/services/version/deploy_workflow.go (1 hunks)
  • go/apps/ctrl/services/version/get_version.go (1 hunks)
  • go/apps/ctrl/services/version/service.go (1 hunks)
  • go/cmd/ctrl/main.go (1 hunks)
  • go/cmd/deploy/main.go (1 hunks)
  • go/cmd/run/main.go (1 hunks)
  • go/cmd/version/main.go (1 hunks)
  • go/demo_api/Dockerfile (1 hunks)
  • go/demo_api/go.mod (1 hunks)
  • go/demo_api/main.go (1 hunks)
  • go/go.mod (7 hunks)
  • go/main.go (2 hunks)
  • go/pkg/builder/mock.go (1 hunks)
  • go/pkg/cli/bubbletea.go (1 hunks)
  • go/pkg/cli/deployment_display.go (1 hunks)
  • go/pkg/cli/output.go (1 hunks)
  • go/pkg/db/build_find_by_id.sql_generated.go (1 hunks)
  • go/pkg/db/build_find_latest_by_version_id.sql_generated.go (1 hunks)
  • go/pkg/db/build_insert.sql_generated.go (1 hunks)
  • go/pkg/db/build_update_failed.sql_generated.go (1 hunks)
  • go/pkg/db/build_update_status.sql_generated.go (1 hunks)
  • go/pkg/db/build_update_succeeded.sql_generated.go (1 hunks)
  • go/pkg/db/models_generated.go (8 hunks)
  • go/pkg/db/querier_generated.go (8 hunks)
  • go/pkg/db/queries/build_find_by_id.sql (1 hunks)
  • go/pkg/db/queries/build_find_latest_by_version_id.sql (1 hunks)
  • go/pkg/db/queries/build_insert.sql (1 hunks)
  • go/pkg/db/queries/build_update_failed.sql (1 hunks)
  • go/pkg/db/queries/build_update_status.sql (1 hunks)
  • go/pkg/db/queries/build_update_succeeded.sql (1 hunks)
  • go/pkg/db/queries/version_find_by_id.sql (1 hunks)
  • go/pkg/db/queries/version_insert.sql (1 hunks)
  • go/pkg/db/queries/version_update_status.sql (1 hunks)
  • go/pkg/db/schema.sql (1 hunks)
  • go/pkg/db/version_find_by_id.sql_generated.go (1 hunks)
  • go/pkg/db/version_insert.sql_generated.go (1 hunks)
  • go/pkg/db/version_update_status.sql_generated.go (1 hunks)
  • go/pkg/db/workspace_find_by_id.sql_generated.go (2 hunks)
  • go/pkg/db/workspace_list.sql_generated.go (3 hunks)
  • go/pkg/git/git.go (1 hunks)
  • go/pkg/hydra/MIGRATION_BEST_PRACTICES.md (1 hunks)
  • go/pkg/hydra/MIGRATION_PROGRESS.md (1 hunks)
  • go/pkg/hydra/chaos_simulation_test.go (0 hunks)
  • go/pkg/hydra/data_consistency_test.go (4 hunks)
  • go/pkg/hydra/database_performance_test.go (0 hunks)
  • go/pkg/hydra/doc.go (3 hunks)
  • go/pkg/hydra/engine.go (8 hunks)
  • go/pkg/hydra/engine_test.go (2 hunks)
  • go/pkg/hydra/event_driven_consistency_test.go (0 hunks)
  • go/pkg/hydra/marshaller.go (1 hunks)
  • go/pkg/hydra/marshaller_test.go (1 hunks)
  • go/pkg/hydra/migration_validation_test.go (1 hunks)
  • go/pkg/hydra/models.go (0 hunks)
  • go/pkg/hydra/query_pattern_test.go.bak (1 hunks)
  • go/pkg/hydra/simple_consistency_test.go (2 hunks)
  • go/pkg/hydra/sleep.go (2 hunks)
  • go/pkg/hydra/step.go (5 hunks)
  • go/pkg/hydra/step_atomicity_test.go (4 hunks)
  • go/pkg/hydra/step_idempotency_test.go (4 hunks)
  • go/pkg/hydra/store.go (0 hunks)
  • go/pkg/hydra/store/db.go (1 hunks)
  • go/pkg/hydra/store/generate.go (1 hunks)
  • go/pkg/hydra/store/gorm/gorm.go (0 hunks)
  • go/pkg/hydra/store/models.go (1 hunks)
  • go/pkg/hydra/store/querier.go (1 hunks)
  • go/pkg/hydra/store/queries.go (1 hunks)
  • go/pkg/hydra/store/queries/workflows.sql (1 hunks)
  • go/pkg/hydra/store/schema.sql (1 hunks)
  • go/pkg/hydra/store/schema_embed.go (1 hunks)
  • go/pkg/hydra/store/sqlc-queries-analysis.md (1 hunks)
  • go/pkg/hydra/store/sqlc.json (1 hunks)
  • go/pkg/hydra/store/sqlc_store.go.bak (1 hunks)
  • go/pkg/hydra/store/store.go (0 hunks)
  • go/pkg/hydra/store/types.go (0 hunks)
  • go/pkg/hydra/store/workflows.sql.go (1 hunks)
  • go/pkg/hydra/store_coverage_test.go (1 hunks)
  • go/pkg/hydra/store_test.go.bak (13 hunks)
  • go/pkg/hydra/test_helpers.go (1 hunks)
  • go/pkg/hydra/worker.go (17 hunks)
  • go/pkg/hydra/worker_heartbeat_test.go (3 hunks)
  • go/pkg/hydra/workflow.go (7 hunks)
  • go/pkg/hydra/workflow_performance_test.go (1 hunks)
  • go/pkg/shutdown/shutdown.go (2 hunks)
  • go/pkg/testutil/containers/mysql.go (4 hunks)
  • go/pkg/testutil/http.go (1 hunks)
  • go/pkg/uid/uid.go (1 hunks)
⛔ Files not processed due to max files limit (10)
  • go/proto/ctrl/v1/build.proto
  • go/proto/ctrl/v1/routing.proto
  • go/proto/ctrl/v1/service.proto
  • go/proto/ctrl/v1/version.proto
  • go/rfc.md
  • go/test-docker/Dockerfile
  • hydra-security-analysis.md
  • internal/db/drizzle/0000_far_moondragon.sql
  • internal/db/drizzle/meta/0000_snapshot.json
  • internal/db/drizzle/meta/_journal.json
💤 Files with no reviewable changes (11)
  • go/pkg/hydra/store.go
  • go/Taskfile.yml
  • go/pkg/hydra/store/store.go
  • apps/agent/Taskfile.yml
  • Taskfile.yml
  • go/pkg/hydra/store/types.go
  • go/pkg/hydra/models.go
  • go/pkg/hydra/database_performance_test.go
  • go/pkg/hydra/event_driven_consistency_test.go
  • go/pkg/hydra/chaos_simulation_test.go
  • go/pkg/hydra/store/gorm/gorm.go
🧰 Additional context used
🧠 Learnings (57)
📓 Common learnings
Learnt from: chronark
PR: unkeyed/unkey#3161
File: go/pkg/clickhouse/schema/databases/002_ratelimits/006_ratelimits_per_day_v1.sql:1-13
Timestamp: 2025-04-22T14:43:11.724Z
Learning: In the unkey project, the SQL files in clickhouse/schema/databases represent the current production schema and shouldn't be modified directly in PRs. Schema changes require dedicated migration scripts.
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
apps/api/src/pkg/testutil/harness.ts (4)
Learnt from: chronark
PR: unkeyed/unkey#2180
File: apps/dashboard/lib/constants/workspace-navigations.tsx:56-118
Timestamp: 2024-10-04T20:44:38.489Z
Learning: When typing the `workspace` parameter in functions like `createWorkspaceNavigation`, prefer importing the `Workspace` type from the database module and picking the necessary keys (e.g., `features`) instead of redefining the interface.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2707
File: apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts:63-63
Timestamp: 2024-12-05T13:27:55.555Z
Learning: In `apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts`, when determining the maximum number of rate limit overrides (`max`), the intentional use of `const max = hasWorkspaceAccess("ratelimitOverrides", namespace.workspace) || 5;` allows `max` to fall back to `5` when `hasWorkspaceAccess` returns `0` or `false`. This fallback behavior is expected and intended in the codebase.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
go/pkg/hydra/marshaller.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/store/schema_embed.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/db/queries/version_insert.sql (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/db/queries/build_find_latest_by_version_id.sql (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
apps/dashboard/lib/trpc/routers/workspace/create.ts (4)
Learnt from: chronark
PR: unkeyed/unkey#2180
File: apps/dashboard/lib/constants/workspace-navigations.tsx:56-118
Timestamp: 2024-10-04T20:44:38.489Z
Learning: When typing the `workspace` parameter in functions like `createWorkspaceNavigation`, prefer importing the `Workspace` type from the database module and picking the necessary keys (e.g., `features`) instead of redefining the interface.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2707
File: apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts:63-63
Timestamp: 2024-12-05T13:27:55.555Z
Learning: In `apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts`, when determining the maximum number of rate limit overrides (`max`), the intentional use of `const max = hasWorkspaceAccess("ratelimitOverrides", namespace.workspace) || 5;` allows `max` to fall back to `5` when `hasWorkspaceAccess` returns `0` or `false`. This fallback behavior is expected and intended in the codebase.
go/pkg/hydra/doc.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/data_consistency_test.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/marshaller_test.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/db/queries/version_update_status.sql (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/simple_consistency_test.go (2)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
go/pkg/db/workspace_list.sql_generated.go (3)
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
Learnt from: chronark
PR: unkeyed/unkey#2180
File: apps/dashboard/lib/constants/workspace-navigations.tsx:56-118
Timestamp: 2024-10-04T20:44:38.489Z
Learning: When typing the `workspace` parameter in functions like `createWorkspaceNavigation`, prefer importing the `Workspace` type from the database module and picking the necessary keys (e.g., `features`) instead of redefining the interface.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.
go/pkg/db/build_find_latest_by_version_id.sql_generated.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/db/queries/version_find_by_id.sql (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/engine_test.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/db/workspace_find_by_id.sql_generated.go (3)
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
Learnt from: chronark
PR: unkeyed/unkey#2180
File: apps/dashboard/lib/constants/workspace-navigations.tsx:56-118
Timestamp: 2024-10-04T20:44:38.489Z
Learning: When typing the `workspace` parameter in functions like `createWorkspaceNavigation`, prefer importing the `Workspace` type from the database module and picking the necessary keys (e.g., `features`) instead of redefining the interface.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.
go/pkg/hydra/store/sqlc.json (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/store/queries.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/db/version_update_status.sql_generated.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/worker_heartbeat_test.go (2)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
go/pkg/db/build_update_failed.sql_generated.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/apps/ctrl/services/version/service.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/db/queries/build_insert.sql (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/db/version_find_by_id.sql_generated.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/MIGRATION_PROGRESS.md (2)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
Learnt from: chronark
PR: unkeyed/unkey#3161
File: go/pkg/clickhouse/schema/databases/002_ratelimits/006_ratelimits_per_day_v1.sql:1-13
Timestamp: 2025-04-22T14:43:11.724Z
Learning: In the unkey project, the SQL files in clickhouse/schema/databases represent the current production schema and shouldn't be modified directly in PRs. Schema changes require dedicated migration scripts.
go/pkg/db/build_update_status.sql_generated.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/store/sqlc-queries-analysis.md (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/query_pattern_test.go.bak (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/testutil/containers/mysql.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/store/db.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/db/build_insert.sql_generated.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
apps/engineering/content/infrastructure/database-schema.mdx (3)
Learnt from: chronark
PR: unkeyed/unkey#3161
File: go/pkg/clickhouse/schema/databases/002_ratelimits/006_ratelimits_per_day_v1.sql:1-13
Timestamp: 2025-04-22T14:43:11.724Z
Learning: In the unkey project, the SQL files in clickhouse/schema/databases represent the current production schema and shouldn't be modified directly in PRs. Schema changes require dedicated migration scripts.
Learnt from: chronark
PR: unkeyed/unkey#3161
File: go/pkg/clickhouse/schema/databases/001_verifications/002_raw_key_verifications_v1.sql:31-33
Timestamp: 2025-04-22T14:40:51.459Z
Learning: The ClickHouse table schemas in the codebase mirror the production environment and cannot be modified directly in PRs without careful migration planning.
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
deployment/Dockerfile.mysql (1)
Learnt from: chronark
PR: unkeyed/unkey#3161
File: go/pkg/clickhouse/schema/databases/002_ratelimits/006_ratelimits_per_day_v1.sql:1-13
Timestamp: 2025-04-22T14:43:11.724Z
Learning: In the unkey project, the SQL files in clickhouse/schema/databases represent the current production schema and shouldn't be modified directly in PRs. Schema changes require dedicated migration scripts.
go/pkg/hydra/workflow.go (2)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
deployment/init-databases.sql (1)
Learnt from: chronark
PR: unkeyed/unkey#3161
File: go/pkg/clickhouse/schema/databases/002_ratelimits/006_ratelimits_per_day_v1.sql:1-13
Timestamp: 2025-04-22T14:43:11.724Z
Learning: In the unkey project, the SQL files in clickhouse/schema/databases represent the current production schema and shouldn't be modified directly in PRs. Schema changes require dedicated migration scripts.
go/pkg/hydra/store/generate.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/worker.go (2)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
go/pkg/hydra/store_coverage_test.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/step_atomicity_test.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/sleep.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/MIGRATION_BEST_PRACTICES.md (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/go.mod (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/workflow_performance_test.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/store/queries/workflows.sql (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/store_test.go.bak (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/store/schema.sql (3)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
Learnt from: chronark
PR: unkeyed/unkey#3161
File: go/pkg/clickhouse/schema/databases/001_verifications/002_raw_key_verifications_v1.sql:31-33
Timestamp: 2025-04-22T14:40:51.459Z
Learning: The ClickHouse table schemas in the codebase mirror the production environment and cannot be modified directly in PRs without careful migration planning.
Learnt from: chronark
PR: unkeyed/unkey#3161
File: go/pkg/clickhouse/schema/databases/002_ratelimits/006_ratelimits_per_day_v1.sql:1-13
Timestamp: 2025-04-22T14:43:11.724Z
Learning: In the unkey project, the SQL files in clickhouse/schema/databases represent the current production schema and shouldn't be modified directly in PRs. Schema changes require dedicated migration scripts.
go/pkg/db/build_update_succeeded.sql_generated.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/engine.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/migration_validation_test.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/store/querier.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/test_helpers.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/db/schema.sql (4)
Learnt from: chronark
PR: unkeyed/unkey#3161
File: go/pkg/clickhouse/schema/databases/002_ratelimits/006_ratelimits_per_day_v1.sql:1-13
Timestamp: 2025-04-22T14:43:11.724Z
Learning: In the unkey project, the SQL files in clickhouse/schema/databases represent the current production schema and shouldn't be modified directly in PRs. Schema changes require dedicated migration scripts.
Learnt from: chronark
PR: unkeyed/unkey#3161
File: go/pkg/clickhouse/schema/databases/001_verifications/002_raw_key_verifications_v1.sql:31-33
Timestamp: 2025-04-22T14:40:51.459Z
Learning: The ClickHouse table schemas in the codebase mirror the production environment and cannot be modified directly in PRs without careful migration planning.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.
go/pkg/hydra/store/models.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/db/querier_generated.go (2)
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.
go/pkg/hydra/store/sqlc_store.go.bak (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
go/pkg/hydra/store/workflows.sql.go (1)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
🧬 Code Graph Analysis (23)
go/pkg/hydra/data_consistency_test.go (3)
go/pkg/hydra/store/queries.go (1)
  • Query (22-22)
go/pkg/hydra/store/workflows.sql.go (2)
  • GetWorkflowParams (609-612)
  • GetStepParams (579-583)
go/pkg/hydra/store/models.go (2)
  • WorkflowExecutionsStatusCompleted (62-62)
  • WorkflowStepsStatusCompleted (150-150)
go/pkg/hydra/simple_consistency_test.go (3)
go/pkg/hydra/store/queries.go (1)
  • Query (22-22)
go/pkg/hydra/store/workflows.sql.go (1)
  • GetWorkflowParams (609-612)
go/pkg/hydra/store/models.go (1)
  • WorkflowExecutionsStatusCompleted (62-62)
go/pkg/db/workspace_list.sql_generated.go (1)
go/pkg/db/models_generated.go (1)
  • Workspace (830-847)
go/pkg/db/build_find_latest_by_version_id.sql_generated.go (2)
go/pkg/hydra/store/db.go (2)
  • Queries (19-21)
  • DBTX (8-13)
go/pkg/db/models_generated.go (1)
  • Build (555-570)
go/pkg/hydra/engine_test.go (3)
go/pkg/hydra/store/queries.go (1)
  • Query (22-22)
go/pkg/hydra/store/workflows.sql.go (1)
  • GetWorkflowParams (609-612)
go/pkg/hydra/store/models.go (1)
  • WorkflowExecutionsStatusPending (59-59)
go/pkg/hydra/step_idempotency_test.go (3)
go/pkg/hydra/store/queries.go (1)
  • Query (22-22)
go/pkg/hydra/store/workflows.sql.go (1)
  • GetWorkflowParams (609-612)
go/pkg/hydra/store/models.go (2)
  • WorkflowExecutionsStatusPending (59-59)
  • WorkflowExecutionsStatusCompleted (62-62)
go/pkg/hydra/store/queries.go (2)
go/pkg/hydra/store/querier.go (1)
  • Querier (11-39)
go/pkg/hydra/store/db.go (1)
  • Queries (19-21)
go/pkg/db/version_update_status.sql_generated.go (2)
go/pkg/db/models_generated.go (1)
  • VersionsStatus (401-401)
go/pkg/hydra/store/db.go (2)
  • Queries (19-21)
  • DBTX (8-13)
go/pkg/hydra/worker_heartbeat_test.go (3)
go/pkg/hydra/store/queries.go (1)
  • Query (22-22)
go/pkg/hydra/store/workflows.sql.go (2)
  • GetWorkflowParams (609-612)
  • GetLeaseParams (366-369)
go/pkg/hydra/store/models.go (3)
  • WorkflowExecutionsStatusPending (59-59)
  • WorkflowExecutionsStatusRunning (60-60)
  • LeasesKindWorkflow (16-16)
go/pkg/db/build_find_by_id.sql_generated.go (2)
go/pkg/hydra/store/db.go (2)
  • Queries (19-21)
  • DBTX (8-13)
go/pkg/db/models_generated.go (1)
  • Build (555-570)
go/pkg/db/build_update_failed.sql_generated.go (1)
go/pkg/hydra/store/db.go (2)
  • Queries (19-21)
  • DBTX (8-13)
go/apps/ctrl/services/ctrl/liveness.go (2)
go/apps/ctrl/services/ctrl/service.go (1)
  • Service (8-12)
go/gen/proto/ctrl/v1/service.pb.go (6)
  • LivenessRequest (24-28)
  • LivenessRequest (41-41)
  • LivenessRequest (56-58)
  • LivenessResponse (60-67)
  • LivenessResponse (80-80)
  • LivenessResponse (95-97)
go/pkg/db/version_find_by_id.sql_generated.go (2)
go/pkg/hydra/store/db.go (2)
  • Queries (19-21)
  • DBTX (8-13)
go/pkg/db/models_generated.go (1)
  • Version (815-828)
go/pkg/db/build_update_status.sql_generated.go (2)
go/pkg/db/models_generated.go (1)
  • BuildsStatus (99-99)
go/pkg/hydra/store/db.go (2)
  • Queries (19-21)
  • DBTX (8-13)
go/apps/ctrl/config.go (1)
go/pkg/hydra/engine.go (1)
  • Config (27-49)
go/pkg/db/version_insert.sql_generated.go (2)
go/pkg/db/models_generated.go (1)
  • VersionsStatus (401-401)
go/pkg/hydra/store/db.go (2)
  • Queries (19-21)
  • DBTX (8-13)
go/pkg/testutil/containers/mysql.go (1)
go/pkg/testutil/containers/containers.go (1)
  • Containers (14-18)
go/pkg/hydra/store/db.go (1)
go/pkg/hydra/engine.go (1)
  • New (101-156)
go/pkg/db/build_insert.sql_generated.go (1)
go/pkg/hydra/store/db.go (2)
  • Queries (19-21)
  • DBTX (8-13)
go/pkg/hydra/step_atomicity_test.go (3)
go/pkg/hydra/store/queries.go (1)
  • Query (22-22)
go/pkg/hydra/store/workflows.sql.go (1)
  • GetWorkflowParams (609-612)
go/pkg/hydra/store/models.go (1)
  • WorkflowExecutionsStatusCompleted (62-62)
go/pkg/hydra/migration_validation_test.go (2)
go/pkg/hydra/store/queries.go (1)
  • Query (22-22)
go/pkg/hydra/store/workflows.sql.go (1)
  • GetPendingWorkflowsParams (398-403)
go/pkg/hydra/store/querier.go (3)
go/pkg/hydra/store/db.go (2)
  • DBTX (8-13)
  • Queries (19-21)
go/pkg/hydra/store/workflows.sql.go (26)
  • CleanupExpiredLeasesParams (18-21)
  • CompleteWorkflowParams (34-39)
  • CreateCronJobParams (60-71)
  • CreateLeaseParams (97-105)
  • CreateStepParams (130-142)
  • CreateWorkflowParams (175-194)
  • GetCompletedStepParams (225-229)
  • GetCronJobParams (255-258)
  • GetDueCronJobsParams (322-325)
  • GetLeaseParams (366-369)
  • GetPendingWorkflowsParams (398-403)
  • GetPendingWorkflowsFilteredParams (465-471)
  • GetSleepingWorkflowsParams (527-530)
  • GetStepParams (579-583)
  • GetWorkflowParams (609-612)
  • HeartbeatLeaseParams (646-651)
  • ReleaseLeaseParams (668-671)
  • ResetOrphanedWorkflowsParams (690-693)
  • SleepWorkflowParams (706-710)
  • UpdateCronJobParams (723-731)
  • UpdateCronJobLastRunParams (752-758)
  • UpdateLeaseParams (777-785)
  • UpdateStepStatusParams (806-814)
  • UpdateStepStatusWithLeaseParams (840-851)
  • UpdateWorkflowFieldsParams (888-902)
  • UpdateWorkflowToRunningParams (936-943)
go/pkg/hydra/store/models.go (4)
  • WorkflowStep (233-245)
  • CronJob (189-200)
  • Lease (202-210)
  • WorkflowExecution (212-231)
go/pkg/db/querier_generated.go (8)
go/pkg/hydra/store/db.go (1)
  • DBTX (8-13)
go/pkg/db/models_generated.go (2)
  • Build (555-570)
  • Version (815-828)
go/pkg/db/build_insert.sql_generated.go (1)
  • InsertBuildParams (46-52)
go/pkg/db/version_insert.sql_generated.go (1)
  • InsertVersionParams (45-58)
go/pkg/db/build_update_failed.sql_generated.go (1)
  • UpdateBuildFailedParams (22-26)
go/pkg/db/build_update_status.sql_generated.go (1)
  • UpdateBuildStatusParams (20-24)
go/pkg/db/build_update_succeeded.sql_generated.go (1)
  • UpdateBuildSucceededParams (21-24)
go/pkg/db/version_update_status.sql_generated.go (1)
  • UpdateVersionStatusParams (20-24)
🪛 Checkov (3.2.334)
go/demo_api/Dockerfile

[LOW] 12-12: Ensure the base image uses a non latest version tag

(CKV_DOCKER_7)


[LOW] 1-22: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[LOW] 1-22: Ensure that a user for the container has been created

(CKV_DOCKER_3)

deployment/Dockerfile.mysql

[LOW] 1-9: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[LOW] 1-9: Ensure that a user for the container has been created

(CKV_DOCKER_3)

deployment/docker-compose.yaml

[LOW] 90-91: Base64 High Entropy String

(CKV_SECRET_6)

🪛 Hadolint (2.12.0)
go/demo_api/Dockerfile

[warning] 12-12: Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag

(DL3007)


[warning] 14-14: Pin versions in apk add. Instead of apk add <package> use apk add <package>=<version>

(DL3018)

🪛 checkmake (0.2.2)
Makefile

[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)


[warning] 1-1: Missing required phony target "test"

(minphony)

apps/agent/Makefile

[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)

go/Makefile

[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)


[warning] 1-1: Missing required phony target "test"

(minphony)

🪛 LanguageTool
go/pkg/hydra/MIGRATION_PROGRESS.md

[uncategorized] ~204-~204: Possible missing preposition found.
Context: ... VARBINARY vs LONGBLOB: Size limits prevent DoS attacks - ENUMs vs VARCHAR: Typ...

(AI_HYDRA_LEO_MISSING_TO)


[uncategorized] ~211-~211: You might be missing the article “the” here.
Context: ...ce Consistency**: Both stores implement same store.Store interface ### Security E...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

go/pkg/hydra/store/sqlc-queries-analysis.md

[grammar] ~212-~212: Before the countable noun ‘in’ an article or a possessive pronoun is necessary.
Context: ...ting) Purpose: Get all workflows in namespace for testing GORM Query: ```go s.d...

(IN_NN_CC_VBG)


[grammar] ~308-~308: Before the countable noun ‘in’ an article or a possessive pronoun is necessary.
Context: ...(Testing) Purpose: Get all steps in namespace for testing GORM Query: ```go s.d...

(IN_NN_CC_VBG)

apps/engineering/content/infrastructure/database-schema.mdx

[uncategorized] ~50-~50: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...ified Table Names All schema files use fully-qualified table names to ensure tables are create...

(HYPHENATED_LY_ADVERB_ADJECTIVE)


[uncategorized] ~82-~82: A period might be missing here.
Context: ...a - This will enable better tooling and consistency ### Hydra Database The hydra databa...

(AI_EN_LECTOR_MISSING_PUNCTUATION_PERIOD)


[uncategorized] ~86-~86: Possible missing comma found.
Context: ...ydra/store/schema.sql` as its source of truth since it's Go-native and doesn't use Dr...

(AI_HYDRA_LEO_MISSING_COMMA)

go/pkg/hydra/MIGRATION_BEST_PRACTICES.md

[uncategorized] ~45-~45: You might be missing the article “the” here.
Context: ...ration Migration Problem: Managing complexity of large-scale migrations. *Solution...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

🪛 markdownlint-cli2 (0.17.2)
go/pkg/hydra/MIGRATION_PROGRESS.md

13-13: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


14-14: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


23-23: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


24-24: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


36-36: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


37-37: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


40-40: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


79-79: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


80-80: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


89-89: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


90-90: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


94-94: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


103-103: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


104-104: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


108-108: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


111-111: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


113-113: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


117-117: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


118-118: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


125-125: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


126-126: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


128-128: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


134-134: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


141-141: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


142-142: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


149-149: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


150-150: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


150-150: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


160-160: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


161-161: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


162-162: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


176-176: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


177-177: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


179-179: Trailing spaces
Expected: 0 or 2; Actual: 1

(MD009, no-trailing-spaces)


199-199: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


200-200: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


203-203: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


204-204: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


208-208: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


209-209: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


213-213: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


214-214: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


220-220: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


221-221: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


228-228: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


229-229: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


233-233: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


234-234: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


240-240: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


241-241: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


246-246: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


247-247: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


263-263: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


273-273: Files should end with a single newline character

(MD047, single-trailing-newline)

go/pkg/hydra/store/sqlc-queries-analysis.md

8-8: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


15-15: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


18-18: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


20-20: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


22-22: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


31-31: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


34-34: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


38-38: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


40-40: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


46-46: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


49-49: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


63-63: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


65-65: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


76-76: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


79-79: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


82-82: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


90-90: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


92-92: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


98-98: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


101-101: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


110-110: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


112-112: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


120-120: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


123-123: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


123-123: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


124-124: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


128-128: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


129-129: Ordered list item prefix
Expected: 1; Actual: 2; Style: 1/1/1

(MD029, ol-prefix)


129-129: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


129-129: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


130-130: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


141-141: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


143-143: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


159-159: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


162-162: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


170-170: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


172-172: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


178-178: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


181-181: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


186-186: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


188-188: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


196-196: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


199-199: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


211-211: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


214-214: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


218-218: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


220-220: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


226-226: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


229-229: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


231-231: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


233-233: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


241-241: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


244-244: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


249-249: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


251-251: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


257-257: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


260-260: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


265-265: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


267-267: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


276-276: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


279-279: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


279-279: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


280-280: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


284-284: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


285-285: Ordered list item prefix
Expected: 1; Actual: 2; Style: 1/1/1

(MD029, ol-prefix)


285-285: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


285-285: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


286-286: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


296-296: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


298-298: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


307-307: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


310-310: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


314-314: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


316-316: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


322-322: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


326-326: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


327-327: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


331-331: Ordered list item prefix
Expected: 1; Actual: 2; Style: 1/2/3

(MD029, ol-prefix)


333-333: Ordered list item prefix
Expected: 2; Actual: 3; Style: 1/2/3

(MD029, ol-prefix)


333-333: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


334-334: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


338-338: Ordered list item prefix
Expected: 1; Actual: 4; Style: 1/1/1

(MD029, ol-prefix)


338-338: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


339-339: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


345-345: Ordered list item prefix
Expected: 1; Actual: 5; Style: 1/1/1

(MD029, ol-prefix)


345-345: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


346-346: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


357-357: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


402-402: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


405-405: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


407-407: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


409-409: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


414-414: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


417-417: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


425-425: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


427-427: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


433-433: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


436-436: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


440-440: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


442-442: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


447-447: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


450-450: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


454-454: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


456-456: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


460-460: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


463-463: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


467-467: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


469-469: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


474-474: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


477-477: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


481-481: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


483-483: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


490-490: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


493-493: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


493-493: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


494-494: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


498-498: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


499-499: Ordered list item prefix
Expected: 1; Actual: 2; Style: 1/1/1

(MD029, ol-prefix)


499-499: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


499-499: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


500-500: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


504-504: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


506-506: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


517-517: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


520-520: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


524-524: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


526-526: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


532-532: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


535-535: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


539-539: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


541-541: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


546-546: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


549-549: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


553-553: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


555-555: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


562-562: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


565-565: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


574-574: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


576-576: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


584-584: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


587-587: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


592-592: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


597-597: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


598-598: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


602-602: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


603-603: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


607-607: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


608-608: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


616-616: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


616-616: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


625-625: Files should end with a single newline character

(MD047, single-trailing-newline)

go/pkg/hydra/MIGRATION_BEST_PRACTICES.md

21-21: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


39-39: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


168-168: Trailing spaces
Expected: 0 or 2; Actual: 1

(MD009, no-trailing-spaces)


169-169: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


178-178: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


187-187: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


193-193: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


194-194: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


199-199: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


200-200: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


205-205: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


206-206: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


211-211: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


212-212: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


226-226: Files should end with a single newline character

(MD047, single-trailing-newline)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
  • GitHub Check: Test Go API Local / Test (Shard 6/8)
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Build / Build
  • GitHub Check: Test Packages / Test ./packages/hono
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Test Packages / Test ./apps/dashboard
  • GitHub Check: Test Packages / Test ./packages/nextjs
  • GitHub Check: Test Packages / Test ./packages/api
  • GitHub Check: Test Packages / Test ./internal/billing
  • GitHub Check: Test Packages / Test ./internal/hash
  • GitHub Check: Test Packages / Test ./internal/keys
  • GitHub Check: Test Packages / Test ./packages/cache
  • GitHub Check: Test Packages / Test ./packages/rbac
  • GitHub Check: Test Packages / Test ./internal/resend
  • GitHub Check: Test Packages / Test ./internal/id
  • GitHub Check: Test Packages / Test ./internal/encryption
  • GitHub Check: autofix
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (101)
go/pkg/hydra/marshaller.go (1)

3-5: Import grouping change only – no concerns.

go/demo_api/go.mod (1)

1-3: go 1.24 may not be available in CI yet.

Confirm that your build pipeline runners actually ship the Go 1.24 tool-chain; otherwise set this to the highest supported released version (currently 1.22/1.23).

apps/engineering/content/infrastructure/meta.json (1)

5-5: Change looks good – metadata stays coherent.

apps/api/src/pkg/testutil/harness.ts (1)

270-289: Ensure DB schema includes partition_id (nullable).

The new partitionId: null field will cause an insert failure if the workspaces table hasn’t been migrated yet or if the column is NOT NULL. Double-check that the corresponding migration ran before these tests execute.

go/apps/api/cancel_test.go (2)

23-25: LGTM: MySQL container setup modernization.

The changes to use the new MySQL configuration approach with explicit database name setting align well with the infrastructure modernization mentioned in the AI summary. The explicit DBName assignment ensures proper database targeting.


89-89: LGTM: Appropriate timeout increase for graceful shutdown.

The timeout increase from 30s to 90s is reasonable given the more complex shutdown procedures introduced with the new infrastructure and service orchestration.

go/pkg/db/queries/version_update_status.sql (1)

1-5: LGTM: Clean and consistent SQL query implementation.

The query follows SQLC conventions properly with parameterized inputs and appropriate query type. The structure is consistent with similar queries in the codebase.

apps/dashboard/lib/trpc/routers/workspace/create.ts (1)

64-64: LGTM: Proper schema alignment for partitioning support.

The addition of partitionId: null aligns with the database schema changes and maintains consistency with other nullable fields in the workspace object. The null initialization is appropriate for new optional functionality.

go/pkg/hydra/store/generate.go (1)

1-6: SQLC generation setup confirmed

  • Verified go/pkg/hydra/store/sqlc.json exists and contains a valid configuration:
    • Engine: “mysql”
    • Queries directory: queries/
    • Schema file: schema.sql
    • Go generation settings (package “store”, output “.”, output_db_file_name set to “delete_me”, etc.)
  • The rm delete_me.go directive correctly cleans up the intermediate file.

LGTM!

go/apps/api/integration/harness.go (1)

57-62: Excellent refactoring for better configuration control.

The change from direct DSN strings to MySQL config objects provides better control and explicitness. Setting the database name explicitly (DBName = "unkey") makes the configuration more transparent and maintainable.

go/pkg/db/queries/build_update_succeeded.sql (1)

1-6: Well-structured SQL query with good security practices.

The query properly updates build status using parameterized inputs to prevent SQL injection. The use of sqlc.arg() for all parameters and the :exec directive for non-returning queries follows SQLC best practices.

go/pkg/testutil/http.go (1)

61-63: LGTM: Clean refactoring of MySQL configuration

The change to explicitly set the database name and format the DSN provides better control over the database connection configuration. This aligns well with the broader refactoring to standardize database setup.

go/main.go (2)

8-12: LGTM: Clean CLI command restructuring

The new import structure properly organizes the CLI commands and follows Go import conventions.


24-26: LGTM: Logical command ordering

The command ordering is well-structured with primary commands (run, version, deploy) listed before utility commands (healthcheck, quotacheck).

go/pkg/db/queries/version_find_by_id.sql (1)

1-16: LGTM: Well-structured SQLC query

The query follows proper SQLC conventions with safe parameter binding and comprehensive field selection. The :one annotation is appropriate for a find-by-ID query.

go/pkg/hydra/store/schema_embed.go (1)

1-12: LGTM: Clean schema embedding implementation

The implementation properly uses Go's embed directive to include the SQL schema in the binary. The documentation clearly explains the purpose and benefits of this approach.

go/pkg/db/queries/build_find_by_id.sql (1)

1-18: LGTM! Clean and efficient single-record query.

The query structure is correct for SQLC and follows proper parameterization. The :one annotation is appropriate for finding by primary key.

go/pkg/hydra/doc.go (3)

49-57: Good documentation update for the SQLC migration.

The simplified engine creation example correctly reflects the new DSN-based approach, replacing the previous GORM database setup.


134-144: Helpful addition of marshalling options documentation.

The new marshalling section provides clear examples of how to configure different marshalling formats, which is valuable for users.


222-222: Correctly updated schema instructions.

The change from auto-migration to manual schema file creation is consistent with the SQLC migration approach.

go/pkg/db/queries/version_insert.sql (1)

1-29: Well-structured insert query following SQLC best practices.

The query correctly uses the :exec annotation for insert operations and properly parameterizes all fields using sqlc.arg(). This follows secure coding practices and SQLC conventions.

go/pkg/db/workspace_list.sql_generated.go (1)

14-14: Generated code correctly reflects partition_id schema addition.

The generated code properly includes the new partition_id column in the SQL query and scans it into the PartitionID field of the Workspace struct, which is consistent with the model updates.

Also applies to: 31-31, 51-51

go/pkg/hydra/step_atomicity_test.go (4)

11-11: LGTM: Store import added for SQLC migration

The import is correctly added to support the new SQLC-based query interface.


70-77: LGTM: GetWorkflow call updated for SQLC migration

The migration from engine.store.GetWorkflow to store.Query.GetWorkflow with explicit database handle and parameter struct is correct. The status constant is also properly updated to use the new namespaced constant.


93-98: LGTM: Consistent GetWorkflow migration pattern

The changes follow the same correct migration pattern as the previous instance, maintaining consistency throughout the file.


181-188: LGTM: Final GetWorkflow call correctly migrated

The third instance of the migration is consistent with the previous ones, properly using the new SQLC query interface and status constants.

go/cmd/run/main.go (1)

9-20: LGTM: Well-structured parent CLI command

The run command provides a clean interface for running different Unkey services. The description clearly explains the purpose of each subcommand, and the command structure follows good CLI design patterns.

go/apps/ctrl/services/ctrl/service.go (2)

8-12: LGTM: Clean service structure

The Service struct properly embeds the gRPC handler and includes the necessary fields for instance identification and database access. The structure follows standard Go service patterns.


14-20: LGTM: Proper service initialization

The constructor correctly initializes all fields, including the embedded gRPC handler. The parameter ordering and naming are clear and consistent.

go/pkg/hydra/engine_test.go (2)

12-12: LGTM: Store import added for SQLC migration

The import is correctly added to support the new SQLC-based query interface, consistent with the migration pattern.


121-126: LGTM: GetWorkflow call updated for SQLC migration

The migration from engine.store.GetWorkflow to store.Query.GetWorkflow with explicit database handle and parameter struct is correct. The status constant is also properly updated to use the new namespaced constant store.WorkflowExecutionsStatusPending.

go/pkg/db/workspace_find_by_id.sql_generated.go (1)

13-13: LGTM - Partition ID support added correctly

The addition of partition_id to the SELECT statement, documentation comment, and scan operation is consistent and correct. The generated code properly handles the new partition field.

Also applies to: 19-19, 28-28

go/pkg/db/queries/build_insert.sql (1)

1-32: LGTM - Well-structured insert query

The SQL structure is clean and follows good practices with proper parameter binding using sqlc.arg() and appropriate use of NULL for optional fields.

go/pkg/hydra/step_idempotency_test.go (3)

11-11: LGTM - Correct import for new store package

The import addition for the new SQLC-based store package is appropriate for the migration.


73-76: LGTM - Consistent migration to SQLC query interface

The changes from engine.store.GetWorkflow() to store.Query.GetWorkflow() with explicit database handle and parameter struct passing are consistent with the SQLC migration pattern. The API changes maintain the same functionality while providing better type safety.

Also applies to: 84-87, 123-126


78-78: LGTM - Updated status constants for new store

The migration from old status constants to store.WorkflowExecutionsStatus* constants is correct and maintains compatibility with the new SQLC-generated types.

Also applies to: 128-128, 145-145

go/pkg/hydra/store/queries.go (1)

3-21: LGTM - Excellent documentation and example usage

The comprehensive documentation with example usage makes the API clear and helps developers understand how to use the new SQLC-based query interface.

go/apps/ctrl/services/ctrl/liveness.go (1)

11-22: LGTM - Standard liveness endpoint implementation

The liveness check implementation follows best practices by returning essential health information including status, version, and instance ID. The simple implementation ensures reliability for health monitoring.

go/pkg/hydra/marshaller_test.go (1)

10-64: Excellent test coverage for JSON marshaller.

The tests are well-structured and comprehensive, covering different data types and correctly handling JSON unmarshalling behavior (like number conversion to float64). The use of subtests and proper assertion patterns with testify makes this a solid test implementation.

go/demo_api/main.go (1)

17-54: Clean and well-structured demo API implementation.

The code follows HTTP best practices with proper status codes, content types, and structured responses. The environment variable configuration and clean separation of concerns make this a solid demo API implementation.

go/pkg/hydra/workflow_performance_test.go (1)

411-422: Good refactoring for GORM to SQLC migration.

The changes properly consolidate engine creation through the unified test helper and remove direct SQLite/GORM dependencies, which aligns well with the migration strategy. The type assertion handling for testing.TB interface is appropriate for benchmark usage.

go/pkg/hydra/store/sqlc.json (1)

1-44: Well-configured SQLC setup for the GORM to SQLC migration.

The configuration appropriately targets MySQL with sensible generation options. The type overrides for binary columns and enabled features like interfaces and DB argument methods align well with the migration strategy from GORM to SQLC.

go/pkg/uid/uid.go (1)

37-45: LGTM! New prefix constants are well-structured.

The new prefix constants follow the established naming conventions and are properly organized. The additions support the new control plane functionality and workflow engine being introduced in this PR.

go/pkg/hydra/data_consistency_test.go (3)

83-87: LGTM! Correctly updated to use SQLC-generated queries.

The test properly migrates from direct store method calls to the new SQLC-generated query interface, passing the correct parameters and using the new status constants.


168-172: LGTM! Proper migration to SQLC query interface.

The step retrieval correctly uses the new store.Query.GetStep method with the appropriate parameter structure.


179-179: LGTM! Status constant updated correctly.

The status comparison properly uses the new store.WorkflowStepsStatusCompleted constant from the SQLC-generated enums.

go/pkg/db/version_find_by_id.sql_generated.go (1)

1-65: LGTM! Standard SQLC-generated query implementation.

The generated code follows proper SQLC conventions with:

  • Correct SQL query structure selecting all version fields
  • Proper method signature with context and DBTX interface
  • Accurate field scanning into the Version struct
  • Standard generated code patterns

This provides type-safe database access for version retrieval.

go/pkg/db/build_find_latest_by_version_id.sql_generated.go (1)

1-75: LGTM! Well-structured SQLC-generated query for latest build retrieval.

The generated code correctly implements finding the latest build by version ID with:

  • Proper SQL query with ORDER BY created_at DESC LIMIT 1
  • Standard SQLC method signature and patterns
  • Correct field mapping and scanning into Build struct
  • Type-safe database access with proper error handling

The query logic is sound for retrieving the most recent build for a given version.

go/apps/ctrl/services/version/service.go (1)

11-27: LGTM! Well-structured service implementation with proper dependency injection.

The service follows good patterns with:

  • Proper embedding of the unimplemented handler
  • Clear dependency injection through constructor
  • Appropriate dependencies (database, hydra engine, builder service, logger)
  • Clean struct organization

The implementation provides a solid foundation for version management functionality.

go/pkg/hydra/worker_heartbeat_test.go (5)

10-10: LGTM: Store import updated for SQLC migration.

The import change aligns with the migration from GORM to SQLC as documented in the retrieved learnings.


63-66: LGTM: Proper SQLC query usage for workflow retrieval.

The migration from direct store methods to SQLC queries is implemented correctly, using the new store.Query.GetWorkflow method with proper parameter struct and updated status constants.

Also applies to: 70-70


74-77: LGTM: Consistent SQLC pattern for workflow status check.

The workflow status verification follows the same pattern as the previous query, maintaining consistency in the migration approach.

Also applies to: 79-79


82-85: LGTM: Proper lease retrieval using SQLC queries.

The lease retrieval correctly uses the new store.Query.GetLease method with appropriate parameters and constants.


96-99: LGTM: Consistent lease update verification.

The updated lease retrieval maintains the same pattern, ensuring consistency throughout the test.

go/pkg/db/build_update_status.sql_generated.go (1)

1-35: LGTM: Well-structured SQLC-generated update method.

The generated code follows SQLC conventions correctly with proper parameter binding and error handling. The use of BuildsStatus type ensures type safety for status updates.

go/Makefile (2)

17-21: LGTM: Comprehensive full test setup.

The full test target properly sets up the integration test environment with appropriate timeouts and test options. Good use of tparse for better test output formatting.


23-24: LGTM: Efficient unit test configuration.

The unit test target uses appropriate flags for fast feedback with race detection and proper timeout settings.

go/pkg/db/version_update_status.sql_generated.go (1)

1-35: LGTM: Consistent SQLC-generated version update method.

The generated code follows the same pattern as the build status update, ensuring consistency across the codebase. Proper use of VersionsStatus type for type safety.

go/pkg/db/build_update_failed.sql_generated.go (2)

37-42: LGTM: Correct parameter usage for build failure update.

The dual use of arg.Now for both completed_at and updated_at is appropriate for failure scenarios where both timestamps should be set to the same value when the build fails.


13-20: LGTM: Well-designed failure update query.

The SQL query correctly sets the status to 'failed' and captures both completion time and error message, providing comprehensive failure tracking.

go/pkg/shutdown/shutdown.go (1)

200-251: Well-implemented signal handling with proper cleanup.

The WaitForSignal method provides a clean abstraction for graceful shutdown handling. The implementation properly:

  • Handles SIGINT and SIGTERM signals
  • Cleans up signal notifications with defer signal.Stop(sigChan)
  • Uses appropriate timeout defaults (30s) with override capability
  • Integrates seamlessly with the existing shutdown mechanism
  • Provides comprehensive documentation and examples

This reduces boilerplate code for server applications and maintains consistency with the existing shutdown pattern.

go/pkg/db/build_update_succeeded.sql_generated.go (1)

1-36: SQLC-generated query implementation looks correct.

The generated code properly updates build status to 'succeeded' with appropriate timestamp handling. The use of arg.Now for both completed_at and updated_at parameters is intentional and correct, ensuring both fields are set to the same timestamp value.

go/pkg/db/build_find_by_id.sql_generated.go (1)

1-71: SQLC-generated find query implementation is correct.

The generated code properly implements the find-by-id pattern with appropriate column selection and field scanning. The MySQL-specific backticks around the table name and the comprehensive field scanning into the Build struct follow sqlc best practices.

go/pkg/hydra/store/db.go (1)

1-27: Clean database abstraction layer supporting the SQLC migration.

The DBTX interface provides a solid foundation for database operations with proper context support. The abstraction works well with both *sql.DB and *sql.Tx, and the WithTx method enables seamless transaction handling while maintaining the interface contract.

This aligns with the planned migration from GORM to SQLC as mentioned in the retrieved learnings, providing type-safe database access with explicit SQL control.

go/pkg/hydra/store_test.go.bak (1)

16-24: Good migration to MySQL containers for testing.

The switch from SQLite to MySQL containers provides better test environment consistency with production. The use of containers.New(t) and containersClient.RunMySQL() ensures proper test isolation.

go/apps/api/run.go (1)

231-241: Shutdown refactoring looks good.

The migration to use the centralized shutdown utility simplifies the code and provides consistent shutdown behavior across services.

Makefile (1)

27-30: Add error handling for integration tests.

The integration target doesn't handle errors properly. If seeding fails, the tests might still run with invalid data.

 integration: up
-	@cd apps/api && \
-	$(MAKE) seed && \
-	pnpm test:integration
+	@cd apps/api && \
+	$(MAKE) seed || (echo "Seeding failed" && exit 1) && \
+	pnpm test:integration

Likely an incorrect or invalid review comment.

go/go.mod (2)

13-15: LGTM - Terminal UI dependencies added for new CLI features.

The addition of charmbracelet libraries (bubbles, bubbletea, lipgloss) aligns well with the PR's introduction of new CLI components and terminal UI features. These are mature, well-maintained libraries for building terminal applications.


44-44: golang.org/x/net v0.40.0 upgrade verified

Upgrade in go/go.mod at line 44 brings in all recent security patches (CVE fixes for XSS, HTTP proxy bypass, resource consumption, HTTP/2 memory growth, header-close issues) and the official release notes list no breaking changes.

• Location: go/go.mod, line 44
• No additional action required—v0.40.0 is safe to use.

go/pkg/db/version_insert.sql_generated.go (1)

1-107: LGTM - Well-structured SQLC generated code.

The generated code follows proper patterns:

  • Appropriate use of sql.NullString for nullable fields
  • json.RawMessage for JSON column handling
  • Custom VersionsStatus type for type safety
  • Proper use of DBTX interface for database abstraction
  • Context-aware database operations

This aligns well with the GORM to SQLC migration effort documented in the retrieved learnings.

deployment/docker-compose.yaml (4)

6-8: LGTM - Custom MySQL Dockerfile enables database initialization.

The change from using the stock mysql:8.0 image to building from a custom Dockerfile allows for proper database initialization with the required databases and user setup.


53-53: LGTM - Consistent command format.

The command format change from ["api"] to ["run", "api"] maintains consistency with the new ctrl service command format.


72-91: LGTM - Well-configured control plane service.

The new ctrl service is properly configured with:

  • Appropriate dependencies on mysql and otel
  • Correct port mapping (7091)
  • Required environment variables for database connections
  • Proper authentication token setup

90-90: Static analysis false positive - auth token is expected.

The static analysis warning about "Base64 High Entropy String" is a false positive. The UNKEY_AUTH_TOKEN environment variable is expected to contain a high-entropy authentication token for security purposes.

go/pkg/db/build_insert.sql_generated.go (2)

12-44: LGTM - Appropriate default values for initial build creation.

The SQL insert uses sensible default values for initial build creation:

  • status: 'pending' - reasonable initial state
  • build_tool: 'docker' - default build tool
  • NULL values for optional fields that will be populated later

This pattern supports creating builds in a pending state that can be updated as the build progresses.


46-52: LGTM - Minimal parameter struct for build creation.

The InsertBuildParams struct only includes the essential fields needed for initial build creation, with other fields set to defaults in the SQL. This is a clean approach that simplifies the API while ensuring required fields are populated.

go/pkg/hydra/migration_validation_test.go (1)

24-74: LGTM - Comprehensive SQLC integration validation.

The test effectively validates the SQLC migration by:

  • Verifying the Query singleton is accessible
  • Testing database connectivity through the new interface
  • Using reflection to ensure deprecated store methods are removed
  • Testing actual query execution with proper parameters

This provides good coverage for the migration validation requirements.

go/pkg/git/git.go (1)

1-121: Well-structured Git information extraction package.

The implementation is robust with proper error handling, sensible defaults, and comprehensive git state detection including detached HEAD scenarios.

go/cmd/ctrl/main.go (1)

1-170: Well-implemented CLI command with comprehensive configuration options.

The command properly handles TLS configuration validation, provides sensible defaults, and validates the configuration before starting the control plane service.

go/pkg/hydra/store/sqlc-queries-analysis.md (1)

357-401: Well-designed transactional lease acquisition pattern.

The SELECT FOR UPDATE with proper row locking and atomic upsert pattern effectively prevents race conditions in lease acquisition. This is a significant improvement over the GORM implementation.

go/apps/ctrl/run.go (1)

78-87: Good migration to DSN-based Hydra initialization.

The simplified Hydra engine initialization using DSN instead of requiring a pre-created store is a clean improvement that aligns with the SQLC migration strategy.

go/pkg/hydra/step.go (1)

75-84: Excellent OpenTelemetry tracing implementation.

The tracing span includes all relevant attributes (step name, workflow name, execution ID, namespace) which will greatly aid in debugging and monitoring.

go/pkg/hydra/MIGRATION_PROGRESS.md (1)

26-35: Excellent security improvements with size limits.

Using VARBINARY with explicit size limits (10MB for inputs, 1MB for outputs) instead of LONGBLOB is a crucial security improvement that prevents DoS attacks through unbounded data growth.

go/pkg/hydra/worker.go (1)

328-619: Excellent migration to SQLC with enhanced correctness guarantees.

The refactored executeWorkflow method demonstrates best practices:

  • Comprehensive OpenTelemetry tracing with proper span context propagation
  • Lease-validated database operations ensuring correctness under concurrent execution
  • Proper error handling and logging at each step
  • Transaction support where needed

The implementation correctly handles workflow lifecycle transitions while preventing race conditions through lease validation.

go/pkg/hydra/test_helpers.go (1)

18-77: Well-executed test helper migration to SQLC.

The test helpers have been properly updated to:

  • Use direct SQL connections instead of GORM
  • Generate unique namespaces for test isolation
  • Use the new SQLC query interface consistently
  • Handle errors appropriately

The implementation aligns perfectly with the broader SQLC migration.

go/pkg/hydra/workflow.go (1)

213-257: Well-implemented tracing integration with comprehensive attribute tracking.

The tracing implementation properly:

  • Creates spans with descriptive names
  • Records all relevant attributes (workflow name, execution ID, namespace, worker ID)
  • Handles error recording at appropriate points
  • Sets workflow status attributes based on execution outcome
  • Properly propagates the traced context to the wrapped workflow
go/apps/ctrl/services/version/deploy_workflow.go (1)

143-256: No additional polling timeout needed – workflow timeout already applies

The create_version.go workflow is started with hydra.WithTimeout(25*time.Minute), so the context passed into the “wait-for-completion” step will be cancelled automatically after 25 minutes. Adding a separate time.Timer inside the polling loop would be redundant. If you need a shorter build‐poll timeout, consider one of the following instead:

  • Use context.WithTimeout(stepCtx, <shorterDuration>) within the step to enforce a sub-limit.
  • Adjust the hydra.WithTimeout(…) value in go/apps/ctrl/services/version/create_version.go to your desired maximum build-wait time.

Relevant locations:

  • go/apps/ctrl/services/version/create_version.go (workflow started with hydra.WithTimeout(25*time.Minute))
  • go/apps/ctrl/services/version/deploy_workflow.go (polling loop in Step "wait-for-completion")

Likely an incorrect or invalid review comment.

go/pkg/cli/deployment_display.go (1)

23-89: Excellent thread-safety implementation with proper mutex usage.

The implementation correctly uses sync.RWMutex to protect shared state, with appropriate read locks for read operations and write locks for modifications. The mutex is properly acquired and released in all methods that access shared data.

go/pkg/hydra/store/schema.sql (1)

5-6: Review BLOB size for input_data in schema.sql

I didn’t find any size validations for input_data in the generated Go code (workflows.sql.go), so this column will accept up to 4 GB by default. Please confirm your typical payload sizes—if input blobs never exceed 16 MB, switching to MEDIUMBLOB can reduce storage and memory overhead.

• File: go/pkg/hydra/store/schema.sql (lines 5–6)

    input_data LONGBLOB,   -- Large binary data for workflow inputs
    output_data MEDIUMBLOB -- Medium binary data for workflow outputs
go/pkg/hydra/MIGRATION_BEST_PRACTICES.md (1)

55-121: Excellent code quality patterns for SQLC migration.

The type conversion helpers and consistent error handling patterns provide a solid foundation for the migration. The transaction support implementation with proper rollback handling is particularly well done.

go/pkg/hydra/engine.go (3)

27-49: Good migration from Store interface to DSN-based configuration.

The change aligns with the SQLC migration strategy, and the documentation clearly explains the purpose of each field.


101-156: Excellent constructor implementation with robust error handling.

The retry logic with exponential backoff ensures database availability, and the validation ensures all required fields are provided. The connection testing with ping is a good practice.


184-204: Correct implementation using SQLC query pattern.

The method properly uses nullable types for optional fields and follows the new query pattern established by the migration.

go/cmd/version/main.go (1)

209-312: Well-implemented Docker build and push operations.

The implementation properly captures output for debugging, handles errors gracefully, and provides clear feedback to users. The streaming output display is particularly user-friendly.

go/pkg/db/querier_generated.go (1)

86-1058: Generated SQLC queries align with new features.

The new query methods for builds and versions follow consistent patterns and support the version management features introduced in this PR. The addition of partition_id to workspace queries maintains consistency with the updated schema.

go/pkg/hydra/store/querier.go (1)

11-41: Well-designed SQLC interface for workflow management.

The Querier interface provides comprehensive coverage of workflow operations with consistent method signatures. The type assertion on line 41 ensures compile-time verification that the generated Queries struct implements this interface correctly.

go/pkg/hydra/store/queries/workflows.sql (2)

1-189: Well-structured SQL queries with good patterns.

The queries demonstrate good practices:

  • Consistent use of parameterized queries preventing SQL injection
  • Proper multi-tenancy with namespace filtering
  • Smart use of COALESCE for partial updates
  • Appropriate transaction boundaries for lease management

41-57: Lease validation parameters are correctly ordered

Verified that the generated UpdateWorkflowFieldsParams struct fields (ResourceID, WorkerID, ExpiresAt) and their binding in the ExecContext call exactly match the SQL placeholders for resource_id, worker_id, and expires_at. No changes required.

go/pkg/db/schema.sql (1)

16-26: Redundant unique constraint in keys_permissions table.

The UNIQUE constraint on (key_id, permission_id) is redundant since the PRIMARY KEY already includes these columns, ensuring their uniqueness.

Remove the redundant constraint:

 	CONSTRAINT `keys_permissions_key_id_permission_id_workspace_id` PRIMARY KEY(`key_id`,`permission_id`,`workspace_id`),
 	CONSTRAINT `keys_permissions_temp_id_unique` UNIQUE(`temp_id`),
-	CONSTRAINT `key_id_permission_id_idx` UNIQUE(`key_id`,`permission_id`)

Likely an incorrect or invalid review comment.

go/pkg/db/models_generated.go (1)

1-847: Well-generated SQLC models with proper type safety.

The generated models correctly implement:

  • Scanner interface for database deserialization
  • Valuer interface for nullable types
  • Proper struct tags for database and JSON serialization
  • New domain models (Build, Version, Partition, etc.) align with the schema changes
go/pkg/hydra/store/workflows.sql.go (1)

800-827: Verify the use case for updateStepStatus without lease verification

This method updates step status without verifying lease ownership, unlike updateStepStatusWithLease. This could lead to race conditions or unauthorized updates if not used carefully.

Please verify that this method is only used in scenarios where lease verification is not required (e.g., system operations, cleanup tasks). Consider adding documentation to clarify when to use this method vs. updateStepStatusWithLease.

Comment on lines +1 to +2
.PHONY: install fmt test build race lint generate

Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Missing standard phony entry points (all, clean).

checkmake rightfully flags the absence of all and clean targets. Including them keeps the interface of all repo Makefiles uniform and prevents CI jobs or local scripts that expect these targets from breaking.

-.PHONY: install fmt test build race lint generate
+.PHONY: all clean install fmt test build race lint generate
+
+# Default target
+all: build
+
+# Remove build artefacts
+clean:
+	@rm -f unkey
📝 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
.PHONY: install fmt test build race lint generate
.PHONY: all clean install fmt test build race lint generate
# Default target
all: build
# Remove build artefacts
clean:
@rm -f unkey
🧰 Tools
🪛 checkmake (0.2.2)

[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)

🤖 Prompt for AI Agents
In apps/agent/Makefile at lines 1 to 2, add standard phony targets `all` and
`clean` to the .PHONY declaration and define these targets. The `all` target
should typically depend on the main build or install targets, and the `clean`
target should remove generated files or build artifacts. This will align the
Makefile with repo conventions and prevent CI or scripts from failing due to
missing these common targets.

Comment on lines +22 to +26
generate:
go get github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen
mkdir -p ./pkg/openapi
go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=./pkg/openapi/config.yaml ./pkg/openapi/openapi.json
buf generate No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

go get mutates go.mod; switch to version-pinned go install.

Since Go 1.20 go get in build scripts is deprecated and pollutes the module graph. Use go install <pkg>@<version> for reproducible builds.

-	go get github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen
+	go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@v2.8.0
🤖 Prompt for AI Agents
In apps/agent/Makefile around lines 22 to 26, replace the use of 'go get' with
'go install' including a specific version suffix to avoid mutating go.mod and
ensure reproducible builds. Change the command to 'go install
github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@<version>' where
<version> is the desired version tag or commit hash.

Comment on lines +9 to +11
test:
go test -cover -json -failfast ./... | tparse -all -progress

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

tparse is required but never installed – tests will fail on fresh machines.

Either vendor tparse in the repo or add an explicit go install before use to avoid “command not found”.

test: | tools
	go test -cover -json -failfast ./... | tparse -all -progress

+# Ensure helpers are present
+tools:
+	go install github.com/mfridman/tparse@latest
🤖 Prompt for AI Agents
In apps/agent/Makefile around lines 9 to 11, the test target uses the `tparse`
command which is not guaranteed to be installed on fresh machines, causing test
failures. Fix this by adding a step before running tests to explicitly install
`tparse` using `go install` or by vendoring `tparse` in the repository to ensure
it is always available when running tests.

Comment on lines +15 to +18
race:
go install github.com/amit-davidson/Chronos/cmd/chronos
~/go/bin/chronos --file=./cmd/main.go --mod=$$(pwd)

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Hard-coded ~/go/bin breaks for users with a custom GOPATH.

Derive the bin path from go env GOPATH instead of assuming ~/go.

-	~/go/bin/chronos --file=./cmd/main.go --mod=$$(pwd)
+	$$(go env GOPATH)/bin/chronos --file=./cmd/main.go --mod=$$(pwd)
📝 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
race:
go install github.com/amit-davidson/Chronos/cmd/chronos
~/go/bin/chronos --file=./cmd/main.go --mod=$$(pwd)
race:
go install github.com/amit-davidson/Chronos/cmd/chronos
$$(go env GOPATH)/bin/chronos --file=./cmd/main.go --mod=$$(pwd)
🤖 Prompt for AI Agents
In apps/agent/Makefile around lines 15 to 18, the path to the chronos binary is
hard-coded as ~/go/bin, which fails for users with a custom GOPATH. Replace the
hard-coded path with a dynamic one by using the output of `go env GOPATH` to
construct the binary path, ensuring it works regardless of the user's GOPATH
configuration.

Comment on lines +1 to +7
-- name: UpdateBuildFailed :exec
UPDATE builds SET
status = 'failed',
completed_at = sqlc.arg(now),
error_message = sqlc.arg(error_message),
updated_at = sqlc.arg(now)
WHERE id = sqlc.arg(id); No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider parameterizing the status value for consistency.

The query hardcodes the status value as 'failed' while other similar queries in the codebase use parameters. For consistency and flexibility, consider making the status value a parameter.

-- name: UpdateBuildFailed :exec
UPDATE builds SET 
-    status = 'failed',
+    status = sqlc.arg(status),
    completed_at = sqlc.arg(now),
    error_message = sqlc.arg(error_message),
    updated_at = sqlc.arg(now)
WHERE id = sqlc.arg(id);
📝 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
-- name: UpdateBuildFailed :exec
UPDATE builds SET
status = 'failed',
completed_at = sqlc.arg(now),
error_message = sqlc.arg(error_message),
updated_at = sqlc.arg(now)
WHERE id = sqlc.arg(id);
-- name: UpdateBuildFailed :exec
UPDATE builds SET
status = sqlc.arg(status),
completed_at = sqlc.arg(now),
error_message = sqlc.arg(error_message),
updated_at = sqlc.arg(now)
WHERE id = sqlc.arg(id);
🤖 Prompt for AI Agents
In go/pkg/db/queries/build_update_failed.sql lines 1 to 7, the status value is
hardcoded as 'failed' in the UPDATE statement. To maintain consistency with
other queries and improve flexibility, change the status assignment to use a
parameter instead of a fixed string. Replace the hardcoded 'failed' with
sqlc.arg(status) and ensure the corresponding parameter is passed when executing
the query.

Comment on lines +119 to 126
// Check if the step creation actually happened (lease validation)
rowsAffected, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("failed to create sleep step: %w", err)
return fmt.Errorf("failed to check step creation result: %w", err)
}
if rowsAffected == 0 {
return fmt.Errorf("sleep step creation failed: lease expired or invalid")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Error messages may leak implementation details.

The error messages expose internal implementation details about lease validation. Consider using more generic error messages for security.

-		return fmt.Errorf("sleep step creation failed: lease expired or invalid")
+		return fmt.Errorf("unable to create sleep step: operation not permitted")
📝 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
// Check if the step creation actually happened (lease validation)
rowsAffected, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("failed to create sleep step: %w", err)
return fmt.Errorf("failed to check step creation result: %w", err)
}
if rowsAffected == 0 {
return fmt.Errorf("sleep step creation failed: lease expired or invalid")
}
// Check if the step creation actually happened (lease validation)
rowsAffected, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("failed to check step creation result: %w", err)
}
if rowsAffected == 0 {
return fmt.Errorf("unable to create sleep step: operation not permitted")
}
🤖 Prompt for AI Agents
In go/pkg/hydra/sleep.go around lines 119 to 126, the error messages reveal
internal details about lease validation which could be a security risk. Replace
the specific error messages with more generic ones that do not expose
implementation details, such as using a general failure message like "sleep step
creation failed" without mentioning lease expiration or validation specifics.

Comment on lines +88 to +114
result, err := wctx.db.ExecContext(wctx.ctx, `
INSERT INTO workflow_steps (
id, execution_id, step_name, status, output_data, error_message,
started_at, completed_at, max_attempts, remaining_attempts, namespace
)
SELECT ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?
WHERE EXISTS (
SELECT 1 FROM leases
WHERE resource_id = ? AND kind = 'workflow'
AND worker_id = ? AND expires_at > ?
)`,
stepID,
wctx.ExecutionID(),
stepName,
store.WorkflowStepsStatusRunning,
[]byte{},
sql.NullString{String: "", Valid: false},
sql.NullInt64{Int64: now, Valid: true},
sql.NullInt64{Int64: 0, Valid: false},
1, // Sleep doesn't need retries
1,
wctx.namespace,
wctx.ExecutionID(), // resource_id for lease check
wctx.workerID, // worker_id for lease check
now, // expires_at check
)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential SQL injection risk with direct query construction.

While the code uses parameterized queries which generally protect against SQL injection, constructing complex SQL statements directly is risky. Consider using the SQLC-generated queries consistently instead of raw SQL for better maintainability and type safety.

-	result, err := wctx.db.ExecContext(wctx.ctx, `
-		INSERT INTO workflow_steps (
-		    id, execution_id, step_name, status, output_data, error_message,
-		    started_at, completed_at, max_attempts, remaining_attempts, namespace
-		) 
-		SELECT ?, ?, ?, ?, ?, ?,
-		       ?, ?, ?, ?, ?
-		WHERE EXISTS (
-		    SELECT 1 FROM leases 
-		    WHERE resource_id = ? AND kind = 'workflow' 
-		    AND worker_id = ? AND expires_at > ?
-		)`,
+	// Use SQLC-generated query for type safety and consistency
+	result, err := store.Query.CreateStepWithLeaseCheck(wctx.ctx, wctx.db, store.CreateStepWithLeaseCheckParams{
+		ID:                stepID,
+		ExecutionID:       wctx.ExecutionID(),
+		StepName:          stepName,
+		Status:            store.WorkflowStepsStatusRunning,
+		OutputData:        []byte{},
+		ErrorMessage:      sql.NullString{String: "", Valid: false},
+		StartedAt:         sql.NullInt64{Int64: now, Valid: true},
+		CompletedAt:       sql.NullInt64{Int64: 0, Valid: false},
+		MaxAttempts:       1,
+		RemainingAttempts: 1,
+		Namespace:         wctx.namespace,
+		LeaseResourceID:   wctx.ExecutionID(),
+		LeaseWorkerID:     wctx.workerID,
+		LeaseExpiresAt:    now,
+	})

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In go/pkg/hydra/sleep.go around lines 88 to 114, the raw SQL query for inserting
workflow steps poses a potential SQL injection risk and reduces maintainability.
Refactor this code to use the SQLC-generated query methods instead of
constructing the SQL string directly. This will ensure parameterization, improve
type safety, and align with the project's database access patterns.

Comment on lines +64 to +77
**SQL Equivalent**:
```sql
SELECT * FROM workflow_executions
WHERE namespace = ?
AND (
status = 'pending'
OR (status = 'failed' AND next_retry_at <= ?)
OR (status = 'sleeping' AND sleep_until <= ?)
)
AND (? = 0 OR workflow_name = ANY(?)) -- Optional workflow name filter
ORDER BY created_at ASC
LIMIT ? OFFSET ?
```
**Performance Critical**: This is the hottest query path - needs optimal indexing
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Critical performance optimization needed for hot path query.

The GetPendingWorkflows query is identified as the most critical for performance but the optional workflow name filter uses ANY(?) which may not be optimized well by MySQL. Consider using IN clause or separate queries.


🌐 Web query:

What is the most efficient way to handle optional array filters in MySQL queries for performance-critical paths?

💡 Result:

The most efficient way to handle optional array filters in MySQL for performance-critical paths is to dynamically construct your WHERE clause to include only the filters provided, rather than relying on static queries with null checks or using patterns like (? IS NULL OR col = ?) for each parameter. This targeted approach ensures the query optimizer can leverage indexes effectively and reduces unnecessary full table scans.

Key strategies:

  • Dynamic Query Construction: Build your SQL query in your application code so that only relevant filters are included in the WHERE clause when their corresponding parameters are present. This avoids the common pitfall of writing a single query with multiple OR clauses or null checks, which can prevent MySQL from using indexes efficiently[3][4].
  • Indexing: Ensure that your filtered columns (those that might be queried frequently) are indexed properly. For multi-column filters, consider composite indexes that mirror your most common filtering patterns[5][8].
  • Avoid Patterns That Hinder Index Usage: Patterns such as (? IS NULL OR col = ?) can seem convenient but often lead to poor query performance because they make it difficult for MySQL to select and utilize indexes optimally[4][8]. Use these only for very small tables or low-traffic queries.
  • Limit Data Early: Always apply filters as early as possible in your query, before operations like ORDER BY or JOIN. This reduces the number of rows processed, scanned, or sorted[6][8].

Example: Dynamic Query Assembly

Suppose you have optional filters on category, status, and start_date. Instead of:

SELECT * FROM items
WHERE (? IS NULL OR category = ?)
  AND (? IS NULL OR status = ?)
  AND (? IS NULL OR created_at >= ?)

which can degrade performance due to poor index usage,

Dynamically generate the WHERE clause:

SELECT * FROM items
WHERE 1=1

Then, in your application code, append each filter only if its value is set:

  • If category is provided: add AND category = ?
  • If status is provided: add AND status = ?
  • If start_date is provided: add AND created_at >= ?

Prepare statements accordingly. This approach keeps the query optimizer effective and leverages indexes optimally[3][4].

Additional Performance Tips

  • Use EXPLAIN: Analyze your query plans to ensure indexes are being used as expected[5][8].
  • Use LIMIT and selected columns: Retrieve only what is needed, and limit the result set for large tables[5][8].
  • Partitioning: For very large tables and range queries (like dates), table partitioning may further improve performance, especially when combined with the above dynamic filtering[2].

In summary:
For best performance in MySQL when dealing with optional array filters, generate queries dynamically to include only the necessary WHERE clauses, ensure proper indexing, and avoid constructs that disable index usage. Apply filters early and always validate with EXPLAIN to confirm your optimizations are effective[3][4][5][8].

Citations:


Optimize hot‐path GetPendingWorkflows SQL by dynamically assembling the workflow_name filter

Using a static

AND (? = 0 OR workflow_name = ANY(?))

pattern can prevent MySQL’s optimizer from using indexes effectively. Instead, only include a workflow_name IN (…) clause when you actually have names to filter on. You can achieve this by:

• Generating two SQLC queries (one with the filter, one without)
• Or assembling the WHERE clause in your Go code at runtime and appending
AND workflow_name IN (?) only if the slice is non‐empty

Also ensure you have an index on workflow_name (or a composite index on (namespace, workflow_name, status, created_at)) and validate with EXPLAIN that your new query plan uses it.

Locations to update:

  • go/pkg/hydra/store/sqlc-queries-analysis.md (lines 64–77) – revise the example to show dynamic filter inclusion or separate queries
  • The actual SQLC query definition or Go function that executes GetPendingWorkflows – implement the conditional filter instead of ANY(?)
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

65-65: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


76-76: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
In go/pkg/hydra/store/sqlc-queries-analysis.md lines 64 to 77, update the SQL
example to remove the static "AND (? = 0 OR workflow_name = ANY(?))" filter and
instead show how to dynamically include "AND workflow_name IN (...)" only when
the workflow_name slice is non-empty. Then, in the Go code or SQLC query
definition for GetPendingWorkflows, implement this conditional filter logic by
either creating two separate queries (one with and one without the workflow_name
filter) or by assembling the WHERE clause at runtime to append the filter only
if needed. Also ensure appropriate indexing on workflow_name or a composite
index including namespace, workflow_name, status, and created_at, and verify the
query plan uses the index with EXPLAIN.

Comment on lines +130 to +145
h2cHandler := h2c.NewHandler(mux, &http2.Server{
MaxHandlers: 0,
MaxConcurrentStreams: 0,
MaxDecoderHeaderTableSize: 0,
MaxEncoderHeaderTableSize: 0,
MaxReadFrameSize: 0,
PermitProhibitedCipherSuites: false,
IdleTimeout: 0,
ReadIdleTimeout: 0,
PingTimeout: 0,
WriteByteTimeout: 0,
MaxUploadBufferPerConnection: 0,
MaxUploadBufferPerStream: 0,
NewWriteScheduler: nil,
CountError: nil,
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Simplify HTTP/2 server configuration.

Most fields are set to their zero values. Consider only setting non-default values for cleaner code.

-	h2cHandler := h2c.NewHandler(mux, &http2.Server{
-		MaxHandlers:                  0,
-		MaxConcurrentStreams:         0,
-		MaxDecoderHeaderTableSize:    0,
-		MaxEncoderHeaderTableSize:    0,
-		MaxReadFrameSize:             0,
-		PermitProhibitedCipherSuites: false,
-		IdleTimeout:                  0,
-		ReadIdleTimeout:              0,
-		PingTimeout:                  0,
-		WriteByteTimeout:             0,
-		MaxUploadBufferPerConnection: 0,
-		MaxUploadBufferPerStream:     0,
-		NewWriteScheduler:            nil,
-		CountError:                   nil,
-	})
+	h2cHandler := h2c.NewHandler(mux, &http2.Server{})
📝 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
h2cHandler := h2c.NewHandler(mux, &http2.Server{
MaxHandlers: 0,
MaxConcurrentStreams: 0,
MaxDecoderHeaderTableSize: 0,
MaxEncoderHeaderTableSize: 0,
MaxReadFrameSize: 0,
PermitProhibitedCipherSuites: false,
IdleTimeout: 0,
ReadIdleTimeout: 0,
PingTimeout: 0,
WriteByteTimeout: 0,
MaxUploadBufferPerConnection: 0,
MaxUploadBufferPerStream: 0,
NewWriteScheduler: nil,
CountError: nil,
})
h2cHandler := h2c.NewHandler(mux, &http2.Server{})
🤖 Prompt for AI Agents
In go/apps/ctrl/run.go around lines 130 to 145, the http2.Server struct is being
initialized with many fields explicitly set to their zero values, which is
unnecessary. Simplify the code by removing all fields that are set to zero or
nil, and only specify fields that need non-default values. This will make the
code cleaner and easier to maintain.

Comment on lines +160 to +175
### Immediate Next Tasks
1. **Generate SQLC Code**:
```bash
cd store && go generate
```

2. **Implement First SQLC Query**: Start with simple read operation like `GetWorkflow`
- Implement SQLC version in `store/sqlc_store.go`
- Add feature flag or method to switch between stores
- Write comparison tests to ensure identical behavior

3. **Add Migration Testing**:
- Create tests that call both GORM and SQLC versions
- Verify identical results and performance characteristics
- Establish benchmarks for comparison

Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Clear migration roadmap with actionable next steps.

The phased migration approach starting with read operations is a safe strategy. The immediate next tasks are well-defined.

Would you like me to help generate the SQLC queries for the initial read operations (GetWorkflow, GetStep, GetLease, GetCronJob) to kickstart Phase 1 of the migration?

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

160-160: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


161-161: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


162-162: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
In go/pkg/hydra/MIGRATION_PROGRESS.md around lines 160 to 175, the roadmap
outlines next steps for migrating to SQLC with initial read operations. To
proceed, generate SQLC queries for the initial read operations GetWorkflow,
GetStep, GetLease, and GetCronJob. Create corresponding SQL query files and
update the store/sqlc_store.go with the generated code. This will enable
implementing the first SQLC queries and facilitate comparison testing as
planned.

Copy link
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.

Review continued from previous batch...

Comment on lines +40 to +42
for i := 0; i < s.maxLines+2; i++ {
fmt.Println()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider checking terminal dimensions before clearing lines.

Printing a fixed number of empty lines assumes the terminal has sufficient height. This could cause display issues on smaller terminals.

Consider querying terminal size first:

 func (s *StreamingOutput) Start() {
-	// Clear the lines we'll be using
-	for i := 0; i < s.maxLines+2; i++ {
-		fmt.Println()
-	}
+	// Clear the lines we'll be using, but ensure we don't exceed terminal height
+	// You may want to use a terminal size library like golang.org/x/term
+	linesToClear := s.maxLines + 2
+	for i := 0; i < linesToClear; i++ {
+		fmt.Println()
+	}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In go/pkg/cli/output.go around lines 40 to 42, the code prints a fixed number of
empty lines without checking terminal height, which may cause display issues on
small terminals. Modify the code to first query the terminal dimensions and then
print only as many empty lines as the terminal height allows, ensuring it does
not exceed the terminal's visible area.

Comment on lines +113 to +117
if final {
fmt.Printf("%s %s\033[K\n", spinner, s.title)
} else {
fmt.Printf("%s %s\033[K\n", spinner, s.title)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove redundant conditional logic.

Both branches of the conditional execute identical code.

 	// Title line
-	if final {
-		fmt.Printf("%s %s\033[K\n", spinner, s.title)
-	} else {
-		fmt.Printf("%s %s\033[K\n", spinner, s.title)
-	}
+	fmt.Printf("%s %s\033[K\n", spinner, s.title)
📝 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
if final {
fmt.Printf("%s %s\033[K\n", spinner, s.title)
} else {
fmt.Printf("%s %s\033[K\n", spinner, s.title)
}
// Title line
fmt.Printf("%s %s\033[K\n", spinner, s.title)
🤖 Prompt for AI Agents
In go/pkg/cli/output.go around lines 113 to 117, the if-else conditional is
redundant because both branches execute the same fmt.Printf statement. Remove
the if-else structure entirely and keep only a single call to fmt.Printf with
the given arguments to simplify the code.

Comment on lines +99 to +102
func (s *StreamingOutput) Stop() {
close(s.done)
time.Sleep(150 * time.Millisecond) // Let final render complete
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Protect against multiple Stop() calls and document the sleep duration.

Calling Stop() multiple times will panic on the second call due to closing an already closed channel. The 150ms sleep duration should be documented.

+var stopOnce sync.Once
+
 // Stop stops the display and shows final state
 func (s *StreamingOutput) Stop() {
-	close(s.done)
-	time.Sleep(150 * time.Millisecond) // Let final render complete
+	stopOnce.Do(func() {
+		close(s.done)
+		// Sleep briefly to allow the final render to complete
+		// This ensures the checkmark is displayed before returning
+		time.Sleep(150 * time.Millisecond)
+	})
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In go/pkg/cli/output.go around lines 99 to 102, the Stop() method closes the
done channel without protection, causing a panic if called multiple times. Add a
mechanism to ensure the done channel is only closed once, such as using a
sync.Once or a boolean flag with a mutex. Also, add a comment explaining the
reason for the 150ms sleep duration to clarify its purpose for letting the final
render complete.

Comment on lines +218 to +234
func stripANSI(str string) string {
// Simple ANSI stripping - you might want a more robust solution
var result strings.Builder
inEscape := false

for _, ch := range str {
if ch == '\033' {
inEscape = true
} else if inEscape && ch == 'm' {
inEscape = false
} else if !inEscape {
result.WriteRune(ch)
}
}

return result.String()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider using a robust ANSI stripping solution.

The current implementation only handles color codes ending with 'm' and will miss cursor movement, line clearing, and other ANSI sequences.

Consider using a well-tested library like github.com/acarl005/stripansi or a regex-based solution:

import "regexp"

var ansiRegex = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`)

func stripANSI(str string) string {
    return ansiRegex.ReplaceAllString(str, "")
}
🤖 Prompt for AI Agents
In go/pkg/cli/bubbletea.go around lines 218 to 234, the current stripANSI
function only removes ANSI color codes ending with 'm' and misses other ANSI
sequences like cursor movements and line clearing. Replace the manual parsing
with a more robust solution by importing "regexp", defining a regex pattern that
matches all ANSI escape sequences, and using it to remove these sequences from
the input string. This will ensure all ANSI codes are properly stripped.

Comment on lines +193 to +215
func cleanDockerOutput(line string) string {
line = strings.TrimSpace(line)

// Remove ANSI escape codes
line = stripANSI(line)

// Skip empty lines
if line == "" {
return ""
}

// Skip certain Docker output that's just noise
if strings.HasPrefix(line, "#") && len(line) < 5 {
return ""
}

// Shorten long lines
if len(line) > 76 {
line = line[:73] + "..."
}

return line
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Rename function to reflect generic usage.

The function cleanDockerOutput is Docker-specific in name but used for all command output. Consider renaming it to be more generic.

-// cleanDockerOutput cleans up Docker build output for better display
-func cleanDockerOutput(line string) string {
+// cleanCommandOutput cleans up command output for better display
+func cleanCommandOutput(line string) string {

Also update the call site:

-			line = cleanDockerOutput(line)
+			line = cleanCommandOutput(line)

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In go/pkg/cli/bubbletea.go around lines 193 to 215, the function
cleanDockerOutput is named specifically for Docker output but is used for
general command output. Rename the function to a more generic name like
cleanCommandOutput and update all call sites accordingly to reflect its broader
usage.

Comment on lines +452 to +519
const getPendingWorkflowsFiltered = `-- name: GetPendingWorkflowsFiltered :many
SELECT id, workflow_name, status, input_data, output_data, error_message, created_at, started_at, completed_at, max_attempts, remaining_attempts, next_retry_at, namespace, trigger_type, trigger_source, sleep_until, trace_id, span_id FROM workflow_executions
WHERE namespace = ?
AND (
status = 'pending'
OR (status = 'failed' AND next_retry_at <= ?)
OR (status = 'sleeping' AND sleep_until <= ?)
)
AND workflow_name IN (/*SLICE:workflow_names*/?)
ORDER BY created_at ASC
LIMIT ?
`

type GetPendingWorkflowsFilteredParams struct {
Namespace string `db:"namespace" json:"namespace"`
NextRetryAt sql.NullInt64 `db:"next_retry_at" json:"next_retry_at"`
SleepUntil sql.NullInt64 `db:"sleep_until" json:"sleep_until"`
WorkflowName string `db:"workflow_name" json:"workflow_name"`
Limit int32 `db:"limit" json:"limit"`
}

func (q *Queries) GetPendingWorkflowsFiltered(ctx context.Context, db DBTX, arg GetPendingWorkflowsFilteredParams) ([]WorkflowExecution, error) {
rows, err := db.QueryContext(ctx, getPendingWorkflowsFiltered,
arg.Namespace,
arg.NextRetryAt,
arg.SleepUntil,
arg.WorkflowName,
arg.Limit,
)
if err != nil {
return nil, err
}
defer rows.Close()
items := []WorkflowExecution{}
for rows.Next() {
var i WorkflowExecution
if err := rows.Scan(
&i.ID,
&i.WorkflowName,
&i.Status,
&i.InputData,
&i.OutputData,
&i.ErrorMessage,
&i.CreatedAt,
&i.StartedAt,
&i.CompletedAt,
&i.MaxAttempts,
&i.RemainingAttempts,
&i.NextRetryAt,
&i.Namespace,
&i.TriggerType,
&i.TriggerSource,
&i.SleepUntil,
&i.TraceID,
&i.SpanID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Parameter type mismatch for workflow name filtering

The SQL query at line 460 expects a slice of workflow names (/*SLICE:workflow_names*/) but the generated params struct only has a single WorkflowName string field. This limits the query to filtering by only one workflow name instead of multiple.

The underlying SQL query definition needs to be corrected to either:

  1. Accept a slice parameter properly, or
  2. Remove the SLICE annotation if only single workflow filtering is intended

Since this is generated code, please fix the underlying SQL query in the workflows.sql file.

🤖 Prompt for AI Agents
In go/pkg/hydra/store/workflows.sql.go around lines 452 to 519, the SQL query
expects a slice of workflow names for filtering (indicated by
/*SLICE:workflow_names*/), but the params struct defines only a single string
field WorkflowName. To fix this, update the underlying SQL query in the
workflows.sql file to correctly accept a slice parameter for workflow names, and
regenerate the code so the params struct uses a slice type (e.g., []string) for
workflow names instead of a single string. Alternatively, if only single
workflow filtering is intended, remove the SLICE annotation from the SQL query
to match the single string parameter.

Comment on lines +361 to +384
const getLease = `-- name: GetLease :one
SELECT resource_id, kind, namespace, worker_id, acquired_at, expires_at, heartbeat_at FROM leases
WHERE resource_id = ? AND kind = ?
`

type GetLeaseParams struct {
ResourceID string `db:"resource_id" json:"resource_id"`
Kind LeasesKind `db:"kind" json:"kind"`
}

func (q *Queries) GetLease(ctx context.Context, db DBTX, arg GetLeaseParams) (Lease, error) {
row := db.QueryRowContext(ctx, getLease, arg.ResourceID, arg.Kind)
var i Lease
err := row.Scan(
&i.ResourceID,
&i.Kind,
&i.Namespace,
&i.WorkerID,
&i.AcquiredAt,
&i.ExpiresAt,
&i.HeartbeatAt,
)
return i, err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: Missing namespace filtering in getLease query

The query retrieves leases without filtering by namespace, which could allow cross-namespace access and break multi-tenancy isolation. This is a security vulnerability.

The SQL query should include namespace filtering:

SELECT ... FROM leases 
WHERE resource_id = ? AND kind = ? AND namespace = ?

Since this is generated code, please fix the underlying SQL query in the workflows.sql file.

🤖 Prompt for AI Agents
In go/pkg/hydra/store/workflows.sql.go around lines 361 to 384, the GetLease SQL
query lacks filtering by namespace, risking cross-namespace data access. To fix
this, update the underlying SQL query in the workflows.sql file to add "AND
namespace = ?" to the WHERE clause. Then regenerate the Go code so the
GetLeaseParams struct includes Namespace and the query uses it as a parameter to
ensure proper multi-tenancy isolation.

Comment on lines +640 to +661
const heartbeatLease = `-- name: HeartbeatLease :exec
UPDATE leases
SET heartbeat_at = ?, expires_at = ?
WHERE resource_id = ? AND worker_id = ?
`

type HeartbeatLeaseParams struct {
HeartbeatAt int64 `db:"heartbeat_at" json:"heartbeat_at"`
ExpiresAt int64 `db:"expires_at" json:"expires_at"`
ResourceID string `db:"resource_id" json:"resource_id"`
WorkerID string `db:"worker_id" json:"worker_id"`
}

func (q *Queries) HeartbeatLease(ctx context.Context, db DBTX, arg HeartbeatLeaseParams) error {
_, err := db.ExecContext(ctx, heartbeatLease,
arg.HeartbeatAt,
arg.ExpiresAt,
arg.ResourceID,
arg.WorkerID,
)
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: Missing namespace filtering in heartbeatLease query

The query updates leases without filtering by namespace, potentially allowing cross-namespace lease manipulation.

The SQL query should include namespace filtering:

UPDATE leases 
SET heartbeat_at = ?, expires_at = ?
WHERE resource_id = ? AND worker_id = ? AND namespace = ?

Since this is generated code, please fix the underlying SQL query in the workflows.sql file.

🤖 Prompt for AI Agents
In go/pkg/hydra/store/workflows.sql.go lines 640 to 661, the HeartbeatLease SQL
query lacks filtering by namespace, which risks cross-namespace lease updates.
To fix this, update the underlying SQL query in the workflows.sql file to add
"AND namespace = ?" in the WHERE clause, and extend the HeartbeatLeaseParams
struct and the HeartbeatLease function to accept and pass the namespace
parameter accordingly.

Comment on lines +663 to +676
const releaseLease = `-- name: ReleaseLease :exec
DELETE FROM leases
WHERE resource_id = ? AND worker_id = ?
`

type ReleaseLeaseParams struct {
ResourceID string `db:"resource_id" json:"resource_id"`
WorkerID string `db:"worker_id" json:"worker_id"`
}

func (q *Queries) ReleaseLease(ctx context.Context, db DBTX, arg ReleaseLeaseParams) error {
_, err := db.ExecContext(ctx, releaseLease, arg.ResourceID, arg.WorkerID)
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: Missing namespace filtering in releaseLease query

The query deletes leases without filtering by namespace, potentially allowing cross-namespace lease manipulation.

The SQL query should include namespace filtering:

DELETE FROM leases 
WHERE resource_id = ? AND worker_id = ? AND namespace = ?

Since this is generated code, please fix the underlying SQL query in the workflows.sql file.

🤖 Prompt for AI Agents
In go/pkg/hydra/store/workflows.sql.go around lines 663 to 676, the ReleaseLease
SQL query deletes leases without filtering by namespace, risking cross-namespace
lease manipulation. To fix this, update the underlying SQL query in the
workflows.sql file to include "AND namespace = ?" in the WHERE clause. Then
regenerate the Go code so the ReleaseLeaseParams struct and method include the
namespace parameter and use it in the query execution.

Comment on lines +771 to +798
const updateLease = `-- name: UpdateLease :exec
UPDATE leases
SET worker_id = ?, acquired_at = ?, expires_at = ?, heartbeat_at = ?
WHERE resource_id = ? AND kind = ? AND expires_at < ?
`

type UpdateLeaseParams struct {
WorkerID string `db:"worker_id" json:"worker_id"`
AcquiredAt int64 `db:"acquired_at" json:"acquired_at"`
ExpiresAt int64 `db:"expires_at" json:"expires_at"`
HeartbeatAt int64 `db:"heartbeat_at" json:"heartbeat_at"`
ResourceID string `db:"resource_id" json:"resource_id"`
Kind LeasesKind `db:"kind" json:"kind"`
ExpiresAt_2 int64 `db:"expires_at_2" json:"expires_at_2"`
}

func (q *Queries) UpdateLease(ctx context.Context, db DBTX, arg UpdateLeaseParams) error {
_, err := db.ExecContext(ctx, updateLease,
arg.WorkerID,
arg.AcquiredAt,
arg.ExpiresAt,
arg.HeartbeatAt,
arg.ResourceID,
arg.Kind,
arg.ExpiresAt_2,
)
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: Missing namespace filtering in updateLease query

The query updates expired leases without filtering by namespace, potentially allowing cross-namespace lease acquisition.

The SQL query should include namespace filtering:

UPDATE leases 
SET worker_id = ?, acquired_at = ?, expires_at = ?, heartbeat_at = ?
WHERE resource_id = ? AND kind = ? AND expires_at < ? AND namespace = ?

Since this is generated code, please fix the underlying SQL query in the workflows.sql file.

🤖 Prompt for AI Agents
In go/pkg/hydra/store/workflows.sql.go around lines 771 to 798, the updateLease
SQL query lacks filtering by namespace, which risks cross-namespace lease
updates. To fix this, add a namespace parameter to the WHERE clause of the SQL
query: include "AND namespace = ?" after the existing conditions. Then update
the UpdateLeaseParams struct to include a Namespace field and modify the
UpdateLease method to pass this new parameter when executing the query. Since
this code is generated, locate and update the original SQL query in the
workflows.sql file to include the namespace filter, then regenerate this Go
code.

@chronark chronark changed the title chore: use makefiles (merge after 3426) chore: use makefiles Jul 7, 2025
@chronark chronark merged commit c2ab6ac into main Jul 7, 2025
23 of 26 checks passed
@chronark chronark deleted the makefile branch July 7, 2025 20:35
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