Skip to content

feat: aggregated view for all twap parts - #7

Merged
kernelwhisperer merged 2 commits into
mainfrom
feat/aggregated-view-for-parts
Sep 9, 2026
Merged

kernelwhisperer merged 2 commits into
mainfrom
feat/aggregated-view-for-parts

Conversation

@kernelwhisperer

@kernelwhisperer kernelwhisperer commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a unified API view of TWAP parts, including scheduled parts that do not yet have discrete orders. Clients can retrieve all known parts without merging separate queries.

Part of FE-479 Show Sheduled parts for TWAPs for EOAs

Changes

  • Adds partOrders, combining discrete orders and candidates without duplicate order UIDs.
  • Keeps a stable sortKey when candidates become discrete orders.
  • Supports server-side filters, pagination, sorting, and total counts.
  • Adds programmaticOrders with an exact partOrdersCount.
  • Updates the parent cursor when the indexer discovers candidates.
  • Uses SQL views without additional persistent storage.
  • Adds PostgreSQL and GraphQL integration tests to CI.
  • Starts local PostgreSQL through Docker before the development server.

How to Test

  1. Create a TWAP with multiple parts.
  2. Query partOrders. Check that future parts appear as unconfirmed.
  3. After a part executes, check that its execution data appears without duplicates.
  4. Check that partOrdersCount matches the number of unique parts.

Checklist

  • Tests pass locally
  • Linting passes
  • Documentation updated (if needed)
  • Breaking changes documented (if any)

Breaking Changes

No public API breaking changes. Existing queries remain available.

Local development now requires Docker because pnpm dev starts PostgreSQL through Docker Compose.

image

@kernelwhisperer kernelwhisperer self-assigned this Sep 8, 2026
@linear-code

linear-code Bot commented Sep 8, 2026

Copy link
Copy Markdown

FE-479

@Danziger Danziger 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.

Minor AI comment about docs, so approving already:

⚠️ AI Review (Cursor Grok 4.6, worked 9m): new GraphQL surface is undocumented; SDK still cannot consume unconfirmed

Finding: [NON-BLOCKING] Document partOrders / programmaticOrders / unconfirmed, and fix the generator sync docs

  • Location: schema/views.ts, src/api/gql-docs/conditional-order-generator.ts:974, docs/api-reference.md GraphQL map
  • This PR adds two public GraphQL types and a new part status, unconfirmed, but gql-docs, docs/api-reference.md, and AGENTS.md still describe only the old tables.
  • conditionalOrderGenerator.updatedAtBlock still says the cursor is not bumped for allCandidatesKnown and that clients should fetch changed parts via discreteOrder. This PR now bumps that cursor when candidates appear, and the new parts collection is partOrders.
  • Clients following the current field docs will keep missing scheduled parts after deploy.

Suggested fix

  • Add gql-docs for partOrder and programmaticOrder, including unconfirmed and sortKey.
  • Update the generator cursor docs to: bump on child part/candidate changes; fetch partOrders (not only discreteOrder).
  • Add the two views to the GraphQL map in docs/api-reference.md.

Finding: [QUESTION] How does @cowprotocol/sdk-composable pick this up? 1.4.2 still cannot show scheduled parts

  • Location: schema/views.ts:13 (partOrder.status), schema/views.ts:56 (partOrdersCount)
  • CoW Swap FE-479 goes through ProgrammaticOrderApi. Published 1.4.2 still queries discreteOrders (aliased as partOrders) and discreteOrders(limit: 1) { totalCount } for partOrdersCount.
  • Its part-status picklist is open | fulfilled | expired | cancelled | unfilled. unconfirmed will fail validation.
  • Precomputed TWAP parts share one creationDate (the parent event timestamp). The new sortKey is the stable order; the SDK still orderBy: "creationDate".

Is a stacked SDK PR switching to partOrders + sortKey + unconfirmed (and programmaticOrders.partOrdersCount or equivalent) coming with this, or should that land before anything claims FE-479 is unblocked?

Suggested fix

  • Confirm the SDK query/schema change in this thread, or link the PR.
  • When it switches, orderBy must be sortKey, not creationDate.
Review scope and related context

Checked against base fix/mark-twap-completed, the current diff, GraphQL tests, and the CoW Swap consumer (ProgrammaticOrderApi 1.4.2).

Not repeated as findings:

  • Dedup, promotion, and pagination of the SQL view look correct and are covered by tests/schema/part-orders.test.ts.
  • Poller returning() + bumpGeneratorsUpdatedAt is the path that actually moves the cursor after creation; precompute’s allCandidatesKnown bump is the same block as generator insert.
  • No existing review threads.
🤖 Prompt for AI agents
Verify these findings against current code. Keep the change minimal.

Context:
- schema/views.ts introduces partOrders (discrete ∪ leftover candidates, status "unconfirmed") and programmaticOrders.partOrdersCount.
- src/api/gql-docs/conditional-order-generator.ts still documents discreteOrder-only part sync and no cursor bump for allCandidatesKnown.
- docs/api-reference.md GraphQL map does not mention the new views.
- @cowprotocol/sdk-composable 1.4.2 still queries discreteOrders and rejects status "unconfirmed"; it orderBy creationDate, but precomputed TWAP parts share one creationDate.

Expected:
- Update gql-docs and api-reference for partOrders, programmaticOrders, unconfirmed, sortKey, and the generator cursor.
- Answer whether a stacked SDK PR will switch to this view; if coding, do not change the SDK from this repo.

Generated using the pr-review skill from the CoW Protocol skills repo.

Base automatically changed from fix/mark-twap-completed to main September 9, 2026 07:47
@kernelwhisperer
kernelwhisperer force-pushed the feat/aggregated-view-for-parts branch from b33fb58 to 31bff08 Compare September 9, 2026 07:48
@kernelwhisperer
kernelwhisperer merged commit fb75af6 into main Sep 9, 2026
4 checks passed
@kernelwhisperer
kernelwhisperer deleted the feat/aggregated-view-for-parts branch September 9, 2026 08:05
kernelwhisperer added a commit to cowprotocol/cowswap that referenced this pull request Sep 10, 2026
Instead of querying only "discrete" parts, now we query candidates as
well (scheduled).

Depends on
cowprotocol/cow-programmatic-orders-api#7
Depends on cowprotocol/cow-sdk#1002

Part of [FE-479 Show Sheduled parts for TWAPs for
EOAs](https://linear.app/cowswap/issue/FE-479/show-sheduled-parts-for-twaps-for-eoas)

<img width="1209" height="256" alt="image"
src="https://github.com/user-attachments/assets/d0aa282b-2c89-4375-8a68-4bf71c136a5d"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
  - Improved TWAP order status handling for unconfirmed part orders.
- Candidate-only parts now transition correctly from scheduled
placeholders to pending orders after refresh.
- Cancelled or expired parent orders no longer expose candidates as
scheduled.
- Pagination now correctly respects server page size, selected pages,
and final-part indicators.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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