Conversation
textbee is public, so it qualifies for CodeRabbit's Open Source plan (the Pro+ feature set at no cost). Reviews are comment-only on the chill profile, so nothing gates a merge. Two settings are load-bearing and easy to get wrong: base_branches always includes the default branch and cannot exclude it, so main is reviewed implicitly and dev has to be listed explicitly. Without it, every feature PR would go unreviewed since they all target dev. The skip-ai-review label is the only lever left for skipping the dev to main roll-ups, which would otherwise re-review code already seen. CodeRabbit auto-reads CLAUDE.md from the repo root as review guidelines, but this repo's CLAUDE.md sits one directory above the git root and .cursor/rules is not on its auto-read list. The no-em-dash and pnpm-only rules are therefore encoded directly in tone_instructions and a global path instruction. Validated against schema.v2.json. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The workflow fired on push only, so pull requests carried no checks of their own. CodeRabbit's github-checks tool waits on GitHub Checks and comments on failures, which gave it nothing to read, and outside contributors got no CI signal before merge. It also ran everything in one workflow, with web and api sharing a single job. On the last green run that job was 5m23s, of which the e2e suite was 2m52s while already carrying continue-on-error, so it dominated wall clock while gating nothing. An api-only change paid for all of it plus both android builds, because a workflow-level paths filter is all or nothing. Now api, web and android each have their own workflow and their own paths filter, which needs no third-party change-detection action, and web e2e is its own job so the blocking signal lands in about 90 seconds. Also folded in, since the files were being rewritten anyway: - permissions: contents: read. Nothing was declared, so the token got default write scope on every run. - concurrency with cancel-in-progress, and timeout-minutes. A hung job previously burned the six hour default. - Action versions. actionlint rejected setup-node@v3, cache@v3 and setup-java@v3 as too old for current runners, and gradle-build-action is deprecated in favour of gradle/actions/setup-gradle. - setup-node's built-in pnpm cache replaces the manual store-path and actions/cache block. pnpm is installed first so the cache has a package manager to query. - The android job is skipped on fork pull requests. It writes google-services.json from repository secrets, and GitHub withholds secrets from forks, so it would fail every outside contribution. - google-services.json is written through an env var instead of shell interpolation, so the secret never lands on a command line and JSON containing quotes cannot break the redirect. - fail-fast: false on the android matrix, so a dev failure no longer cancels the prod build. - Dropped the android_variant dispatch input. It was declared but never referenced; the matrix always built both variants. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…specs Four specs had been failing on main for as long as the run history goes back. The old workflow set continue-on-error on the e2e step rather than the job, and a step with continue-on-error reports its conclusion as success even when the command exits non-zero, so the failures never surfaced. Splitting e2e into its own job made them visible. None of them were stale. Every string they assert on still exists in the source. Three are hydration races of the shape ab96e73 fixed for the messaging specs: the sections stream behind a loading.tsx boundary, so the HTML paints before React attaches handlers, and a click landing in that gap is silently dropped. The test then waits out its timeout on a dialog that was never going to open. Both specs now navigate through a helper that waits on a value only the client render can produce: the gateway stats figure on the dashboard, and the fetched device id in the guide. Prism tokens are not usable as that signal, because react-syntax-highlighter renders its spans server side too, so they are already in the SSR payload. The clipboard spec had a second, unrelated cause. It asserted on the button's "Copied" label, and code-block.tsx clears that label two seconds after the click, so the assertion raced a window narrow enough to miss on a loaded runner. It now polls the clipboard, which is the behaviour under test and does not expire. Verified with --repeat-each=4 --retries=0 --workers=2: 56 passed. Single worker runs are why local looked green while CI failed; the specs' own comments note that parallel workers background the page, which one worker never reproduces. No production code changed. These were test bugs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add CodeRabbit review, split CI into per-app workflows
Date filter changes for webhook history were ignored by react-query because start and end were only sent as request params, not cache keys. Fixes #256
…routes The scheme was registered without a name, so it landed in the OpenAPI doc as api_key and no operation referenced it. Swagger UI stored the key but never sent the header. Name the scheme x-api-key and add ApiSecurity to every AuthGuard route, mirroring the existing ApiBearerAuth placement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Make Swagger UI actually send the x-api-key header
…lter-query-key fix(web): include start/end in webhook notifications query key
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 17 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. 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, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe pull request adds repository automation, documents API-key security in Swagger, centralizes webhook notification query keys, and synchronizes API guide and dashboard end-to-end tests with hydrated data. ChangesRepository automation
API security documentation
Webhook notification queries
End-to-end test synchronization
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (3)
.github/workflows/android.yaml (2)
88-91: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExplain or remove the disabled test step.
The
Run Android testsstep is commented out with no rationale, unlike thee2ejob inweb.yaml, which documents itscontinue-on-errorwith a clear comment and TODO. As written, this silently drops unit test coverage from CI, and a future reader cannot tell whether it is temporary or intentional.Add a short comment stating why the step is disabled and what would need to happen to re-enable it, or remove the dead block if the tests are permanently retired.
Do you want me to open an issue to track re-enabling./gradlew test${{ matrix.variant }}DebugUnitTest?🤖 Prompt for 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. In @.github/workflows/android.yaml around lines 88 - 91, Document the disabled “Run Android tests” block with a concise comment explaining why `./gradlew test${{ matrix.variant }}DebugUnitTest` is currently disabled and what must happen before re-enabling it, or remove the commented-out step if Android unit tests are permanently retired.
63-66: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winRemove or align the Gradle version input.
The wrapper uses Gradle
7.5, whilesetup-gradlerequests7.2. The build invokes./gradlew, so Gradle7.2is unused. Removegradle-version, or set it to7.5to avoid the redundant download.🤖 Prompt for 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. In @.github/workflows/android.yaml around lines 63 - 66, Update the Setup Gradle step to remove the redundant gradle-version input, or align it with the wrapper’s Gradle 7.5 version; preserve the existing ./gradlew-based build flow..github/workflows/api.yaml (1)
69-73: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd a lint step to match the web workflow's quality gates.
The job runs
BuildandUnit testbut never runs lint.api/package.jsonexposes"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix".web.yamlrunspnpm lintandpnpm typecheckbefore tests, butapi.yamlhas no equivalent step, so lint regressions in the API package will not be caught by CI.♻️ Proposed addition
- name: Install dependencies run: pnpm install + - name: Lint + run: pnpm lint + - name: Build run: pnpm run build🤖 Prompt for 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. In @.github/workflows/api.yaml around lines 69 - 73, Add a dedicated lint step to the API workflow job, invoking the package’s existing `pnpm lint` script before `Build` and `Unit test`, so API lint regressions are caught by CI.
🤖 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 @.coderabbit.yaml:
- Around line 92-96: Update the comment above the enabled github-checks
configuration to state that it waits for all GitHub Checks, then comments on
failures; leave the configuration unchanged.
In @.github/workflows/android.yaml:
- Around line 52-55: Update the Android workflow’s “Checkout repository” step to
set actions/checkout’s persist-credentials option to false, matching the
corresponding checkout steps in the other workflows; leave the existing ref
selection unchanged.
In @.github/workflows/api.yaml:
- Around line 45-49: Update the Checkout repository steps in the workflow
configurations to set persist-credentials to false alongside the existing
checkout options. Apply this consistently in the API, web, and Android
workflows, while preserving the current ref selection and checkout behavior.
In @.github/workflows/web.yaml:
- Around line 45-51: Update every actions/checkout step in the checks and e2e
jobs of web.yaml, and the corresponding checkout steps in api.yaml and
android.yaml, to set persist-credentials to false. Preserve the existing
checkout refs and other options.
In `@api/src/billing/billing.controller.ts`:
- Line 16: Adjust the Swagger security metadata in the billing controller so
unguarded GET /billing/plans and POST /billing/webhook/polar do not inherit
bearer or x-api-key requirements. Move `@ApiBearerAuth`() and
`@ApiSecurity`('x-api-key') from controller scope to the guarded billing methods,
or explicitly set operation-level security to empty for these public operations.
In `@web/e2e/api-guide.spec.ts`:
- Around line 110-116: Update the clipboard assertion in the polling block of
the API guide test to compare against the complete expected copied code block,
rather than merely checking for the api.textbee.dev substring. Normalize
whitespace as needed while preserving the existing polling behavior.
---
Nitpick comments:
In @.github/workflows/android.yaml:
- Around line 88-91: Document the disabled “Run Android tests” block with a
concise comment explaining why `./gradlew test${{ matrix.variant
}}DebugUnitTest` is currently disabled and what must happen before re-enabling
it, or remove the commented-out step if Android unit tests are permanently
retired.
- Around line 63-66: Update the Setup Gradle step to remove the redundant
gradle-version input, or align it with the wrapper’s Gradle 7.5 version;
preserve the existing ./gradlew-based build flow.
In @.github/workflows/api.yaml:
- Around line 69-73: Add a dedicated lint step to the API workflow job, invoking
the package’s existing `pnpm lint` script before `Build` and `Unit test`, so API
lint regressions are caught by CI.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: ee0be272-af33-470e-bcfe-07f9e955b072
📒 Files selected for processing (17)
.coderabbit.yaml.github/workflows/android.yaml.github/workflows/api.yaml.github/workflows/build-and-test.yaml.github/workflows/web.yamlapi/src/auth/auth.controller.tsapi/src/billing/billing.controller.tsapi/src/gateway/gateway.controller.tsapi/src/main.tsapi/src/support/support.controller.tsapi/src/webhook/webhook.controller.tsweb/e2e/api-guide.spec.tsweb/e2e/dashboard.spec.tsweb/lib/api/hooks.test.tsxweb/lib/api/hooks.tsweb/lib/api/query-keys.test.tsweb/lib/api/query-keys.ts
💤 Files with no reviewable changes (1)
- .github/workflows/build-and-test.yaml
| - name: Checkout repository | ||
| uses: actions/checkout@v7 | ||
| with: | ||
| ref: ${{ github.event_name == 'workflow_dispatch' && inputs.branch || github.ref }} | ||
|
|
||
| # pnpm has to be on PATH before setup-node, or its pnpm cache resolution | ||
| # has no package manager to query. |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Consider disabling credential persistence on both checkout steps.
Neither the checks job's checkout (lines 45-51) nor the e2e job's checkout (lines 98-101) sets persist-credentials: false. Neither job pushes or commits, so the persisted GITHUB_TOKEN is unnecessary and stays readable for the whole job, including by pnpm install and Playwright browser install scripts.
This finding repeats in api.yaml and android.yaml. See the consolidated comment for a single fix across all three files.
Also applies to: 98-101
🧰 Tools
🪛 zizmor (1.28.0)
[warning] 45-51: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for 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.
In @.github/workflows/web.yaml around lines 45 - 51, Update every
actions/checkout step in the checks and e2e jobs of web.yaml, and the
corresponding checkout steps in api.yaml and android.yaml, to set
persist-credentials to false. Preserve the existing checkout refs and other
options.
Source: Linters/SAST tools
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 5 file(s) based on 6 unresolved review comments. Files modified:
Commit: The changes have been pushed to the Time taken:
Lines 53–58 uses: actions/checkout@v7
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.branch || github.ref }}
+ persist-credentials: false
- name: Set up JDK 17
uses: actions/setup-java@v5
Lines 47–52 uses: actions/checkout@v7
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.branch || github.ref }}
+ persist-credentials: false
# pnpm has to be on PATH before setup-node, or its pnpm cache resolution
# has no package manager to query.
Lines 46–51 uses: actions/checkout@v7
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.branch || github.ref }}
+ persist-credentials: false
# pnpm has to be on PATH before setup-node, or its pnpm cache resolution
# has no package manager to query.Lines 99–104 uses: actions/checkout@v7
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.branch || github.ref }}
+ persist-credentials: false
- name: Install pnpm
uses: pnpm/action-setup@v6 |
Fixed 5 file(s) based on 6 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
The bot regenerated both pnpm lockfiles, floating every dependency to the newest allowed version. That pulled zod 4.4.3 into @polar-sh/sdk, which broke @polar-sh/sdk/webhooks type resolution and failed the API build on CI. Restored from 967ddd4 and verified with a local pnpm install (no diff, zod pinned back to 3.25.76). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The page's first Copy code button belongs to the Base URL chip, so the exact-match assertion CodeRabbit added could never pass. Click the button inside the #send-sms section instead, and build the expected snippet from buildEndpoints() so the test cannot drift from the source template. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
actions/checkout writes the GITHUB_TOKEN into .git/config by default, where any later step can read it. None of these jobs push or use git auth after checkout, so persist-credentials: false removes the exposure. Applies the CodeRabbit suggestion it could not commit itself. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CodeRabbit's auto-fix agent regenerated both lockfiles on PR vernu#270, floating zod to v4 inside @polar-sh/sdk and breaking the API build. Path filters already excluded lockfiles from review but do not stop the fix agent from committing whatever its sandbox produces. - lockfile-guard workflow fails any PR where a pnpm-lock.yaml changes without its sibling package.json - packageManager pins pnpm@9.14.2 in api and web, and CI reads the pin via package_json_file instead of a loose version: 9 - CI installs use --frozen-lockfile so an out-of-sync lockfile fails at install time instead of being silently re-resolved - .coderabbit.yaml instructs the fix agent to never run installs or commit lockfile changes Closes vernu#271 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary by CodeRabbit
New Features
Bug Fixes
Tests