Skip to content

fix all open github issues#11

Merged
ndbroadbent merged 11 commits into
mainfrom
nathan/fix-github-issues-2-4-5-6
Nov 28, 2025
Merged

fix all open github issues#11
ndbroadbent merged 11 commits into
mainfrom
nathan/fix-github-issues-2-4-5-6

Conversation

@ndbroadbent

@ndbroadbent ndbroadbent commented Nov 28, 2025

Copy link
Copy Markdown
Member
  • feat: add session timeout control to settings page (Add session timeout control to main settings page #6)
  • feat: add get/list deploy-approval CLI commands (Add get/list deploy-approvals commands to CLI #5)
  • fix: add logging when session TTL provider fails or returns invalid value
  • feat: move approve/reject buttons below deploy request info (Move approve/reject buttons below deploy request approval info #4)
  • fix: apply consistent app name resolution across all CLI commands
  • fix: use transactional update for MFA settings to prevent partial state
  • fix: use runWithMFAGuard for API token operations to properly handle MFA flow
  • fix: show spinner only on clicked deploy approval button, not all buttons
  • feat: add version display to web UI, CLI version command, and gateway command
  • fix: use hardcoded default when global setting not in database

Summary by CodeRabbit

Release Notes

  • New Features
    • Added gateway info command displaying gateway server details, version, and commit hash
    • Enhanced version command to report CLI, gateway, and rack server versions
    • Added deploy approval listing with filtering by status and rack
    • Added deploy approval request search by git branch/commit
    • Session timeout is now configurable in admin settings UI with database persistence

✏️ Tip: You can customize this high-level summary in your review settings.

ndbroadbent and others added 10 commits November 28, 2025 13:20
- Add session_timeout_minutes global setting with 5 minute default
- Replace static SESSION_IDLE_TIMEOUT with dynamic RGW_SETTING_SESSION_TIMEOUT_MINUTES
- Add SessionTTLProvider interface to session manager for dynamic TTL fetching
- Add StaticTTLProvider for test convenience
- Add /api/v1/settings/session-configuration endpoint for session config
- Add SessionTimeoutCard component to admin settings page
- Refactor settings/service.go into focused files to stay under 500 line limit:
 - service_global.go: global settings methods
 - service_app.go: app settings methods
 - service_mfa.go: MFA settings methods
 - service_deploy.go: deploy settings methods
 - service_session.go: session timeout methods
 - service_env_helpers.go: env var helper methods
- Update tests to use StaticTTLProvider

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add `deploy-approval list` and `deploy-approval get` subcommands to the CLI
to enable querying deploy approval requests:

- `list`: Lists deploy approval requests with filters (status, open-only, limit)
- `get`: Retrieves details for a specific deploy approval request by UUID

Includes UUID validation on the get command to prevent path traversal attacks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…alue

Addresses coderabbit suggestion to add observability when the TTL provider
returns an error or non-positive value, helping operators detect misconfigurations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Relocated the ActionButtons component below RequestDetailsCard in the
deploy approval request detail page. This improves UX by allowing users
to review the request details before taking action.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Addresses GitHub issue #2: Commands with -a/--app flag now consistently
resolve app names from .convox/app file or directory name when not
explicitly provided.

Changes:
- Add resolveAppFlag() helper in common.go to centralize app resolution
- Add appFlagHelp constant for consistent help text
- Update all commands with -a flag to call resolveAppFlag() before
 delegating to Convox SDK
- Affected commands: builds, apps info, deploy, releases, env, logs,
 ps, exec, run, restart, scale, resources

This ensures the CLI works correctly from any directory with a
.convox/app file, matching the behavior users expect from the
original convox CLI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Address coderabbit review suggestion: the three SetGlobalSetting calls in
SetMFASettings were executed sequentially without a transaction. If one
failed, earlier settings would remain persisted, leaving MFA configuration
in a partially updated state.

Changes:
- Add UpsertSettingsInTx to db/settings.go for atomic batch updates
- Add SetGlobalSettingsInTx helper to settings service
- Update SetMFASettings to use transactional batch update
- All three MFA settings now succeed or fail together

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…MFA flow

Fixes GitHub issue #10: MFA modal was getting stuck after verification when
creating API tokens because handleStepUpError didn't provide onResolve/onReject
callbacks, so the result was never captured.

Changes:
- Update create-token-dialog to use runWithMFAGuard instead of handleStepUpError
- Update edit-token-dialog to use runWithMFAGuard
- Update delete-token-dialog to use runWithMFAGuard
- Add guards for MFA cancellation (check for undefined response)
- Remove unused handleStepUpError from use-token-mutations
- Update test mock to include runWithMFAGuard

The runWithMFAGuard pattern properly wraps the async operation and returns
a Promise that resolves with the result when MFA verification succeeds,
allowing the calling code to handle the response correctly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…tons

Fixes GitHub issue #8: When clicking the approve tick on the deploy approvals
table, all tick buttons were changing to spinners instead of just the one
that was clicked.

Changes:
- Add approvingId state to track which specific request is being approved
- Pass approvingId and rejectingId to row components instead of global pending
- Compare request ID with tracking ID to determine which button shows spinner
- Clear tracking ID on mutation success/error

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
… command

- Add build-time version injection via Vite (package.json version + git commit hash)
- Display version in web UI sidebar footer
- Update backend /api/v1/info endpoint to include version info
- Add ldflags to Go build for version injection
- Add `rack-gateway version` command showing client, gateway, and server versions
- Add `rack-gateway gateway` command showing gateway server info

Also includes:
- Fix API token edit dialog not closing after save (mutation wasn't returning response)
- Fix deploy approval reject loading indicator (was using dialog state instead of mutation state)
- Eliminate code duplication in GetApprovedDeployCommands (use extractStringSlice helper)
- Add test assertion for edit dialog close after rename

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
When GetAppSetting falls back to a global default for ci_provider or
vcs_provider, it was passing "" as the default to GetGlobalSetting.
This caused it to return "" instead of the hardcoded default from
DefaultGlobalSettings when no global setting was in the database.

On EU/US racks, default_ci_provider was not in the database, so
ci_provider returned "" instead of "circleci", causing CircleCI
auto job approval to silently fail.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 28, 2025

Copy link
Copy Markdown

Walkthrough

This PR embeds version metadata (from package.json and git commit hash) into the gateway binary at build time, comprehensively refactors settings management to use a TTL provider interface for session configuration, adds new CLI commands for displaying gateway information and managing deploy approval requests with multi-rack search support, and extends the web UI with session timeout configuration and improved deploy approval workflows.

Changes

Cohort / File(s) Summary
Build & Versioning
Dockerfile, taskfiles/Taskfile.go.yml, internal/gateway/version/version.go
Adds Node.js/npm to builder dependencies; reads version from web/package.json and git commit hash; embeds both into binary via ldflags during gateway build.
Settings Service Refactoring
internal/gateway/settings/defaults.go, internal/gateway/settings/groups.go, internal/gateway/settings/service*.go
Splits monolithic settings service into focused modules (service_global.go, service_app.go, service_mfa.go, service_session.go, service_deploy.go, service_env_helpers.go); adds batch upsert capability; introduces session timeout as a database-backed global setting with hardcoded fallback defaults.
Session & Auth Architecture
internal/gateway/auth/session_manager.go, internal/gateway/config/config.go, internal/gateway/app/setup.go
Introduces SessionTTLProvider interface and StaticTTLProvider implementation; refactors SessionManager to fetch TTL dynamically from provider; removes static SessionIdleTimeout from config; separates settings and MFA initialization into dedicated methods.
Session/Auth Test Updates
internal/gateway/auth/*_test.go, internal/gateway/handlers/*_test.go, internal/gateway/middleware/*_test.go
Updates ~12 test files to pass StaticTTLProvider instead of raw time.Duration to NewSessionManager.
Gateway API & Handlers
internal/gateway/handlers/dto.go, internal/gateway/handlers/api_handler_info.go, internal/gateway/handlers/settings.go, internal/gateway/handlers/settings_test.go, internal/gateway/routes/route_registration.go
Adds VersionInfo struct with version/commit hash to API responses; introduces UpdateGlobalSessionConfiguration and DeleteGlobalSessionConfiguration handlers; wires new PUT/DELETE routes for session config management.
Database
internal/gateway/db/settings.go, internal/gateway/db/deploy_approval_requests_queries.go
Adds batch upsert capability (UpsertSettingsInTx); extends deploy approval request filtering with GitBranch and GitCommitHash options.
CLI Infrastructure
internal/cli/common.go, internal/cli/auth.go, internal/cli/convox_*.go
Introduces resolveAppFlag helper for consistent app resolution; adds new GetGatewayInfo function; updates multiple commands to resolve app flag early and use centralized flag help text.
CLI: Gateway Command
internal/cli/cli_gateway.go, internal/cli/cli_version.go, internal/cli/root.go
Adds new top-level gateway command displaying gateway URL, version, commit hash, and integrated services; extends version command to show client, gateway, and server versions with login-aware behavior.
CLI: Deploy Approval Commands
internal/cli/deploy_approvals_*.go
Adds DeployApprovalListCommand for filtering and listing approvals; adds DeployApprovalShowCommand for ID or search-based lookup; introduces shared helpers for rack/branch/commit resolution and multi-rack search patterns; removes legacy resolveWaitRacks.
CLI Types
internal/cli/types.go
Adds GatewayInfoResponse, GatewayUserInfo, GatewayRackSummary, GatewayIntegrationsInfo, and GatewayVersionInfo structs for API communication.
Deploy Approval Admin
internal/gateway/handlers/deploy_approval_admin.go
Refactors list option parsing to support new GitBranch and GitCommitHash filters; adds parseNonNegativeInt helper for validation.
Web API Types
web/src/api/openapi.json, web/src/api/types.generated.ts, web/src/api/schemas/*.ts
Adds handlers.VersionInfo schema and updates handlers.InfoResponse to include version property; generates TypeScript interfaces.
Web Frontend Components
web/src/pages/settings-page.tsx, web/src/pages/settings/session-timeout-card.tsx
Adds new SessionTimeoutCard component to settings page for viewing/editing session timeout; supports save, clear, and cancel actions with mutation handling.
Web Token Management UI
web/src/pages/tokens-page/, web/src/pages/tokens-page/use-token-mutations.ts
Refactors token dialogs (create, delete, edit) to use runWithMFAGuard from useStepUp hook instead of error-based MFA handling; removes handleStepUpError from token mutations.
Web Deploy Approvals
web/src/pages/deploy-approval-request-detail-page.tsx, web/src/pages/deploy-approval-requests-page.tsx
Adds per-item loading state (separate IDs for approving/rejecting) instead of global flags; updates component props to reflect new state shape.
Web Build & Environment
web/vite.config.ts, web/src/vite-env.d.ts, web/tsconfig.tests.json, web/src/components/layout.tsx
Injects __APP_VERSION__ and __COMMIT_HASH__ via Vite define; declares global types; displays version in sidebar layout.
Web E2E & Testing
web/e2e/manage.spec.ts, web/src/pages/tokens-page.test.tsx, web/.eslintrc.json
Adds dialog-close wait in token rename test; updates StepUp mock to include runWithMFAGuard; enables react plugin and disables react/jsx-no-bind rule.
Configuration & Documentation
docs/CONFIGURATION.md, .deepsource.toml, CLAUDE.md, web/biome.json
Updates SESSION_IDLE_TIMEOUT to RGW_SETTING_SESSION_TIMEOUT_MINUTES with UI/DB precedence; adds DeepSource/ESLint documentation; defines global linter exceptions for version constants.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60–90 minutes

Areas requiring extra attention:

  • Settings service refactoring (internal/gateway/settings/service*.go): ~1,000+ lines of logic split across 6 new modules; verify correct fallback logic, transaction handling in batch upsert, and absence of regressions in getter/setter paths.
  • SessionTTLProvider interface & adoption across auth, handlers, and middleware: ~12 test files updated; confirm all call sites correctly instantiate StaticTTLProvider and no TTL initialization paths are missed.
  • TTL provider integration in setup.go: new initSettingsService() and initMFAConfig() methods; ensure initialization order is correct and both depend on the SettingsService properly.
  • Deploy approval search logic (deploy_approvals_show.go, deploy_approvals_approve.go): multi-rack iteration with fallback patterns; verify error handling and search precedence (pending vs. approved).
  • Web token mutations refactoring: removal of handleStepUpError and migration to runWithMFAGuard; check all three token dialog flows (create, delete, edit) for correct MFA cancellation handling and state cleanup.
  • Deploy approval per-item loading state in web: ID-based loading flags instead of boolean; ensure correct row identification and loading state display consistency.

Possibly related PRs

  • nathan/fix security and linting issues #3: Shares overlapping gateway settings service refactoring, session configuration endpoints, and deploy-approval handler/database/web UI patterns; likely a related or prior iteration.

Poem

🐰 The version hops from build to binary deep,
Settings now awake from database sleep,
TTL providers dance, so new and keen,
Approvals search through racks between,
While tokens guard with MFA's gentle keep!

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'fix all open github issues' is vague and overly broad. It doesn't specify which issues are being addressed or describe the primary changes. The actual PR addresses multiple distinct features and fixes (session timeout, CLI commands, MFA flow, etc.), making the generic title misleading about the scope. Use a more specific title that captures the primary focus, such as 'Add session timeout settings and deploy approval CLI commands' or reference the specific issue numbers like 'Fix GitHub issues #2, #4, #5, #6'.
Docstring Coverage ⚠️ Warning Docstring coverage is 26.53% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch nathan/fix-github-issues-2-4-5-6

Comment @coderabbitai help to get the list of available commands and usage tips.

@deepsource-io

deepsource-io Bot commented Nov 28, 2025

Copy link
Copy Markdown

Here's the code health analysis summary for commits 03b1426..d719bb1. View details on DeepSource ↗.

Analysis Summary

AnalyzerStatusSummaryLink
DeepSource JavaScript LogoJavaScript✅ Success
🎯 30 occurences resolved
View Check ↗
DeepSource Go LogoGo✅ SuccessView Check ↗

💡 If you’re a repository administrator, you can configure the quality gates from the settings.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (10)
docs/CONFIGURATION.md (1)

28-29: Consider minor grammar improvement.

The documentation update correctly reflects the new session timeout configuration mechanism. However, the sentence on line 29 could be slightly improved for clarity.

Consider revising for better grammar:

-- `RGW_SETTING_SESSION_TIMEOUT_MINUTES` (default: `5`)
-  - Sliding inactivity window for browser sessions in minutes. Can also be configured via the Settings page in the admin UI (database value takes precedence).
+  - Sliding inactivity window for browser sessions in minutes. This can also be configured via the Settings page in the admin UI (database value takes precedence).
web/src/pages/settings-page.tsx (1)

63-65: Consider UI layout consistency.

The SessionTimeoutCard is wrapped in its own two-column grid, creating a standalone row. This differs from the pattern on lines 59-62 where MfaConfigCard and DestructiveActionsCard share a row.

If no second card is planned for this row, consider placing it outside the grid or using a single-column layout for clarity:

-        <div className="grid gap-6 md:grid-cols-2">
-          <SessionTimeoutCard disabled={!isAdmin} settings={globalSettings} />
-        </div>
+        <SessionTimeoutCard disabled={!isAdmin} settings={globalSettings} />

Or, if a second card might be added later, this structure is fine. Otherwise, the current implementation works correctly and the card integrates properly with admin gating and settings data.

internal/cli/deploy_approvals_get.go (1)

13-57: Deploy approval “get” command is solid; consider stricter output handling

The command flow (rack resolution, UUID validation, gatewayRequest, and dual JSON/human output) is clean and consistent with existing patterns. One optional improvement would be to treat non-empty, non-json values for --output as invalid instead of silently falling back to the human format, e.g. by switching on output and returning an error for unknown formats.

Also applies to: 59-93

internal/cli/auth.go (1)

130-157: GetGatewayInfo implementation looks correct; optional error‑formatting tweak

The helper correctly builds the URL, sends an authenticated request via HTTPClient, validates StatusOK, and decodes into GatewayInfoResponse; resource handling is safe.

If you want error messages consistent with other auth flows, you could optionally reuse RenderGatewayError when StatusCode != http.StatusOK instead of returning the raw body string. Not required for correctness.

internal/cli/convox_env.go (1)

25-25: Env command app handling is improved; consider centralizing resolution later

Using appFlagHelp and resolveAppFlag for env edit/set/unset aligns these flows with other CLI commands and looks good.

As a follow‑up, you might consider reusing resolveAppFlag (or a shared helper under the hood) in envGetGateway/envListGateway as well, so all env commands rely on a single app resolution path and can’t drift over time.

Also applies to: 42-44, 58-58, 74-74, 86-88, 102-102, 116-118, 132-132

internal/gateway/handlers/auth_test.go (1)

91-91: SessionManager TTLProvider wiring in tests is correct

Updating NewSessionManager call sites to use &auth.StaticTTLProvider{TTL: time.Hour} is consistent with the new constructor and keeps test behavior the same as the previous fixed one‑hour TTL. If you find yourself adding more tests like this, a small helper (e.g., newTestSessionManager(t, db *db.Database)) could reduce repetition, but not required here.

Also applies to: 152-152, 198-198, 231-231, 266-266, 304-304, 393-393, 410-410

internal/gateway/settings/service_session.go (1)

6-21: Consider error handling pattern for graceful degradation.

Both methods return a default value (5 minutes) even when an error occurs. This pattern provides graceful degradation but may mask configuration issues. If the intent is to always provide a valid timeout (even on error), consider documenting this behavior in the function comments to clarify that callers can rely on the returned value regardless of error.

Alternatively, if errors should halt execution, follow the standard Go pattern of returning zero values with the error.

internal/gateway/settings/service_mfa.go (1)

57-77: Consider avoiding mutation of input parameter.

Lines 64 and 67 modify the input settings parameter by setting default values. While this works, it's generally better practice to either:

  1. Return a new *db.MFASettings with corrected values, or
  2. Document this side effect clearly in the function comment

This makes the function's behavior more explicit and avoids surprising callers.

Example:

-// SetMFASettings stores MFA configuration in the database atomically.
+// SetMFASettings stores MFA configuration in the database atomically.
+// Non-positive TTL and step-up window values are replaced with defaults (30 days and 10 minutes).
 // All settings are updated within a single transaction to prevent partial updates.
 func (s *Service) SetMFASettings(settings *db.MFASettings, updatedByUserID *int64) error {
internal/cli/deploy_approvals_list.go (1)

92-121: Consider simplifying the return type.

The function always returns nil and never produces an error. You could simplify by removing the error return, or keep it for API consistency with other print functions.

-func printDeployApprovalTable(requests []deployApprovalRequest) error {
+func printDeployApprovalTable(requests []deployApprovalRequest) {
 	fmt.Printf("%-36s  %-10s  %-20s  %-40s  %s\n",
 		"ID", "STATUS", "CREATED", "MESSAGE", "TOKEN")
 	fmt.Println(strings.Repeat("-", 130))
 
 	for _, req := range requests {
 		// ... existing logic ...
 	}
-
-	return nil
 }

If kept as-is for consistency, this is acceptable.

internal/gateway/settings/service_global.go (1)

29-42: Consider adding audit logging for settings modifications.

The methods SetGlobalSetting, DeleteGlobalSetting, and SetGlobalSettingsInTx modify global configuration without audit logging. Based on coding guidelines for internal/gateway/**/*.go, sensitive data operations should use the audit logger.

Consider adding audit log entries when settings are created, updated, or deleted, capturing the user ID and the affected setting keys.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03b1426 and f71aaae.

⛔ Files ignored due to path filters (1)
  • internal/gateway/openapi/generated/swagger.json is excluded by !**/generated/**
📒 Files selected for processing (66)
  • Dockerfile (1 hunks)
  • docs/CONFIGURATION.md (1 hunks)
  • internal/cli/auth.go (1 hunks)
  • internal/cli/cli_gateway.go (1 hunks)
  • internal/cli/cli_version.go (1 hunks)
  • internal/cli/common.go (1 hunks)
  • internal/cli/convox_apps.go (2 hunks)
  • internal/cli/convox_builds.go (11 hunks)
  • internal/cli/convox_deploy.go (10 hunks)
  • internal/cli/convox_env.go (8 hunks)
  • internal/cli/convox_logs.go (2 hunks)
  • internal/cli/convox_processes.go (14 hunks)
  • internal/cli/convox_resources.go (8 hunks)
  • internal/cli/deploy_approvals_command.go (1 hunks)
  • internal/cli/deploy_approvals_get.go (1 hunks)
  • internal/cli/deploy_approvals_list.go (1 hunks)
  • internal/cli/root.go (1 hunks)
  • internal/cli/types.go (1 hunks)
  • internal/gateway/app/setup.go (2 hunks)
  • internal/gateway/auth/cli_only_test.go (1 hunks)
  • internal/gateway/auth/service_test.go (2 hunks)
  • internal/gateway/auth/session_manager.go (5 hunks)
  • internal/gateway/config/config.go (0 hunks)
  • internal/gateway/db/settings.go (1 hunks)
  • internal/gateway/handlers/api_handler_info.go (2 hunks)
  • internal/gateway/handlers/auth_mfa_verification_test.go (2 hunks)
  • internal/gateway/handlers/auth_test.go (8 hunks)
  • internal/gateway/handlers/deploy_approval_requests_mfa_test.go (1 hunks)
  • internal/gateway/handlers/dto.go (1 hunks)
  • internal/gateway/handlers/settings.go (2 hunks)
  • internal/gateway/handlers/settings_test.go (1 hunks)
  • internal/gateway/middleware/auth_test.go (1 hunks)
  • internal/gateway/middleware/mfa_stepup_totp_test.go (1 hunks)
  • internal/gateway/routes/route_registration.go (1 hunks)
  • internal/gateway/settings/defaults.go (4 hunks)
  • internal/gateway/settings/groups.go (2 hunks)
  • internal/gateway/settings/service.go (0 hunks)
  • internal/gateway/settings/service_app.go (1 hunks)
  • internal/gateway/settings/service_deploy.go (1 hunks)
  • internal/gateway/settings/service_env_helpers.go (1 hunks)
  • internal/gateway/settings/service_global.go (1 hunks)
  • internal/gateway/settings/service_mfa.go (1 hunks)
  • internal/gateway/settings/service_session.go (1 hunks)
  • internal/gateway/settings/service_test.go (1 hunks)
  • internal/gateway/version/version.go (1 hunks)
  • taskfiles/Taskfile.go.yml (1 hunks)
  • web/biome.json (1 hunks)
  • web/e2e/manage.spec.ts (1 hunks)
  • web/src/api/openapi.json (3 hunks)
  • web/src/api/schemas/handlersInfoResponse.ts (1 hunks)
  • web/src/api/schemas/handlersVersionInfo.ts (1 hunks)
  • web/src/api/schemas/index.ts (1 hunks)
  • web/src/api/types.generated.ts (2 hunks)
  • web/src/components/layout.tsx (1 hunks)
  • web/src/pages/deploy-approval-request-detail-page.tsx (1 hunks)
  • web/src/pages/deploy-approval-requests-page.tsx (10 hunks)
  • web/src/pages/settings-page.tsx (2 hunks)
  • web/src/pages/settings/session-timeout-card.tsx (1 hunks)
  • web/src/pages/tokens-page.test.tsx (1 hunks)
  • web/src/pages/tokens-page/create-token-dialog.tsx (3 hunks)
  • web/src/pages/tokens-page/delete-token-dialog.tsx (3 hunks)
  • web/src/pages/tokens-page/edit-token-dialog.tsx (3 hunks)
  • web/src/pages/tokens-page/use-token-mutations.ts (1 hunks)
  • web/src/vite-env.d.ts (1 hunks)
  • web/tsconfig.tests.json (1 hunks)
  • web/vite.config.ts (2 hunks)
💤 Files with no reviewable changes (2)
  • internal/gateway/config/config.go
  • internal/gateway/settings/service.go
🧰 Additional context used
📓 Path-based instructions (17)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: Maximum 500 lines per Go code file - refactor immediately if approaching this limit or split into smaller, focused modules
Maximum 100 lines per function (Go) - enforced by golangci-lint using funlen linter
Maximum 50 statements per function (Go) - enforced by golangci-lint
Maximum cognitive complexity of 15 (Go) - enforced by golangci-lint using gocognit linter
Line length maximum 120 characters - enforced by golangci-lint lll rule. Exception: For Go struct tag lines that cannot be broken without invalidating formatting (where gofmt/goimports always rejoin them and field+tag exceeds 120 chars), add //nolint:lll at end of line only
No //nolint comments allowed except for struct tag line length exceptions - fix the code instead of suppressing warnings
Forbidden patterns in Go: panic (use error returns), fmt.Print* except in CLI output (use proper logging), time.Sleep (use context with timeout)
Zero code duplication allowed in production code - threshold 10 lines or 50 tokens, enforced by jscpd
Use govulncheck to check for known Go vulnerabilities - required security scan

Files:

  • internal/cli/root.go
  • internal/gateway/auth/cli_only_test.go
  • internal/cli/convox_apps.go
  • internal/cli/common.go
  • internal/cli/convox_env.go
  • internal/gateway/settings/service_mfa.go
  • internal/cli/cli_gateway.go
  • internal/gateway/db/settings.go
  • internal/gateway/settings/service_test.go
  • internal/gateway/handlers/api_handler_info.go
  • internal/cli/types.go
  • internal/gateway/handlers/deploy_approval_requests_mfa_test.go
  • internal/gateway/settings/service_deploy.go
  • internal/gateway/routes/route_registration.go
  • internal/gateway/settings/defaults.go
  • internal/cli/deploy_approvals_list.go
  • internal/cli/deploy_approvals_get.go
  • internal/cli/cli_version.go
  • internal/gateway/auth/service_test.go
  • internal/cli/convox_resources.go
  • internal/gateway/settings/service_global.go
  • internal/gateway/settings/service_app.go
  • internal/gateway/settings/groups.go
  • internal/gateway/version/version.go
  • internal/cli/auth.go
  • internal/gateway/auth/session_manager.go
  • internal/gateway/settings/service_env_helpers.go
  • internal/gateway/settings/service_session.go
  • internal/gateway/handlers/settings.go
  • internal/gateway/handlers/auth_test.go
  • internal/gateway/handlers/auth_mfa_verification_test.go
  • internal/cli/convox_processes.go
  • internal/cli/convox_logs.go
  • internal/cli/deploy_approvals_command.go
  • internal/gateway/middleware/auth_test.go
  • internal/cli/convox_builds.go
  • internal/gateway/handlers/dto.go
  • internal/cli/convox_deploy.go
  • internal/gateway/handlers/settings_test.go
  • internal/gateway/middleware/mfa_stepup_totp_test.go
  • internal/gateway/app/setup.go
**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

Maximum 1000 lines per Go test file - refactor immediately if approaching this limit or split tests into multiple files

Files:

  • internal/gateway/auth/cli_only_test.go
  • internal/gateway/settings/service_test.go
  • internal/gateway/handlers/deploy_approval_requests_mfa_test.go
  • internal/gateway/auth/service_test.go
  • internal/gateway/handlers/auth_test.go
  • internal/gateway/handlers/auth_mfa_verification_test.go
  • internal/gateway/middleware/auth_test.go
  • internal/gateway/handlers/settings_test.go
  • internal/gateway/middleware/mfa_stepup_totp_test.go
internal/gateway/auth/**/*.go

📄 CodeRabbit inference engine (internal/gateway/CLAUDE.md)

Validate requests against configured Google Workspace domain in authentication handlers

Files:

  • internal/gateway/auth/cli_only_test.go
  • internal/gateway/auth/service_test.go
  • internal/gateway/auth/session_manager.go
internal/gateway/**/*.go

📄 CodeRabbit inference engine (internal/gateway/CLAUDE.md)

Use audit logger for all sensitive data in Go files

Files:

  • internal/gateway/auth/cli_only_test.go
  • internal/gateway/settings/service_mfa.go
  • internal/gateway/db/settings.go
  • internal/gateway/settings/service_test.go
  • internal/gateway/handlers/api_handler_info.go
  • internal/gateway/handlers/deploy_approval_requests_mfa_test.go
  • internal/gateway/settings/service_deploy.go
  • internal/gateway/routes/route_registration.go
  • internal/gateway/settings/defaults.go
  • internal/gateway/auth/service_test.go
  • internal/gateway/settings/service_global.go
  • internal/gateway/settings/service_app.go
  • internal/gateway/settings/groups.go
  • internal/gateway/version/version.go
  • internal/gateway/auth/session_manager.go
  • internal/gateway/settings/service_env_helpers.go
  • internal/gateway/settings/service_session.go
  • internal/gateway/handlers/settings.go
  • internal/gateway/handlers/auth_test.go
  • internal/gateway/handlers/auth_mfa_verification_test.go
  • internal/gateway/middleware/auth_test.go
  • internal/gateway/handlers/dto.go
  • internal/gateway/handlers/settings_test.go
  • internal/gateway/middleware/mfa_stepup_totp_test.go
  • internal/gateway/app/setup.go
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Maximum 500 lines per TypeScript/TSX code file - refactor immediately if approaching this limit or split into smaller, focused modules

Use TypeScript strict mode and avoid using any type

Files:

  • web/src/api/schemas/handlersInfoResponse.ts
  • web/src/pages/deploy-approval-request-detail-page.tsx
  • web/e2e/manage.spec.ts
  • web/src/api/schemas/handlersVersionInfo.ts
  • web/src/pages/settings/session-timeout-card.tsx
  • web/vite.config.ts
  • web/src/pages/deploy-approval-requests-page.tsx
  • web/src/api/types.generated.ts
  • web/src/pages/tokens-page/create-token-dialog.tsx
  • web/src/api/schemas/index.ts
  • web/src/pages/tokens-page.test.tsx
  • web/src/pages/settings-page.tsx
  • web/src/pages/tokens-page/delete-token-dialog.tsx
  • web/src/pages/tokens-page/use-token-mutations.ts
  • web/src/vite-env.d.ts
  • web/src/components/layout.tsx
  • web/src/pages/tokens-page/edit-token-dialog.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{js,jsx,ts,tsx}: No // biome-ignore comments allowed - fix the code, don't suppress the linter. Zero tolerance enforcement.
Zero code duplication allowed in production code - threshold 10 lines or 50 tokens, enforced by jscpd

Files:

  • web/src/api/schemas/handlersInfoResponse.ts
  • web/src/pages/deploy-approval-request-detail-page.tsx
  • web/e2e/manage.spec.ts
  • web/src/api/schemas/handlersVersionInfo.ts
  • web/src/pages/settings/session-timeout-card.tsx
  • web/vite.config.ts
  • web/src/pages/deploy-approval-requests-page.tsx
  • web/src/api/types.generated.ts
  • web/src/pages/tokens-page/create-token-dialog.tsx
  • web/src/api/schemas/index.ts
  • web/src/pages/tokens-page.test.tsx
  • web/src/pages/settings-page.tsx
  • web/src/pages/tokens-page/delete-token-dialog.tsx
  • web/src/pages/tokens-page/use-token-mutations.ts
  • web/src/vite-env.d.ts
  • web/src/components/layout.tsx
  • web/src/pages/tokens-page/edit-token-dialog.tsx
web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (web/CLAUDE.md)

Always import toast from @/components/ui/use-toast, never directly from react-hot-toast

Files:

  • web/src/api/schemas/handlersInfoResponse.ts
  • web/src/pages/deploy-approval-request-detail-page.tsx
  • web/e2e/manage.spec.ts
  • web/src/api/schemas/handlersVersionInfo.ts
  • web/src/pages/settings/session-timeout-card.tsx
  • web/vite.config.ts
  • web/src/pages/deploy-approval-requests-page.tsx
  • web/src/api/types.generated.ts
  • web/src/pages/tokens-page/create-token-dialog.tsx
  • web/src/api/schemas/index.ts
  • web/src/pages/tokens-page.test.tsx
  • web/src/pages/settings-page.tsx
  • web/src/pages/tokens-page/delete-token-dialog.tsx
  • web/src/pages/tokens-page/use-token-mutations.ts
  • web/src/vite-env.d.ts
  • web/src/components/layout.tsx
  • web/src/pages/tokens-page/edit-token-dialog.tsx
web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (web/.cursor/rules/ultracite.mdc)

web/**/*.{ts,tsx,js,jsx}: Don't use accessKey attribute on any HTML element
Don't set aria-hidden="true" on focusable elements
Don't add ARIA roles, states, and properties to elements that don't support them
Don't use distracting elements like <marquee> or <blink>
Only use the scope prop on <th> elements
Don't assign non-interactive ARIA roles to interactive HTML elements
Make sure label elements have text content and are associated with an input
Don't assign interactive ARIA roles to non-interactive HTML elements
Don't assign tabIndex to non-interactive HTML elements
Don't use positive integers for tabIndex property
Don't include "image", "picture", or "photo" in img alt prop
Don't use explicit role property that's the same as the implicit/default role
Make static elements with click handlers use a valid role attribute
Always include a title element for SVG elements
Give all elements requiring alt text meaningful information for screen readers
Make sure anchors have content that's accessible to screen readers
Assign tabIndex to non-interactive HTML elements with aria-activedescendant
Include all required ARIA attributes for elements with ARIA roles
Make sure ARIA properties are valid for the element's supported roles
Always include a type attribute for button elements
Make elements with interactive roles and handlers focusable
Give heading elements content that's accessible to screen readers (not hidden with aria-hidden)
Always include a lang attribute on the html element
Always include a title attribute for iframe elements
Accompany onClick with at least one of: onKeyUp, onKeyDown, or onKeyPress
Accompany onMouseOver/onMouseOut with onFocus/onBlur
Include caption tracks for audio and video elements
Use semantic elements instead of role attributes in JSX
Make sure all anchors are valid and navigable
Ensure all ARIA properties (aria-*) are valid
Use valid, non-abstract ARIA roles for elements with ARIA roles
Use vali...

Files:

  • web/src/api/schemas/handlersInfoResponse.ts
  • web/src/pages/deploy-approval-request-detail-page.tsx
  • web/e2e/manage.spec.ts
  • web/src/api/schemas/handlersVersionInfo.ts
  • web/src/pages/settings/session-timeout-card.tsx
  • web/vite.config.ts
  • web/src/pages/deploy-approval-requests-page.tsx
  • web/src/api/types.generated.ts
  • web/src/pages/tokens-page/create-token-dialog.tsx
  • web/src/api/schemas/index.ts
  • web/src/pages/tokens-page.test.tsx
  • web/src/pages/settings-page.tsx
  • web/src/pages/tokens-page/delete-token-dialog.tsx
  • web/src/pages/tokens-page/use-token-mutations.ts
  • web/src/vite-env.d.ts
  • web/src/components/layout.tsx
  • web/src/pages/tokens-page/edit-token-dialog.tsx
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,tsx,jsx}: Use clear and descriptive variable names that convey intent
Write modular code by breaking down large functions into smaller, reusable functions
Add comments to explain complex logic and edge cases
Use proper error handling with try-catch blocks and meaningful error messages
Prefer functional programming patterns over imperative code where applicable
Keep functions small and focused on a single responsibility
Avoid deep nesting and use early returns to improve readability

Files:

  • web/src/api/schemas/handlersInfoResponse.ts
  • web/src/pages/deploy-approval-request-detail-page.tsx
  • web/e2e/manage.spec.ts
  • web/src/api/schemas/handlersVersionInfo.ts
  • web/src/pages/settings/session-timeout-card.tsx
  • web/vite.config.ts
  • web/src/pages/deploy-approval-requests-page.tsx
  • web/src/api/types.generated.ts
  • web/src/pages/tokens-page/create-token-dialog.tsx
  • web/src/api/schemas/index.ts
  • web/src/pages/tokens-page.test.tsx
  • web/src/pages/settings-page.tsx
  • web/src/pages/tokens-page/delete-token-dialog.tsx
  • web/src/pages/tokens-page/use-token-mutations.ts
  • web/src/vite-env.d.ts
  • web/src/components/layout.tsx
  • web/src/pages/tokens-page/edit-token-dialog.tsx
web/e2e/**/*.spec.ts

📄 CodeRabbit inference engine (CLAUDE.md)

For fast feedback when changing ONLY E2E test files, run cd web && bunx playwright test directly instead of task web:e2e. Only use this when test files are the ONLY changes.

Files:

  • web/e2e/manage.spec.ts
web/**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (web/CLAUDE.md)

web/**/*.{test,spec}.{ts,tsx}: Use relative paths (not path aliases like @/) in vi.mock() calls - Vitest treats aliased and relative paths as different module instances
When mocking React Query queries that child components read from cache without a queryFn, add enabled: false to prevent React Query from attempting to fetch
Suppress React Query console errors about missing queryFn in tests using vi.spyOn(console, 'error').mockImplementation() to filter 'No queryFn was passed' messages
Use mockImplementation with URL routing instead of sequential mockResolvedValueOnce for mocking parallel React Query requests
Test router basepath handling for /app, including /login and /auth/callback routes in Vitest unit tests
Test auth flows, API adapters (with mocked network, not depending on browser), and critical UI/behavior for Users, Tokens, and Audit pages in unit tests

Files:

  • web/e2e/manage.spec.ts
  • web/src/pages/tokens-page.test.tsx
web/**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (web/.cursor/rules/ultracite.mdc)

web/**/*.{test,spec}.{ts,tsx,js,jsx}: Don't nest describe() blocks too deeply in test files
Don't use callbacks in asynchronous tests and hooks
Don't have duplicate hooks in describe blocks
Don't use export or module.exports in test files
Don't use focused tests
Make sure the assertion function, like expect, is placed inside an it() function call
Don't use disabled tests

Files:

  • web/e2e/manage.spec.ts
  • web/src/pages/tokens-page.test.tsx
internal/gateway/db/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Database layer code should follow Repository pattern for data access abstractions

Files:

  • internal/gateway/db/settings.go
web/vite.config.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use process.env.GATEWAY_PORT for proxy configuration instead of hardcoding ports

Files:

  • web/vite.config.ts
internal/gateway/auth/session_manager.go

📄 CodeRabbit inference engine (internal/gateway/CLAUDE.md)

Implement session creation and validation in auth/session_manager.go with opaque tokens stored in database

Files:

  • internal/gateway/auth/session_manager.go
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Maximum 1000 lines per TypeScript test file - refactor immediately if approaching this limit or split tests into multiple files

Files:

  • web/src/pages/tokens-page.test.tsx
**/*.test.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Write unit tests for all critical functionality

Files:

  • web/src/pages/tokens-page.test.tsx
🧬 Code graph analysis (38)
internal/cli/root.go (1)
internal/cli/cli_gateway.go (1)
  • GatewayCommand (11-19)
internal/gateway/auth/cli_only_test.go (1)
internal/gateway/auth/session_manager.go (2)
  • NewSessionManager (67-73)
  • StaticTTLProvider (31-33)
web/src/api/schemas/handlersInfoResponse.ts (1)
web/src/api/schemas/handlersVersionInfo.ts (1)
  • HandlersVersionInfo (9-12)
internal/cli/common.go (2)
internal/convox/commands.go (1)
  • Command (13-18)
internal/cli/utils.go (1)
  • ResolveApp (78-86)
internal/gateway/settings/service_mfa.go (3)
internal/gateway/settings/service.go (1)
  • Service (16-18)
internal/gateway/db/settings.go (2)
  • MFASettings (239-243)
  • SettingUpdate (135-138)
internal/gateway/settings/defaults.go (3)
  • KeyMFARequireAllUsers (28-28)
  • KeyTrustedDeviceTTLDays (32-32)
  • KeyStepUpWindowMinutes (31-31)
web/src/pages/deploy-approval-request-detail-page.tsx (1)
web/src/components/deploy-approval-request/details.tsx (3)
  • RequestHeader (45-89)
  • RequestDetailsCard (153-172)
  • ActionButtons (101-147)
internal/cli/cli_gateway.go (5)
internal/cli/utils.go (1)
  • SilenceOnError (17-26)
internal/cli/rack.go (1)
  • SelectedRack (11-32)
internal/cli/config.go (1)
  • LoadRackAuth (149-175)
internal/cli/auth.go (1)
  • GetGatewayInfo (131-157)
internal/cli/types.go (2)
  • GatewayInfoResponse (103-108)
  • GatewayIntegrationsInfo (125-129)
web/e2e/manage.spec.ts (1)
web/e2e/fixtures.ts (1)
  • expect (311-311)
internal/gateway/db/settings.go (1)
internal/gateway/db/database.go (1)
  • Database (21-26)
internal/gateway/settings/service_test.go (3)
internal/gateway/testutil/dbtest/dbtest.go (1)
  • NewDatabase (50-65)
internal/gateway/settings/service.go (2)
  • NewService (21-23)
  • SourceGlobalDefault (33-33)
internal/gateway/settings/defaults.go (2)
  • KeyCIProvider (96-96)
  • KeyVCSProvider (107-107)
internal/gateway/handlers/api_handler_info.go (3)
internal/gateway/handlers/dto.go (2)
  • VersionInfo (182-185)
  • InfoResponse (188-193)
internal/gateway/version/version.go (2)
  • Version (6-6)
  • CommitHash (9-9)
web/src/lib/api.ts (1)
  • InfoResponse (84-84)
internal/gateway/handlers/deploy_approval_requests_mfa_test.go (1)
internal/gateway/auth/session_manager.go (2)
  • NewSessionManager (67-73)
  • StaticTTLProvider (31-33)
internal/gateway/settings/service_deploy.go (2)
internal/gateway/settings/service.go (1)
  • Service (16-18)
internal/gateway/settings/defaults.go (3)
  • KeyAllowDestructiveActions (23-23)
  • KeyDeployApprovalsEnabled (26-26)
  • KeyDeployApprovalWindowMinutes (27-27)
internal/cli/deploy_approvals_get.go (1)
internal/convox/commands.go (1)
  • Command (13-18)
internal/cli/cli_version.go (1)
internal/cli/globals.go (1)
  • Version (25-25)
internal/gateway/auth/service_test.go (1)
internal/gateway/auth/session_manager.go (2)
  • NewSessionManager (67-73)
  • StaticTTLProvider (31-33)
web/src/pages/settings/session-timeout-card.tsx (6)
web/src/pages/settings/types.ts (1)
  • GlobalSettingsResponse (3-3)
web/src/contexts/step-up-context.tsx (1)
  • useStepUp (353-359)
web/src/hooks/use-mutation.ts (1)
  • useMutation (65-88)
web/src/lib/api.ts (1)
  • api (428-460)
web/src/api/schemas/settingsSetting.ts (1)
  • SettingsSetting (10-15)
web/src/lib/error-utils.ts (1)
  • toastAPIError (14-19)
internal/gateway/settings/service_global.go (3)
internal/gateway/settings/service.go (2)
  • Service (16-18)
  • Setting (37-41)
internal/gateway/settings/defaults.go (1)
  • DefaultGlobalSettings (160-170)
internal/gateway/db/settings.go (1)
  • SettingUpdate (135-138)
web/src/pages/deploy-approval-requests-page.tsx (2)
web/src/hooks/use-mutation.ts (1)
  • useMutation (65-88)
web/src/lib/api.ts (1)
  • rejectDeployApprovalRequest (184-188)
internal/gateway/settings/groups.go (1)
internal/gateway/settings/defaults.go (1)
  • GlobalSettingSessionTimeoutMinutes (16-16)
web/src/pages/tokens-page/create-token-dialog.tsx (2)
web/src/pages/tokens-page/use-token-mutations.ts (1)
  • useTokenMutations (8-63)
web/src/contexts/step-up-context.tsx (1)
  • useStepUp (353-359)
internal/cli/auth.go (3)
internal/cli/types.go (1)
  • GatewayInfoResponse (103-108)
internal/cli/globals.go (1)
  • HTTPClient (31-31)
internal/cli/logging/logging.go (1)
  • Errorf (20-20)
internal/gateway/auth/session_manager.go (3)
internal/gateway/db/database.go (1)
  • Database (21-26)
internal/gateway/rbac/rbac.go (1)
  • Database (16-25)
internal/gateway/logging/logging.go (2)
  • Errorf (65-65)
  • Warnf (62-62)
internal/gateway/settings/service_env_helpers.go (2)
internal/gateway/settings/service.go (1)
  • Service (16-18)
internal/gateway/settings/defaults.go (4)
  • KeyProtectedEnvVars (102-102)
  • KeySecretEnvVars (105-105)
  • KeyApprovedDeployCommands (95-95)
  • KeyServiceImagePatterns (106-106)
internal/gateway/settings/service_session.go (2)
internal/gateway/settings/service.go (1)
  • Service (16-18)
internal/gateway/settings/defaults.go (1)
  • KeySessionTimeoutMinutes (29-29)
internal/gateway/handlers/settings.go (1)
internal/gateway/settings/groups.go (2)
  • GlobalSettingGroupKeyStrings (48-55)
  • GlobalSettingGroupSessionConfiguration (14-14)
internal/gateway/handlers/auth_test.go (1)
internal/gateway/auth/session_manager.go (2)
  • NewSessionManager (67-73)
  • StaticTTLProvider (31-33)
internal/gateway/handlers/auth_mfa_verification_test.go (1)
internal/gateway/auth/session_manager.go (2)
  • NewSessionManager (67-73)
  • StaticTTLProvider (31-33)
internal/gateway/middleware/auth_test.go (1)
internal/gateway/auth/session_manager.go (2)
  • NewSessionManager (67-73)
  • StaticTTLProvider (31-33)
web/src/pages/settings-page.tsx (1)
web/src/pages/settings/session-timeout-card.tsx (1)
  • SessionTimeoutCard (21-172)
web/src/pages/tokens-page/delete-token-dialog.tsx (2)
web/src/pages/tokens-page/use-token-mutations.ts (1)
  • useTokenMutations (8-63)
web/src/contexts/step-up-context.tsx (1)
  • useStepUp (353-359)
web/src/pages/tokens-page/use-token-mutations.ts (1)
web/src/lib/api.ts (1)
  • api (428-460)
internal/cli/convox_builds.go (1)
internal/convox/commands.go (1)
  • Command (13-18)
internal/gateway/handlers/dto.go (2)
internal/gateway/version/version.go (2)
  • Version (6-6)
  • CommitHash (9-9)
internal/cli/globals.go (1)
  • Version (25-25)
web/src/pages/tokens-page/edit-token-dialog.tsx (2)
web/src/pages/tokens-page/use-token-mutations.ts (1)
  • useTokenMutations (8-63)
web/src/contexts/step-up-context.tsx (1)
  • useStepUp (353-359)
internal/gateway/handlers/settings_test.go (1)
internal/gateway/auth/session_manager.go (2)
  • NewSessionManager (67-73)
  • StaticTTLProvider (31-33)
internal/gateway/middleware/mfa_stepup_totp_test.go (1)
internal/gateway/auth/session_manager.go (2)
  • NewSessionManager (67-73)
  • StaticTTLProvider (31-33)
internal/gateway/app/setup.go (2)
internal/gateway/settings/service.go (1)
  • NewService (21-23)
internal/gateway/auth/session_manager.go (2)
  • SessionManager (41-45)
  • NewSessionManager (67-73)
🪛 LanguageTool
docs/CONFIGURATION.md

[style] ~29-~29: To form a complete sentence, be sure to include a subject.
Context: ...window for browser sessions in minutes. Can also be configured via the Settings pag...

(MISSING_IT_THERE)

⏰ 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). (4)
  • GitHub Check: build-image
  • GitHub Check: web-tests
  • GitHub Check: lint
  • GitHub Check: go-tests

Comment thread internal/gateway/db/settings.go Outdated
Comment thread web/vite.config.ts
@ndbroadbent ndbroadbent changed the title nathan/fix github issues 2 4 5 6 fix all open github issues Nov 28, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/cli/deploy_approvals_request.go (1)

236-268: Refactor polling loop to avoid time.Sleep and use a context-aware ticker

The waitForDeployApproval function uses time.Sleep(interval) at line 266, which is forbidden by the project's golangci-lint forbidigo rule. The linting configuration explicitly prohibits time.Sleep with the message "avoid time.Sleep; use context with timeout."

Refactor to use time.Ticker driven by cmd.Context() (optionally wrapped with context.WithTimeout when timeout > 0) so that:

  • Cancellation via context (e.g., CTRL‑C or parent context cancellation) is honored.
  • Timeout is managed by context rather than manual time.Since(start) checks.
  • The loop no longer calls time.Sleep directly.

Suggested approach:

  • Derive a context from cmd.Context() with context.WithTimeout when timeout > 0.
  • Use a time.Ticker for interval.
  • In the loop, select on ctx.Done() vs <-ticker.C, performing the status fetch and status/timeout handling on ticker ticks.

This change is required to pass the linting checks in CI.

🧹 Nitpick comments (5)
internal/gateway/handlers/deploy_approval_admin.go (1)

48-62: Consider consistent error handling for invalid numeric input.

The helper silently ignores non-numeric strings (returns 0, true on line 55) but explicitly rejects negative values with an error response. This inconsistency could lead to confusing behavior—limit=-5 returns a 400 error, but limit=abc silently defaults to 0.

If silent fallback is intentional (e.g., for backwards compatibility), consider adding a brief comment explaining this design choice. Otherwise, consider returning an error for non-numeric values as well.

internal/cli/deploy_approvals_wait.go (1)

245-247: Consider using context-aware sleep for CLI polling.

Per coding guidelines, time.Sleep is a forbidden pattern—context with timeout is preferred. While this is a CLI command (not a server handler), using time.After with context cancellation would allow graceful shutdown on Ctrl+C during the polling loop.

+func (w *deployApprovalWaiter) sleep(ctx context.Context) error {
+	select {
+	case <-time.After(w.pollInterval):
+		return nil
+	case <-ctx.Done():
+		return ctx.Err()
+	}
+}
-func (w *deployApprovalWaiter) sleep() {
-	time.Sleep(w.pollInterval)
-}

Based on coding guidelines regarding time.Sleep usage.

internal/cli/deploy_approvals_list.go (1)

58-68: Consider warning on rack query failures instead of silently continuing.

When a gateway request fails for a rack, the error is silently ignored. This could mask connectivity issues or authentication problems. Consider printing a warning so users know which racks failed:

 	for _, rack := range racks {
 		var result deployApprovalRequestList
 		if err := gatewayRequest(cmd, rack, http.MethodGet, endpoint, nil, &result); err != nil {
-			// Continue to next rack on error
+			fmt.Fprintf(cmd.ErrOrStderr(), "Warning: failed to query rack %s: %v\n", rack, err)
 			continue
 		}
internal/cli/deploy_approvals_approve.go (1)

123-127: Clarify error handling for stdin read failures.

The error message "aborted" is returned for any read error, including EOF when input is piped. Consider distinguishing:

-		if _, err := reader.ReadString('\n'); err != nil {
-			return fmt.Errorf("aborted")
+		if _, err := reader.ReadString('\n'); err != nil {
+			return fmt.Errorf("approval aborted: %w", err)
 		}

This provides more context if the command is used non-interactively.

internal/cli/deploy_approvals_show.go (1)

128-152: Consider consolidating with findPendingRequest to reduce duplication.

This function shares significant logic with findPendingRequest in deploy_approvals_approve.go—both build query parameters, iterate racks, and return the first matching request. The main difference is the return signature.

Consider extracting a shared helper that both can use, or unifying the signatures. This would reduce duplication (~20 lines) and ensure consistent behavior.

Example unified helper:

func findRequest(cmd *cobra.Command, racks []string, status, branch, commit string) (*deployApprovalRequest, string, error) {
    // ... shared logic ...
    // Returns (request, rack, nil) on success, (nil, "", nil) if not found
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f71aaae and d719bb1.

📒 Files selected for processing (14)
  • .deepsource.toml (1 hunks)
  • CLAUDE.md (1 hunks)
  • internal/cli/deploy_approvals_approve.go (2 hunks)
  • internal/cli/deploy_approvals_command.go (1 hunks)
  • internal/cli/deploy_approvals_list.go (1 hunks)
  • internal/cli/deploy_approvals_request.go (1 hunks)
  • internal/cli/deploy_approvals_shared.go (2 hunks)
  • internal/cli/deploy_approvals_show.go (1 hunks)
  • internal/cli/deploy_approvals_wait.go (1 hunks)
  • internal/gateway/db/deploy_approval_requests_queries.go (2 hunks)
  • internal/gateway/db/settings.go (3 hunks)
  • internal/gateway/handlers/deploy_approval_admin.go (1 hunks)
  • web/.eslintrc.json (1 hunks)
  • web/vite.config.ts (2 hunks)
✅ Files skipped from review due to trivial changes (2)
  • web/.eslintrc.json
  • .deepsource.toml
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/cli/deploy_approvals_command.go
  • web/vite.config.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: Maximum 500 lines per Go code file - refactor immediately if approaching this limit or split into smaller, focused modules
Maximum 100 lines per function (Go) - enforced by golangci-lint using funlen linter
Maximum 50 statements per function (Go) - enforced by golangci-lint
Maximum cognitive complexity of 15 (Go) - enforced by golangci-lint using gocognit linter
Line length maximum 120 characters - enforced by golangci-lint lll rule. Exception: For Go struct tag lines that cannot be broken without invalidating formatting (where gofmt/goimports always rejoin them and field+tag exceeds 120 chars), add //nolint:lll at end of line only
No //nolint comments allowed except for struct tag line length exceptions - fix the code instead of suppressing warnings
Forbidden patterns in Go: panic (use error returns), fmt.Print* except in CLI output (use proper logging), time.Sleep (use context with timeout)
Zero code duplication allowed in production code - threshold 10 lines or 50 tokens, enforced by jscpd
Use govulncheck to check for known Go vulnerabilities - required security scan

Files:

  • internal/gateway/db/settings.go
  • internal/cli/deploy_approvals_list.go
  • internal/gateway/handlers/deploy_approval_admin.go
  • internal/gateway/db/deploy_approval_requests_queries.go
  • internal/cli/deploy_approvals_shared.go
  • internal/cli/deploy_approvals_request.go
  • internal/cli/deploy_approvals_approve.go
  • internal/cli/deploy_approvals_wait.go
  • internal/cli/deploy_approvals_show.go
internal/gateway/db/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Database layer code should follow Repository pattern for data access abstractions

Files:

  • internal/gateway/db/settings.go
  • internal/gateway/db/deploy_approval_requests_queries.go
internal/gateway/**/*.go

📄 CodeRabbit inference engine (internal/gateway/CLAUDE.md)

Use audit logger for all sensitive data in Go files

Files:

  • internal/gateway/db/settings.go
  • internal/gateway/handlers/deploy_approval_admin.go
  • internal/gateway/db/deploy_approval_requests_queries.go
🧬 Code graph analysis (5)
internal/gateway/db/settings.go (1)
internal/gateway/db/database.go (1)
  • Database (21-26)
internal/gateway/handlers/deploy_approval_admin.go (2)
internal/gateway/db/deploy_approval_requests_queries.go (1)
  • DeployApprovalRequestListOptions (82-90)
internal/gateway/openapi/serve.go (1)
  • JSON (26-28)
internal/cli/deploy_approvals_shared.go (1)
internal/cli/rack.go (1)
  • SelectedRack (11-32)
internal/cli/deploy_approvals_request.go (1)
internal/cli/rack.go (1)
  • SelectedRack (11-32)
internal/cli/deploy_approvals_approve.go (2)
internal/convox/commands.go (1)
  • Command (13-18)
internal/cli/utils.go (1)
  • SilenceOnError (17-26)
⏰ 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). (4)
  • GitHub Check: web-tests
  • GitHub Check: go-tests
  • GitHub Check: lint
  • GitHub Check: build-image
🔇 Additional comments (18)
CLAUDE.md (1)

92-101: Clear and actionable DeepSource documentation.

The new section effectively explains the distinction between local Biome linting and CI-based DeepSource ESLint analysis, with concrete guidance on where and how to disable rules. The example of react/jsx-no-bind with rationale is helpful for developers.

internal/gateway/handlers/deploy_approval_admin.go (1)

25-46: LGTM!

The refactored option parsing is cleaner with composite literal initialization and proper use of the parseNonNegativeInt helper for validation.

internal/gateway/db/deploy_approval_requests_queries.go (1)

82-90: LGTM!

The new GitBranch and GitCommitHash filter fields are cleanly integrated following the existing pattern of conditional WHERE clause construction with parameterized queries.

Also applies to: 109-116

internal/cli/deploy_approvals_shared.go (3)

99-108: Verify //nolint:gosec usage aligns with project policy.

Per coding guidelines, //nolint comments are generally not allowed except for struct tag line length exceptions. This //nolint:gosec suppresses G204 (subprocess launched with variable) which is a false positive here since the command is hardcoded.

Consider whether this exception is acceptable under project policy, or if there's an alternative approach (e.g., adding the file to gosec's exclude list).

Based on coding guidelines regarding nolint usage.


74-97: LGTM!

The resolveRacks helper properly handles empty input, comma-separated values, and whitespace trimming. Good defensive programming with the empty racks check at the end.


110-124: LGTM!

The fallback logic to current git branch when neither branch nor commit is specified is clean and provides good UX for the common case.

internal/cli/deploy_approvals_wait.go (1)

62-65: LGTM!

Good refactoring to use the centralized resolveRacks helper, reducing code duplication.

internal/cli/deploy_approvals_list.go (2)

82-101: LGTM!

Clean URL construction using url.Values for proper parameter encoding.


103-152: LGTM!

The table formatting handles both single and multi-rack display modes well, with appropriate truncation for long values.

internal/cli/deploy_approvals_approve.go (2)

63-87: LGTM!

The dual-mode execution flow (ID-based vs search-based) is cleanly implemented with proper UUID validation for direct approval.


108-141: LGTM!

The search-based approval flow with interactive confirmation provides good UX. The error messages correctly report which criterion (branch or commit) was used for the search.

internal/cli/deploy_approvals_show.go (2)

61-85: LGTM!

The execution flow cleanly handles both ID-based and search-based lookups with proper UUID validation.


154-191: LGTM!

Comprehensive output formatting with proper handling of optional fields (token name, approval timestamps, notes).

internal/gateway/db/settings.go (4)

68-90: LGTM! SQL constants successfully eliminate duplication.

The extraction of SQL upsert statements into named constants addresses the code duplication concern from the previous review. The SQL syntax is correct for PostgreSQL, including the COALESCE(app_name, '') for handling NULL in the unique constraint and the ?::jsonb cast for proper type handling.


119-134: LGTM! Clean delegation to centralized core function.

The UpsertSetting method now correctly delegates to upsertSettingCore with nil transaction parameter, maintaining its non-transactional behavior while eliminating code duplication.


136-174: LGTM! Well-structured atomic batch update operation.

The new UpsertSettingsInTx function provides atomic batch update capability with correct transaction handling:

  • Early return for empty updates (defensive programming)
  • Proper transaction lifecycle: Begin → deferred Rollback → explicit Commit
  • Consistent error wrapping with context (scope and key)
  • Leverages the centralized upsertSettingCore for each setting

The transaction pattern ensures all-or-nothing semantics for batch updates, which is essential for maintaining configuration consistency.


92-117: execTx method exists with correct signature—refactoring is sound.

The execTx method is properly defined in internal/gateway/db/database.go (line 304) with the expected signature func (d *Database) execTx(tx *sql.Tx, q string, args ...interface{}) (sql.Result, error). The implementation correctly delegates to tx.Exec() after logging and rebinding the query. The centralized upsertSettingCore function successfully eliminates duplication by abstracting transaction vs. non-transaction execution paths, and all method calls are valid.

internal/cli/deploy_approvals_request.go (1)

79-101: Centralizing rack resolution via SelectedRack is consistent with other CLI commands

Using SelectedRack() here instead of a per-command rack flag brings this command in line with the shared rack selection logic used elsewhere (env, login state, global --rack), and the error path clearly surfaces when no rack is selected. This looks correct and simplifies configuration flow for deploy approval requests.

@ndbroadbent ndbroadbent merged commit 271e671 into main Nov 28, 2025
10 checks passed
@ndbroadbent ndbroadbent deleted the nathan/fix-github-issues-2-4-5-6 branch November 28, 2025 04:57
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