Skip to content

feat(wallet): ensures managed wallet supports read-only mode during blockchain outage#2011

Merged
ygrishajev merged 1 commit intomainfrom
feature/managed-wallets-api
Oct 6, 2025
Merged

feat(wallet): ensures managed wallet supports read-only mode during blockchain outage#2011
ygrishajev merged 1 commit intomainfrom
feature/managed-wallets-api

Conversation

@ygrishajev
Copy link
Contributor

@ygrishajev ygrishajev commented Oct 3, 2025

Summary by CodeRabbit

  • New Features

    • Resilient fallback readers for deployments and leases enabling read-only access during node outages.
    • SDK typings made public for deployment and lease pagination responses.
  • Bug Fixes

    • Improved error handling and 404 behavior with graceful fallback to secondary data.
    • Pagination: next_key may be null when no further results exist.
  • Tests

    • Integration tests added to simulate outages, verify read-only behavior and recovery.

@ygrishajev ygrishajev requested a review from a team as a code owner October 3, 2025 15:55
@ygrishajev ygrishajev changed the title feat(wallet): ensures managed wallet supports read-only mode during b… feat(wallet): ensures managed wallet supports read-only mode during blockchain outage Oct 3, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

Walkthrough

Wires DB-backed fallback readers for deployments and leases into controllers, routes, and services; moves lease-fallback listing into a new FallbackLeaseReaderService; updates DeploymentReaderService to prefer HTTP then fall back to DB; adjusts HTTP-SDK exports/types; and extends functional tests for outage simulation and seeding.

Changes

Cohort / File(s) Summary of Changes
Controller wiring
apps/api/src/deployment/controllers/lease/lease.controller.ts
Injects FallbackLeaseReaderService into LeaseController and uses its list for fallback lease listing (replacing prior LeaseService.listLeasesFallback).
Router wiring
apps/api/src/deployment/routes/deployments/deployments.router.ts
Replaces DatabaseDeploymentReaderService with FallbackDeploymentReaderService; routes call findAll / findByOwnerAndDseq instead of previous methods.
Deployment reader (HTTP-first + DB fallback)
apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts
Adds HTTP-wrapper helpers (getDeployment, getDeploymentsList, getLeaseList) with try/catch and shouldFallbackToDatabase logic; injects FallbackDeploymentReaderService and FallbackLeaseReaderService; routes calls through these helpers and enforces 404s.
Fallback deployment reader rename + constants/method renames
apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts
Renames DatabaseDeploymentReaderServiceFallbackDeploymentReaderService; FALLBACK_VALUEUNKNOWN_DB_PLACEHOLDER; renames listDeploymentsfindAll, getDeploymentInfofindByOwnerAndDseq; updates response payloads.
New fallback lease reader
apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts
Adds FallbackLeaseReaderService with list(params) that pages via LeaseRepository, transforms leases + escrow_payment payloads, maps denoms (including env-driven USDC IBC handling), and returns pagination metadata.
Lease service cleanup
apps/api/src/deployment/services/lease/lease.service.ts
Removes listLeasesFallback, transformLease, and mapDenom (fallback listing and transform logic moved to new reader); drops related imports/constants.
Functional tests — outage scenarios & seeding
apps/api/test/functional/managed-api-deployment-flow.spec.ts
Adds outage simulation helpers (blockNode/unblockNode via nock), seeds deployments/groups/leases tied to walletAddress, updates helper signatures (createDeployment, createLease), adds getDeploymentList and typed response, and verifies read behavior during outage and recovery.
HTTP SDK types/exports
packages/http-sdk/src/deployment/deployment-http.service.ts, packages/http-sdk/src/lease/lease-http.service.ts
Exports DeploymentListResponse and PaginationParams; makes RestAkashLeaseListResponse.pagination.next_key `string

Sequence Diagram(s)

sequenceDiagram
  participant C as Client
  participant R as Router/Controller
  participant DR as DeploymentReaderService
  participant HS as HTTP SDK
  participant FDR as FallbackDeploymentReaderService
  participant FLR as FallbackLeaseReaderService
  participant DB as Database

  C->>R: GET /deployments or /deployments/:id
  R->>DR: request list/find
  DR->>HS: HTTP SDK call (primary)
  alt HTTP success
    HS-->>DR: data
    DR-->>R: return data
    R-->>C: 200 OK
  else HTTP failure → fallback
    note right of DR: shouldFallbackToDatabase() => true
    DR->>FDR: findAll / findByOwnerAndDseq
    FDR->>DB: query
    DB-->>FDR: rows
    FDR-->>DR: fallback data
    DR-->>R: return fallback data
    R-->>C: 200 OK (fallback)
  end

  C->>R: GET /leases?fallback=true
  R->>FLR: list(params)
  FLR->>DB: LeaseRepository paged query
  DB-->>FLR: leases + count
  FLR-->>R: transformed leases + pagination
  R-->>C: 200 OK
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • stalniy
  • baktun14

Poem

"I nibble logs and hop the stack,
When nodes fall short I find the track. 🐇
HTTP first, then burrow deep,
DB crumbs saved while others sleep.
A twitch, a hop — your data keeps."

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title concisely and accurately describes the central feature of this changeset by indicating that managed wallets will operate in read-only mode during blockchain outages, which directly reflects the addition of fallback reader services and associated outage simulation tests implemented in the PR. It specifies the affected module (wallet) and the key behavior change without extraneous detail.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ 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 feature/managed-wallets-api

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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

@ygrishajev ygrishajev force-pushed the feature/managed-wallets-api branch from aa688d7 to d68a627 Compare October 3, 2025 15:56
@codecov
Copy link

codecov bot commented Oct 3, 2025

Codecov Report

❌ Patch coverage is 83.14607% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 45.94%. Comparing base (0a25bb5) to head (475dd00).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ces/deployment-reader/deployment-reader.service.ts 71.11% 10 Missing and 3 partials ⚠️
...back-lease-reader/fallback-lease-reader.service.ts 93.54% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2011      +/-   ##
==========================================
+ Coverage   45.89%   45.94%   +0.04%     
==========================================
  Files        1012     1013       +1     
  Lines       28560    28605      +45     
  Branches     7454     7477      +23     
==========================================
+ Hits        13108    13142      +34     
- Misses      14237    14256      +19     
+ Partials     1215     1207       -8     
Flag Coverage Δ *Carryforward flag
api 82.22% <83.14%> (-0.04%) ⬇️
deploy-web 23.85% <ø> (ø)
log-collector 75.35% <ø> (ø)
notifications 88.16% <ø> (ø)
provider-console 81.48% <ø> (ø) Carriedforward from 0a25bb5
provider-proxy 84.98% <ø> (ø) Carriedforward from 0a25bb5

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...c/deployment/controllers/lease/lease.controller.ts 100.00% <100.00%> (ø)
...eployment/routes/deployments/deployments.router.ts 97.10% <100.00%> (ø)
...yment-reader/fallback-deployment-reader.service.ts 97.10% <100.00%> (ø)
...api/src/deployment/services/lease/lease.service.ts 100.00% <100.00%> (+4.00%) ⬆️
...back-lease-reader/fallback-lease-reader.service.ts 93.54% <93.54%> (ø)
...ces/deployment-reader/deployment-reader.service.ts 81.87% <71.11%> (-4.49%) ⬇️

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (2)
apps/api/test/functional/managed-api-deployment-flow.spec.ts (1)

462-567: Remove as any casts when attaching DB metadata.

Casting to any violates our TS guidelines and hides real typing errors. Instead, extend the deployment payload with a refinished type (e.g., intersect with { _dbId: string; _deploymentGroupId: string }) so both creation and lease helpers stay type-safe without falling back to any.

apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts (1)

110-114: Switch list flows to the fallback-aware lease reader

Line 112 still calls leaseHttpService.list, and Line 154 does the same. When the RPC endpoint is down, those direct HTTP calls reject before the new database fallback can run, so /v1/deployments and listWithResources remain broken in "read-only" mode. Please route these through getLeaseList(...), which already encapsulates the HTTP-first/DB-fallback logic.

Apply this diff:

       .for(deployments)
-      .process(async deployment => this.leaseHttpService.list({ owner, dseq: deployment.deployment.deployment_id.dseq }));
+      .process(async deployment => this.getLeaseList({ owner, dseq: deployment.deployment.deployment_id.dseq }));
@@
-    const leaseResponse = await this.leaseHttpService.list({ owner: address, state: "active" });
+    const leaseResponse = await this.getLeaseList({ owner: address, state: "active" });

Also applies to: 153-154

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a25bb5 and d68a627.

📒 Files selected for processing (9)
  • apps/api/src/deployment/controllers/lease/lease.controller.ts (2 hunks)
  • apps/api/src/deployment/routes/deployments/deployments.router.ts (3 hunks)
  • apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts (7 hunks)
  • apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts (4 hunks)
  • apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts (1 hunks)
  • apps/api/src/deployment/services/lease/lease.service.ts (1 hunks)
  • apps/api/test/functional/managed-api-deployment-flow.spec.ts (9 hunks)
  • packages/http-sdk/src/deployment/deployment-http.service.ts (2 hunks)
  • packages/http-sdk/src/lease/lease-http.service.ts (1 hunks)
🧰 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:

  • packages/http-sdk/src/lease/lease-http.service.ts
  • apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts
  • apps/api/src/deployment/services/lease/lease.service.ts
  • apps/api/test/functional/managed-api-deployment-flow.spec.ts
  • apps/api/src/deployment/routes/deployments/deployments.router.ts
  • packages/http-sdk/src/deployment/deployment-http.service.ts
  • apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts
  • apps/api/src/deployment/controllers/lease/lease.controller.ts
  • apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • packages/http-sdk/src/lease/lease-http.service.ts
  • apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts
  • apps/api/src/deployment/services/lease/lease.service.ts
  • apps/api/test/functional/managed-api-deployment-flow.spec.ts
  • apps/api/src/deployment/routes/deployments/deployments.router.ts
  • packages/http-sdk/src/deployment/deployment-http.service.ts
  • apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts
  • apps/api/src/deployment/controllers/lease/lease.controller.ts
  • apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.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, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/api/test/functional/managed-api-deployment-flow.spec.ts
🧠 Learnings (1)
📚 Learning: 2025-06-03T15:06:34.211Z
Learnt from: baktun14
PR: akash-network/console#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.

Applied to files:

  • apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts
🧬 Code graph analysis (5)
apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts (4)
apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts (1)
  • singleton (11-187)
apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts (1)
  • singleton (9-93)
packages/http-sdk/src/deployment/deployment-http.service.ts (4)
  • DeploymentHttpService (134-196)
  • RestAkashDeploymentInfoResponse (100-106)
  • PaginationParams (126-132)
  • DeploymentListResponse (108-114)
packages/http-sdk/src/lease/lease-http.service.ts (3)
  • LeaseHttpService (60-84)
  • LeaseListParams (50-58)
  • RestAkashLeaseListResponse (4-48)
apps/api/test/functional/managed-api-deployment-flow.spec.ts (4)
apps/api/src/deployment/http-schemas/deployment.schema.ts (1)
  • ListDeploymentsResponseSchema (123-133)
apps/indexer/drizzle/schema.ts (4)
  • deployment (180-203)
  • lease (110-178)
  • bid (47-69)
  • deploymentGroup (21-45)
apps/api/src/utils/constants.ts (1)
  • apiNodeUrl (19-19)
apps/api/test/seeders/deployment-group.seeder.ts (1)
  • createDeploymentGroup (5-13)
apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts (4)
apps/api/src/deployment/controllers/lease/lease.controller.ts (1)
  • singleton (11-31)
apps/api/src/deployment/repositories/lease/lease.repository.ts (1)
  • DatabaseLeaseListParams (14-26)
apps/api/src/deployment/http-schemas/lease-rpc.schema.ts (1)
  • FallbackLeaseListResponse (72-72)
apps/indexer/drizzle/schema.ts (1)
  • lease (110-178)
apps/api/src/deployment/controllers/lease/lease.controller.ts (2)
apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts (1)
  • singleton (28-332)
apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts (1)
  • singleton (9-93)
apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts (2)
apps/api/src/deployment/controllers/lease/lease.controller.ts (1)
  • singleton (11-31)
apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts (1)
  • singleton (28-332)
⏰ 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). (3)
  • GitHub Check: validate / validate-app
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build

@ygrishajev ygrishajev force-pushed the feature/managed-wallets-api branch from d68a627 to 0d41505 Compare October 6, 2025 08:09
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
apps/api/test/functional/managed-api-deployment-flow.spec.ts (1)

428-467: Replace any casts with typed metadata.

The (data.data as any) and (deployment as any) casts violate our no-any rule and hide real type mismatches. Please extend the deployment type so the extra DB metadata is typed instead of using any.

 type AuthType = "mTLS" | "JWT";
 
+type DeploymentWithDbIds = CreateDeploymentResponse["data"] & {
+  _dbId: string;
+  _deploymentGroupId: string;
+};
+-  async function createDeployment(apiKey: string, walletAddress: string): Promise<CreateDeploymentResponse["data"]> {
+  async function createDeployment(apiKey: string, walletAddress: string): Promise<DeploymentWithDbIds> {-    (data.data as any)._dbId = deploymentDbId;
-    (data.data as any)._deploymentGroupId = deploymentGroup.id;
-
-    return data.data;
+    return {
+      ...data.data,
+      _dbId: deploymentDbId,
+      _deploymentGroupId: deploymentGroup.id
+    };
   }
 …
-    deployment: CreateDeploymentResponse["data"],
+    deployment: DeploymentWithDbIds,-        deploymentId: (deployment as any)._dbId,
-        deploymentGroupId: (deployment as any)._deploymentGroupId,
+        deploymentId: deployment._dbId,
+        deploymentGroupId: deployment._deploymentGroupId,

As per coding guidelines

Also applies to: 521-571

♻️ Duplicate comments (2)
apps/api/test/functional/managed-api-deployment-flow.spec.ts (1)

20-23: Import schema as a value to use typeof.

ListDeploymentsResponseSchema is brought in with import type, but z.infer<typeof …> needs the runtime schema. This still fails TS (“Cannot use '…' as a value because it was imported using 'import type'”). Switch to a value import.

-import type { ListDeploymentsResponseSchema } from "@src/deployment/http-schemas/deployment.schema";
+import { ListDeploymentsResponseSchema } from "@src/deployment/http-schemas/deployment.schema";
apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts (1)

322-328: Restore pagination when falling back to deployments DB

Handing the HTTP-style payload straight to fallbackDeploymentReaderService.findAll discards the requested pagination fields (offset, limit, key, countTotal, reverse). On outage the fallback therefore always returns the first 100 rows, making every downstream page unreachable—the same regression flagged in the earlier review and still unresolved. Please flatten the pagination block before delegating so the DB reader receives the expected skip/limit/... inputs.

       return await this.deploymentHttpService.findAll(params);
     } catch (error) {
       if (this.shouldFallbackToDatabase(error)) {
-        return await this.fallbackDeploymentReaderService.findAll(params);
+        const { owner, state, pagination } = params;
+        const offsetFromKey =
+          pagination?.key !== undefined ? Number.parseInt(pagination.key, 10) : undefined;
+
+        return await this.fallbackDeploymentReaderService.findAll({
+          owner,
+          state,
+          skip: pagination?.offset ?? (!Number.isNaN(offsetFromKey) ? offsetFromKey : undefined),
+          limit: pagination?.limit,
+          key: !Number.isNaN(offsetFromKey) ? pagination?.key : undefined,
+          countTotal: pagination?.countTotal,
+          reverse: pagination?.reverse
+        });
       }
 
       throw error;
     }
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d68a627 and 0d41505.

📒 Files selected for processing (9)
  • apps/api/src/deployment/controllers/lease/lease.controller.ts (2 hunks)
  • apps/api/src/deployment/routes/deployments/deployments.router.ts (3 hunks)
  • apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts (6 hunks)
  • apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts (5 hunks)
  • apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts (1 hunks)
  • apps/api/src/deployment/services/lease/lease.service.ts (1 hunks)
  • apps/api/test/functional/managed-api-deployment-flow.spec.ts (9 hunks)
  • packages/http-sdk/src/deployment/deployment-http.service.ts (2 hunks)
  • packages/http-sdk/src/lease/lease-http.service.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/api/src/deployment/routes/deployments/deployments.router.ts
  • packages/http-sdk/src/lease/lease-http.service.ts
  • packages/http-sdk/src/deployment/deployment-http.service.ts
  • apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts
🧰 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/deployment/controllers/lease/lease.controller.ts
  • apps/api/src/deployment/services/lease/lease.service.ts
  • apps/api/test/functional/managed-api-deployment-flow.spec.ts
  • apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts
  • apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • apps/api/src/deployment/controllers/lease/lease.controller.ts
  • apps/api/src/deployment/services/lease/lease.service.ts
  • apps/api/test/functional/managed-api-deployment-flow.spec.ts
  • apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts
  • apps/api/src/deployment/services/deployment-reader/deployment-reader.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, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/api/test/functional/managed-api-deployment-flow.spec.ts
🧠 Learnings (1)
📚 Learning: 2025-06-03T15:06:34.211Z
Learnt from: baktun14
PR: akash-network/console#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.

Applied to files:

  • apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts
  • apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts
🧬 Code graph analysis (4)
apps/api/src/deployment/controllers/lease/lease.controller.ts (2)
apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts (1)
  • singleton (9-93)
apps/api/src/deployment/repositories/lease/lease.repository.ts (1)
  • singleton (28-122)
apps/api/test/functional/managed-api-deployment-flow.spec.ts (4)
apps/api/src/deployment/http-schemas/deployment.schema.ts (1)
  • ListDeploymentsResponseSchema (123-133)
apps/indexer/drizzle/schema.ts (3)
  • deployment (180-203)
  • lease (110-178)
  • deploymentGroup (21-45)
apps/api/src/utils/constants.ts (1)
  • apiNodeUrl (19-19)
apps/api/test/seeders/deployment-group.seeder.ts (1)
  • createDeploymentGroup (5-13)
apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts (2)
apps/api/src/deployment/repositories/deployment/deployment.repository.ts (1)
  • DatabaseDeploymentListParams (22-30)
apps/api/src/types/rest/akashDeploymentListResponse.ts (1)
  • RestAkashDeploymentListResponse (1-94)
apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts (4)
apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts (1)
  • singleton (11-187)
apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts (1)
  • singleton (9-93)
packages/http-sdk/src/deployment/deployment-http.service.ts (4)
  • DeploymentHttpService (134-196)
  • RestAkashDeploymentInfoResponse (100-106)
  • PaginationParams (126-132)
  • DeploymentListResponse (108-114)
packages/http-sdk/src/lease/lease-http.service.ts (3)
  • LeaseHttpService (60-84)
  • LeaseListParams (50-58)
  • RestAkashLeaseListResponse (4-48)
⏰ 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). (7)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: Validate local packages

baktun14
baktun14 previously approved these changes Oct 6, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (3)
apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts (2)

326-328: Restore DB fallback pagination translation.

The fallback still forwards HTTP-style pagination, so the DB reader receives none of skip/limit/key/countTotal/reverse and reverts to its defaults—every paginated request collapses to the first page during outages. Please unpack params.pagination into the shape expected by FallbackDeploymentReaderService.

-        return await this.fallbackDeploymentReaderService.findAll(params);
+        const { owner, state, pagination } = params;
+
+        return await this.fallbackDeploymentReaderService.findAll({
+          owner,
+          state,
+          skip: pagination?.offset,
+          limit: pagination?.limit,
+          key: pagination?.key,
+          countTotal: pagination?.countTotal,
+          reverse: pagination?.reverse
+        });

338-340: Lease fallback still drops pagination.

Same issue here: the DB lease reader expects flattened skip/limit/key but we forward the HTTP params untouched, so any paginated outage request is stuck on the first page. Translate the HTTP pagination before delegating.

-        return await this.fallbackLeaseReaderService.list(params);
+        const { owner, dseq, state, pagination } = params;
+        const offsetFromKey =
+          pagination?.key !== undefined ? Number.parseInt(pagination.key, 10) : undefined;
+
+        return await this.fallbackLeaseReaderService.list({
+          owner,
+          dseq,
+          state,
+          limit: pagination?.limit,
+          key: Number.isNaN(offsetFromKey) ? pagination?.key : undefined,
+          skip: Number.isNaN(offsetFromKey) ? pagination?.offset : offsetFromKey
+        });
apps/api/test/functional/managed-api-deployment-flow.spec.ts (1)

20-22: Fix type-only import usage (duplicate issue).

This issue was already flagged in a previous review. ListDeploymentsResponseSchema is imported via import type, but line 22 uses it with typeof for z.infer. Type-only imports are erased at runtime, causing a TypeScript compilation error.

Change line 20 to a regular value import:

-import type { ListDeploymentsResponseSchema } from "@src/deployment/http-schemas/deployment.schema";
+import { ListDeploymentsResponseSchema } from "@src/deployment/http-schemas/deployment.schema";
🧹 Nitpick comments (2)
apps/api/src/deployment/controllers/lease/lease.controller.ts (1)

28-30: Clean delegation to the new fallback reader service.

The method correctly delegates to FallbackLeaseReaderService.list, maintaining the same signature and behavior. The refactoring properly centralizes fallback logic into a dedicated service.

Optionally, you can remove the redundant await keyword since you're directly returning the promise:

  async listLeasesFallback(params: DatabaseLeaseListParams): Promise<FallbackLeaseListResponse> {
-    return await this.fallbackLeaseReaderService.list(params);
+    return this.fallbackLeaseReaderService.list(params);
  }
apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts (1)

51-51: Extract decimal precision constant.

The magic number 18 appears three times for decimal precision. Extract it as a named constant (e.g., DECIMAL_PRECISION = 18) to improve maintainability and signal intent.

Apply this diff to extract the constant at the top of the class:

 @singleton()
 export class FallbackLeaseReaderService {
+  private static readonly DECIMAL_PRECISION = 18;
+
   constructor(private readonly leaseRepository: LeaseRepository) {}

Then reference it in the transformLease method:

         price: {
           denom: mappedDenom,
-          amount: lease.price.toFixed(18)
+          amount: lease.price.toFixed(FallbackLeaseReaderService.DECIMAL_PRECISION)
         },
         rate: {
           denom: mappedDenom,
-          amount: lease.price.toFixed(18)
+          amount: lease.price.toFixed(FallbackLeaseReaderService.DECIMAL_PRECISION)
         },
         withdrawn: {
           denom: mappedDenom,
-          amount: lease.withdrawnAmount.toFixed(18)
+          amount: lease.withdrawnAmount.toFixed(FallbackLeaseReaderService.DECIMAL_PRECISION)
         }

Also applies to: 66-66, 74-74

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d41505 and 475dd00.

📒 Files selected for processing (9)
  • apps/api/src/deployment/controllers/lease/lease.controller.ts (2 hunks)
  • apps/api/src/deployment/routes/deployments/deployments.router.ts (3 hunks)
  • apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts (6 hunks)
  • apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts (5 hunks)
  • apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts (1 hunks)
  • apps/api/src/deployment/services/lease/lease.service.ts (1 hunks)
  • apps/api/test/functional/managed-api-deployment-flow.spec.ts (9 hunks)
  • packages/http-sdk/src/deployment/deployment-http.service.ts (2 hunks)
  • packages/http-sdk/src/lease/lease-http.service.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/http-sdk/src/lease/lease-http.service.ts
🧰 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:

  • packages/http-sdk/src/deployment/deployment-http.service.ts
  • apps/api/src/deployment/controllers/lease/lease.controller.ts
  • apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts
  • apps/api/src/deployment/services/lease/lease.service.ts
  • apps/api/src/deployment/routes/deployments/deployments.router.ts
  • apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts
  • apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts
  • apps/api/test/functional/managed-api-deployment-flow.spec.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • packages/http-sdk/src/deployment/deployment-http.service.ts
  • apps/api/src/deployment/controllers/lease/lease.controller.ts
  • apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts
  • apps/api/src/deployment/services/lease/lease.service.ts
  • apps/api/src/deployment/routes/deployments/deployments.router.ts
  • apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts
  • apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts
  • apps/api/test/functional/managed-api-deployment-flow.spec.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, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/api/test/functional/managed-api-deployment-flow.spec.ts
🧠 Learnings (1)
📚 Learning: 2025-06-03T15:06:34.211Z
Learnt from: baktun14
PR: akash-network/console#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.

Applied to files:

  • apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts
  • apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts
🔇 Additional comments (15)
apps/api/src/deployment/services/lease/lease.service.ts (1)

7-7: Verify that LeaseRepository is still used.

Since the fallback methods were removed from this service and moved to FallbackLeaseReaderService, confirm that LeaseRepository is still referenced by the remaining methods in this file. If unused, remove the import.

apps/api/src/deployment/controllers/lease/lease.controller.ts (1)

8-8: LGTM! Clean dependency injection.

The import and constructor injection of FallbackLeaseReaderService correctly follows the dependency injection pattern and maintains proper TypeScript typing.

Also applies to: 14-14

packages/http-sdk/src/deployment/deployment-http.service.ts (2)

108-111: LGTM!

Exporting DeploymentListResponse enables fallback reader services to properly type their responses during blockchain outages, which aligns with the PR objectives.


126-129: LGTM!

Exporting PaginationParams allows fallback services to maintain consistent pagination typing across HTTP and DB-backed implementations.

apps/api/src/deployment/routes/deployments/deployments.router.ts (3)

31-31: LGTM!

The import path correctly reflects the service refactoring from DatabaseDeploymentReaderService to FallbackDeploymentReaderService.


350-355: LGTM!

The service resolution, method call, and null-check are all correct. The renamed findByOwnerAndDseq method receives the same parameters (owner, dseq) as the previous getDeploymentInfo method, and the null-check ensures safe handling of missing deployments.


333-338: Verify return type compatibility with response schema.

The service resolution and method call look correct. The renamed findAll method receives the same parameters as the previous listDeployments method.

Ensure that findAll returns a type compatible with FallbackDeploymentListResponseSchema. The AI summary mentions "updated payload shapes," so verify that downstream consumers can handle any format changes (e.g., UNKNOWN_DB_PLACEHOLDER fields).

apps/api/src/deployment/services/fallback-lease-reader/fallback-lease-reader.service.ts (1)

51-51: Verify type compatibility for toFixed(18).

The toFixed() method is only available on the Number type. If lease.price or lease.withdrawnAmount are stored as string, BigInt, or Decimal types (common in blockchain contexts), calling toFixed(18) will throw a runtime error at lines 51, 66, and 74. Confirm that these fields are numeric, or add explicit type coercion (e.g., Number(lease.price).toFixed(18) or use a decimal library).

Run the following script to inspect the Lease schema and confirm field types:

Also applies to: 66-66, 74-74

apps/api/src/deployment/services/fallback-deployment-reader/fallback-deployment-reader.service.ts (1)

9-15: LGTM! Excellent refactoring.

The renaming of the constant to UNKNOWN_DB_PLACEHOLDER, the class to FallbackDeploymentReaderService, and the method to findAll all improve code clarity and follow better naming conventions.

apps/api/test/functional/managed-api-deployment-flow.spec.ts (6)

166-297: Well-structured outage simulation test.

The test is well-organized with clear phases (blockchain up, down, and restored) and comprehensive assertions. The error handling in the catch block ensures proper cleanup.


299-319: LGTM! setup() follows coding guidelines.

The setup() function correctly:

  • Positioned at the bottom of the describe block
  • Returns an object with required data and utilities
  • No explicit return type specified
  • Uses inline parameter types (none in this case)

As per coding guidelines


321-356: Outage simulation utilities are well-implemented.

The blockNode() and unblockNode() functions provide clean abstractions for simulating blockchain outages using nock interceptors. The use of nock.cleanAll() ensures proper cleanup.


420-428: Signature update aligns with seeding requirements.

The addition of the walletAddress parameter enables proper foreign key relationships in the seeded database records.


510-527: Signature update supports proper lease seeding.

The addition of walletAddress enables seeding lease records with correct ownership data.


648-663: Clean implementation of deployment list retrieval.

The function is well-documented and properly typed. The implementation is straightforward and follows the established patterns in the test file.

@ygrishajev ygrishajev merged commit 2a005c6 into main Oct 6, 2025
63 checks passed
@ygrishajev ygrishajev deleted the feature/managed-wallets-api branch October 6, 2025 09:48
@coderabbitai coderabbitai bot mentioned this pull request Oct 15, 2025
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.

2 participants

Comments