Skip to content

Comments

fix(deployment): implement countByOwner method and corresponding tests#2763

Open
baktun14 wants to merge 1 commit intomainfrom
fix/deployment-list-pagination
Open

fix(deployment): implement countByOwner method and corresponding tests#2763
baktun14 wants to merge 1 commit intomainfrom
fix/deployment-list-pagination

Conversation

@baktun14
Copy link
Contributor

@baktun14 baktun14 commented Feb 17, 2026

Why

The deployments table at stats.akash.network/addresses/{address}/deployments shows "Page 1 of 1" even when an address has many deployments. The Cosmos SDK node returns an incorrect pagination.total value equal
to the page size (e.g. "10") instead of the true total count, resulting in pageCount = ceil(10/10) = 1 and making pagination navigation impossible.
https://stats.akash.network/addresses/akash10lq8uyfl52d6t467qmd58e7jzl9ecmvet2m57p/deployments

What

  • Added countByOwner(owner, status?) method to DeploymentRepository that performs a fast COUNT query against the database, optionally filtering by active/closed status
  • Modified DeploymentReaderService.listWithResources to use the DB count instead of the unreliable Cosmos SDK pagination.total
  • Parallelized the lease fetch, provider list fetch, and DB count query with Promise.all for improved performance
  • Set countTotal: false in the Cosmos SDK request since we no longer rely on its total
  • Added unit tests for DeploymentRepository.countByOwner (3 tests) and DeploymentReaderService.listWithResources (7 tests)

Summary by CodeRabbit

  • New Features

    • Deployment listings now return counts sourced from the backend and include owner/dseq mapping in results.
  • Tests

    • Added comprehensive tests for deployment counting and listing behavior across status filters and pagination.
  • Chores

    • Improved listing performance by parallelizing backend requests and optimizing count retrieval for faster, more reliable responses.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 17, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Adds DeploymentRepository.countByOwner(owner, status?) for owner+status counting and refactors DeploymentReaderService.listWithResources to use that repository count, parallelize lease/provider/count fetches with Promise.all, and source total count from the repository instead of HTTP pagination.

Changes

Cohort / File(s) Summary
Repository method & tests
apps/api/src/deployment/repositories/deployment/deployment.repository.ts, apps/api/src/deployment/repositories/deployment/deployment.repository.spec.ts
New countByOwner(owner, status?) method that builds a where clause for owner and optional status (active: closedHeight = null, closed: closedHeight != null) and returns Deployment.count. Tests assert the exact where passed for no-status, active, and closed cases and returned values.
Service refactor & tests
apps/api/src/deployment/services/deployment-reader/deployment-reader.service.ts, apps/api/src/deployment/services/deployment-reader/deployment-reader.service.spec.ts
Injects DeploymentRepository; listWithResources now runs lease fetch, provider fetch (conditional), and countByOwner concurrently via Promise.all, uses repository count as the response count, sets pagination.countTotal→false, and updates mappings. Tests cover count source, status propagation, pagination translation, provider fetch behavior, and result mapping.

Sequence Diagram

sequenceDiagram
    actor Client
    participant DRS as DeploymentReaderService
    participant HTTP as DeploymentHttpService
    participant LHS as LeaseHttpService
    participant Repo as DeploymentRepository
    participant DB as Database

    Client->>DRS: listWithResources(owner, status, skip, limit)

    Note over DRS: Start Promise.all for 3 concurrent operations

    par Lease fetch
        DRS->>LHS: getList(...)
        LHS-->>DRS: leaseList
    and Deployment list & providers
        DRS->>HTTP: getList(..., countTotal=false)
        HTTP-->>DRS: deploymentList
        alt deploymentList not empty
            DRS->>HTTP: getProviders(...)
            HTTP-->>DRS: providerList
        end
    and Count fetch
        DRS->>Repo: countByOwner(owner, status)
        Repo->>DB: Deployment.count(where)
        DB-->>Repo: count
        Repo-->>DRS: count
    end

    DRS->>DRS: map deployments with owner/dseq
    DRS-->>Client: { deployments, count, leases, providers? }
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A little rabbit tallies the lot,
Hops through counts without a second thought.
Three calls in parallel, neat and spry,
Owners, leases, providers — numbers by and by.
A tiny hop, a tidy fix — count done quick! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: implementing a new countByOwner method in DeploymentRepository and adding corresponding tests for both the repository and service.
Description check ✅ Passed The PR description is well-structured with clear 'Why' and 'What' sections that explain the issue, solution, and implementation details including all changes made.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 fix/deployment-list-pagination

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

@codecov
Copy link

codecov bot commented Feb 17, 2026

⚠️ JUnit XML file not found

The CLI was unable to find any JUnit XML files to upload.
For more help, visit our troubleshooting guide.

@ygrishajev
Copy link
Contributor

I believe that requesting data from 1 source and pagination from another would cause another set of issues eventually. Switching entirely to the indexer is obviously not an option too due to performance issues.

Why can't this be fixed on the rpc node? Have this been requested to @akash-network/core ?

@baktun14 baktun14 force-pushed the fix/deployment-list-pagination branch from 5ead5d0 to 44f0bc2 Compare February 19, 2026 22:10
@baktun14
Copy link
Contributor Author

The hybrid approach (RPC for deployments, DB for count) is intentional because pagination.count_total is broken at the Akash RPC node level. It always returns the page size instead of the actual total:

# limit=5, count_total=true → total is 5 (wrong, should be 146)
curl "https://rpc.akt.dev/rest/akash/deployment/v1beta4/deployments/list?filters.owner=akash1p2e73vphy9umsx02y6xqr49yeu0dn9s3pytkvk&filters.state=active&pagination.limit=5&pagination.count_total=true"
→ { "total": "5", "count": 5 }

# limit=1000, all 146 active fit in one page → total matches but only because page_size == actual_count
curl "https://rpc.akt.dev/rest/akash/deployment/v1beta4/deployments/list?filters.owner=akash1p2e73vphy9umsx02y6xqr49yeu0dn9s3pytkvk&filters.state=active&pagination.limit=1000"
→ { "total": "146", "count": 146 }

# limit=1000, no state filter, >1000 deployments → total is 1000 (wrong, capped at page size)
curl "https://rpc.akt.dev/rest/akash/deployment/v1beta4/deployments/list?filters.owner=akash1p2e73vphy9umsx02y6xqr49yeu0dn9s3pytkvk&pagination.limit=1000&pagination.count_total=true"
→ { "total": "1000", "next_key": "...", "count": 1000 }

This happens with both offset-based and key-based pagination, regardless of whether count_total=true is set. The node simply ignores it.

Since we can't get an accurate total count from the RPC, the DB count is the only viable option for pagination. This should probably also be reported to @akash-network/node as a node-level bug.

@ygrishajev
Copy link
Contributor

@baktun14 let's first escalate this to to @akash-network/core, see how fast we can get this fixed. Coz it forces us to apply this hack which is not ideal also

@cloud-j-luna
Copy link
Member

Hey! In regard to the node, that behaviour is as designed due to the performance hit the node gets when going through all the deployments. That means the total is set to the total amount of deployments returned on the query.

One possible solution could be to offer an "infinite scroll" UX where scrolling down queries the next batch of n deployments. This way we don't need to hack and it might be a good compromise given the cost/benefit of pagination in this specific view. Thoughts?

@baktun14
Copy link
Contributor Author

baktun14 commented Feb 23, 2026

Hey! In regard to the node, that behaviour is as designed due to the performance hit the node gets when going through all the deployments. That means the total is set to the total amount of deployments returned on the query.

One possible solution could be to offer an "infinite scroll" UX where scrolling down queries the next batch of n deployments. This way we don't need to hack and it might be a good compromise given the cost/benefit of pagination in this specific view. Thoughts?

I don't think this is a good solution for pagination ui's when displaying with a table, which is what we use everywhere.

What is the issue and why can't it be fixed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants