-
-
Notifications
You must be signed in to change notification settings - Fork 67
feat: add electron platform support #1395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Warning Rate limit exceeded@riderx has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 25 minutes and 40 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (29)
📝 WalkthroughWalkthroughAdds first-class Electron platform support across locales, DB schema/migration/seed, TypeScript DB types, backend validation/channel selection, analytics/cloudflare mappings, frontend channel/platform handling, and tests. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant UpdatesFn as Updates Function
participant PG as Database
participant Stats as Stats Logger
Client->>UpdatesFn: POST /updates { platform: "electron", version_name, ... }
UpdatesFn->>PG: SELECT channel WHERE id=? (include electron column)
PG-->>UpdatesFn: channelData (electron: false | true)
alt channel.electron == false
UpdatesFn->>Stats: record "disablePlatformElectron"
UpdatesFn->>Client: 200 { error: "Electron updates disabled", version, previous_version_name }
else
UpdatesFn->>PG: insert build/update row / proceed normal flow
UpdatesFn->>Client: 200 { success }
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
There was a problem hiding this 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: 0c81b9f8ae
ℹ️ 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".
| if (!channelData.channels.electron && platform === 'electron') { | ||
| cloudlog({ requestId: c.get('requestId'), message: 'Cannot update, electron is disabled', id: device_id, date: new Date().toISOString() }) | ||
| await sendStatsAndDevice(c, device, [{ action: 'disablePlatformElectron', versionName: version.name }]) | ||
| return simpleError200(c, 'disabled_platform_electron', 'Cannot update, electron is disabled', { | ||
| version: version.name, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure electron flag is loaded before blocking updates
The new check !channelData.channels.electron will always evaluate to true because channelData comes from requestInfosPostgres/getSchemaUpdatesAlias in pg.ts, which only selects ios and android flags (no electron). As a result, every /updates request with platform=electron returns disabled_platform_electron even when the channel allows Electron. Populate electron in the channel select (and schema) or derive the platform flag directly so Electron devices can actually update.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
supabase/functions/_backend/plugins/channel_self.ts (1)
571-573: Invert condition to properly close PG clients in PUT and GET handlersThe
finallyblocks in PUT (lines 572–573) and GET (lines 616–617) handlers only callcloseClientwhenpgClientis falsy:if (!pgClient) await closeClient(c, pgClient)This prevents closure of actual clients, causing resource leaks. The POST and DELETE handlers demonstrate the correct pattern with unconditional
await closeClient(c, pgClient). Fix by inverting the condition:🔧 Proposed fix
PUT handler: finally { - if (!pgClient) - await closeClient(c, pgClient) + if (pgClient) + await closeClient(c, pgClient) GET handler: finally { - if (!pgClient) - await closeClient(c, pgClient) + if (pgClient) + await closeClient(c, pgClient)supabase/functions/_backend/utils/pg.ts (1)
698-731: Addelectroncolumn definition to channels table schema inpostgres_schema.ts.The Drizzle ORM schema definition in
postgres_schema.tsis missing theelectronboolean column on the channels table. The database migration (20260108000000_add_electron_platform.sql) adds the column to the database, but TypeScript type definitions are not updated. This causes the code inpg.tsto referenceschema.channels.electronwhich doesn't exist, resulting in compilation failures.Additionally, the
channelSelectobject ingetSchemaUpdatesAlias()is missing theelectronfield, which should be added for consistency with the other platform columns.Required changes
In
postgres_schema.ts, add to the channels table definition (alongsideiosandandroid):electron: boolean('electron').notNull().default(true),In the
getSchemaUpdatesAlias()function inpg.ts, add to thechannelSelectobject:electron: channelAlias.electron,
🤖 Fix all issues with AI agents
In @supabase/functions/_backend/plugins/channel_self.ts:
- Line 25: The devicePlatformScheme is wrong: replace
z.literal(['ios','android','electron']) with
z.enum(['ios','android','electron']) so individual platform strings validate
correctly; update the inline channel typing objects (the channel shape declared
inline where channels are indexed by platform) to include electron: boolean
alongside ios and android so indexing with 'electron' is typed; and fix the PG
client close logic in the PUT and GET handlers by changing the guard from if
(!pgClient) to if (pgClient) so pgClient.end() runs only when the client exists.
In @supabase/seed.sql:
- Around line 537-542: The seed data is inconsistent: the "no_access" channel
(id 2 / name 'no_access') is inserted with electron='t' in reset_and_seed_data
but electron=false in reset_and_seed_app_data, which breaks tests expecting it
to be excluded on Electron; update the INSERT tuple for the 'no_access' row in
reset_and_seed_data (the row with id 2 / name 'no_access') to set electron to
false (align with reset_and_seed_app_data) so tests like the Expect
not.toContain('no_access') for Electron pass consistently.
🧹 Nitpick comments (2)
messages/vi.json (1)
77-77: Consider reordering Electron keys for consistency.The new Electron platform translation keys are currently placed after the iOS keys, but alphabetically "electron" comes before "ios". For consistency with the other locale files (ja.json, pt-br.json) and to maintain alphabetical ordering, consider moving these entries before their corresponding iOS entries:
- Line 77
action-disable-platform-electronshould be placed before line 76 (ios)- Line 416
channel-platform-electronshould be placed before line 415 (ios)- Line 1119
platform-electronshould be placed before line 1118 (ios)The translation content itself is correct and follows the established Vietnamese language patterns.
Also applies to: 416-416, 1119-1119
tests/updates.test.ts (1)
333-341: Electron platform validity test is correct, consider a slightly stronger assertionThis test does its job of guarding against
400 invalid_json_bodywhenplatform = 'electron'. If you want a bit more confidence, you could also assert on the response body (e.g.json.error !== 'invalid_json_body'or an explicit200), but that’s optional.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (28)
messages/de.jsonmessages/en.jsonmessages/es.jsonmessages/fr.jsonmessages/hi.jsonmessages/id.jsonmessages/it.jsonmessages/ja.jsonmessages/ko.jsonmessages/pl.jsonmessages/pt-br.jsonmessages/ru.jsonmessages/tr.jsonmessages/vi.jsonmessages/zh-cn.jsonsrc/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.tssupabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/plugins/updates.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.tssupabase/functions/_backend/utils/update.tssupabase/migrations/20260108000000_add_electron_platform.sqlsupabase/seed.sqltests/channel_self.test.tstests/updates.test.ts
🧰 Additional context used
📓 Path-based instructions (20)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use single quotes and no semicolons per @antfu/eslint-config
Files:
tests/updates.test.tssrc/components/dashboard/AppSetting.vuetests/channel_self.test.tssupabase/functions/_backend/plugins/updates.tssupabase/functions/_backend/utils/update.tssupabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/pg.tssrc/components/dashboard/DeploymentBanner.vuesupabase/functions/_backend/utils/cloudflare.tssrc/types/supabase.types.tssupabase/functions/_backend/utils/supabase.types.ts
tests/**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Backend tests should be located in the
tests/directory and use Vitest test runner
Files:
tests/updates.test.tstests/channel_self.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use TypeScript strict mode with path aliases mapping
~/tosrc/
Files:
tests/updates.test.tstests/channel_self.test.tssupabase/functions/_backend/plugins/updates.tssupabase/functions/_backend/utils/update.tssupabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/cloudflare.tssrc/types/supabase.types.tssupabase/functions/_backend/utils/supabase.types.ts
tests/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Backend tests must use helpers from
tests/test-utils.tsincludinggetEndpointUrl(path)for correct worker routing andUSE_CLOUDFLARE_WORKERS=truefor CF Workers testing
Files:
tests/updates.test.tstests/channel_self.test.ts
**/{tests,__tests__,test,spec}/**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (AGENTS.md)
Always cover database changes with Postgres-level tests and complement them with end-to-end tests for affected user flows.
Files:
tests/updates.test.tstests/channel_self.test.ts
supabase/migrations/**/*.sql
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Database migrations must be created with
supabase migration new <feature_slug>and never modify previously committed migrations
supabase/migrations/**/*.sql: When a feature requires schema changes, create a single migration file with the Supabase CLI (supabase migration new <feature_slug>) and keep editing that file until the feature ships; never edit previously committed migrations.
A migration that introduces a new table may include seed inserts for that table, but treat that seeding as part of the current feature and do not modify previously committed migrations.
Do not create new cron jobs; instead update theprocess_all_cron_tasksfunction in a new migration file to add your job if needed.
Files:
supabase/migrations/20260108000000_add_electron_platform.sql
src/**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
src/**/*.vue: Use Vue 3 with Composition API and<script setup>syntax for frontend components
Style components using TailwindCSS with DaisyUI components
src/**/*.vue: Use Vue 3<script setup>syntax exclusively for all Vue component scripts
Use Tailwind utility classes for layout and spacing in Vue components
Use DaisyUI components (d-btn,d-input,d-card) for interactive elements in Vue components
Use Konsta components ONLY for safe area helpers (top/bottom insets) in Vue components; avoid other uses
UseuseRoute()fromvue-routerto access route parameters anduseRouter()for programmatic navigation in Vue components
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vue
src/components/**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
Reusable Vue components should be organized in
src/components/directory
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vue
{capacitor.config.{ts,js},src/**/*.{ts,tsx,vue}}
📄 CodeRabbit inference engine (CLAUDE.md)
Mobile apps should use Capacitor with app ID
ee.forgr.capacitor_gofor native mobile functionality
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.ts
src/**/*.{ts,tsx,vue,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use
~/alias for imports fromsrc/directory in frontend TypeScript and Vue components
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.ts
src/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Frontend ESLint must pass before commit; run
bun lint:fixto auto-fix issues in frontend files
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.ts
**/{src,app}/{components,views,pages}/**/*.{vue,css,scss}
📄 CodeRabbit inference engine (AGENTS.md)
The web client is built with Vue.js and Tailwind CSS; lean on utility classes and composition-friendly patterns rather than bespoke CSS.
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vue
**/{src,app}/{components,views,pages}/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
Use DaisyUI (
d-prefixed classes) for buttons, inputs, and other interactive primitives to keep behavior and spacing consistent.
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vue
**/{src,app}/**/*.{vue,ts,tsx,js}
📄 CodeRabbit inference engine (AGENTS.md)
Konsta components are reserved for the safe area helpers. Avoid importing
konstaanywhere else in the app.
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.ts
**/{src,app}/**/*.{css,scss,vue}
📄 CodeRabbit inference engine (AGENTS.md)
Capgo's design uses deep slate bases with the 'Extract' azure highlight (
--color-azure-500: #119eff) and soft radii; mirror the palette fromsrc/styles/style.css(e.g.,--color-primary-500: #515271) when introducing new UI.
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vue
supabase/functions/_backend/**
📄 CodeRabbit inference engine (CLAUDE.md)
Backend logic should be organized in
supabase/functions/_backend/with subdirectories for plugins, private endpoints, public endpoints, triggers, and utilities
Files:
supabase/functions/_backend/plugins/updates.tssupabase/functions/_backend/utils/update.tssupabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/supabase.types.ts
supabase/functions/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Supabase Edge Functions use Deno runtime
Files:
supabase/functions/_backend/plugins/updates.tssupabase/functions/_backend/utils/update.tssupabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/supabase.types.ts
supabase/functions/_backend/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
supabase/functions/_backend/**/*.{ts,js}: Backend code must be placed insupabase/functions/_backend/as shared code deployed to Cloudflare Workers (API/Plugin/Files workers), Supabase Edge Functions, and other platforms
UsecreateHonofromutils/hono.tsfor all Hono framework application initialization and routing
All database operations must usegetPgClient()orgetDrizzleClient()fromutils/pg.tsfor PostgreSQL access during active migration to Cloudflare D1
All Hono endpoint handlers must acceptContext<MiddlewareKeyVariables>and usec.get('requestId'),c.get('apikey'), andc.get('auth')for request context
Use structured logging withcloudlog({ requestId: c.get('requestId'), message: '...' })for all backend logging
UsemiddlewareAPISecretfor internal API endpoints andmiddlewareKeyfor external API keys; validate againstowner_orgin theapikeystable
Checkc.get('auth')?.authTypeto determine authentication type ('apikey' vs 'jwt') in backend endpoints
Use Drizzle ORM query patterns withschemafrompostgress_schema.tsfor all database operations; usealiasV2()for self-joins or multiple table references
Files:
supabase/functions/_backend/plugins/updates.tssupabase/functions/_backend/utils/update.tssupabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/supabase.types.ts
supabase/functions/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Backend ESLint must pass before commit; run
bun lint:backendfor backend files
Files:
supabase/functions/_backend/plugins/updates.tssupabase/functions/_backend/utils/update.tssupabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/supabase.types.ts
supabase/seed.sql
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Seed database with
supabase db resetto apply all migrations and test data fromsupabase/seed.sqlUpdating
supabase/seed.sqlto back new or evolved tests is expected; keep fixtures focused on current behavior while leaving committed migrations unchanged.
Files:
supabase/seed.sql
🧠 Learnings (22)
📚 Learning: 2026-01-08T00:40:00.524Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to **/{tests,__tests__,test,spec}/**/*.{ts,tsx,js} : Always cover database changes with Postgres-level tests and complement them with end-to-end tests for affected user flows.
Applied to files:
tests/updates.test.tssrc/types/supabase.types.ts
📚 Learning: 2026-01-08T00:40:00.524Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to supabase/migrations/**/*.sql : A migration that introduces a new table may include seed inserts for that table, but treat that seeding as part of the current feature and do not modify previously committed migrations.
Applied to files:
supabase/migrations/20260108000000_add_electron_platform.sqlsupabase/seed.sql
📚 Learning: 2026-01-08T00:40:00.524Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to supabase/seed.sql : Updating `supabase/seed.sql` to back new or evolved tests is expected; keep fixtures focused on current behavior while leaving committed migrations unchanged.
Applied to files:
supabase/migrations/20260108000000_add_electron_platform.sqlsupabase/seed.sql
📚 Learning: 2026-01-08T00:40:00.524Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to supabase/migrations/**/*.sql : Do not create new cron jobs; instead update the `process_all_cron_tasks` function in a new migration file to add your job if needed.
Applied to files:
supabase/migrations/20260108000000_add_electron_platform.sql
📚 Learning: 2026-01-08T00:40:00.524Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to supabase/migrations/**/*.sql : When a feature requires schema changes, create a single migration file with the Supabase CLI (`supabase migration new <feature_slug>`) and keep editing that file until the feature ships; never edit previously committed migrations.
Applied to files:
supabase/migrations/20260108000000_add_electron_platform.sql
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/migrations/**/*.sql : Database migrations must be created with `supabase migration new <feature_slug>` and never modify previously committed migrations
Applied to files:
supabase/migrations/20260108000000_add_electron_platform.sql
📚 Learning: 2025-12-25T11:22:13.039Z
Learnt from: WcaleNieWolny
Repo: Cap-go/capgo PR: 1300
File: supabase/migrations/20251224103713_2fa_enforcement.sql:85-96
Timestamp: 2025-12-25T11:22:13.039Z
Learning: In SQL migrations under the repository (e.g., supabase/migrations), enforce that when an org has enforcing_2fa=true, all users (including super_admins) must have 2FA enabled before accessing any org functions, including check_org_members_2fa_enabled. Do not grant admin exceptions to 2FA requirements. This ensures consistent security enforcement across all org-related operations; implement this rule within relevant migrations and associated stored procedures/tests.
Applied to files:
supabase/migrations/20260108000000_add_electron_platform.sql
📚 Learning: 2025-05-29T18:21:17.703Z
Learnt from: WcaleNieWolny
Repo: Cap-go/capgo PR: 1107
File: src/components/dashboard/AppSetting.vue:85-182
Timestamp: 2025-05-29T18:21:17.703Z
Learning: In setUpdateChannelSync function in src/components/dashboard/AppSetting.vue, the database update code at the end is intentionally outside the conflict-resolution if block and should run for cases where sync is being toggled without conflicts or after conflicts are resolved. The return statements inside the dialog handling correctly prevent database updates when the user cancels.
Applied to files:
src/components/dashboard/AppSetting.vue
📚 Learning: 2025-12-23T01:19:04.593Z
Learnt from: riderx
Repo: Cap-go/capgo PR: 1297
File: src/components/dashboard/DeploymentBanner.vue:77-79
Timestamp: 2025-12-23T01:19:04.593Z
Learning: In the Cap-go codebase, ensure that app permission checks never include the role 'owner'. App-level permissions should be based on the user_min_right enum with values: read, upload, write, admin, super_admin (and NOT owner). This pattern applies across Vue components that perform permission checks; if you find a check referencing 'owner' for app-level access, replace it with the appropriate user_min_right value and keep organization-level owner handling in organization.ts.
Applied to files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vue
📚 Learning: 2026-01-08T00:40:00.524Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to playwright/e2e/**/*.{ts,js} : Cover customer-facing flows with the Playwright MCP suite. Add scenarios under `playwright/e2e` and run them locally with `bun run test:front` before shipping UI changes.
Applied to files:
tests/channel_self.test.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/utils/postgress_schema.ts : Schema definitions must be placed in `utils/postgress_schema.ts` using Drizzle ORM and never edited in committed migration files
Applied to files:
supabase/functions/_backend/plugins/updates.tssrc/types/supabase.types.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Use shared backend code from `supabase/functions/_backend/` across all deployment platforms; never create platform-specific implementations outside this directory
Applied to files:
supabase/functions/_backend/plugins/updates.tssupabase/functions/_backend/utils/pg.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Check `c.get('auth')?.authType` to determine authentication type ('apikey' vs 'jwt') in backend endpoints
Applied to files:
supabase/functions/_backend/plugins/updates.tssupabase/functions/_backend/utils/update.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/**/*.{ts,js} : Backend ESLint must pass before commit; run `bun lint:backend` for backend files
Applied to files:
supabase/functions/_backend/utils/update.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to cloudflare_workers/plugin/index.ts : Plugin Worker (port 8788) routes: `/updates`, `/channel_self`, `/stats`
Applied to files:
supabase/functions/_backend/plugins/channel_self.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : All database operations must use `getPgClient()` or `getDrizzleClient()` from `utils/pg.ts` for PostgreSQL access during active migration to Cloudflare D1
Applied to files:
supabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Use Drizzle ORM query patterns with `schema` from `postgress_schema.ts` for all database operations; use `aliasV2()` for self-joins or multiple table references
Applied to files:
supabase/functions/_backend/utils/pg.tssrc/types/supabase.types.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to cloudflare_workers/api/index.ts : API Worker (port 8787) routes: `/bundle`, `/app`, `/device`, `/channel`, `/private/*`, `/triggers`
Applied to files:
src/components/dashboard/DeploymentBanner.vue
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Use structured logging with `cloudlog({ requestId: c.get('requestId'), message: '...' })` for all backend logging
Applied to files:
supabase/functions/_backend/utils/cloudflare.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/seed.sql : Seed database with `supabase db reset` to apply all migrations and test data from `supabase/seed.sql`
Applied to files:
supabase/seed.sql
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Run `bun types` after schema changes to regenerate TypeScript types from Supabase
Applied to files:
src/types/supabase.types.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-05T17:34:25.556Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-05T17:34:25.556Z
Learning: Applies to supabase/functions/**/*.ts : Supabase Edge Functions use Deno runtime
Applied to files:
src/types/supabase.types.tssupabase/functions/_backend/utils/supabase.types.ts
🧬 Code graph analysis (5)
tests/updates.test.ts (1)
tests/test-utils.ts (2)
getBaseData(210-212)postUpdate(469-476)
tests/channel_self.test.ts (1)
tests/test-utils.ts (2)
resetAndSeedAppData(225-287)getBaseData(210-212)
supabase/functions/_backend/utils/update.ts (3)
supabase/functions/_backend/utils/logging.ts (1)
cloudlog(3-15)supabase/functions/_backend/utils/stats.ts (1)
sendStatsAndDevice(86-96)supabase/functions/_backend/utils/hono.ts (1)
simpleError200(213-222)
supabase/functions/_backend/plugins/channel_self.ts (2)
supabase/functions/_backend/utils/postgres_schema.ts (1)
channels(63-82)supabase/functions/_backend/utils/pg.ts (1)
getCompatibleChannelsPg(695-739)
src/types/supabase.types.ts (1)
supabase/functions/_backend/utils/supabase.types.ts (1)
Json(1-7)
🪛 GitHub Actions: Run tests
supabase/functions/_backend/utils/update.ts
[error] 229-229: TS2339: Property 'electron' does not exist on type '{ id: number; name: string; app_id: string; allow_dev: boolean; allow_prod: boolean; allow_emulator: boolean; allow_device: boolean; disable_auto_update_under_native: boolean; disable_auto_update: "none" | ... 3 more ... | "version_number"; ios: boolean; android: boolean; allow_device_self_set: boolean; public: bool...'.
supabase/functions/_backend/plugins/channel_self.ts
[error] 208-208: TS7053: Element implicitly has an 'any' type because expression of type '"ios" | "android" | "electron"' can't be used to index type '{ name: string; ios: boolean; android: boolean; }'. Property 'electron' does not exist on type '{ name: string; ios: boolean; android: boolean; }'.
[error] 366-366: TS7053: Element implicitly has an 'any' type because expression of type '"ios" | "android" | "electron"' can't be used to index type '{ ios: boolean; android: boolean; }'. Property 'electron' does not exist on type '{ ios: boolean; android: boolean; }'.
supabase/functions/_backend/utils/pg.ts
[error] 319-319: TS2339: Property 'electron' does not exist on type 'PgTableWithColumns<Required<Update<{ name: "channels"; schema: undefined; columns: { id: PgColumn<{ name: "id"; tableName: "channels"; dataType: "number"; columnType: "PgBigInt53"; data: number; driverParam: string | number; notNull: true; ... 7 more ...; generated: undefined; }, {}, {}>; ... 16 more ...; allow_prod...'.
[error] 710-710: TS2339: Property 'electron' does not exist on type 'PgTableWithColumns<{ name: "channels"; schema: undefined; columns: { id: PgColumn<{ name: "id"; tableName: "channels"; dataType: "number"; columnType: "PgBigInt53"; data: number; driverParam: string | number; notNull: true; ... 7 more ...; generated: undefined; }, {}, {}>; ... 16 more ...; allow_prod: PgColumn<...>;...'.
[error] 722-722: TS2339: Property 'electron' does not exist on type 'PgTableWithColumns<{ name: "channels"; schema: undefined; columns: { id: PgColumn<{ name: "id"; tableName: "channels"; dataType: "number"; columnType: "PgBigInt53"; data: number; driverParam: string | number; notNull: true; ... 7 more ...; generated: undefined; }, {}, {}>; ... 16 more ...; allow_prod: PgColumn<...>;...'.
🔇 Additional comments (37)
messages/it.json (1)
76-76: LGTM! Electron platform translations are consistent and correct.The three new Italian translation keys for Electron platform support mirror the existing Android and iOS patterns perfectly:
- Line 76: Action message follows the "Bloccato - Piattaforma X disabilitata" structure with correct feminine agreement
- Line 415: Channel platform label follows the "Solo X" pattern
- Line 1118: Simple platform name (proper noun, correctly untranslated)
The translations are grammatically correct and maintain consistency with the existing codebase.
Also applies to: 415-415, 1118-1118
supabase/functions/_backend/plugins/updates.ts (1)
31-56: Electron platform added correctly to request validationExtending
platformto accept'electron'matches the existing pattern and keeps error handling intact. No additional issues spotted in this schema block.messages/ru.json (1)
75-78: Electron RU translations consistent with existing platform stringsThe new Russian entries for disabling Electron, Electron-only channels, and the Electron platform label are grammatically correct and align with the existing Android/iOS counterparts. JSON structure and commas are also valid.
Also applies to: 413-417, 1117-1120
messages/zh-cn.json (1)
75-78: Electron zh-CN translations align with Android/iOS phrasingThe added zh-CN strings for Electron platform disabling, Electron-only channels, and the platform label follow the same structure and tone as the Android/iOS entries, with correct JSON formatting.
Also applies to: 413-417, 1117-1120
messages/es.json (1)
75-78: Electron ES translations are consistent and correctly wiredThe Spanish messages for blocking the Electron platform, Electron-only channels, and the Electron platform label are consistent with the Android/iOS variants and fit the existing wording style. JSON syntax is correct.
Also applies to: 413-417, 1117-1119
messages/de.json (3)
76-76: Electron disable-action translation matches existing platform variantsText and structure align with the Android/iOS equivalents; JSON remains valid.
414-414: Electron channel label consistent with Android/iOS channel labels“Nur Electron” mirrors “Nur Android” / “Nur iOS” and fits the UI usage.
1118-1118: Platform label for Electron is coherent with other platformsUses the same pattern as
platform-android/platform-iosand is appropriate as a product name.messages/pl.json (3)
77-77: Polish disable-action string for Electron is consistentMatches the pattern and tone of Android/iOS disable-platform messages.
416-416: Electron-only channel label is aligned with existing Polish labels“Tylko Electron” is parallel to “Tylko Android” / “Tylko dla iOS” and reads naturally.
1119-1119: Platform name entry for Electron is correct and consistentReuses the product name as done for Android/iOS; no issues.
messages/fr.json (3)
76-76: French disable-action text for Electron matches Android/iOS patternsSentence structure and terminology are consistent with the other platforms.
415-415: Electron-only channel label is well aligned with French UI copy“Uniquement Electron” mirrors “Uniquement Android” / “Uniquement sur iOS” appropriately.
1118-1118: Electron platform label integrates cleanly with existing platform listUses the same style as
platform-android/platform-ios; no localization or syntax issues.messages/ja.json (1)
76-76: LGTM! Electron platform translations added correctly.The three new Electron platform translation keys have been added with proper alphabetical ordering and consistent formatting that matches the existing Android and iOS platform translations. The Japanese translations follow the established pattern and terminology.
Also applies to: 415-415, 1118-1118
messages/pt-br.json (1)
76-76: LGTM! Electron platform translations added correctly.The three new Electron platform translation keys have been added with proper alphabetical ordering and consistent formatting that matches the existing Android and iOS platform translations. The Portuguese (Brazilian) translations follow the established pattern and terminology.
Also applies to: 415-415, 1118-1118
messages/vi.json (1)
77-77: Translations are accurate and consistent.The Vietnamese translations for the Electron platform follow the same pattern and terminology as the existing Android and iOS platform translations, maintaining consistency across the file.
Also applies to: 416-416, 1119-1119
messages/hi.json (1)
75-77: Electron Hindi translations are consistent and correctly keyedThe new Electron-related keys mirror the existing Android/iOS patterns and use appropriate Hindi phrasing; no issues from a code/structure perspective.
Also applies to: 413-416, 1117-1119
src/components/dashboard/AppSetting.vue (1)
34-34: Channel model and query correctly extended withelectronExtending the local
channelstype and SELECT to include theelectronflag keeps this component in sync with the updated schema and other platform flags without affecting existing iOS/Android logic.Also applies to: 235-248
messages/ko.json (1)
75-77: Electron Korean translations are consistent with existing platform keysThe new Electron-related keys are correctly named, localized, and aligned with the Android/iOS counterparts; no issues from a code perspective.
Also applies to: 413-416, 1117-1119
messages/id.json (1)
76-78: Electron translations are consistent with existing platform keysThe new Indonesian strings for
action-disable-platform-electron,channel-platform-electron, andplatform-electronfollow the same naming, tone, and placement as the Android/iOS entries. No issues from a structure or keying perspective.Also applies to: 413-417, 1117-1119
messages/en.json (1)
79-81: Electron strings align with existing platform wordingThe added English entries for
action-disable-platform-electron,channel-platform-electron, andplatform-electronare consistent with the Android/iOS variants and the backend action/error naming. No structural or phrasing issues.Also applies to: 446-450, 1044-1048
messages/tr.json (1)
75-79: Turkish Electron translations look correct and consistentThe Turkish strings for
action-disable-platform-electron,channel-platform-electron, andplatform-electronfollow the same pattern as the Android/iOS entries and read naturally. No key, placement, or consistency problems.Also applies to: 413-417, 1117-1120
supabase/functions/_backend/utils/update.ts (1)
229-236: I don't have a review comment to rewrite. Please provide:
- The original review comment (within
<review_comment>tags)- Any relevant code context
- Any capability results if verification has already been performed
Once you provide these, I will output the rewritten comment in the required format.
tests/channel_self.test.ts (2)
416-438: LGTM! Good extension of existing platform compatibility test.The Electron test block follows the established pattern for iOS and Android, with clear comments documenting the expected channel configurations. The assertions correctly verify that
electron_only,beta, andproductionchannels are returned whiledevelopmentandno_accessare excluded based on theirelectronflag.
440-465: LGTM! Dedicated Electron channel compatibility test.This test provides focused coverage for Electron platform behavior, complementing the multi-platform test above. The expected channel configuration is well-documented in the comments.
supabase/migrations/20260108000000_add_electron_platform.sql (1)
9-10: Verify thatDEFAULT trueis the intended behavior for existing channels.Setting
DEFAULT truemeans all existing channels will automatically support Electron platform. This could be intentional (Electron apps get updates from existing channels by default) or unintentional (existing channels weren't designed for Electron and should opt-in).Confirm this aligns with the product requirements. If existing channels should not automatically support Electron, consider using
DEFAULT falseinstead.supabase/seed.sql (1)
856-866: LGTM! Channel configurations inreset_and_seed_app_dataare correct.The electron flags align with test expectations:
production: electron=true (included for Electron)beta: electron=true (included for Electron)development: electron=false (excluded for Electron)no_access: electron=false (excluded for Electron)electron_only: electron=true, ios=false, android=false (Electron-exclusive)src/components/dashboard/DeploymentBanner.vue (3)
69-72: LGTM! Type definition correctly extended for Electron.The
DefaultChanneltype now includeselectronin the Pick selection, ensuring type safety for the new platform field.
104-116: LGTM! Platform filtering and target generation correctly includes Electron.The channel filter and platform mapping logic correctly handle Electron alongside iOS and Android.
308-317: LGTM! Platform label generation updated for Electron.The
getPlatformLabelfunction now handles theelectronplatform with proper i18n support.supabase/functions/_backend/utils/cloudflare.ts (4)
191-193: LGTM! Platform encoding extended for Electron.The platform value mapping is clear and consistent:
0= Android (default)1= iOS2= ElectronThis is documented in the comment and correctly applied in both write and read operations.
586-586: LGTM! Platform decoding correctly handles Electron.The mapping is consistent with the encoding in
trackDevicesCF, ensuring data integrity when reading device information from Analytics Engine.
1146-1158: LGTM! Admin platform overview interface extended for Electron.The
AdminPlatformOverviewinterface now includeselectron_devicesalongside the existingandroid_devicesandios_devicesfields.
1376-1406: LGTM! Platform overview query and aggregation includes Electron devices.The query correctly counts devices with
double1 = 2as Electron devices, and the result is properly propagated through the function.src/types/supabase.types.ts (1)
10-34: Auto-generated types correctly reflect Electron platform support.The type definitions are properly regenerated to include:
electron: booleanfield in channels table (Row/Insert/Update)"electron"value inplatform_osenum"disablePlatformElectron"instats_actionenum- Updated Constants to match
Based on learnings, ensure
bun typeswas run after the schema migration to generate these types.Also applies to: 631-631, 652-652, 673-673, 3066-3066, 3130-3130, 3323-3323, 3387-3387
supabase/functions/_backend/utils/supabase.types.ts (1)
10-34: Backend types are in sync with frontend types.The backend type definitions mirror the frontend types exactly, which is correct for auto-generated Supabase types. The Electron platform support is properly reflected in:
- Channels table with
electronboolean fieldplatform_osenum including"electron"stats_actionenum with"disablePlatformElectron"This ensures type safety across both frontend and backend code when working with Electron channels.
Also applies to: 631-631, 652-652, 673-673, 3066-3066, 3130-3130, 3323-3323, 3387-3387
There was a problem hiding this 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
🧹 Nitpick comments (3)
supabase/functions/_backend/utils/pg.ts (2)
320-320: Consider refactoring the platform mapping for maintainability.The nested ternary correctly handles all three platforms but could be more readable as an object lookup or switch statement, especially if more platforms are added in the future.
♻️ Optional refactor for improved readability
- const platformQuery = platform === 'android' ? channelAlias.android : platform === 'electron' ? channelAlias.electron : channelAlias.ios + const platformMap = { + android: channelAlias.android, + electron: channelAlias.electron, + ios: channelAlias.ios, + } as const + const platformQuery = platformMap[platform as keyof typeof platformMap] ?? channelAlias.ios
711-711: Platform column mapping works correctly but could be more maintainable.Similar to Line 320, this nested ternary correctly handles platform mapping but checks platforms in a different order (ios→electron→android vs android→electron→ios). While functionally correct due to the typed union parameter, consistent ordering and a refactored approach would improve maintainability.
♻️ Optional refactor for consistency
- const platformColumn = platform === 'ios' ? schema.channels.ios : platform === 'electron' ? schema.channels.electron : schema.channels.android + const platformColumnMap = { + ios: schema.channels.ios, + android: schema.channels.android, + electron: schema.channels.electron, + } as const + const platformColumn = platformColumnMap[platform]Note: Since
platformis strongly typed as the union'ios' | 'android' | 'electron', no fallback is needed.supabase/functions/_backend/utils/postgres_schema.ts (1)
75-77: Consider standardizing the method call order for consistency.The
ioscolumn uses.default(true).notNull()whileandroidandelectronuse.notNull().default(true). While both orderings work correctly in Drizzle ORM, standardizing the order improves code consistency and maintainability.♻️ Proposed fix to standardize the ordering
- ios: boolean('ios').default(true).notNull(), - android: boolean('android').notNull().default(true), - electron: boolean('electron').notNull().default(true), + ios: boolean('ios').notNull().default(true), + android: boolean('android').notNull().default(true), + electron: boolean('electron').notNull().default(true),
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
supabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/postgres_schema.tssupabase/seed.sql
🚧 Files skipped from review as they are similar to previous changes (1)
- supabase/functions/_backend/plugins/channel_self.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use single quotes and no semicolons per @antfu/eslint-config
Files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/pg.ts
supabase/functions/_backend/**
📄 CodeRabbit inference engine (CLAUDE.md)
Backend logic should be organized in
supabase/functions/_backend/with subdirectories for plugins, private endpoints, public endpoints, triggers, and utilities
Files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/pg.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use TypeScript strict mode with path aliases mapping
~/tosrc/
Files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/pg.ts
supabase/functions/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Supabase Edge Functions use Deno runtime
Files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/pg.ts
supabase/functions/_backend/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
supabase/functions/_backend/**/*.{ts,js}: Backend code must be placed insupabase/functions/_backend/as shared code deployed to Cloudflare Workers (API/Plugin/Files workers), Supabase Edge Functions, and other platforms
UsecreateHonofromutils/hono.tsfor all Hono framework application initialization and routing
All database operations must usegetPgClient()orgetDrizzleClient()fromutils/pg.tsfor PostgreSQL access during active migration to Cloudflare D1
All Hono endpoint handlers must acceptContext<MiddlewareKeyVariables>and usec.get('requestId'),c.get('apikey'), andc.get('auth')for request context
Use structured logging withcloudlog({ requestId: c.get('requestId'), message: '...' })for all backend logging
UsemiddlewareAPISecretfor internal API endpoints andmiddlewareKeyfor external API keys; validate againstowner_orgin theapikeystable
Checkc.get('auth')?.authTypeto determine authentication type ('apikey' vs 'jwt') in backend endpoints
Use Drizzle ORM query patterns withschemafrompostgress_schema.tsfor all database operations; usealiasV2()for self-joins or multiple table references
Files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/pg.ts
supabase/functions/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Backend ESLint must pass before commit; run
bun lint:backendfor backend files
Files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/pg.ts
supabase/seed.sql
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Seed database with
supabase db resetto apply all migrations and test data fromsupabase/seed.sqlUpdating
supabase/seed.sqlto back new or evolved tests is expected; keep fixtures focused on current behavior while leaving committed migrations unchanged.
Files:
supabase/seed.sql
🧠 Learnings (8)
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/utils/postgress_schema.ts : Schema definitions must be placed in `utils/postgress_schema.ts` using Drizzle ORM and never edited in committed migration files
Applied to files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/pg.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Use Drizzle ORM query patterns with `schema` from `postgress_schema.ts` for all database operations; use `aliasV2()` for self-joins or multiple table references
Applied to files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/pg.ts
📚 Learning: 2026-01-08T00:40:00.524Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to supabase/migrations/**/*.sql : A migration that introduces a new table may include seed inserts for that table, but treat that seeding as part of the current feature and do not modify previously committed migrations.
Applied to files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/seed.sql
📚 Learning: 2026-01-08T00:40:00.524Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to supabase/seed.sql : Updating `supabase/seed.sql` to back new or evolved tests is expected; keep fixtures focused on current behavior while leaving committed migrations unchanged.
Applied to files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/seed.sql
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : All database operations must use `getPgClient()` or `getDrizzleClient()` from `utils/pg.ts` for PostgreSQL access during active migration to Cloudflare D1
Applied to files:
supabase/functions/_backend/utils/pg.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Use shared backend code from `supabase/functions/_backend/` across all deployment platforms; never create platform-specific implementations outside this directory
Applied to files:
supabase/functions/_backend/utils/pg.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Check `c.get('auth')?.authType` to determine authentication type ('apikey' vs 'jwt') in backend endpoints
Applied to files:
supabase/functions/_backend/utils/pg.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/seed.sql : Seed database with `supabase db reset` to apply all migrations and test data from `supabase/seed.sql`
Applied to files:
supabase/seed.sql
🔇 Additional comments (8)
supabase/seed.sql (4)
537-542: LGTM! Comprehensive electron platform seeding.The channel inserts properly seed the electron column across diverse platform combinations, including an electron-only channel for isolated testing. The seed data aligns well with the test plan objectives.
556-557: Verify the electron plugin_version selection.The electron test device uses plugin_version='7.0.0' while other test devices use '4.15.3'. Please confirm this version jump is intentional and aligns with Electron plugin requirements.
563-563: Sequence correctly updated for new channel.The channel_id_seq increment appropriately accounts for the new electron_only channel.
755-866: LGTM! Function properly extended for electron support.The
reset_and_seed_app_datafunction correctly adds electron column handling while maintaining backward compatibility. The channel platform combinations align with the main seed data.supabase/functions/_backend/utils/pg.ts (3)
260-260: LGTM! Electron field properly added to channel selection.The electron column is correctly integrated into the channelSelect object, maintaining consistency with the existing ios/android pattern.
699-703: Excellent type safety for electron platform support.The function signature correctly constrains the platform parameter to the union type and extends the return type to include the electron boolean. This provides strong compile-time guarantees.
723-732: Query correctly includes electron column in SELECT and WHERE clauses.The electron field is properly selected and the WHERE clause correctly uses the platformColumn variable to filter by the appropriate platform boolean.
supabase/functions/_backend/utils/postgres_schema.ts (1)
77-77: The GET and POST endpoints must be updated to handle the new electron column.The schema change is correct, but the channel endpoints have gaps:
GET endpoint (
public/channel/get.ts): ThegetAll()andgetOne()functions are missingios,android, andelectronin their SELECT column lists. These fields should be included in the queries on lines 25–35 and 50–60.POST endpoint (
public/channel/post.ts): TheChannelSetinterface (line 11–23) is missingelectron?: boolean, and the channel object construction (line 67–71) doesn't include the electron field spread like it does foriosandandroid. Addelectronas an optional field and include...(body.electron == null ? {} : { electron: body.electron })in the object.Trigger (
triggers/on_channel_update.ts): Review whether theelectronfield should be included in the public channel uniqueness logic (lines 22–64). Currently, the logic only considersiosandandroidcombinations.⛔ Skipped due to learnings
Learnt from: CR Repo: Cap-go/capgo PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-12-23T02:53:12.055Z Learning: Applies to supabase/functions/_backend/utils/postgress_schema.ts : Schema definitions must be placed in `utils/postgress_schema.ts` using Drizzle ORM and never edited in committed migration filesLearnt from: CR Repo: Cap-go/capgo PR: 0 File: AGENTS.md:0-0 Timestamp: 2026-01-08T00:40:00.524Z Learning: Applies to **/{tests,__tests__,test,spec}/**/*.{ts,tsx,js} : Always cover database changes with Postgres-level tests and complement them with end-to-end tests for affected user flows.Learnt from: CR Repo: Cap-go/capgo PR: 0 File: AGENTS.md:0-0 Timestamp: 2026-01-08T00:40:00.524Z Learning: Applies to supabase/seed.sql : Updating `supabase/seed.sql` to back new or evolved tests is expected; keep fixtures focused on current behavior while leaving committed migrations unchanged.Learnt from: CR Repo: Cap-go/capgo PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-12-23T02:53:12.055Z Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : All database operations must use `getPgClient()` or `getDrizzleClient()` from `utils/pg.ts` for PostgreSQL access during active migration to Cloudflare D1Learnt from: CR Repo: Cap-go/capgo PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-12-23T02:53:12.055Z Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Use Drizzle ORM query patterns with `schema` from `postgress_schema.ts` for all database operations; use `aliasV2()` for self-joins or multiple table references
There was a problem hiding this 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/utils/pg.ts (1)
701-734: Implementation correct; however, add Postgres-level unit tests.The electron platform support is properly implemented with type-safe parameters, complete field mappings, and comprehensive end-to-end tests in
channel_self.test.ts(lines 417-437, 440-465). All callers correctly pass the platform parameter, and the schema includes the electron field.However, per project guidelines, database changes must be covered with both Postgres-level unit tests and end-to-end tests. Currently only E2E tests exist. Add a dedicated test file (e.g.,
tests/pg.test.ts) with direct unit tests forgetCompatibleChannelsPgcovering the electron platform branch logic.
🧹 Nitpick comments (1)
supabase/functions/_backend/utils/pg.ts (1)
320-320: Consider refactoring for consistency with getCompatibleChannelsPg pattern.The nested ternary logic is correct but could be refactored to use an extracted variable pattern like line 713 for improved readability and consistency:
+ const platformColumn = platform === 'android' ? channelAlias.android : platform === 'electron' ? channelAlias.electron : channelAlias.ios - const platformQuery = platform === 'android' ? channelAlias.android : platform === 'electron' ? channelAlias.electron : channelAlias.iosAdditionally, consider typing the
platformparameter (line 312) as'ios' | 'android' | 'electron'instead ofstringfor better type safety, similar to getCompatibleChannelsPg.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
supabase/functions/_backend/utils/pg.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use single quotes and no semicolons per @antfu/eslint-config
Files:
supabase/functions/_backend/utils/pg.ts
supabase/functions/_backend/**
📄 CodeRabbit inference engine (CLAUDE.md)
Backend logic should be organized in
supabase/functions/_backend/with subdirectories for plugins, private endpoints, public endpoints, triggers, and utilities
Files:
supabase/functions/_backend/utils/pg.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use TypeScript strict mode with path aliases mapping
~/tosrc/
Files:
supabase/functions/_backend/utils/pg.ts
supabase/functions/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Supabase Edge Functions use Deno runtime
Files:
supabase/functions/_backend/utils/pg.ts
supabase/functions/_backend/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
supabase/functions/_backend/**/*.{ts,js}: Backend code must be placed insupabase/functions/_backend/as shared code deployed to Cloudflare Workers (API/Plugin/Files workers), Supabase Edge Functions, and other platforms
UsecreateHonofromutils/hono.tsfor all Hono framework application initialization and routing
All database operations must usegetPgClient()orgetDrizzleClient()fromutils/pg.tsfor PostgreSQL access during active migration to Cloudflare D1
All Hono endpoint handlers must acceptContext<MiddlewareKeyVariables>and usec.get('requestId'),c.get('apikey'), andc.get('auth')for request context
Use structured logging withcloudlog({ requestId: c.get('requestId'), message: '...' })for all backend logging
UsemiddlewareAPISecretfor internal API endpoints andmiddlewareKeyfor external API keys; validate againstowner_orgin theapikeystable
Checkc.get('auth')?.authTypeto determine authentication type ('apikey' vs 'jwt') in backend endpoints
Use Drizzle ORM query patterns withschemafrompostgress_schema.tsfor all database operations; usealiasV2()for self-joins or multiple table references
Files:
supabase/functions/_backend/utils/pg.ts
supabase/functions/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Backend ESLint must pass before commit; run
bun lint:backendfor backend files
Files:
supabase/functions/_backend/utils/pg.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to **/{tests,__tests__,test,spec}/**/*.{ts,tsx,js} : Always cover database changes with Postgres-level tests and complement them with end-to-end tests for affected user flows.
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to playwright/e2e/**/*.{ts,js} : Cover customer-facing flows with the Playwright MCP suite. Add scenarios under `playwright/e2e` and run them locally with `bun run test:front` before shipping UI changes.
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : All database operations must use `getPgClient()` or `getDrizzleClient()` from `utils/pg.ts` for PostgreSQL access during active migration to Cloudflare D1
Applied to files:
supabase/functions/_backend/utils/pg.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Use Drizzle ORM query patterns with `schema` from `postgress_schema.ts` for all database operations; use `aliasV2()` for self-joins or multiple table references
Applied to files:
supabase/functions/_backend/utils/pg.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Check `c.get('auth')?.authType` to determine authentication type ('apikey' vs 'jwt') in backend endpoints
Applied to files:
supabase/functions/_backend/utils/pg.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/utils/postgress_schema.ts : Schema definitions must be placed in `utils/postgress_schema.ts` using Drizzle ORM and never edited in committed migration files
Applied to files:
supabase/functions/_backend/utils/pg.ts
🧬 Code graph analysis (1)
supabase/functions/_backend/utils/pg.ts (1)
supabase/functions/_backend/utils/postgres_schema.ts (1)
channels(63-83)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Analyze (java-kotlin)
🔇 Additional comments (3)
supabase/functions/_backend/utils/pg.ts (3)
260-260: LGTM! Electron field added to channel selection.The addition of the electron field to channelSelect is consistent with the ios and android fields and aligns with the database schema.
564-571: LGTM! getMainChannelsPg properly extended for Electron support.Both the return type signature and the query selection have been correctly updated to include the electron field.
641-658: LGTM! getChannelsPg properly extended for Electron support.The function signature and query have been correctly updated to include the electron field in both the return type and the select statement.
14c9040 to
8b4e954
Compare
There was a problem hiding this 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 (3)
src/components/dashboard/DeploymentBanner.vue (2)
95-97: Keep docs consistent with the actual permission check (no app-level “owner”).
hasAdminPermissioncorrectly usesadmin/super_adminonly; please update the header comment that claims “owner” visibility to avoid reintroducing that pattern later. (Based on learnings, app-level checks should not useowner.)
467-542: Add e2e test for Electron platform in deployment banner and deploy dialog flow.The DeploymentBanner component supports the Electron platform and provides a customer-facing deployment workflow for admins. Per the Playwright MCP guidelines, this flow requires e2e coverage. Add a scenario under
playwright/e2e/that covers the banner appearance with Electron-enabled channels and the deploy dialog interaction, then runbun run test:frontbefore shipping.supabase/functions/_backend/utils/cloudflare.ts (1)
1190-1202: Verify and fix platform aggregation inconsistency:readLastMonthDevicesByPlatformCFsilently drops electron devices.While
AdminPlatformOverviewcorrectly includes electron in its platform breakdown,readLastMonthDevicesByPlatformCF(used in logsnag_insights.ts) only counts android and ios—the query omitsWHEN double1 = 2for electron, and theDevicesByPlatforminterface lacks anelectronfield. Thetotalcount includes electron devices, but the platform-specific breakdown loses track of them.Update:
- Add
electron: numbertoDevicesByPlatforminterface- Add electron case to the query:
COUNT(DISTINCT CASE WHEN double1 = 2 THEN blob1 END) AS electron- Include
electronin the return object- Update the comment to reflect: "Platform: double1 = 0 for android, 1 for ios, 2 for electron"
🧹 Nitpick comments (3)
src/components/dashboard/DeploymentBanner.vue (2)
172-180: Supabase channel query updated for Electron—consider handling query errors explicitly.
Right nowpublicChannelserrors will silently hide the banner; at least log/toast on error (even if you keep the “banner disappears on failure” behavior).
308-317: Avoid hard-coded' & 'joining; make platform labels locale-aware.
For 3+ platforms this also becomes awkward. PreferIntl.ListFormat(with the current locale) or an i18n-driven separator/list pattern.supabase/functions/_backend/utils/pg.ts (1)
432-474: Add platform filter to defaultChannel branch for fail-fast validation.The concern is valid: when
defaultChannelis specified, the query omits the platform filter, allowing a channel withelectron = false(for example) to be returned for anelectronclient. While downstream validation at lines 218–235 ofupdate.tscatches platform mismatches and returns explicit errors (e.g.,disabled_platform_electron), filtering at query time is more defensive and efficient.Proposed change (enforce platform match for defaultChannel lookups)
const channelQuery = (includeManifest ? baseQuery.leftJoin(schema.manifest, eq(schema.manifest.app_version_id, versionAlias.id)) : baseQuery) .where(!defaultChannel ? and( eq(channelAlias.public, true), eq(channelAlias.app_id, app_id), eq(platformQuery, true), ) : and( eq(channelAlias.app_id, app_id), eq(channelAlias.name, defaultChannel), + eq(platformQuery, true), ), )
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (29)
messages/de.jsonmessages/en.jsonmessages/es.jsonmessages/fr.jsonmessages/hi.jsonmessages/id.jsonmessages/it.jsonmessages/ja.jsonmessages/ko.jsonmessages/pl.jsonmessages/pt-br.jsonmessages/ru.jsonmessages/tr.jsonmessages/vi.jsonmessages/zh-cn.jsonsrc/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.tssupabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/plugins/updates.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/supabase.types.tssupabase/functions/_backend/utils/update.tssupabase/migrations/20260108000000_add_electron_platform.sqlsupabase/seed.sqltests/channel_self.test.tstests/updates.test.ts
🚧 Files skipped from review as they are similar to previous changes (19)
- src/components/dashboard/AppSetting.vue
- messages/tr.json
- messages/it.json
- messages/vi.json
- messages/pt-br.json
- messages/de.json
- messages/ja.json
- messages/zh-cn.json
- supabase/functions/_backend/plugins/updates.ts
- tests/channel_self.test.ts
- messages/id.json
- supabase/functions/_backend/utils/update.ts
- supabase/migrations/20260108000000_add_electron_platform.sql
- messages/en.json
- messages/fr.json
- messages/hi.json
- tests/updates.test.ts
- supabase/functions/_backend/plugins/channel_self.ts
- messages/ru.json
🧰 Additional context used
📓 Path-based instructions (16)
src/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use Vue 3<script setup>syntax exclusively for all Vue component scripts
Use Tailwind utility classes for layout and spacing in Vue components
Use DaisyUI components (d-btn,d-input,d-card) for interactive elements in Vue components
Use Konsta components ONLY for safe area helpers (top/bottom insets) in Vue components; avoid other uses
UseuseRoute()fromvue-routerto access route parameters anduseRouter()for programmatic navigation in Vue components
src/**/*.vue: Use Vue 3 with Composition API and<script setup>syntax for frontend development
Use TailwindCSS with DaisyUI components for styling
Files:
src/components/dashboard/DeploymentBanner.vue
src/**/*.{ts,tsx,vue,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use
~/alias for imports fromsrc/directory in frontend TypeScript and Vue components
Files:
src/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.ts
src/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Frontend ESLint must pass before commit; run
bun lint:fixto auto-fix issues in frontend files
Files:
src/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.ts
**/{src,app}/{components,views,pages}/**/*.{vue,css,scss}
📄 CodeRabbit inference engine (AGENTS.md)
The web client is built with Vue.js and Tailwind CSS; lean on utility classes and composition-friendly patterns rather than bespoke CSS.
Files:
src/components/dashboard/DeploymentBanner.vue
**/{src,app}/{components,views,pages}/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
Use DaisyUI (
d-prefixed classes) for buttons, inputs, and other interactive primitives to keep behavior and spacing consistent.
Files:
src/components/dashboard/DeploymentBanner.vue
**/{src,app}/**/*.{vue,ts,tsx,js}
📄 CodeRabbit inference engine (AGENTS.md)
Konsta components are reserved for the safe area helpers. Avoid importing
konstaanywhere else in the app.
Files:
src/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.ts
**/{src,app}/**/*.{css,scss,vue}
📄 CodeRabbit inference engine (AGENTS.md)
Capgo's design uses deep slate bases with the 'Extract' azure highlight (
--color-azure-500: #119eff) and soft radii; mirror the palette fromsrc/styles/style.css(e.g.,--color-primary-500: #515271) when introducing new UI.
Files:
src/components/dashboard/DeploymentBanner.vue
**/*.{js,ts,vue,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use ESLint with
@antfu/eslint-configwith single quotes, no semicolons, and Vue 3 Composition API preferred
Files:
src/components/dashboard/DeploymentBanner.vuesupabase/functions/_backend/utils/postgres_schema.tssrc/types/supabase.types.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use path alias
~/to map tosrc/directory for imports in TypeScript/Vue files
Files:
src/components/dashboard/DeploymentBanner.vuesupabase/functions/_backend/utils/postgres_schema.tssrc/types/supabase.types.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
src/components/**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
Organize frontend components in
src/components/directory for reusable Vue components
Files:
src/components/dashboard/DeploymentBanner.vue
supabase/functions/_backend/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
supabase/functions/_backend/**/*.{ts,js}: Backend code must be placed insupabase/functions/_backend/as shared code deployed to Cloudflare Workers (API/Plugin/Files workers), Supabase Edge Functions, and other platforms
UsecreateHonofromutils/hono.tsfor all Hono framework application initialization and routing
All database operations must usegetPgClient()orgetDrizzleClient()fromutils/pg.tsfor PostgreSQL access during active migration to Cloudflare D1
All Hono endpoint handlers must acceptContext<MiddlewareKeyVariables>and usec.get('requestId'),c.get('apikey'), andc.get('auth')for request context
Use structured logging withcloudlog({ requestId: c.get('requestId'), message: '...' })for all backend logging
UsemiddlewareAPISecretfor internal API endpoints andmiddlewareKeyfor external API keys; validate againstowner_orgin theapikeystable
Checkc.get('auth')?.authTypeto determine authentication type ('apikey' vs 'jwt') in backend endpoints
Use Drizzle ORM query patterns withschemafrompostgress_schema.tsfor all database operations; usealiasV2()for self-joins or multiple table references
Files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
supabase/functions/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Backend ESLint must pass before commit; run
bun lint:backendfor backend files
Files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
supabase/functions/_backend/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Core backend logic should be organized in
supabase/functions/_backend/with subdirectories for plugins, private, public, triggers, and utils
Files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
supabase/functions/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Backend API endpoints use TypeScript in Supabase Edge Functions with Deno runtime
Files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable TypeScript strict mode
Files:
supabase/functions/_backend/utils/postgres_schema.tssrc/types/supabase.types.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
supabase/seed.sql
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Seed database with
supabase db resetto apply all migrations and test data fromsupabase/seed.sqlUpdating
supabase/seed.sqlto back new or evolved tests is expected; keep fixtures focused on current behavior while leaving committed migrations unchanged.
Files:
supabase/seed.sql
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to playwright/e2e/**/*.{ts,js} : Cover customer-facing flows with the Playwright MCP suite. Add scenarios under `playwright/e2e` and run them locally with `bun run test:front` before shipping UI changes.
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to cloudflare_workers/api/index.ts : API Worker (port 8787) routes: `/bundle`, `/app`, `/device`, `/channel`, `/private/*`, `/triggers`
Applied to files:
src/components/dashboard/DeploymentBanner.vue
📚 Learning: 2025-12-23T01:19:04.593Z
Learnt from: riderx
Repo: Cap-go/capgo PR: 1297
File: src/components/dashboard/DeploymentBanner.vue:77-79
Timestamp: 2025-12-23T01:19:04.593Z
Learning: In the Cap-go codebase, ensure that app permission checks never include the role 'owner'. App-level permissions should be based on the user_min_right enum with values: read, upload, write, admin, super_admin (and NOT owner). This pattern applies across Vue components that perform permission checks; if you find a check referencing 'owner' for app-level access, replace it with the appropriate user_min_right value and keep organization-level owner handling in organization.ts.
Applied to files:
src/components/dashboard/DeploymentBanner.vue
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/utils/postgress_schema.ts : Schema definitions must be placed in `utils/postgress_schema.ts` using Drizzle ORM and never edited in committed migration files
Applied to files:
supabase/functions/_backend/utils/postgres_schema.tssrc/types/supabase.types.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2026-01-08T00:40:00.524Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to supabase/migrations/**/*.sql : A migration that introduces a new table may include seed inserts for that table, but treat that seeding as part of the current feature and do not modify previously committed migrations.
Applied to files:
supabase/functions/_backend/utils/postgres_schema.tssupabase/seed.sql
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Use Drizzle ORM query patterns with `schema` from `postgress_schema.ts` for all database operations; use `aliasV2()` for self-joins or multiple table references
Applied to files:
src/types/supabase.types.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2026-01-09T16:10:23.878Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T16:10:23.878Z
Learning: Applies to supabase/functions/**/*.ts : Backend API endpoints use TypeScript in Supabase Edge Functions with Deno runtime
Applied to files:
src/types/supabase.types.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2026-01-08T00:40:00.524Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to **/{tests,__tests__,test,spec}/**/*.{ts,tsx,js} : Always cover database changes with Postgres-level tests and complement them with end-to-end tests for affected user flows.
Applied to files:
src/types/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : All database operations must use `getPgClient()` or `getDrizzleClient()` from `utils/pg.ts` for PostgreSQL access during active migration to Cloudflare D1
Applied to files:
src/types/supabase.types.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2026-01-09T16:10:23.878Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T16:10:23.878Z
Learning: Applies to supabase/functions/_backend/**/*.ts : Core backend logic should be organized in `supabase/functions/_backend/` with subdirectories for plugins, private, public, triggers, and utils
Applied to files:
src/types/supabase.types.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Run `bun types` after schema changes to regenerate TypeScript types from Supabase
Applied to files:
src/types/supabase.types.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Use structured logging with `cloudlog({ requestId: c.get('requestId'), message: '...' })` for all backend logging
Applied to files:
supabase/functions/_backend/utils/cloudflare.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Use shared backend code from `supabase/functions/_backend/` across all deployment platforms; never create platform-specific implementations outside this directory
Applied to files:
supabase/functions/_backend/utils/cloudflare.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Check `c.get('auth')?.authType` to determine authentication type ('apikey' vs 'jwt') in backend endpoints
Applied to files:
supabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2026-01-08T00:40:00.524Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T00:40:00.524Z
Learning: Applies to supabase/seed.sql : Updating `supabase/seed.sql` to back new or evolved tests is expected; keep fixtures focused on current behavior while leaving committed migrations unchanged.
Applied to files:
supabase/seed.sql
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/seed.sql : Seed database with `supabase db reset` to apply all migrations and test data from `supabase/seed.sql`
Applied to files:
supabase/seed.sql
📚 Learning: 2026-01-09T16:10:23.878Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T16:10:23.878Z
Learning: Applies to supabase/migrations/**/*.sql : Use `get_identity_org_appid()` in RLS policies with both app_id references in `get_identity_org_appid()` and `check_min_rights()` parameters
Applied to files:
supabase/seed.sql
📚 Learning: 2026-01-09T16:10:23.878Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T16:10:23.878Z
Learning: Applies to supabase/migrations/**/*.sql : `get_identity_org_allowed()` is an absolute last resort RLS function only when table has NO app_id column and NO way to join to get an app_id
Applied to files:
supabase/seed.sql
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/**/*.{ts,js} : Backend ESLint must pass before commit; run `bun lint:backend` for backend files
Applied to files:
supabase/functions/_backend/utils/supabase.types.ts
🧬 Code graph analysis (3)
src/types/supabase.types.ts (1)
supabase/functions/_backend/utils/supabase.types.ts (1)
Json(1-7)
supabase/functions/_backend/utils/pg.ts (1)
supabase/functions/_backend/utils/postgres_schema.ts (1)
channels(63-83)
supabase/functions/_backend/utils/supabase.types.ts (1)
src/types/supabase.types.ts (1)
Json(1-7)
🔇 Additional comments (25)
messages/ko.json (1)
76-77: Electron translation keys look consistent and correctly wired.
Newaction-disable-platform-electron,channel-platform-electron, andplatform-electronentries follow existing key conventions and keep wording aligned with other platform labels.Also applies to: 415-416, 1131-1134
messages/pl.json (1)
76-78: Electron translation keys are correct and consistent.
The added Polish entries mirror the existing platform/action/channel patterns and appear correctly integrated.Also applies to: 415-417, 1130-1134
messages/es.json (1)
75-78: Spanish Electron strings match existing platform phrasing.
New Electron keys follow the same structure as Android/iOS and should render correctly in UI.Also applies to: 413-417, 1130-1134
src/components/dashboard/DeploymentBanner.vue (2)
69-73: Types updated cleanly to carryelectronthrough the component.
DefaultChannel+PlatformKeychanges are minimal and keep the rest of the code strongly typed.Also applies to: 81-87
99-116: Deploy target computation correctly includes Electron channels.
Filtering + platform array composition looks correct and keeps ordering stable across platforms.supabase/functions/_backend/utils/postgres_schema.ts (1)
63-83: Schema addition forchannels.electronis consistent withios/android.
notNull().default(true)keeps existing rows compatible while enabling Electron-specific filtering. Migration, schema definition, and seed fixtures are all properly synchronized.supabase/seed.sql (4)
537-542: Seed channels: electron column + electron_only channel look consistent.Good update to explicitly seed
channels.electronand provide anelectron_onlyfixture for test coverage. Based on learnings, keep fixtures minimal and aligned with current tests.
755-756: reset_and_seed_app_data: electron propagation is good; ensure channel naming/flags match backend expectations.The
electron_onlychannel is seeded and its id captured—nice for deterministic tests that need platform-specific selection.Also applies to: 856-867
556-557: Electron device seed fixture is acceptable as-is.os_version: 'Linux 5.15'is valid; the field accepts any string value regardless of platform, with no numeric-only requirement in the backend parsing logic.
563-563: Sequence bump verified:channel_id_seqnextval is safe.Max seeded channel id = 5, and
setval(..., 6, false)correctly makes the nextnextval()return 6. No other INSERT paths in seed data or migrations set higher channel ids.supabase/functions/_backend/utils/pg.ts (4)
370-385: Channel select shape: electron is correctly propagated.This keeps the “channelData.channels.electron” surface consistent across the DB layer.
682-706: getMainChannelsPg: return type update is aligned and low-risk.
758-791: getChannelsPg: return type update is aligned and low-risk.
820-864: platformColumn approach is clearer; callsite at line 535 of channel_self.ts properly handles the union type.The single callsite in the codebase correctly casts the
platformparameter to the required union type ('ios' | 'android' | 'electron') before passing it togetCompatibleChannelsPg, ensuring type safety and compilation.supabase/functions/_backend/utils/cloudflare.ts (2)
199-202: trackDevicesCF: platform mapping updated cleanly for Electron.
589-606: readDevicesCF: mapping back to'electron'is correct; ensure any UI filters accept it.supabase/functions/_backend/utils/supabase.types.ts (3)
618-705: channels typing: electron field is correctly represented in Row/Insert/Update.
3068-3074: Enums/constants: platform_os + disablePlatformElectron updates look consistent.Also applies to: 3310-3331, 3392-3394
9-34: Type surface: graphql_public addition is fine; no downstream code assumes onlypublic. The type system was designed to support multiple schemas through generic helpers that accept optionalschema: keyof DatabaseWithoutInternalsparameters. All runtime code explicitly accessesDatabase['public'], so the addition is additive with no breaking changes.src/types/supabase.types.ts (6)
10-34: Verify graphql_public namespace addition.The new
graphql_publicnamespace appears to be unrelated to Electron platform support. This might be a side effect of updating Supabase types or runningbun typeswith a newer Supabase version. Confirm whether this change is intentional and related to this PR.
631-631: LGTM: Electron field properly added to channels table.The
electronboolean field is consistently added across Row, Insert, and Update types for the channels table, matching the pattern of existingiosandandroidfields. The optional modifier on Insert/Update types is appropriate.Also applies to: 652-652, 673-673
3113-3115: LGTM: Stats action enum values added for Electron support.The new stats_action enum values follow the existing pattern:
disablePlatformElectronaligns withdisablePlatformIosanddisablePlatformAndroiddisableProdBuildanddisableDeviceappear to be general additions that complement existing disable actionsThese additions support proper analytics tracking for Electron platform configurations.
Also applies to: 3136-3136
3311-3313: LGTM: Constants properly updated to mirror type changes.The Constants object correctly reflects all enum changes:
graphql_public.Enumsadded (empty, matching the type definition)- "electron" added to
platform_osarray- New stats_action values included
These runtime constants enable type-safe enum validation throughout the application.
Also applies to: 3329-3329, 3370-3372, 3393-3393
448-448: TheRelationships: []array in thebuild_logstype definition is correct. Thebuild_logstable in the schema has no foreign key constraints—only CHECK constraints onbillable_seconds,build_time_unit, andplatform. This is the original schema design from the migration that created the table, not a removal. The types file accurately reflects the current database structure.Likely an incorrect or invalid review comment.
3072-3072: Electron platform integration is already complete.The addition of "electron" to the
platform_osenum is properly integrated throughout the backend. Device registration, channel queries, and update endpoints all correctly handle the new platform—including dedicated disable checks (update.ts:235), platform column selection (pg.ts:835), and channel filtering (pg.ts:442).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request adds comprehensive support for the Electron platform across the Capgo update system. Electron devices can now receive over-the-air updates alongside iOS and Android devices.
Key Changes:
- Database migration adds
electronenum value toplatform_os, addsdisablePlatformElectronstats action, and addselectronboolean column to channels table - Backend API endpoints updated to validate and handle electron platform requests
- Analytics tracking extended to track electron devices (platform value = 2)
- Frontend components updated to display electron platform information
- Comprehensive test coverage added for electron platform flows
- Translations added across all 15 supported languages
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| supabase/migrations/20260108000000_add_electron_platform.sql | Migration adding electron to platform_os enum, disablePlatformElectron action, and electron column to channels |
| supabase/seed.sql | Seed data updated with electron column values and electron_only test channel |
| supabase/functions/_backend/utils/postgres_schema.ts | Drizzle schema updated with electron boolean column |
| supabase/functions/_backend/utils/pg.ts | Database queries updated to include electron platform filtering and selection |
| supabase/functions/_backend/utils/update.ts | Update logic extended to block updates when electron is disabled on channel |
| supabase/functions/_backend/utils/cloudflare.ts | Analytics tracking updated to track electron devices (platform=2) |
| supabase/functions/_backend/plugins/updates.ts | Validation schema updated to accept electron platform (contains bug with z.literal) |
| supabase/functions/_backend/plugins/channel_self.ts | Platform handling updated for electron; fixes critical connection cleanup bugs |
| supabase/functions/_backend/utils/supabase.types.ts | TypeScript types regenerated with electron platform support |
| src/types/supabase.types.ts | Frontend TypeScript types updated with electron platform support |
| src/components/dashboard/DeploymentBanner.vue | UI updated to display and handle electron deployment targets |
| src/components/dashboard/AppSetting.vue | Channel queries updated to include electron field |
| messages/*.json (15 files) | Translations added for electron platform across all languages |
| tests/updates.test.ts | Test added to verify electron platform is accepted |
| tests/channel_self.test.ts | Comprehensive tests added for electron channel compatibility filtering |
| defaultChannel: z.optional(z.string()), | ||
| is_prod: z.boolean(), | ||
| platform: z.literal(['android', 'ios'], { | ||
| platform: z.literal(['android', 'ios', 'electron'], { |
Copilot
AI
Jan 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect use of z.literal() with an array. For validating a string that must be one of several specific values, use z.enum() instead. This should be z.enum(['android', 'ios', 'electron'], { ... }) to properly validate platform values. The current code with z.literal() may not work as intended for enum validation.
| platform: z.literal(['android', 'ios', 'electron'], { | |
| platform: z.enum(['android', 'ios', 'electron'], { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @supabase/functions/_backend/utils/supabase.types.ts:
- Line 3075: The platform type and validation checks were extended to include
"electron" but several validators and type annotations still only allow
'ios'|'android' or explicitly reject electron; update the platform union and
validation arrays to include "electron" wherever platforms are checked
(specifically the validation schema used in the create_device handler, the
platform type and validation logic inside the build request handler, and the
type annotation in the build status handler), and update the user-facing error
message that currently says "platform must be ios or android" to include
"electron".
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
supabase/functions/_backend/utils/supabase.types.ts
🧰 Additional context used
📓 Path-based instructions (5)
supabase/functions/_backend/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
supabase/functions/_backend/**/*.{ts,js}: Backend code must be placed insupabase/functions/_backend/as shared code deployed to Cloudflare Workers (API/Plugin/Files workers), Supabase Edge Functions, and other platforms
UsecreateHonofromutils/hono.tsfor all Hono framework application initialization and routing
All database operations must usegetPgClient()orgetDrizzleClient()fromutils/pg.tsfor PostgreSQL access during active migration to Cloudflare D1
All Hono endpoint handlers must acceptContext<MiddlewareKeyVariables>and usec.get('requestId'),c.get('apikey'), andc.get('auth')for request context
Use structured logging withcloudlog({ requestId: c.get('requestId'), message: '...' })for all backend logging
UsemiddlewareAPISecretfor internal API endpoints andmiddlewareKeyfor external API keys; validate againstowner_orgin theapikeystable
Checkc.get('auth')?.authTypeto determine authentication type ('apikey' vs 'jwt') in backend endpoints
Use Drizzle ORM query patterns withschemafrompostgress_schema.tsfor all database operations; usealiasV2()for self-joins or multiple table references
Files:
supabase/functions/_backend/utils/supabase.types.ts
supabase/functions/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Backend ESLint must pass before commit; run
bun lint:backendfor backend files
Files:
supabase/functions/_backend/utils/supabase.types.ts
supabase/functions/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
supabase/functions/**/*.ts: Never use the Supabase admin SDK (with service key) for user-facing APIs; always use the client SDK with user authentication so RLS policies are enforced
The admin SDK should only be used for accessing data that is not user-accessible or for internal operations (triggers, CRON jobs, etc.)
When admin access is unavoidable for a user-facing endpoint, sanitize all user inputs carefully to prevent PostgREST query injection
Files:
supabase/functions/_backend/utils/supabase.types.ts
**/*.{js,ts,vue}
📄 CodeRabbit inference engine (AGENTS.md)
Use single quotes and no semicolons in JavaScript/TypeScript code
Files:
supabase/functions/_backend/utils/supabase.types.ts
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
Use path aliases:
~/maps tosrc/for imports in TypeScript files
Files:
supabase/functions/_backend/utils/supabase.types.ts
🧠 Learnings (9)
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/utils/postgress_schema.ts : Schema definitions must be placed in `utils/postgress_schema.ts` using Drizzle ORM and never edited in committed migration files
Applied to files:
supabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Use Drizzle ORM query patterns with `schema` from `postgress_schema.ts` for all database operations; use `aliasV2()` for self-joins or multiple table references
Applied to files:
supabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : All database operations must use `getPgClient()` or `getDrizzleClient()` from `utils/pg.ts` for PostgreSQL access during active migration to Cloudflare D1
Applied to files:
supabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Check `c.get('auth')?.authType` to determine authentication type ('apikey' vs 'jwt') in backend endpoints
Applied to files:
supabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2026-01-09T18:24:11.070Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T18:24:11.070Z
Learning: Applies to supabase/functions/**/*.ts : Never use the Supabase admin SDK (with service key) for user-facing APIs; always use the client SDK with user authentication so RLS policies are enforced
Applied to files:
supabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2026-01-09T18:24:11.070Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T18:24:11.070Z
Learning: Applies to supabase/functions/**/*.ts : The admin SDK should only be used for accessing data that is not user-accessible or for internal operations (triggers, CRON jobs, etc.)
Applied to files:
supabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2026-01-09T18:24:11.070Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T18:24:11.070Z
Learning: Applies to supabase/seed.sql : Update `supabase/seed.sql` to back new or evolved tests, keeping fixtures focused on current behavior while leaving committed migrations unchanged
Applied to files:
supabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Run `bun types` after schema changes to regenerate TypeScript types from Supabase
Applied to files:
supabase/functions/_backend/utils/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Backend code must be placed in `supabase/functions/_backend/` as shared code deployed to Cloudflare Workers (API/Plugin/Files workers), Supabase Edge Functions, and other platforms
Applied to files:
supabase/functions/_backend/utils/supabase.types.ts
🧬 Code graph analysis (1)
supabase/functions/_backend/utils/supabase.types.ts (1)
src/types/supabase.types.ts (1)
Json(1-7)
🔇 Additional comments (4)
supabase/functions/_backend/utils/supabase.types.ts (4)
631-631: LGTM! Electron field added correctly to channels table types.The
electronboolean field is properly added to thechannelstable Row, Insert, and Update types with correct optionality, consistent with the existingiosandandroidfields.Also applies to: 652-652, 673-673
10-34: No action required. Thegraphql_publicnamespace is auto-generated by Supabase's type generation tool (bun types/supabase gen types typescript) from the built-inpg_graphqlPostgreSQL extension. This is standard behavior and expected to appear in the generated types file. No SQL migrations are needed for this system-provided schema.
3116-3118: LGTM. Thestats_actionenum correctly adds "disablePlatformElectron" alongside the migration, type definitions, and backend implementation inupdate.ts(lines 235-237) that properly handles the new electron platform disable action.
448-448: No action needed. TheRelationships: []forbuild_logsis correct and intentional—the table has no foreign key constraints as defined in the migration20251119001847_add_native_build_system.sql. This is an auto-generated types file, so the empty array accurately reflects the actual database schema.
| disable_update: "major" | "minor" | "patch" | "version_number" | "none" | ||
| key_mode: "read" | "write" | "all" | "upload" | ||
| platform_os: "ios" | "android" | ||
| platform_os: "ios" | "android" | "electron" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, verify the file exists and check the context around the specified lines
cat -n supabase/functions/_backend/utils/supabase.types.ts | sed -n '3070,3080p'Repository: Cap-go/capgo
Length of output: 501
🏁 Script executed:
# Also check line 3332 for the constant array
cat -n supabase/functions/_backend/utils/supabase.types.ts | sed -n '3325,3335p'Repository: Cap-go/capgo
Length of output: 498
🏁 Script executed:
# Search for all platform_os usage patterns
rg -n "platform_os" supabase/functions/_backend/ --type=ts -C 1Repository: Cap-go/capgo
Length of output: 2576
🏁 Script executed:
# Search for switch statements on platform or platform checks
rg -n "switch.*platform|case\s+['\"]ios['\"]|case\s+['\"]android['\"]" supabase/functions/_backend/ --type=ts -C 2Repository: Cap-go/capgo
Length of output: 38
🏁 Script executed:
# Search for explicit platform value checks (if statements, ternary operators, etc.)
rg -n '===\s*["\']ios["\']|===\s*["\']android["\']|==\s*["\']ios["\']|==\s*["\']android["\']|platform.*["\']ios["\']|platform.*["\']android["\']' supabase/functions/_backend/ --type=ts -C 2Repository: Cap-go/capgo
Length of output: 124
🏁 Script executed:
# Search for filter or includes checks on platform arrays or values
rg -n 'includes.*platform|filter.*platform|\[.*ios.*android.*\]' supabase/functions/_backend/ --type=ts -C 2Repository: Cap-go/capgo
Length of output: 1952
🏁 Script executed:
# Check if there are any hardcoded lists of platforms that don't include electron
rg -n '\["ios",\s*"android"\]|\[\'ios\',\s*\'android\'\]|ios.*android.*(?!electron)' supabase/functions/_backend/ --type=tsRepository: Cap-go/capgo
Length of output: 275
🏁 Script executed:
# Find more instances of hardcoded platform checks
rg -n "ios.*android" supabase/functions/_backend/ --type=ts -A 1 -B 1Repository: Cap-go/capgo
Length of output: 7646
🏁 Script executed:
# Check the create_device.ts file more completely
cat -n supabase/functions/_backend/private/create_device.ts | head -30Repository: Cap-go/capgo
Length of output: 1106
🏁 Script executed:
# Check the build/request.ts file more completely around line 64
cat -n supabase/functions/_backend/public/build/request.ts | sed -n '55,75p'Repository: Cap-go/capgo
Length of output: 1136
Update type definitions and validation in build and device endpoints to support electron.
The enum additions to platform_os at lines 3075 and 3332 are correct, but the changes are incomplete. Multiple endpoints still reject or don't support the 'electron' platform:
supabase/functions/_backend/private/create_device.tsline 13: Validation schema only accepts['ios', 'android']supabase/functions/_backend/public/build/request.tslines 10 and 64-66: Type annotation and validation check hardcoded to only accept['ios', 'android'], explicitly rejecting electron with error message "platform must be ios or android"supabase/functions/_backend/public/build/status.tsline 11: Type annotation missing electron support
These locations must be updated to include 'electron' alongside the existing platforms, or the new enum value will cause API rejections.
🤖 Prompt for AI Agents
In @supabase/functions/_backend/utils/supabase.types.ts at line 3075, The
platform type and validation checks were extended to include "electron" but
several validators and type annotations still only allow 'ios'|'android' or
explicitly reject electron; update the platform union and validation arrays to
include "electron" wherever platforms are checked (specifically the validation
schema used in the create_device handler, the platform type and validation logic
inside the build request handler, and the type annotation in the build status
handler), and update the user-facing error message that currently says "platform
must be ios or android" to include "electron".
3b55e6b to
d3df775
Compare
There was a problem hiding this 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 (3)
src/components/dashboard/DeploymentBanner.vue (1)
17-21: Fix misleading permission comment (“owner” role) to match actual checks + repo policy.
Docs say “admin, super_admin, or owner” (Line 18-20), but the code checks only['admin', 'super_admin'](Line 95-97). Also aligns with the project rule to avoid app-levelownerchecks.Proposed fix
- * - Only visible to users with admin, super_admin, or owner roles + * - Only visible to users with admin or super_admin rolesAlso applies to: 95-97
src/components/dashboard/AppSetting.vue (1)
534-584: Bug confirmed: Electron-only channels are incorrectly set to private.The query at lines 566-571 updates all channels with
ios=false AND android=falsetopublic=false. Since Electron-only channels haveios=false, android=false, electron=true, they match this filter and will be unintentionally depublicized.The proposed fix is correct:
Proposed fix
const { error: hiddenError } = await supabase .from('channels') .update({ public: false }) .eq('app_id', props.appId) .eq('ios', false) .eq('android', false) + .eq('electron', false)This ensures only truly hidden channels (with no platform support) are set to private.
supabase/functions/_backend/plugins/channel_self.ts (1)
598-606: Inconsistent conditional check in PUT handler.The PUT handler calls
getPgClient(c)without the optional second parameter (line 592), same as POST and DELETE handlers. However, only PUT has theif (pgClient)conditional in its finally block.
- POST (line 577-579):
getPgClient(c)→ no conditional- DELETE (line 628-630):
getPgClient(c)→ no conditional- PUT (line 603-604):
getPgClient(c)→ has conditionalEither remove the conditional to match POST/DELETE, or add conditionals to all handlers for consistency.
Suggested fix (remove unnecessary conditional)
try { res = await put(c, getDrizzleClient(pgClient as any), bodyParsed) } finally { - if (pgClient) - await closeClient(c, pgClient) + await closeClient(c, pgClient) }
🧹 Nitpick comments (3)
messages/es.json (1)
415-415: “Solo Electron” is consistent with “Solo Android” (but differs from “Solo para iOS”).
Probably fine, but consider whether you want the “Solo/solo para” phrasing standardized across platform labels in the UI.supabase/functions/_backend/utils/cloudflare.ts (2)
71-72:trackDeviceUsageCFdoes not handle Electron platform.The
trackDeviceUsageCFfunction only maps'ios'→ 1 and defaults to 0 for everything else. This means Electron devices will be counted as Android in the MAU analytics. Consider extending this to matchtrackDevicesCF.♻️ Suggested fix to add Electron support
- // Platform: 0 = android, 1 = ios - const platformValue = platform?.toLowerCase() === 'ios' ? 1 : 0 + // Platform: 0 = android, 1 = ios, 2 = electron + const platformLower = platform?.toLowerCase() + const platformValue = platformLower === 'ios' ? 1 : platformLower === 'electron' ? 2 : 0Apply the same change at both lines 71-72 and 87-88.
Also applies to: 87-88
821-849:readLastMonthDevicesByPlatformCFdoes not include Electron in its return type or query.The
DevicesByPlatforminterface andreadLastMonthDevicesByPlatformCFfunction only trackiosandandroid. Consider extending these to includeelectronfor consistency with the admin overview.♻️ Suggested extension for Electron support
export interface DevicesByPlatform { total: number ios: number android: number + electron: number } export async function readLastMonthDevicesByPlatformCF(c: Context): Promise<DevicesByPlatform> { if (!c.env.DEVICE_USAGE) { - return { total: 0, ios: 0, android: 0 } + return { total: 0, ios: 0, android: 0, electron: 0 } } const oneMonthAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10) - // Platform: double1 = 0 for android, 1 for ios + // Platform: double1 = 0 for android, 1 for ios, 2 for electron const query = `SELECT COUNT(DISTINCT blob1) AS total, COUNT(DISTINCT CASE WHEN double1 = 1 THEN blob1 END) AS ios, - COUNT(DISTINCT CASE WHEN double1 = 0 THEN blob1 END) AS android + COUNT(DISTINCT CASE WHEN double1 = 0 THEN blob1 END) AS android, + COUNT(DISTINCT CASE WHEN double1 = 2 THEN blob1 END) AS electron FROM device_usage WHERE timestamp >= toDateTime('${formatDateCF(oneMonthAgo)}') AND timestamp < now()`And update the return statement accordingly.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (29)
messages/de.jsonmessages/en.jsonmessages/es.jsonmessages/fr.jsonmessages/hi.jsonmessages/id.jsonmessages/it.jsonmessages/ja.jsonmessages/ko.jsonmessages/pl.jsonmessages/pt-br.jsonmessages/ru.jsonmessages/tr.jsonmessages/vi.jsonmessages/zh-cn.jsonsrc/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.tssupabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/plugins/updates.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/pg.tssupabase/functions/_backend/utils/postgres_schema.tssupabase/functions/_backend/utils/supabase.types.tssupabase/functions/_backend/utils/update.tssupabase/migrations/20260108000000_add_electron_platform.sqlsupabase/seed.sqltests/channel_self.test.tstests/updates.test.ts
🚧 Files skipped from review as they are similar to previous changes (18)
- messages/pt-br.json
- messages/vi.json
- messages/tr.json
- supabase/migrations/20260108000000_add_electron_platform.sql
- supabase/functions/_backend/plugins/updates.ts
- messages/hi.json
- messages/ko.json
- tests/channel_self.test.ts
- messages/ja.json
- messages/ru.json
- messages/id.json
- messages/zh-cn.json
- supabase/functions/_backend/utils/pg.ts
- messages/de.json
- messages/pl.json
- tests/updates.test.ts
- messages/fr.json
- supabase/functions/_backend/utils/postgres_schema.ts
🧰 Additional context used
📓 Path-based instructions (10)
src/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.vue: Use Vue 3<script setup>syntax exclusively for all Vue component scripts
Use Tailwind utility classes for layout and spacing in Vue components
Use DaisyUI components (d-btn,d-input,d-card) for interactive elements in Vue components
Use Konsta components ONLY for safe area helpers (top/bottom insets) in Vue components; avoid other uses
UseuseRoute()fromvue-routerto access route parameters anduseRouter()for programmatic navigation in Vue components
src/**/*.vue: Use Vue 3 with Composition API and<script setup>syntax for frontend components
Use lean utility classes and composition-friendly patterns rather than bespoke CSS in Vue components
Use DaisyUI (d-prefixed classes) for buttons, inputs, and other interactive primitives to keep behavior and spacing consistent
Konsta components are reserved for the safe area helpers; avoid importingkonstaanywhere else in the app
Prefer Vue 3 Composition API in Vue components
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vue
src/**/*.{ts,tsx,vue,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use
~/alias for imports fromsrc/directory in frontend TypeScript and Vue components
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.ts
src/**/*.{vue,ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Frontend ESLint must pass before commit; run
bun lint:fixto auto-fix issues in frontend files
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.ts
src/**/*.{vue,css}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{vue,css}: Use TailwindCSS with DaisyUI components for styling
Mirror the palette fromsrc/styles/style.css(e.g.,--color-primary-500: #515271) when introducing new UI colors
Files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vue
**/*.{js,ts,vue}
📄 CodeRabbit inference engine (AGENTS.md)
Use single quotes and no semicolons in JavaScript/TypeScript code
Files:
src/components/dashboard/AppSetting.vuesupabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/supabase.types.tssrc/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/update.ts
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
Use path aliases:
~/maps tosrc/for imports in TypeScript files
Files:
src/components/dashboard/AppSetting.vuesupabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/supabase.types.tssrc/components/dashboard/DeploymentBanner.vuesrc/types/supabase.types.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/update.ts
supabase/functions/_backend/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
supabase/functions/_backend/**/*.{ts,js}: Backend code must be placed insupabase/functions/_backend/as shared code deployed to Cloudflare Workers (API/Plugin/Files workers), Supabase Edge Functions, and other platforms
UsecreateHonofromutils/hono.tsfor all Hono framework application initialization and routing
All database operations must usegetPgClient()orgetDrizzleClient()fromutils/pg.tsfor PostgreSQL access during active migration to Cloudflare D1
All Hono endpoint handlers must acceptContext<MiddlewareKeyVariables>and usec.get('requestId'),c.get('apikey'), andc.get('auth')for request context
Use structured logging withcloudlog({ requestId: c.get('requestId'), message: '...' })for all backend logging
UsemiddlewareAPISecretfor internal API endpoints andmiddlewareKeyfor external API keys; validate againstowner_orgin theapikeystable
Checkc.get('auth')?.authTypeto determine authentication type ('apikey' vs 'jwt') in backend endpoints
Use Drizzle ORM query patterns withschemafrompostgress_schema.tsfor all database operations; usealiasV2()for self-joins or multiple table references
Files:
supabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/supabase.types.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/update.ts
supabase/functions/**/*.{ts,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Backend ESLint must pass before commit; run
bun lint:backendfor backend files
Files:
supabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/supabase.types.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/update.ts
supabase/functions/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
supabase/functions/**/*.ts: Never use the Supabase admin SDK (with service key) for user-facing APIs; always use the client SDK with user authentication so RLS policies are enforced
The admin SDK should only be used for accessing data that is not user-accessible or for internal operations (triggers, CRON jobs, etc.)
When admin access is unavoidable for a user-facing endpoint, sanitize all user inputs carefully to prevent PostgREST query injection
Files:
supabase/functions/_backend/plugins/channel_self.tssupabase/functions/_backend/utils/supabase.types.tssupabase/functions/_backend/utils/cloudflare.tssupabase/functions/_backend/utils/update.ts
supabase/seed.sql
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Seed database with
supabase db resetto apply all migrations and test data fromsupabase/seed.sqlUpdate
supabase/seed.sqlto back new or evolved tests, keeping fixtures focused on current behavior while leaving committed migrations unchanged
Files:
supabase/seed.sql
🧠 Learnings (14)
📚 Learning: 2025-05-29T18:21:17.703Z
Learnt from: WcaleNieWolny
Repo: Cap-go/capgo PR: 1107
File: src/components/dashboard/AppSetting.vue:85-182
Timestamp: 2025-05-29T18:21:17.703Z
Learning: In setUpdateChannelSync function in src/components/dashboard/AppSetting.vue, the database update code at the end is intentionally outside the conflict-resolution if block and should run for cases where sync is being toggled without conflicts or after conflicts are resolved. The return statements inside the dialog handling correctly prevent database updates when the user cancels.
Applied to files:
src/components/dashboard/AppSetting.vue
📚 Learning: 2025-12-23T01:19:04.593Z
Learnt from: riderx
Repo: Cap-go/capgo PR: 1297
File: src/components/dashboard/DeploymentBanner.vue:77-79
Timestamp: 2025-12-23T01:19:04.593Z
Learning: In the Cap-go codebase, ensure that app permission checks never include the role 'owner'. App-level permissions should be based on the user_min_right enum with values: read, upload, write, admin, super_admin (and NOT owner). This pattern applies across Vue components that perform permission checks; if you find a check referencing 'owner' for app-level access, replace it with the appropriate user_min_right value and keep organization-level owner handling in organization.ts.
Applied to files:
src/components/dashboard/AppSetting.vuesrc/components/dashboard/DeploymentBanner.vue
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to cloudflare_workers/plugin/index.ts : Plugin Worker (port 8788) routes: `/updates`, `/channel_self`, `/stats`
Applied to files:
supabase/functions/_backend/plugins/channel_self.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : All database operations must use `getPgClient()` or `getDrizzleClient()` from `utils/pg.ts` for PostgreSQL access during active migration to Cloudflare D1
Applied to files:
supabase/functions/_backend/plugins/channel_self.tssrc/types/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to cloudflare_workers/api/index.ts : API Worker (port 8787) routes: `/bundle`, `/app`, `/device`, `/channel`, `/private/*`, `/triggers`
Applied to files:
src/components/dashboard/DeploymentBanner.vue
📚 Learning: 2026-01-09T18:24:11.070Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T18:24:11.070Z
Learning: Applies to supabase/seed.sql : Update `supabase/seed.sql` to back new or evolved tests, keeping fixtures focused on current behavior while leaving committed migrations unchanged
Applied to files:
supabase/seed.sqlsrc/types/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/seed.sql : Seed database with `supabase db reset` to apply all migrations and test data from `supabase/seed.sql`
Applied to files:
supabase/seed.sql
📚 Learning: 2026-01-09T18:24:11.070Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-09T18:24:11.070Z
Learning: Applies to supabase/migrations/**/*.sql : `get_identity_org_allowed()` is an absolute last resort; only use it when the table genuinely has NO app_id column and there is NO way to join to get an app_id
Applied to files:
supabase/seed.sql
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Use Drizzle ORM query patterns with `schema` from `postgress_schema.ts` for all database operations; use `aliasV2()` for self-joins or multiple table references
Applied to files:
src/types/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/utils/postgress_schema.ts : Schema definitions must be placed in `utils/postgress_schema.ts` using Drizzle ORM and never edited in committed migration files
Applied to files:
src/types/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Run `bun types` after schema changes to regenerate TypeScript types from Supabase
Applied to files:
src/types/supabase.types.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Use structured logging with `cloudlog({ requestId: c.get('requestId'), message: '...' })` for all backend logging
Applied to files:
supabase/functions/_backend/utils/cloudflare.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Use shared backend code from `supabase/functions/_backend/` across all deployment platforms; never create platform-specific implementations outside this directory
Applied to files:
supabase/functions/_backend/utils/cloudflare.ts
📚 Learning: 2025-12-23T02:53:12.055Z
Learnt from: CR
Repo: Cap-go/capgo PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T02:53:12.055Z
Learning: Applies to supabase/functions/_backend/**/*.{ts,js} : Check `c.get('auth')?.authType` to determine authentication type ('apikey' vs 'jwt') in backend endpoints
Applied to files:
supabase/functions/_backend/utils/update.ts
🧬 Code graph analysis (3)
supabase/functions/_backend/plugins/channel_self.ts (2)
supabase/functions/_backend/utils/postgres_schema.ts (1)
channels(63-83)supabase/functions/_backend/utils/pg.ts (2)
getCompatibleChannelsPg(759-803)getDrizzleClient(220-222)
src/types/supabase.types.ts (1)
supabase/functions/_backend/utils/supabase.types.ts (1)
Json(1-7)
supabase/functions/_backend/utils/update.ts (3)
supabase/functions/_backend/utils/logging.ts (1)
cloudlog(3-15)supabase/functions/_backend/utils/stats.ts (1)
sendStatsAndDevice(86-96)supabase/functions/_backend/utils/hono.ts (1)
simpleError200(213-222)
🔇 Additional comments (27)
messages/it.json (3)
76-76: Translation is consistent with existing Android/iOS “platform disabled” wording.
Matches the established “Bloccato - Piattaforma … disabilitata” pattern.
415-415: “Solo Electron” channel label matches the existing single-platform labels.
Consistent with “Solo Android” / “Solo iOS”.
1132-1132: Platform label “Electron” is correct and consistent with other platform labels.
Keeping it as the product/platform name (not translated) matches Android/iOS handling.messages/es.json (2)
76-76: Translation matches existing “Bloqueado - Plataforma … deshabilitada” pattern.
Looks consistent with the Android/iOS equivalents.
1132-1132: “Electron” as a proper name is appropriate here.
No issues.supabase/functions/_backend/utils/supabase.types.ts (2)
619-619: LGTM! Electron field additions to channels table types are consistent.The
electron: booleanfield is correctly added as required inRow, and optional (electron?: boolean) in bothInsertandUpdatetypes, which aligns with typical database column patterns where defaults are applied.Also applies to: 640-640, 661-661
3063-3063: LGTM! Platform enum and stats_action enum properly extended for Electron.The
platform_osenum now includes"electron"alongside"ios"and"android", andstats_actionincludes"disablePlatformElectron"consistent with existingdisablePlatformIosanddisablePlatformAndroidactions.Also applies to: 3127-3127, 3317-3317, 3381-3381
supabase/seed.sql (4)
537-542: LGTM! Channel seed data correctly includes Electron platform support.The channel inserts properly include the
electroncolumn with appropriate boolean values:
production(id=1): electron='t'(true)no_access(id=2): electron='f'(false)two_default(id=3): electron='t'(true)productionfor stats app (id=4): electron='t'(true)electron_only(id=5): ios='f', android='f', electron='t'- correctly models an Electron-only channel.
556-557: LGTM! Electron test device properly added to seed data.The new device entry uses
platform='electron'with appropriate metadata (plugin_version='7.0.0',os_version='Linux 5.15'), providing test coverage for Electron platform queries.
563-563: LGTM! Sequence correctly updated for new channel.The
channel_id_seqis properly incremented from 5 to 6 to accommodate the newelectron_onlychannel.
855-866: LGTM!reset_and_seed_app_datafunction properly updated for Electron support.The function correctly:
- Declares
electron_only_channel_idvariable (line 755)- Adds
electroncolumn to channel inserts- Creates an
electron_onlychannel withios='f', android='f', electron='t'- Captures the new channel ID via the SELECT/INTO pattern
Note: The
electron_onlychannel doesn't have a correspondingdeploy_historyentry (lines 867-872), which is intentional based on the test scenarios, but worth verifying this is the expected behavior for your tests.supabase/functions/_backend/utils/cloudflare.ts (3)
199-201: LGTM! Platform encoding correctly extended for Electron intrackDevicesCF.The platform value mapping is clear and correct:
'ios'→ 1'electron'→ 2- everything else (android) → 0
594-594: LGTM! Platform decoding correctly handles Electron inreadDevicesCF.The reverse mapping properly converts the numeric platform value back to the string representation, maintaining consistency with the encoding in
trackDevicesCF.
1198-1198: LGTM! Admin platform overview properly extended for Electron devices.The
AdminPlatformOverviewinterface andgetAdminPlatformOverviewfunction correctly:
- Add
electron_devicesto the interface- Query
sum(if(double1 = 2, 1, 0)) AS electron_devicesin the platform query- Include
electron_devicesin the Promise.all type annotation- Return
electron_devicesin the final payloadAlso applies to: 1419-1427, 1447-1447, 1480-1480
src/types/supabase.types.ts (4)
3072-3137: Enums/Constants updated correctly for Electron + new stats actions.
platform_osincludes"electron"(Line 3072) andstats_actionaddsdisablePlatformElectron(Line 3136) with matchingConstants.public.Enums.*entries (Line 3329-3394). This should keep frontend/backends aligned.Also applies to: 3310-3419
10-34: Verify no stale__InternalSupabasecoupling remains after addinggraphql_publicschema.The new
Database.graphql_publicnamespace appears correct, butDatabaseWithoutInternals = Omit<Database, "__InternalSupabase">(line 3193) suggests code may still expect that internal key. Search the codebase for references to__InternalSupabase,DatabaseWithoutInternals, andgraphql_publicto confirm no broken or redundant coupling exists.
618-705:channels.electrontyping is correct and consistent with the database schema.The migration file
supabase/migrations/20260108000000_add_electron_platform.sqldefines the column asboolean DEFAULT true NOT NULL, which matches the type definition:Row.electron: boolean(required) andInsert.electron?: boolean/Update.electron?: boolean(optional). No changes needed.
448-449: No action needed—build_logs has no foreign key relationships in the database schema.The
Relationships: []accurately reflects the actual database design. Tests querybuild_logsdirectly and function without issue. No codegen utilities or ORM helpers in the codebase consume relationship metadata from type definitions.Likely an incorrect or invalid review comment.
messages/en.json (1)
78-81: Electron i18n keys follow existing conventions.
action-disable-platform-electron,channel-platform-electron, andplatform-electronmatch the established key structure and should plug into the newdisablePlatformElectronstat/action and UI labels.Also applies to: 447-451, 1059-1063
src/components/dashboard/AppSetting.vue (1)
34-35: Channel fetch/type updated correctly to includeelectron.
Addingelectronto the local channel shape (Line 34) and selecting it from Supabase (Line 238) is aligned with the new schema.Also applies to: 235-248
src/components/dashboard/DeploymentBanner.vue (1)
69-116: Deployment banner now correctly accounts for Electron default channels and labels.
The platform list/filtering andgetPlatformLabel()changes correctly incorporateelectron.Also applies to: 175-180, 308-317
supabase/functions/_backend/utils/update.ts (1)
216-242: Electron platform disable guard is consistent with existing iOS/Android checks.
Stat emission (disablePlatformElectron) andsimpleError200response structure match the established pattern. Thechannels.electronfield is properly selected ingetSchemaUpdatesAlias()(pg.ts:321) and included in all query results.supabase/functions/_backend/plugins/channel_self.ts (5)
26-26: LGTM! Electron platform added to schema validation.The enum extension aligns with the database migration and schema changes for Electron support.
214-216: LGTM! Type annotation correctly includes electron property.The channel type now properly reflects the schema with the
electron: booleanfield for platform-based channel selection.
377-379: LGTM! Type annotation updated for PUT handler.Consistent with the POST handler's channel type annotation for Electron support.
535-535: LGTM! Platform type cast correctly includes electron.The cast matches the
getCompatibleChannelsPgfunction signature that acceptsplatform: 'ios' | 'android' | 'electron'.
648-656: LGTM! Conditional appropriate for optional PG client.The GET handler uses
getPgClient(c, true)with the second parameter, which may indicate an optional/read-only client that could be undefined. The conditional check is appropriate here, unlike the PUT handler which usesgetPgClient(c)without the optional flag.
- Added translations for Electron platform in Vietnamese and Simplified Chinese. - Updated AppSetting component to include Electron in channel management. - Modified DeploymentBanner component to handle Electron channels. - Enhanced Supabase types to support Electron platform in database schema. - Updated backend functions to accommodate Electron in platform checks and channel compatibility. - Added migration script to include Electron in platform_os enum and related database changes. - Seeded database with Electron-specific channels for testing. - Implemented tests for channel retrieval and updates for Electron platform.
- Add electron column to Drizzle schema (postgres_schema.ts) - Add electron to channelSelect in pg.ts to load the flag for updates - Fix z.literal to z.enum in channel_self.ts for proper platform validation - Add electron to inline channel type definitions - Fix inverted PG client close logic in PUT and GET handlers - Fix seed.sql no_access channel electron flag to be consistent 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Include electron flag in getMainChannelsPg and getChannelsPg function return types and select statements to fix TypeScript errors when accessing channelData.channels.electron in channel_self.ts. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Reset supabase.types.ts from main and properly add only Electron changes: - electron boolean field in channels table - electron in platform_os enum - disablePlatformElectron in update_fail_action enum Co-Authored-By: Claude Opus 4.5 <[email protected]>
Add deploy_history entry for electron_only channel to fix lint warning about unused variable. Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Fix misleading permission comments in DeploymentBanner.vue to match
actual code checks (admin, super_admin only, not owner)
- Fix bug where Electron-only channels were incorrectly set to private
by adding .eq('electron', false) to the query filter
- Remove unnecessary conditional check in channel_self.ts PUT handler
to match POST/DELETE handlers for consistency
Co-Authored-By: Claude Opus 4.5 <[email protected]>
15b53bb to
d357b61
Compare
|



Summary
Added full support for the Electron platform across the codebase. Electron devices can now use the Capgo update system alongside iOS and Android devices. This includes database schema updates, backend API support, frontend UI, platform-specific logic, comprehensive tests, and translations in all 15 languages.
Test plan
bun test:backendto verify electron platform validation in channel_self and updates endpointsChecklist
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.