Skip to content

fix(cloudflare): make local workers tests pass#1596

Open
riderx wants to merge 3 commits intomainfrom
riderx/cf-workers-tests
Open

fix(cloudflare): make local workers tests pass#1596
riderx wants to merge 3 commits intomainfrom
riderx/cf-workers-tests

Conversation

@riderx
Copy link
Member

@riderx riderx commented Feb 7, 2026

Summary (AI generated)

  • Keep Cloudflare Workers local testing reliable and keep the Cloudflare backend suite enabled in CI.
  • Pin GitHub Actions dependencies to commit SHAs (addresses Sonar security hotspot).
  • Reduce duplicated rate-limit/logging code in channel_self and device handlers (aimed at Sonar duplication gate).

Test plan (AI generated)

  • bun lint && bun lint:backend
  • bun typecheck
  • ./scripts/test-cloudflare-v2.sh

Screenshots (AI generated)

  • N/A (backend/CI changes)

Checklist (AI generated)

  • My code follows the code style of this project and passes
    bun run lint:backend && bun run lint.
  • My change requires a change to the documentation.
  • I have updated the documentation (https://github.com/Cap-go/website)
    accordingly.
  • My change has adequate E2E test coverage.
  • I have tested my code manually, and I have provided steps how to reproduce
    my tests

Generated with AI

Copilot AI review requested due to automatic review settings February 7, 2026 01:55
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 7, 2026

📝 Walkthrough

Walkthrough

Enables active Cloudflare Workers testing and wiring, adds multiple Cloudflare API routes, refactors per-request rate-limit recording to synchronous guarded calls, updates worker startup to build and supply a runtime env (extracted from Supabase CLI), removes D1 sync from test flows, and adjusts routing for Cloudflare vs Supabase endpoints.

Changes

Cohort / File(s) Summary
CI / Workflows
.github/workflows/tests.yml
Reactivates Cloudflare Workers test workflow using JarvusInnovations/background-action@v1, adds start step and backend test step, removes legacy commented Cloudflare blocks and updates wait-on ports.
Docs
CLOUDFLARE_TESTING.md
Updates env file path to cloudflare_workers/.env.local and clarifies that the start script overrides Supabase keys and sets Cloudflare-local defaults.
Cloudflare API router
cloudflare_workers/api/index.ts
Adds public /webhooks and private /accept_invitation, /invite_new_user_to_org, /set_org_email, /validate_password_compliance, /latency routes and imports; adds /ok trigger.
Worker startup script
scripts/start-cloudflare-workers.sh
Adds robust script/path discovery, Supabase CLI detection and key extraction, builds a temporary runtime env file, starts API/Plugin/Files workers with that env, removes D1 sync orchestration, and adds graceful shutdown/cleanup.
Test runner script
scripts/test-cloudflare-v2.sh
Removes D1 sync step; retains Supabase DB reset then starts Cloudflare Workers and runs tests.
Files upload routing
supabase/functions/_backend/files/files.ts
For HEAD/TUS requests, uses raw request method and routes HEAD TUS to uploadHandler under Workerd (DO) and to supabaseTusHeadHandler otherwise; preserves verb/forwarding behavior.
Rate-limit recording (plugins/device)
supabase/functions/_backend/plugins/channel_self.ts, supabase/functions/_backend/public/device/index.ts
Replaces background-task rate-limit writes with awaited safe recording helpers (try/catch/finally), adds early returns on IP rate-limit checks, and logs failures without breaking primary flows; small signature change returning IP-rate-limit result.
Queue consumer URL selection
supabase/functions/_backend/triggers/queue_consumer.ts
Normalizes function_type and prefers CLOUDFLARE_PP_FUNCTION_URL / CLOUDFLARE_FUNCTION_URL when present, with backward-compatible fallback to SUPABASE_URL.
Stats / device routing
supabase/functions/_backend/utils/stats.ts
Refines CF vs SB routing: prefer Cloudflare Analytics Engine when running under Workerd and DEVICE_INFO binding present; otherwise fall back to Supabase paths.
Webhook validation
supabase/functions/_backend/utils/webhook.ts
Replaces localhost-in-SUPABASE_URL check with an env flag CAPGO_ALLOW_LOCAL_WEBHOOK_URLS === 'true' to allow local webhook URLs.
Test utilities / endpoints
tests/test-utils.ts, tests/error-cases.test.ts
Adds getEndpointUrl() and routes file-related paths (/files, /private/upload_link, /private/download_link, /private/files) to CLOUDFLARE_FILES_URL when configured; tests updated to use helper.
Rate-limit tests
tests/channel-rate-limit.test.ts
Switches to burst-based limit testing with OP_LIMIT_PER_SECOND = 5, diversifies per-call channels to avoid collisions, and verifies operation-level isolation.
Channel_self tests
tests/channel_self.test.ts
Adds getUniqueBaseData() (lowercase random UUID device_id) and replaces prior base-data usage across tests to avoid cache collisions and improve reliability.
Health-check test
tests/ok.test.ts
Makes /ok test environment-aware: if USE_CLOUDFLARE_WORKERS true, call CLOUDFLARE_API_URL/ok; otherwise call local Supabase Edge Function.

Sequence Diagram(s)

sequenceDiagram
  participant CI as CI Workflow
  participant Script as start-cloudflare-workers.sh
  participant SupabaseCLI as Supabase CLI / bunx
  participant EnvFile as runtime .env.tmp
  participant Wrangler as wrangler (workers)
  participant Workers as CF Workers (API/Plugin/Files)
  participant Tests as Test runner (bun run)

  CI->>Script: run start script (background-action)
  Script->>SupabaseCLI: supabase status -> extract SUPABASE_URL, KEYS
  SupabaseCLI-->>Script: return keys
  Script->>EnvFile: write SUPABASE_* and CF defaults
  Script->>Wrangler: start workers with EnvFile (API/Plugin/Files)
  Wrangler->>Workers: launch (listening ports)
  CI->>Tests: run backend tests (USE_CLOUDFLARE true)
  Tests->>Workers: invoke endpoints (files, webhooks, device APIs)
  Workers->>SupabaseCLI: (runtime calls) Supabase endpoints / DB
  Tests-->>CI: report results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

DO NOT MERGE

Poem

🐰 Hop, hop — new routes and env keys gleam,

Workers wake up, spun from a script and a dream.
Rate-limits now settle, recorded in line,
Tests skip old syncs and start on good time.
A rabbit's small cheer for endpoints that shine. 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The PR description is largely incomplete and does not follow the required template structure. Critical sections are missing or inadequately filled. Complete the PR description by filling in all required template sections: provide a detailed Summary, comprehensive Test plan with reproduction steps, Screenshots (if applicable), and ensure all Checklist items are properly addressed with explanations where needed.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: fixing Cloudflare Workers local testing so tests pass. It is concise, specific, and directly related to the primary objective of the changeset.

✏️ 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 riderx/cf-workers-tests

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.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c44d7524a4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 25 to 28
# Build a runtime env file with local Supabase keys so we don't commit secrets.
BASE_ENV_FILE="${ROOT_DIR}/cloudflare_workers/.env.local"
RUNTIME_ENV_FILE="$(mktemp)"
cp "${BASE_ENV_FILE}" "${RUNTIME_ENV_FILE}"

Choose a reason for hiding this comment

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

P2 Badge Use a portable mktemp invocation

On macOS/BSD environments mktemp requires a template argument, so mktemp without parameters exits non‑zero. Because this script runs with set -e, that failure stops the worker boot before any processes start, breaking local Cloudflare testing on macOS. Consider using a portable template like mktemp "${TMPDIR:-/tmp}/capgo-cloudflare-env.XXXXXX" (or mktemp -t capgo-cloudflare-env.XXXXXX) so the script works across developer machines.

Useful? React with 👍 / 👎.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
supabase/functions/_backend/utils/stats.ts (1)

134-138: ⚠️ Potential issue | 🟠 Major

readDeviceVersionCounts should also check getRuntimeKey() when accessing DEVICE_INFO.

At line 135, readDeviceVersionCounts checks c.env.DEVICE_INFO without the getRuntimeKey() === 'workerd' guard, unlike countDevices (line 288) and readDevices (line 298), which both include this check. The comments on those functions explain that DEVICE_INFO bindings are often absent in local Cloudflare testing, so the same guard should apply to readDeviceVersionCounts to avoid binding unavailability errors in local environments.

Change:

if (!c.env.DEVICE_INFO)

to:

if (getRuntimeKey() !== 'workerd' || !c.env.DEVICE_INFO)
tests/channel_self.test.ts (1)

1169-1243: ⚠️ Potential issue | 🟠 Major

Mixed tabs and spaces — ESLint will fail on these lines.

Lines 1169–1243 use tab characters mixed with spaces for indentation. The static analysis reports dozens of no-tabs / no-mixed-spaces-and-tabs / indent errors here. The PR checklist requires lint to pass (bun lint:backend), so this block needs to be reformatted to use spaces only (2-space indent).

Fix: re-indent with spaces

Replace all leading tabs in the it('should clean up old channel_devices entry…') test and its finally block with 2-space indentation. For example:

-	  it('should clean up old channel_devices entry when migrating from old to new version', async () => {
-	    const deviceId = randomUUID()
-	    const data = getUniqueBaseData(APPNAME)
+  it('should clean up old channel_devices entry when migrating from old to new version', async () => {
+    const deviceId = randomUUID()
+    const data = getUniqueBaseData(APPNAME)

Apply the same fix through the entire block (lines 1169–1243).

CLOUDFLARE_TESTING.md (1)

147-147: ⚠️ Potential issue | 🟡 Minor

Stale path: still references internal/cloudflare/.env.local.

Line 147 in the Troubleshooting section still points to the old path. This should match the updated references on lines 33 and 116.

Fix
-- Verify `internal/cloudflare/.env.local` has correct database credentials
+- Verify `cloudflare_workers/.env.local` has correct database credentials
🤖 Fix all issues with AI agents
In `@cloudflare_workers/api/index.ts`:
- Line 8: ESLint reports the import ordering for "app as accept_invitation" is
incorrect; move the import from
'../../supabase/functions/_backend/private/accept_invitation.ts' so it is
alphabetically before the import for
'../../supabase/functions/_backend/private/credits.ts' to satisfy
perfectionist/sort-imports; find the import statement that declares "import {
app as accept_invitation }" in cloudflare_workers/api/index.ts and reposition it
above the "credits" private import (preserving the exact import specifier
names).

In `@scripts/start-cloudflare-workers.sh`:
- Around line 30-33: The current extraction of env values (SUPA_ENV) uses awk
-F= and print $2 for SUPABASE_URL_FROM_STATUS,
SUPABASE_SERVICE_ROLE_KEY_FROM_STATUS, and SUPABASE_ANON_KEY_FROM_STATUS which
drops any '=' characters in the value (breaking JWTs); change the extraction to
split only on the first '=' (e.g., use cut -d'=' -f2- or a sed that strips the
leading "KEY=") when processing SUPA_ENV so SECRET_KEY and PUBLISHABLE_KEY
retain any trailing '=' padding; update the lines that set
SUPABASE_SERVICE_ROLE_KEY_FROM_STATUS and SUPABASE_ANON_KEY_FROM_STATUS (and
optionally SUPABASE_URL_FROM_STATUS) to use that method instead of awk -F=
'{print $2}'.
- Around line 26-28: The script blindly copies BASE_ENV_FILE into
RUNTIME_ENV_FILE which will trigger a cryptic failure under set -e if
cloudflare_workers/.env.local is missing; add an existence guard around
BASE_ENV_FILE (the variable BASE_ENV_FILE) before invoking mktemp/cp: if the
file does not exist, either create an empty file or emit a clear error and exit,
then proceed to create RUNTIME_ENV_FILE (the RUNTIME_ENV_FILE variable via
mktemp) and cp; update the flow around the cp invocation to only run when
BASE_ENV_FILE exists to avoid unexpected script termination.

In `@supabase/functions/_backend/files/files.ts`:
- Around line 594-604: The HEAD TUS routing forwards to uploadHandler but
uploadHandler currently uses c.req.method (which Hono/tiny rewrote to 'GET')
when proxying to the Durable Object; update uploadHandler so it uses
c.req.raw.method when constructing/forwarding the request to the Durable Object
(preserve HEAD and ensure no body is sent for HEAD) instead of c.req.method, so
the DO receives the original HTTP verb; locate references to c.req.method inside
uploadHandler and replace them with c.req.raw.method (and explicitly handle
omitting the body for HEAD).

In `@supabase/functions/_backend/plugins/channel_self.ts`:
- Around line 580-595: The finally block in the channel_self handlers now awaits
recordChannelSelfRequest and thus delays responses; revert to non-blocking
background execution by calling recordChannelSelfRequest and
recordChannelSelfIPRateLimit via the existing backgroundTask helper (or
c.executionCtx.waitUntil if available) instead of awaiting them in the finally
after closeClient, and add a short comment in the finally explaining the
trade-off for CF Worker environments if you intentionally choose to await
instead; update the POST/PUT/DELETE/GET handlers (the finally that wraps
post/put/delete/get + closeClient) to call backgroundTask(() =>
recordChannelSelfRequest(...)) and backgroundTask(() =>
recordChannelSelfIPRateLimit(...)) (or use c.executionCtx.waitUntil(Promise)) so
the response is not delayed.
🧹 Nitpick comments (7)
scripts/test-cloudflare-v2.sh (1)

20-25: Step numbering is inconsistent after removing step 2.

Steps jump from "Step 1" (Line 21) to "Step 3" (Line 25). Renumber to keep them sequential now that the D1 sync step has been removed.

Note: The Shellcheck SC2209 warning on Line 22 is a false positive — PAGER=cat correctly sets the env var to the literal string "cat" to suppress interactive pagers.

Proposed fix
-# 3. Start workers
-echo -e "\n${YELLOW}Step 3: Starting Cloudflare Workers...${NC}"
+# 2. Start workers
+echo -e "\n${YELLOW}Step 2: Starting Cloudflare Workers...${NC}"
-# 4. Run tests
-echo -e "\n${YELLOW}Step 4: Running tests...${NC}"
+# 3. Run tests
+echo -e "\n${YELLOW}Step 3: Running tests...${NC}"
tests/ok.test.ts (1)

27-34: Inconsistency: bypasses getEndpointUrl and targets API worker instead of plugin worker for /ok.

getEndpointUrl('/ok') routes to CLOUDFLARE_PLUGIN_URL (port 8788), but this test hits CLOUDFLARE_API_URL (port 8787) directly. If /ok is a health check on all workers this is fine as a smoke test, but it diverges from the routing convention used elsewhere. Consider using getEndpointUrl('/ok') for consistency, or add a comment explaining why the API worker is targeted specifically. As per coding guidelines, backend tests must use helpers from tests/test-utils.ts including getEndpointUrl(path) for correct worker routing.

supabase/functions/_backend/triggers/queue_consumer.ts (1)

312-332: AbortController is instantiated but never wired — dead timeout timer.

controller and timeoutId are created (Lines 313-314) but signal: controller.signal is commented out at Line 323. The setTimeout still fires after 15s and calls controller.abort() to no effect, and clearTimeout runs in finally. This is harmless but wasteful.

Either uncomment the signal to enable the timeout or remove the AbortController entirely to avoid confusion.

supabase/functions/_backend/public/device/index.ts (2)

23-28: assertDeviceIPRateLimit always throws on limit — the if (ipLimit) guard is dead code.

simpleRateLimit is typed (): never, so it always throws. assertDeviceIPRateLimit therefore either returns undefined or throws — it never returns a truthy value. The if (ipLimit) return ipLimit checks on lines 55–57, 106–108, and 156–158 are unreachable in the rate-limited path.

This works correctly (the throw propagates to Hono's error handler and the finally block still runs), but the guard is misleading. Consider renaming to make the "assert" (throw) semantics explicit, or simply call without capturing the return:

Proposed simplification
-    const ipLimit = await assertDeviceIPRateLimit(c, body.app_id)
-    if (ipLimit)
-      return ipLimit
+    await assertDeviceIPRateLimit(c, body.app_id)

Also applies to: 54-58, 105-108, 155-158


68-89: Consider extracting the duplicated finally blocks into a shared helper.

The rate-limit recording logic in the finally blocks for POST, GET, and DELETE is nearly identical — only the operation string ('set', 'get', 'delete') differs. A small helper would reduce ~57 lines to ~19 + 3 one-liners.

Sketch
async function recordRateLimits(
  c: Context,
  appId: string | undefined,
  deviceId: string | undefined,
  operation: ChannelSelfOperation,
) {
  if (deviceId && appId) {
    try { await recordChannelSelfRequest(c, appId, deviceId, operation) }
    catch (error) { cloudlog({ requestId: c.get('requestId'), message: `Failed to record device ${operation} rate limit`, app_id: appId, device_id: deviceId, error }) }
  }
  if (appId) {
    try { await recordDeviceIPRateLimit(c, appId) }
    catch (error) { cloudlog({ requestId: c.get('requestId'), message: 'Failed to record device IP rate limit', app_id: appId, error }) }
  }
}

Also applies to: 118-139, 168-189

tests/channel_self.test.ts (1)

680-681: Nit: getUniqueBaseData already sets a unique device_id — the subsequent override is redundant.

Several tests call getUniqueBaseData(APPNAME) (which assigns a fresh randomUUID to device_id) and then immediately overwrite data.device_id with another randomUUID(). The second assignment is harmless but unnecessary.

Also applies to: 733-734, 858-860, 956-957, 969-970

tests/channel-rate-limit.test.ts (1)

8-8: Hardcoded limit constant should stay in sync with the source of truth.

OP_LIMIT_PER_SECOND = 5 mirrors OP_RATE_LIMIT_PER_SECOND in channelSelfRateLimit.ts. If the backend constant changes, this test will silently break. Consider importing or adding a comment referencing the source constant.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the local Cloudflare Workers testing workflow so the Cloudflare-targeted Vitest suite can run reliably (locally and in CI) by aligning worker routing, runtime behavior, and test expectations.

Changes:

  • Route test requests to the correct Cloudflare worker (API/Plugin/Files) and adjust a few tests for Cloudflare mode.
  • Improve local Cloudflare runtime behavior (stats fallback when Analytics Engine bindings are missing; rate-limit recording timing; TUS HEAD routing).
  • Add/refresh local testing scripts + documentation, and enable Cloudflare Workers backend tests in CI.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test-utils.ts Routes “files” endpoints to the Files worker in Cloudflare mode.
tests/ok.test.ts Uses Cloudflare worker /ok when running in Cloudflare mode.
tests/error-cases.test.ts Uses getEndpointUrl() so plugin/files requests hit the right worker.
tests/channel_self.test.ts Ensures unique device IDs in many cases; adjusts a migration test to avoid same-channel limiter.
tests/channel-rate-limit.test.ts Updates tests to reflect the 5-ops/sec burst behavior and avoids same-channel limiter conflicts.
supabase/functions/_backend/utils/webhook.ts Gates localhost webhook URL allowance behind CAPGO_ALLOW_LOCAL_WEBHOOK_URLS.
supabase/functions/_backend/utils/stats.ts Falls back to Supabase/Postgres stats paths when Analytics Engine bindings aren’t present in local workerd.
supabase/functions/_backend/triggers/queue_consumer.ts Normalizes function_type and improves Cloudflare URL selection/back-compat for older messages.
supabase/functions/_backend/public/device/index.ts Makes rate-limit recording immediate/synchronous and adjusts IP limiter handling.
supabase/functions/_backend/plugins/channel_self.ts Makes IP limiter return handling consistent; records rate limit synchronously with error logging.
supabase/functions/_backend/files/files.ts Fixes HEAD detection in Hono/tiny and routes TUS HEAD correctly.
scripts/test-cloudflare-v2.sh Updates script comments and removes the obsolete D1 sync step.
scripts/start-cloudflare-workers.sh Generates a runtime env file from local Supabase status and starts the 3 workers.
cloudflare_workers/api/index.ts Adds missing API/private routes and exposes /webhooks; adds triggers /ok.
CLOUDFLARE_TESTING.md Updates env-file location and documents runtime overrides done by the start script.
.github/workflows/tests.yml Starts local Cloudflare workers in CI and runs test:cloudflare:backend.

Comment on lines 32 to 33
SUPABASE_SERVICE_ROLE_KEY_FROM_STATUS="$(printf '%s\n' "${SUPA_ENV}" | awk -F= '/^SECRET_KEY=/{print $2}' | tr -d '"')"
SUPABASE_ANON_KEY_FROM_STATUS="$(printf '%s\n' "${SUPA_ENV}" | awk -F= '/^PUBLISHABLE_KEY=/{print $2}' | tr -d '"')"
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

The keys extracted from supabase status -o env appear to use the wrong variable names (SECRET_KEY / PUBLISHABLE_KEY). Supabase’s env output is typically SERVICE_ROLE_KEY and ANON_KEY, so this script may exit with “Missing Supabase keys…” even when Supabase is running. Update the awk patterns (or switch to supabase status -o json and parse deterministically) so SUPABASE_SERVICE_ROLE_KEY and SUPABASE_ANON_KEY are reliably populated in CI/local runs.

Suggested change
SUPABASE_SERVICE_ROLE_KEY_FROM_STATUS="$(printf '%s\n' "${SUPA_ENV}" | awk -F= '/^SECRET_KEY=/{print $2}' | tr -d '"')"
SUPABASE_ANON_KEY_FROM_STATUS="$(printf '%s\n' "${SUPA_ENV}" | awk -F= '/^PUBLISHABLE_KEY=/{print $2}' | tr -d '"')"
SUPABASE_SERVICE_ROLE_KEY_FROM_STATUS="$(printf '%s\n' "${SUPA_ENV}" | awk -F= '/^(SERVICE_ROLE_KEY|SECRET_KEY)=/{print $2}' | tr -d '"')"
SUPABASE_ANON_KEY_FROM_STATUS="$(printf '%s\n' "${SUPA_ENV}" | awk -F= '/^(ANON_KEY|PUBLISHABLE_KEY)=/{print $2}' | tr -d '"')"

Copilot uses AI. Check for mistakes.
Comment on lines 1169 to 1172
it('should clean up old channel_devices entry when migrating from old to new version', async () => {
const deviceId = randomUUID()
const data = getUniqueBaseData(APPNAME)
data.device_id = deviceId
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

These lines contain tab indentation (\t), which is inconsistent with the surrounding file and is likely to fail formatting/lint rules. Replace the tabs with spaces to keep indentation consistent and avoid CI lint failures.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
supabase/functions/_backend/files/files.ts (1)

26-26: ⚠️ Potential issue | 🟡 Minor

Stale comment: "20 minutes" but the value is 30 minutes.

The constant is 1000 * 60 * 30 (30 minutes), but the comment says "20 minutes."

Suggested fix
-const DO_CALL_TIMEOUT = 1000 * 60 * 30 // 20 minutes
+const DO_CALL_TIMEOUT = 1000 * 60 * 30 // 30 minutes
🧹 Nitpick comments (5)
tests/channel_self.test.ts (2)

680-681: Redundant device_id override after getUniqueBaseData.

getUniqueBaseData already assigns a fresh randomUUID() to device_id (line 21). The immediate re-assignment on line 681 is unnecessary. The same pattern repeats in several other tests (lines 733–734, 786–787, 858–860, 928, 943, 957, 970).

Not urgent, but cleaning these up would make the intent of getUniqueBaseData clearer.


88-263: Tests use it() instead of it.concurrent() — pre-existing but worth noting.

Per coding guidelines, tests should use it.concurrent() for parallel execution. However, many tests here mutate shared channel state (toggling allow_device_self_set, allow_emulator, etc.) and depend on sequential ordering, so switching isn't trivial. This is pre-existing and not introduced by this PR, but worth tracking for a future refactor that isolates state per test. As per coding guidelines, "Design tests for parallel execution; use it.concurrent() instead of it() to run tests in parallel within the same file; create dedicated seed data when tests modify shared resources".

scripts/start-cloudflare-workers.sh (2)

70-77: Duplicate keys possible when .env.local already defines Supabase vars.

cat >> appends to the runtime env file, which already contains the contents of .env.local. If that file already defines SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, etc., the runtime file will have duplicate entries. Depending on how wrangler --env-file resolves duplicates (first-wins vs last-wins), this could either silently work or cause confusion.

Consider either stripping the matching keys from the base file before appending, or documenting that the appended values intentionally override.


46-46: Unquoted ${SUPABASE_CLI} undergoes word-splitting — intentional but fragile.

When SUPABASE_CLI="bunx supabase", the unquoted expansion inside $(...) works because word splitting produces two arguments. This is correct but relies on the value never containing spaces in unexpected places. A brief comment would help future maintainers understand the intent.

supabase/functions/_backend/plugins/channel_self.ts (1)

606-616: res variable is now dead — simplify to direct return.

Since return res moved inside the try block (Line 609), the outer let res declaration on Line 606 is unused. The same pattern repeats in PUT (Line 646), DELETE (Line 686), and GET (Line 727).

♻️ Simplify by removing the intermediate variable (POST example)
-  let res
   try {
-    res = await post(c, getDrizzleClient(pgClient), bodyParsed)
-    return res
+    return await post(c, getDrizzleClient(pgClient), bodyParsed)
   }

Apply the same simplification to the PUT, DELETE, and GET handlers.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 7, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
3.6% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

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.

1 participant