Skip to content

feat(swift-example-app): document sum/average aggregation view (DOC-13/14)#3942

Merged
QuantumExplorer merged 1 commit into
v3.1-devfrom
claude/relaxed-sammet-193054
Jun 20, 2026
Merged

feat(swift-example-app): document sum/average aggregation view (DOC-13/14)#3942
QuantumExplorer merged 1 commit into
v3.1-devfrom
claude/relaxed-sammet-193054

Conversation

@QuantumExplorer

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

The document SUM/AVERAGE aggregation FFI (dash_sdk_document_sum / dash_sdk_document_average) shipped in #3935, but SwiftExampleApp had no way to invoke it — so QA tests DOC-13 (sum) and DOC-14 (average) were stuck at 🔌 SDK-only (FFI exists, no UI to drive it), unlike the COUNT tests DOC-10/11/12 which got a view in #3926.

This adds the missing app surface so those two tests become 🧪 builder-only (drivable in the simulator).

What was done?

  • Swift SDK wrappers (PlatformQueryExtensions.swift): added SDK.documentSum(...) and SDK.documentAverage(...) as thin bridges over the merged FFI, plus the DocumentSumResult / DocumentAverageEntry / DocumentAverageResult result types. These mirror the existing documentCount / DocumentCountResult precedent exactly (contract-handle fetch + defer destroy, withOptionalCString marshalling, limit == 0 guard, SDKError.fromDashSDKError). The only new wire detail is the required non-empty sum_property argument. Per the Swift SDK thin-bridge rule, the wrappers only marshal — the FFI returns the raw (count, sum) pair and the sum / count division for display is done in the view.
  • New view SumAverageDocumentsView.swift: a read-only query view (nothing signed/broadcast) mirroring CountDocumentsView. It has an op selector (Sum / Average), a required numeric sum-property field, optional where / group_by JSON, and renders the total + per-group rows (and the computed average for the avg op) or the platform error.
  • Wiring (TransitionCategoryView.swift): a NavigationLink next to the Count link under Settings → Platform State Transitions → Document.
  • TEST_PLAN.md: DOC-13/14 flipped 🔌 → 🧪 pointing at the new view; the getDocuments catalog row and Appendix B SDK-only gaps list updated accordingly.

No Rust source was changed; the FFI was already merged in #3935.

Accessibility identifiers (for idb-driven QA)

transition.document.sumAverageDocuments (nav link); within the view: sumAverageDocuments.opPicker, .sumPropertyField, .whereField, .groupByField, .runButton, .total (sum), .average (computed), .groupRow.<hexKey>, .errorText, .contractPicker / .docTypePicker.

How Has This Been Tested?

  • Rebuilt the iOS xcframework (./build_ios.sh --target sim --profile dev) so the regenerated DashSDKFFI header carries the new dash_sdk_document_sum / dash_sdk_document_average symbols, then built SwiftExampleApp for the iPhone 16 simulator with warnings-as-errors → BUILD SUCCEEDED. Verified the new symbols are present in the generated header and that sumAverageDocuments strings are present in the linked dylib (no stale-binary trap).
  • Not yet exercised on a live green path: driving a real non-error total requires a funded contract whose document type carries a summable index on a numeric property (the existing countable QA fixture is insufficient — counting only needs documentsCountable). Until such a fixture is published, the view correctly surfaces the platform's "requires a summable index" error. This is a data/fixture concern, not a code one.

Breaking Changes

None. Additive SDK wrapper + new example-app view.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

…3/14)

Add a read-only "Sum / Average Documents" view that drives the document
SUM and AVERAGE aggregation FFI shipped in #3935, moving QA tests DOC-13
(sum) and DOC-14 (average) from SDK-only to builder-only (drivable in the
simulator). Mirrors the COUNT view added in #3926 for DOC-10/11/12.

- Add thin-bridge wrappers SDK.documentSum / SDK.documentAverage over the
  dash_sdk_document_sum / dash_sdk_document_average FFI, plus the
  DocumentSumResult / DocumentAverageEntry / DocumentAverageResult result
  types. The FFI returns the raw (count, sum) pair; the sum/count division
  for display stays in the view (the wrappers only marshal).
- Add SumAverageDocumentsView: op selector (Sum/Average), a required
  numeric sum-property field, optional where/group_by JSON, and result
  rendering (total + per-group rows, computed average for the avg op).
- Wire it next to the Count link under Settings -> Platform State
  Transitions -> Document.
- Flip DOC-13/14 to builder-only in TEST_PLAN.md and drop them from the
  SDK-only gaps list.

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

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@QuantumExplorer, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 37 minutes and 6 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 12db10fc-06a6-4a9a-aac0-2660780c2bc0

📥 Commits

Reviewing files that changed from the base of the PR and between 460a1d4 and d4275e9.

📒 Files selected for processing (4)
  • packages/swift-sdk/Sources/SwiftDashSDK/FFI/PlatformQueryExtensions.swift
  • packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Views/SumAverageDocumentsView.swift
  • packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Views/TransitionCategoryView.swift
  • packages/swift-sdk/SwiftExampleApp/TEST_PLAN.md
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/relaxed-sammet-193054

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@thepastaclaw

thepastaclaw commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

✅ Review complete (commit d4275e9)

@QuantumExplorer QuantumExplorer merged commit cb61ffa into v3.1-dev Jun 20, 2026
16 checks passed
@QuantumExplorer QuantumExplorer deleted the claude/relaxed-sammet-193054 branch June 20, 2026 07:35

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review

Additive Swift wrapper + SwiftExampleApp view exposing the already-merged document SUM/AVERAGE FFI (#3935) for QA DOC-13/14. The JSON-payload shapes, contract-handle fetch/destroy lifecycle, hex-key/empty-key convention, and presentation-layer division of (sum/count) all match the existing documentCount precedent. No Rust changes, no consensus-critical paths, no FFI surface added. One minor UX nit on the result rendering of grouped queries.

💬 1 nitpick(s)

Comment on lines +189 to +244
private func sumResultSections(_ result: DocumentSumResult) -> some View {
Section("Total") {
HStack {
Text("Sum")
Spacer()
Text(result.total.map(String.init) ?? "—")
.fontWeight(.bold)
.foregroundColor(.primary)
.accessibilityIdentifier("sumAverageDocuments.total")
}
}

if result.isGrouped {
Section("Per-group sums") {
ForEach(groupedSumRows(result), id: \.key) { row in
HStack {
Text(row.key)
.font(.system(.footnote, design: .monospaced))
.lineLimit(1)
.truncationMode(.middle)
Spacer()
Text(String(row.value))
.fontWeight(.semibold)
}
.accessibilityIdentifier("sumAverageDocuments.groupRow.\(row.key)")
}
}
}
}

@ViewBuilder
private func averageResultSections(_ result: DocumentAverageResult) -> some View {
Section("Total") {
HStack {
Text("Average")
Spacer()
Text(formatAverage(result.total))
.fontWeight(.bold)
.foregroundColor(.primary)
.accessibilityIdentifier("sumAverageDocuments.average")
}
if let entry = result.total {
HStack {
Text("Count")
Spacer()
Text(String(entry.count))
.foregroundColor(.secondary)
}
HStack {
Text("Sum")
Spacer()
Text(String(entry.sum))
.foregroundColor(.secondary)
}
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

💬 Nitpick: "Total" section renders "—" above per-group rows for grouped queries

DocumentSumResult.total and DocumentAverageResult.total resolve to nil when the request was grouped (no empty-string entry in the FFI payload — see PlatformQueryExtensions.swift:47-49 and :97-99). However, sumResultSections and averageResultSections always emit the Section("Total") block, so a grouped run renders a misleading "Sum: —" / "Average: —" above the real per-group rows. (For averages, the Count/Sum sub-rows are correctly gated by if let entry = result.total, so those stay hidden — just the "Average: —" line is the issue.) Gate the Total section on !result.isGrouped, or label it explicitly so QA isn't reading a placeholder dash as a query failure. Purely UX; does not affect the accessibility identifiers QA depends on.

source: ['claude']

@QuantumExplorer

Copy link
Copy Markdown
Member Author

Companion fix: #3944 — the example-app SDK was pinned to protocol version 11 on testnet (V0 wire), which rejects the V1-only Sum/Average projection this view drives. With #3944 the SDK seeds at the per-network floor (testnet PV12), and DOC-13/14 return proof-verified results in-app (sum 120 / average 30 over a summable fixture). #3944 should land for the testnet green path.

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