feat(deployment): close trial deployments after 24h#1725
Conversation
WalkthroughThis change introduces a complete system for cleaning up stale trial deployments after a configurable period (default 24 hours). It adds environment configuration, a new CLI command, a controller, a service to perform the cleanup, repository methods, supporting types, and comprehensive tests. Test seeders and constants are also updated. Changes
Sequence Diagram(s)sequenceDiagram
participant CLI as CLI Command
participant Controller as TrialController
participant Service as TrialDeploymentsCleanerService
participant Repo as DeploymentRepository
participant WalletRepo as UserWalletRepository
participant BlockRepo as BlockRepository
participant Signer as ManagedSignerService
CLI->>Controller: cleanUpTrialDeployments(options)
Controller->>Service: cleanup(options)
Service->>BlockRepo: getLatestHeight()
Service->>WalletRepo: paginateTrialUserWallets()
loop for each trial wallet (concurrently)
Service->>Repo: findDeploymentsBeforeCutoff({owner, cutoffHeight})
alt stale deployments found
Service->>Signer: sendCloseDeploymentMsgs()
alt fee error
Service->>Signer: authorizeSpending()
Service->>Signer: sendCloseDeploymentMsgs() (retry)
end
end
end
Service-->>Controller: (cleanup complete)
Controller-->>CLI: (done)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~90 minutes Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
npm error Exit handler never called! Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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). (2)
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
apps/api/test/seeders/stale-deployment.seeder.ts (1)
5-11: Consider using a simple function instead of a static-only class.The static analysis tool correctly identifies that this class contains only static members. Consider refactoring to a simple function for better simplicity:
-export class StaleDeploymentSeeder { - static create({ dseq = faker.number.int({ min: 1, max: 99999999 }) }: Partial<StaleDeploymentsOutput> = {}): StaleDeploymentsOutput { - return { - dseq - }; - } -} +export const createStaleDeployment = ({ dseq = faker.number.int({ min: 1, max: 99999999 }) }: Partial<StaleDeploymentsOutput> = {}): StaleDeploymentsOutput => { + return { + dseq + }; +};The functionality is correct, but a simple function would be more appropriate here.
apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts (1)
93-93: Consider more robust error message detection.The fee authorization error detection relies on string matching (
"not allowed to pay fees"). Consider using error codes or more specific error types for more reliable error handling.-if (error.message.includes("not allowed to pay fees")) { +if (error.message.includes("not allowed to pay fees") || error.code === "INSUFFICIENT_FEE_ALLOWANCE") {apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.ts (1)
192-203: Consider using inline type definition for setup parameter.According to the coding guidelines, the setup function should accept a single parameter with inline type definition rather than using a separate interface-like structure.
-function setup(input: { - trialWallets: any[]; - staleDeployments?: StaleDeploymentsOutput[]; - staleDeployments1?: StaleDeploymentsOutput[]; - staleDeployments2?: StaleDeploymentsOutput[]; - closeMessages?: any[]; - closeMessages1?: any[]; - closeMessages2?: any[]; - concurrency?: number; - feeError?: boolean; - networkError?: boolean; -}) { +function setup(input: { + trialWallets: any[]; + staleDeployments?: StaleDeploymentsOutput[]; + staleDeployments1?: StaleDeploymentsOutput[]; + staleDeployments2?: StaleDeploymentsOutput[]; + closeMessages?: any[]; + closeMessages1?: any[]; + closeMessages2?: any[]; + concurrency?: number; + feeError?: boolean; + networkError?: boolean; +}) {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
apps/api/src/billing/config/env.config.ts(1 hunks)apps/api/src/chain/repositories/block.repository.ts(1 hunks)apps/api/src/console.ts(2 hunks)apps/api/src/deployment/controllers/deployment/trial.controller.spec.ts(1 hunks)apps/api/src/deployment/controllers/deployment/trial.controller.ts(1 hunks)apps/api/src/deployment/repositories/deployment/deployment.repository.ts(2 hunks)apps/api/src/deployment/services/draining-deployment/draining-deployment.service.spec.ts(1 hunks)apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.ts(1 hunks)apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts(1 hunks)apps/api/src/deployment/types/trial-deployments.ts(1 hunks)apps/api/src/utils/constants.ts(1 hunks)apps/api/test/functional/gpu.spec.ts(4 hunks)apps/api/test/seeders/index.ts(1 hunks)apps/api/test/seeders/stale-deployment.seeder.ts(1 hunks)
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/general.mdc)
Never use type any or cast to type any. Always define the proper TypeScript types.
Files:
apps/api/src/billing/config/env.config.tsapps/api/src/deployment/types/trial-deployments.tsapps/api/src/chain/repositories/block.repository.tsapps/api/src/utils/constants.tsapps/api/test/seeders/index.tsapps/api/src/deployment/services/draining-deployment/draining-deployment.service.spec.tsapps/api/src/deployment/controllers/deployment/trial.controller.spec.tsapps/api/src/deployment/controllers/deployment/trial.controller.tsapps/api/test/functional/gpu.spec.tsapps/api/test/seeders/stale-deployment.seeder.tsapps/api/src/console.tsapps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.tsapps/api/src/deployment/repositories/deployment/deployment.repository.tsapps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/general.mdc)
**/*.{js,jsx,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code
Files:
apps/api/src/billing/config/env.config.tsapps/api/src/deployment/types/trial-deployments.tsapps/api/src/chain/repositories/block.repository.tsapps/api/src/utils/constants.tsapps/api/test/seeders/index.tsapps/api/src/deployment/services/draining-deployment/draining-deployment.service.spec.tsapps/api/src/deployment/controllers/deployment/trial.controller.spec.tsapps/api/src/deployment/controllers/deployment/trial.controller.tsapps/api/test/functional/gpu.spec.tsapps/api/test/seeders/stale-deployment.seeder.tsapps/api/src/console.tsapps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.tsapps/api/src/deployment/repositories/deployment/deployment.repository.tsapps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts
**/*.spec.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/no-jest-mock.mdc)
Don't use
jest.mock()to mock dependencies in test files. Instead, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under test.
**/*.spec.{ts,tsx}: Usesetupfunction instead ofbeforeEachin test files
setupfunction must be at the bottom of the rootdescribeblock in test files
setupfunction creates an object under test and returns it
setupfunction should accept a single parameter with inline type definition
Don't use shared state insetupfunction
Don't specify return type ofsetupfunction
Files:
apps/api/src/deployment/services/draining-deployment/draining-deployment.service.spec.tsapps/api/src/deployment/controllers/deployment/trial.controller.spec.tsapps/api/test/functional/gpu.spec.tsapps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.ts
🧠 Learnings (10)
apps/api/src/chain/repositories/block.repository.ts (1)
Learnt from: devalpatel67
PR: #1646
File: apps/api/src/provider/services/provider-earnings/provider-earnings.service.ts:41-41
Timestamp: 2025-07-09T03:30:51.075Z
Learning: The getProviderEarningsAtHeight function in apps/api/src/services/db/statsService.ts is designed to be flexible and can be used for different earnings calculations: (1) For total lifetime earnings, pass provider.createdHeight as the second parameter, (2) For date-range earnings, pass fromBlock.height as the second parameter. The second parameter acts as a lower bound and the third parameter as an upper bound for the earnings calculation.
apps/api/test/seeders/index.ts (1)
Learnt from: baktun14
PR: #1428
File: apps/api/src/deployment/controllers/deployment/deployment.controller.ts:0-0
Timestamp: 2025-06-03T15:06:34.211Z
Learning: The getByOwnerAndDseq method in apps/api/src/deployment/controllers/deployment/deployment.controller.ts is intentionally public without the @Protected decorator because it serves public blockchain data from an indexer, following the pattern of public blockchain APIs.
apps/api/src/deployment/services/draining-deployment/draining-deployment.service.spec.ts (1)
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files
apps/api/src/deployment/controllers/deployment/trial.controller.spec.ts (6)
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-07-21T08:24:24.269Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use setup function instead of beforeEach in test files
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function creates an object under test and returns it
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use shared state in setup function
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function must be at the bottom of the root describe block in test files
apps/api/src/deployment/controllers/deployment/trial.controller.ts (1)
Learnt from: baktun14
PR: #1428
File: apps/api/src/deployment/controllers/deployment/deployment.controller.ts:0-0
Timestamp: 2025-06-03T15:06:34.211Z
Learning: The getByOwnerAndDseq method in apps/api/src/deployment/controllers/deployment/deployment.controller.ts is intentionally public without the @Protected decorator because it serves public blockchain data from an indexer, following the pattern of public blockchain APIs.
apps/api/test/functional/gpu.spec.ts (3)
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use setup function instead of beforeEach in test files
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use shared state in setup function
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function creates an object under test and returns it
apps/api/test/seeders/stale-deployment.seeder.ts (2)
Learnt from: baktun14
PR: #1428
File: apps/api/src/deployment/controllers/deployment/deployment.controller.ts:0-0
Timestamp: 2025-06-03T15:06:34.211Z
Learning: The getByOwnerAndDseq method in apps/api/src/deployment/controllers/deployment/deployment.controller.ts is intentionally public without the @Protected decorator because it serves public blockchain data from an indexer, following the pattern of public blockchain APIs.
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function creates an object under test and returns it
apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.ts (7)
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-07-21T08:24:24.269Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use setup function instead of beforeEach in test files
Learnt from: stalniy
PR: #1436
File: apps/api/src/provider/repositories/provider/provider.repository.ts:79-90
Timestamp: 2025-06-08T03:07:13.871Z
Learning: The getProvidersHostUriByAttributes method in apps/api/src/provider/repositories/provider/provider.repository.ts already has comprehensive test coverage in provider.repository.spec.ts, including tests for complex HAVING clause logic with COUNT(*) FILTER (WHERE ...) syntax, signature conditions (anyOf/allOf), and glob pattern matching.
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function creates an object under test and returns it
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use shared state in setup function
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function must be at the bottom of the root describe block in test files
apps/api/src/deployment/repositories/deployment/deployment.repository.ts (2)
Learnt from: baktun14
PR: #1428
File: apps/api/src/deployment/controllers/deployment/deployment.controller.ts:0-0
Timestamp: 2025-06-03T15:06:34.211Z
Learning: The getByOwnerAndDseq method in apps/api/src/deployment/controllers/deployment/deployment.controller.ts is intentionally public without the @Protected decorator because it serves public blockchain data from an indexer, following the pattern of public blockchain APIs.
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files
apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts (1)
Learnt from: baktun14
PR: #1428
File: apps/api/src/deployment/controllers/deployment/deployment.controller.ts:0-0
Timestamp: 2025-06-03T15:06:34.211Z
Learning: The getByOwnerAndDseq method in apps/api/src/deployment/controllers/deployment/deployment.controller.ts is intentionally public without the @Protected decorator because it serves public blockchain data from an indexer, following the pattern of public blockchain APIs.
🧬 Code Graph Analysis (4)
apps/api/src/deployment/types/trial-deployments.ts (1)
apps/api/src/core/types/console.ts (1)
ConcurrencyOptions(5-7)
apps/api/src/utils/constants.ts (1)
apps/indexer/src/shared/constants.ts (1)
averageBlockTime(6-6)
apps/api/test/seeders/stale-deployment.seeder.ts (1)
apps/api/src/deployment/repositories/deployment/deployment.repository.ts (1)
StaleDeploymentsOutput(22-24)
apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts (7)
apps/api/src/chain/repositories/block.repository.ts (1)
singleton(4-17)apps/api/src/deployment/controllers/deployment/trial.controller.ts (1)
singleton(6-13)apps/api/src/deployment/repositories/deployment/deployment.repository.ts (2)
singleton(26-138)StaleDeploymentsOutput(22-24)apps/api/src/billing/providers/config.provider.ts (2)
InjectBillingConfig(11-11)BillingConfig(9-9)apps/api/src/deployment/types/trial-deployments.ts (1)
CleanUpTrialDeploymentsParams(3-3)apps/api/src/utils/constants.ts (1)
averageBlockCountInAnHour(9-9)apps/api/src/billing/repositories/user-wallet/user-wallet.repository.ts (1)
UserWalletOutput(16-20)
🪛 Biome (1.9.4)
apps/api/test/seeders/stale-deployment.seeder.ts
[error] 5-11: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/general.mdc)
Never use type any or cast to type any. Always define the proper TypeScript types.
Files:
apps/api/src/billing/config/env.config.tsapps/api/src/deployment/types/trial-deployments.tsapps/api/src/chain/repositories/block.repository.tsapps/api/src/utils/constants.tsapps/api/test/seeders/index.tsapps/api/src/deployment/services/draining-deployment/draining-deployment.service.spec.tsapps/api/src/deployment/controllers/deployment/trial.controller.spec.tsapps/api/src/deployment/controllers/deployment/trial.controller.tsapps/api/test/functional/gpu.spec.tsapps/api/test/seeders/stale-deployment.seeder.tsapps/api/src/console.tsapps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.tsapps/api/src/deployment/repositories/deployment/deployment.repository.tsapps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/general.mdc)
**/*.{js,jsx,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code
Files:
apps/api/src/billing/config/env.config.tsapps/api/src/deployment/types/trial-deployments.tsapps/api/src/chain/repositories/block.repository.tsapps/api/src/utils/constants.tsapps/api/test/seeders/index.tsapps/api/src/deployment/services/draining-deployment/draining-deployment.service.spec.tsapps/api/src/deployment/controllers/deployment/trial.controller.spec.tsapps/api/src/deployment/controllers/deployment/trial.controller.tsapps/api/test/functional/gpu.spec.tsapps/api/test/seeders/stale-deployment.seeder.tsapps/api/src/console.tsapps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.tsapps/api/src/deployment/repositories/deployment/deployment.repository.tsapps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts
**/*.spec.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/no-jest-mock.mdc)
Don't use
jest.mock()to mock dependencies in test files. Instead, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under test.
**/*.spec.{ts,tsx}: Usesetupfunction instead ofbeforeEachin test files
setupfunction must be at the bottom of the rootdescribeblock in test files
setupfunction creates an object under test and returns it
setupfunction should accept a single parameter with inline type definition
Don't use shared state insetupfunction
Don't specify return type ofsetupfunction
Files:
apps/api/src/deployment/services/draining-deployment/draining-deployment.service.spec.tsapps/api/src/deployment/controllers/deployment/trial.controller.spec.tsapps/api/test/functional/gpu.spec.tsapps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.ts
🧠 Learnings (10)
apps/api/src/chain/repositories/block.repository.ts (1)
Learnt from: devalpatel67
PR: #1646
File: apps/api/src/provider/services/provider-earnings/provider-earnings.service.ts:41-41
Timestamp: 2025-07-09T03:30:51.075Z
Learning: The getProviderEarningsAtHeight function in apps/api/src/services/db/statsService.ts is designed to be flexible and can be used for different earnings calculations: (1) For total lifetime earnings, pass provider.createdHeight as the second parameter, (2) For date-range earnings, pass fromBlock.height as the second parameter. The second parameter acts as a lower bound and the third parameter as an upper bound for the earnings calculation.
apps/api/test/seeders/index.ts (1)
Learnt from: baktun14
PR: #1428
File: apps/api/src/deployment/controllers/deployment/deployment.controller.ts:0-0
Timestamp: 2025-06-03T15:06:34.211Z
Learning: The getByOwnerAndDseq method in apps/api/src/deployment/controllers/deployment/deployment.controller.ts is intentionally public without the @Protected decorator because it serves public blockchain data from an indexer, following the pattern of public blockchain APIs.
apps/api/src/deployment/services/draining-deployment/draining-deployment.service.spec.ts (1)
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files
apps/api/src/deployment/controllers/deployment/trial.controller.spec.ts (6)
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-07-21T08:24:24.269Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use setup function instead of beforeEach in test files
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function creates an object under test and returns it
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use shared state in setup function
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function must be at the bottom of the root describe block in test files
apps/api/src/deployment/controllers/deployment/trial.controller.ts (1)
Learnt from: baktun14
PR: #1428
File: apps/api/src/deployment/controllers/deployment/deployment.controller.ts:0-0
Timestamp: 2025-06-03T15:06:34.211Z
Learning: The getByOwnerAndDseq method in apps/api/src/deployment/controllers/deployment/deployment.controller.ts is intentionally public without the @Protected decorator because it serves public blockchain data from an indexer, following the pattern of public blockchain APIs.
apps/api/test/functional/gpu.spec.ts (3)
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use setup function instead of beforeEach in test files
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use shared state in setup function
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function creates an object under test and returns it
apps/api/test/seeders/stale-deployment.seeder.ts (2)
Learnt from: baktun14
PR: #1428
File: apps/api/src/deployment/controllers/deployment/deployment.controller.ts:0-0
Timestamp: 2025-06-03T15:06:34.211Z
Learning: The getByOwnerAndDseq method in apps/api/src/deployment/controllers/deployment/deployment.controller.ts is intentionally public without the @Protected decorator because it serves public blockchain data from an indexer, following the pattern of public blockchain APIs.
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function creates an object under test and returns it
apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.ts (7)
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-07-21T08:24:24.269Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Use setup function instead of beforeEach in test files
Learnt from: stalniy
PR: #1436
File: apps/api/src/provider/repositories/provider/provider.repository.ts:79-90
Timestamp: 2025-06-08T03:07:13.871Z
Learning: The getProvidersHostUriByAttributes method in apps/api/src/provider/repositories/provider/provider.repository.ts already has comprehensive test coverage in provider.repository.spec.ts, including tests for complex HAVING clause logic with COUNT(*) FILTER (WHERE ...) syntax, signature conditions (anyOf/allOf), and glob pattern matching.
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function creates an object under test and returns it
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use shared state in setup function
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/setup-instead-of-before-each.mdc:0-0
Timestamp: 2025-07-21T08:25:07.474Z
Learning: Applies to **/*.spec.{ts,tsx} : setup function must be at the bottom of the root describe block in test files
apps/api/src/deployment/repositories/deployment/deployment.repository.ts (2)
Learnt from: baktun14
PR: #1428
File: apps/api/src/deployment/controllers/deployment/deployment.controller.ts:0-0
Timestamp: 2025-06-03T15:06:34.211Z
Learning: The getByOwnerAndDseq method in apps/api/src/deployment/controllers/deployment/deployment.controller.ts is intentionally public without the @Protected decorator because it serves public blockchain data from an indexer, following the pattern of public blockchain APIs.
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use queryBy methods instead of getBy methods in test expectations in .spec.tsx files
apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts (1)
Learnt from: baktun14
PR: #1428
File: apps/api/src/deployment/controllers/deployment/deployment.controller.ts:0-0
Timestamp: 2025-06-03T15:06:34.211Z
Learning: The getByOwnerAndDseq method in apps/api/src/deployment/controllers/deployment/deployment.controller.ts is intentionally public without the @Protected decorator because it serves public blockchain data from an indexer, following the pattern of public blockchain APIs.
🧬 Code Graph Analysis (4)
apps/api/src/deployment/types/trial-deployments.ts (1)
apps/api/src/core/types/console.ts (1)
ConcurrencyOptions(5-7)
apps/api/src/utils/constants.ts (1)
apps/indexer/src/shared/constants.ts (1)
averageBlockTime(6-6)
apps/api/test/seeders/stale-deployment.seeder.ts (1)
apps/api/src/deployment/repositories/deployment/deployment.repository.ts (1)
StaleDeploymentsOutput(22-24)
apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts (7)
apps/api/src/chain/repositories/block.repository.ts (1)
singleton(4-17)apps/api/src/deployment/controllers/deployment/trial.controller.ts (1)
singleton(6-13)apps/api/src/deployment/repositories/deployment/deployment.repository.ts (2)
singleton(26-138)StaleDeploymentsOutput(22-24)apps/api/src/billing/providers/config.provider.ts (2)
InjectBillingConfig(11-11)BillingConfig(9-9)apps/api/src/deployment/types/trial-deployments.ts (1)
CleanUpTrialDeploymentsParams(3-3)apps/api/src/utils/constants.ts (1)
averageBlockCountInAnHour(9-9)apps/api/src/billing/repositories/user-wallet/user-wallet.repository.ts (1)
UserWalletOutput(16-20)
🪛 Biome (1.9.4)
apps/api/test/seeders/stale-deployment.seeder.ts
[error] 5-11: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
⏰ 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). (2)
- GitHub Check: validate / validate-app
- GitHub Check: test-build
🔇 Additional comments (21)
apps/api/src/chain/repositories/block.repository.ts (1)
12-16: LGTM! Clean implementation following existing patterns.The new
getLatestHeight()method correctly follows the same pattern asgetLatestProcessedHeight(), with proper type casting and null coalescing. This method serves the clear purpose of retrieving the latest block height without filtering constraints, which aligns well with the trial deployment cleanup functionality.apps/api/src/billing/config/env.config.ts (1)
12-12: LGTM! Well-structured environment configuration.The new
TRIAL_DEPLOYMENT_CLEANUP_HOURSenvironment variable follows the established patterns with proper type coercion and a sensible default of 24 hours. The naming is descriptive and it's appropriately positioned among other trial-related configurations.apps/api/test/seeders/index.ts (1)
13-13: LGTM! Properly exposes the new seeder.The export follows the established pattern and is correctly positioned among other seeder exports.
apps/api/src/deployment/services/draining-deployment/draining-deployment.service.spec.ts (1)
169-169: LGTM! Test expectations correctly updated.The updated expected values properly reflect the change in
averageBlockTimefrom 6.174 to 6. The test logic remains sound and the new values appear to be calculated correctly based on the updated constant.Also applies to: 174-174
apps/api/src/deployment/types/trial-deployments.ts (1)
1-3: LGTM! Well-structured type definition.The interface correctly extends
ConcurrencyOptionsand provides a clear semantic contract for trial deployment cleanup parameters. While currently empty, it establishes a proper foundation for future parameter additions.apps/api/test/functional/gpu.spec.ts (3)
31-32: Good improvement using dynamic date handling.Switching from fixed dates to dynamic
nowanddatevariables improves test reliability and prevents date-related test failures over time.
267-267: Excellent addition of explicit setup call.Adding the explicit
setup()call ensures proper test data initialization before making the API request, following testing best practices.
310-315: Price value adjustments look reasonable.The GPU price statistics changes (AMD: 1.17→1.2, NVIDIA: 0.58→0.6) appear to be test data corrections that align with the current test setup.
Also applies to: 332-337
apps/api/src/deployment/controllers/deployment/trial.controller.spec.ts (1)
1-31: Excellent test implementation following all guidelines!This test perfectly adheres to the coding guidelines:
- ✅ Uses
jest-mock-extendedinstead ofjest.mock()- ✅
setupfunction positioned at the bottom of the describe block- ✅
setupfunction creates and returns the object under test- ✅ No shared state in the setup function
- ✅ Proper TypeScript types throughout
The test logic correctly verifies that the controller delegates to the service with the provided options.
apps/api/src/deployment/controllers/deployment/trial.controller.ts (1)
1-13: Excellent controller implementation!This controller follows excellent practices:
- ✅ Proper use of
tsyringesingleton pattern- ✅ Clean dependency injection
- ✅ Thin controller layer that appropriately delegates to the service
- ✅ Correct TypeScript types
- ✅ Simple, focused responsibility
The delegation pattern is appropriate here, allowing the service layer to handle the complex cleanup logic while the controller serves as the entry point.
apps/api/src/deployment/repositories/deployment/deployment.repository.ts (2)
17-20: Well-defined interface for trial deployment options.The
TrialDeploymentsOptionsinterface clearly defines the required parameters with appropriate types.
65-79: Correct implementation of trial deployments query.The method properly filters deployments by owner, cutoff height, and open status. The simplified approach without joins is appropriate since no lease information is needed for trial deployment cleanup.
apps/api/src/console.ts (2)
16-16: Proper import for the trial controller.The import follows the established pattern for controller imports.
57-65: Well-structured CLI command implementation.The command follows established patterns with proper option validation, error handling, and clear description. The default concurrency of 10 is reasonable for this type of cleanup operation.
apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts (3)
29-40: Good calculation and logging of cleanup parameters.The height calculation logic is sound and the comprehensive logging provides excellent observability for the cleanup process.
42-64: Well-structured pagination and error handling.The pagination approach with concurrency control and per-wallet error handling ensures the cleanup process is resilient and won't fail completely if individual wallets encounter issues.
76-83: Excellent logging for deployment cleanup operations.The detailed logging with owner, deployment count, and specific dseqs provides great visibility into the cleanup process.
apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.ts (4)
28-86: Comprehensive test coverage for successful cleanup scenario.The test properly validates the entire cleanup flow including pagination, deployment querying, message creation, and transaction execution. Good use of multiple wallets to test concurrent processing.
88-112: Good test for empty deployment scenario.Properly verifies that wallets with no stale deployments are skipped and don't trigger unnecessary RPC calls.
114-141: Excellent test for fee authorization retry logic.This test correctly validates the retry mechanism when fee authorization fails, including the refill process and subsequent successful execution.
192-311: Setup function follows guidelines correctly.The setup function is properly positioned at the bottom of the describe block, creates and returns the service under test, and uses proper mocking patterns without shared state.
apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts
Outdated
Show resolved
Hide resolved
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1725 +/- ##
==========================================
- Coverage 72.65% 72.56% -0.09%
==========================================
Files 611 608 -3
Lines 14381 14269 -112
Branches 2470 2463 -7
==========================================
- Hits 10448 10355 -93
+ Misses 3802 3700 -102
- Partials 131 214 +83
*This pull request uses carry forward flags. Click here to find out more.
🚀 New features to boost your workflow:
|
apps/api/src/deployment/repositories/deployment/deployment.repository.ts
Outdated
Show resolved
Hide resolved
.../src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.ts
Outdated
Show resolved
Hide resolved
.../src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.spec.ts
Outdated
Show resolved
Hide resolved
apps/api/src/deployment/services/trial-deployments-cleaner/trial-deployments-cleaner.service.ts
Outdated
Show resolved
Hide resolved
aa5f8bb to
d045c41
Compare
* feat(deployment): close trial deployments that have been running for more than 24h * fix(analytics): gpu pricing test * fix(deployment): update test with new average block time * feat(deployment): add tests for the trial deployments clean up * feat: add clean up trial deployments job on staging * fix: max live blocks constant * fix(billing): pr fixes * fix(deployment): handle missing wallet address in trial deployments cleanup
#1700
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Chores
Refactor