Skip to content

Fix climbing attempt totals - #1860

Merged
Asherlc merged 12 commits into
mainfrom
Asherlc/create-pr-from-instructions-v1
Jul 22, 2026
Merged

Asherlc merged 12 commits into
mainfrom
Asherlc/create-pr-from-instructions-v1

Conversation

@Asherlc

@Asherlc Asherlc commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add a positive canonical climbing attempt count and populate it from Kaya imports.
  • Sum attempt counts in climbing volume/session APIs and provide an idempotent historical Kaya backfill.
  • Add migration, parser/repository/schema tests, real-Postgres coverage, operator documentation, and an incident-baseline entry.

Validation

  • pnpm lint
  • root, server, and web TypeScript checks
  • pnpm test (12,966 passed, 21 skipped)
  • focused Postgres integration tests and migration policy check

Summary by cubic

Fixes climbing attempt totals by adding a canonical attempt_count and summing it in server queries. Adds an idempotent Kaya backfill and incident docs; also aligns mobile expo patches and uses Expo’s online dependency validation in CI.

  • Bug Fixes

    • Added attempt_count to fitness.climbing_entry with a positive check; default 1.
    • Updated volume-by-grade and session summaries to use SUM(attempt_count) instead of row counts.
    • Kaya importer validates attempts as a positive 32-bit integer, rejects invalid values, and writes attemptCount canonically.
  • Migration

    • Deploy 0055_climbing_attempt_count (CHECK added NOT VALID then VALIDATED).
    • Backfill: pnpm backfill:climbing-attempt-count (dry run) then --execute (idempotent).
    • Confirm dashboards show different attempt and send totals.

Written for commit 4551553. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added climbing attempt counts to activity tracking, including validation for positive values.
    • Kaya imports now preserve and validate the number of attempts per climbing entry.
    • Added a safe backfill tool with preview and execution modes to correct existing records.
  • Bug Fixes

    • Climbing volume and session summaries now accurately aggregate attempts instead of counting entries.
  • Documentation

    • Added guidance for running the climbing attempt-count backfill and documented relevant production incidents.

Asherlc added 2 commits July 22, 2026 10:05
Store provider-reported attempts canonically so sends no longer imply a 100% send rate.

Backfill historical Kaya rows from preserved raw payloads after deploying migration 0055.
Copilot AI review requested due to automatic review settings July 22, 2026 17:08
@cursor

cursor Bot commented Jul 22, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sorry @Asherlc, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@greptile-apps greptile-apps Bot 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds validated climbing attempt counts to the database and Kaya importer, changes climbing reports to sum attempts, and introduces an idempotent dry-run or executable backfill. It also updates tests, operational documentation, and records an Expo validation incident.

Changes

Climbing attempt count

Layer / File(s) Summary
Schema and Kaya import
drizzle/0055_climbing_attempt_count.sql, drizzle/meta/_journal.json, src/db/schema/activity.ts, src/providers/kaya/import.ts, src/providers/kaya/import.test.ts, src/db/drizzle-schema.test.ts
Climbing entries gain a positive, non-null attempt_count; Kaya parses, validates, and persists the value.
Attempt-based climbing aggregates
packages/server/src/repositories/climbing-repository.ts, packages/server/src/repositories/climbing-repository.test.ts, packages/server/src/routers/climbing.integration.test.ts
Volume and session summaries calculate attempts with SUM(attempt_count) while preserving send and hardest-grade behavior.
Kaya attempt-count backfill
src/db/climbing-attempt-count-backfill.ts, src/db/climbing-attempt-count-backfill.test.ts, src/db/climbing-attempt-count-backfill.integration.test.ts, scripts/backfill-climbing-attempt-count.ts, scripts/backfill-climbing-attempt-count.test.ts, package.json, src/db/README.md, docs/production-incident-baseline.md
A guarded, idempotent backfill copies valid Kaya raw attempts, supports dry-run and execution modes, and documents operation and incident context.

Expo validation incident

Layer / File(s) Summary
Expo compatibility incident record
docs/production-incident-baseline.md
Documents mutable Expo online metadata, the compatible lockfile patch update, and remaining validation risk.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Kaya
  participant KayaImporter
  participant Database
  participant ClimbingRepository
  Kaya->>KayaImporter: CSV attempts
  KayaImporter->>Database: store attempt_count
  ClimbingRepository->>Database: SUM(attempt_count)
  Database-->>ClimbingRepository: aggregated attempts
Loading

Possibly related PRs

Suggested labels: area/server, area/providers, area/db, type/bug

🚥 Pre-merge checks | ✅ 1 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title is clear and imperative, but it omits the required area prefix for this change. Use a scoped title such as "[server] Fix climbing attempt totals" and keep it under 70 characters without trailing punctuation.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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.

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Storybook previews for 20aa8650 are ready:

This comment updates automatically on each PR push.

@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@greptile-apps greptile-apps Bot 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps Bot 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@greptile-apps greptile-apps Bot 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Mobile Preview

Scan to open on device:

QR code for dofek://preview/pr-1860

Channel pr-1860
Deep Link dofek://preview/pr-1860
Commit b5b2066

To test on device:

  1. Build and install the preview client: PREVIEW_CHANNEL=pr-1860 pnpm expo prebuild --clean -p ios
  2. Or tap deep link on an existing preview build: dofek://preview/pr-1860

Each PR gets its own channel. Build a preview client with PREVIEW_CHANNEL=pr-{N} to test.

@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@greptile-apps greptile-apps Bot 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@greptile-apps greptile-apps Bot 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@greptile-apps greptile-apps Bot 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@greptile-apps greptile-apps Bot 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

…m-instructions-v1

# Conflicts:
#	docs/production-incident-baseline.md
#	packages/server/src/routers/climbing.integration.test.ts
@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@greptile-apps greptile-apps Bot 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/server/src/repositories/climbing-repository.ts`:
- Around line 248-249: Remove the ::int casts from both SUM(ce.attempt_count)
and SUM(attempt_count) expressions in the repository queries, preserving
PostgreSQL’s bigint aggregate type. Leave the z.coerce.number() normalization
unchanged so cumulative attempt totals above the 32-bit integer range remain
supported.

In `@scripts/backfill-climbing-attempt-count.test.ts`:
- Around line 23-43: Add a test in the existing main suite covering rejection
from backfillClimbingAttemptCount: configure the mock to reject with an error,
invoke main with the appropriate arguments, and assert Sentry.captureException
receives that error (and preserve the expected rejection behavior if main
rethrows it). Keep the existing dry-run and unknown-option tests unchanged.

In `@scripts/backfill-climbing-attempt-count.ts`:
- Around line 12-37: Update main around createDatabaseFromEnv and
backfillClimbingAttemptCount to retain the database pool and call its close/end
cleanup after the backfill completes, including error paths. Ensure pool cleanup
occurs before or alongside the existing Sentry.close in finally so the one-off
CLI does not leave idle connections open.

In `@src/db/climbing-attempt-count-backfill.ts`:
- Around line 5-36: The backfill function currently calls db.execute and
separately parses the result with countRowSchema. Update
backfillClimbingAttemptCount to use executeWithSchema from typed-sql.ts for both
SQL branches, passing countRowSchema for centralized validation and row
handling, and return the validated count without the manual parse.

In `@src/providers/kaya/import.ts`:
- Around line 320-323: Update the attempts validation in the importer to use the
established Zod-based runtime validation required for untrusted input, accepting
only integer values from 1 through 2,147,483,647. Preserve the existing
row-level error result for invalid values, and add coverage for the upper bound
and values above it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 54a38fb1-03e2-449e-927e-d71831d95220

📥 Commits

Reviewing files that changed from the base of the PR and between b611e39 and 7b61138.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (17)
  • docs/production-incident-baseline.md
  • drizzle/0055_climbing_attempt_count.sql
  • drizzle/meta/_journal.json
  • package.json
  • packages/server/src/repositories/climbing-repository.test.ts
  • packages/server/src/repositories/climbing-repository.ts
  • packages/server/src/routers/climbing.integration.test.ts
  • scripts/backfill-climbing-attempt-count.test.ts
  • scripts/backfill-climbing-attempt-count.ts
  • src/db/README.md
  • src/db/climbing-attempt-count-backfill.integration.test.ts
  • src/db/climbing-attempt-count-backfill.test.ts
  • src/db/climbing-attempt-count-backfill.ts
  • src/db/drizzle-schema.test.ts
  • src/db/schema/activity.ts
  • src/providers/kaya/import.test.ts
  • src/providers/kaya/import.ts

Comment thread packages/server/src/repositories/climbing-repository.ts Outdated
Comment thread scripts/backfill-climbing-attempt-count.test.ts
Comment thread scripts/backfill-climbing-attempt-count.ts
Comment thread src/db/climbing-attempt-count-backfill.ts Outdated
Comment thread src/providers/kaya/import.ts
@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@greptile-apps greptile-apps Bot 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@Asherlc
Asherlc merged commit 2ec2eb1 into main Jul 22, 2026
120 checks passed
@Asherlc
Asherlc deleted the Asherlc/create-pr-from-instructions-v1 branch July 22, 2026 18:35
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