Skip to content

chore: drop unused columns in "plans"#1259

Merged
riderx merged 5 commits into
mainfrom
drop-plans-unused-columns
Dec 5, 2025
Merged

chore: drop unused columns in "plans"#1259
riderx merged 5 commits into
mainfrom
drop-plans-unused-columns

Conversation

@Dalanir
Copy link
Copy Markdown
Contributor

@Dalanir Dalanir commented Dec 4, 2025

Summary

Drop unused columns in "plans"

Test plan

N/A

Screenshots

N/A

Checklist

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

Summary by CodeRabbit

  • New Features

    • Dynamic per-unit credit pricing fetched and shown across Plans and Usage, including "Pay as you go" displays.
  • Bug Fixes

    • Safer pricing math with defaults and guards to prevent invalid or negative totals; pricing always reflects current per-unit rates.
  • Chores

    • Updated database schema, types, migrations and seed data to align billing and per-unit pricing model.

✏️ Tip: You can customize this high-level summary in your review settings.

@Dalanir Dalanir requested a review from riderx December 4, 2025 17:38
@Dalanir Dalanir self-assigned this Dec 4, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 4, 2025

Walkthrough

Adds credit-unit pricing: new Supabase helper to fetch per-metric credit prices; frontend Plans and Usage components consume these prices and change pricing/display and load flows; large Supabase type/schema surface update (introducing graphql_public); migration and seed adjust plan unit/overage columns.

Changes

Cohort / File(s) Summary
Frontend — Plans & Usage
src/pages/settings/organization/Plans.vue, src/pages/settings/organization/Usage.vue
Add import/use of getCreditUnitPricing; introduce creditUnitPrices state; replace direct plan unit fields with credit-unit lookups (with safe defaults and guarded calculations); update data-loading to fetch pricing concurrently and adjust pricing display/calculation logic.
Service — Supabase helper
src/services/supabase.ts
Add exported type CreditUnitPricing and function getCreditUnitPricing(orgId?) which queries capgo_credits_steps (filter step_min = 0), prioritizes org-specific rows, and reduces results into a metric→price map with try/catch error handling.
Types — Generated Supabase types
src/types/supabase.types.ts, supabase/functions/_backend/utils/supabase.types.ts
Replace __InternalSupabase with a graphql_public namespace; adjust many Table/Row/Insert/Update shapes, Functions, Enums, CompositeTypes, and Constants to align with the new public GraphQL-oriented schema surface.
Database — Migration & Seed
supabase/migrations/20251204163538_drop_plans_overage_columns.sql, supabase/seed.sql, supabase/migrations/20250530233128_base.sql
Migration removes multiple overage/unit and price id columns from public.plans; seed updated to remove those columns and add/adjust build_time_unit in inserted rows; base migration alters extensions and several table columns (devices id, drop plans.version, drop usage_mode enum).
CI — Workflow
.github/workflows/tests.yml
Change Supabase CLI install step to use latest instead of pinned 2.54.11.

Sequence Diagram(s)

sequenceDiagram
    participant Frontend as Plans/Usage Component
    participant API as services/supabase.ts (getCreditUnitPricing)
    participant DB as Database (capgo_credits_steps / plans)

    rect rgb(220,235,255)
    Frontend->>API: getCreditUnitPricing(orgId)
    API->>DB: SELECT * FROM capgo_credits_steps WHERE step_min = 0
    DB-->>API: rows (metric_type, price, org_id, ...)
    API-->>Frontend: CreditUnitPricing map
    end

    rect rgb(255,245,220)
    Frontend->>API: getCurrentPlanNameOrg() / get plans
    API->>DB: Query current plan / plans table
    DB-->>API: plan rows
    API-->>Frontend: plan details
    Frontend->>Frontend: calculatePrice(usage, creditUnitPrices)
    Frontend-->>Frontend: render updated pricing UI
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay special attention to:
    • src/types/supabase.types.ts and supabase/functions/_backend/utils/supabase.types.ts — broad typing/schema changes with high downstream impact.
    • getCreditUnitPricing sorting/priority and fallback logic — ensure correct org-specific selection and step handling.
    • Frontend pricing calculations in Plans.vue and Usage.vue — verify guards (zero/negative), defaults, and UI formatting.
    • Migration/seed consistency — confirm seed rows match the post-migration schema and app expectations.

Possibly related PRs

Poem

🐰 I nibble counts of MAU and byte,
Per-unit carrots gleam in soft light,
I hop through steps to find the price,
I tally units, add them nice,
New fields sprout, old leaves brushed—hooray! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive The PR description is incomplete and minimalist. It provides only a basic summary ('Drop unused columns in "plans"') and marks all checklist items as incomplete, including linting checks, documentation updates, E2E test coverage, and manual testing steps. Expand the description with specific details about which columns are being dropped, why they are unused, and why testing is marked as 'N/A'. Complete the checklist items or provide clear justification for omissions.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'chore: drop unused columns in "plans"' clearly and directly summarizes the main change—removing unused columns from the plans table, which is confirmed by the migration file and database schema changes.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch drop-plans-unused-columns

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 38e952f and c35b0e8.

📒 Files selected for processing (1)
  • .github/workflows/tests.yml (1 hunks)
⏰ 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: Run tests
🔇 Additional comments (1)
.github/workflows/tests.yml (1)

57-57: No action required—using latest for Supabase CLI in this setup action is standard practice.

The supabase/setup-cli@v1 action is designed to accept version: latest, and this pattern is documented in official Supabase examples and the GitHub Marketplace. Using latest for setup actions does not compromise reproducibility, as the setup action itself manages version acquisition deterministically. The straightforward schema migration (DROP COLUMN operations) has no special version requirements.

Likely an incorrect or invalid review comment.


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

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
src/pages/settings/organization/Plans.vue (1)

64-80: if (true) is dead code - pricing shows for all plans unconditionally.

The condition if (true) is always true, meaning all plans will display the per-unit pricing details (mau, storage, bandwidth prices, plus "Dedicated support", "Custom Domain", "SOC II"). This appears to be a refactoring artifact. If this is intentional, remove the if wrapper entirely. If only certain plans should show this, restore the original condition.

-  if (true) {
-    if (creditUnitPrices.value.mau)
-      features[0] += ` included, then $${creditUnitPrices.value.mau}/user`
-
-    if (creditUnitPrices.value.storage)
-      features[1] += ` included, then $${creditUnitPrices.value.storage} per GB`
-
-    if (creditUnitPrices.value.bandwidth)
-      features[2] += ` included, then $${creditUnitPrices.value.bandwidth} per GB`
-
-    if (plan.build_time_unit && buildTimeDisplay)
-      features[buildTimeIndex] += ` included, then $${plan.build_time_unit} per hour`
-
-    features.push('Dedicated support')
-    features.push('Custom Domain')
-    features.push('SOC II')
-  }
+  // Add per-unit pricing details for all plans
+  if (creditUnitPrices.value.mau)
+    features[0] += ` included, then $${creditUnitPrices.value.mau}/user`
+
+  if (creditUnitPrices.value.storage)
+    features[1] += ` included, then $${creditUnitPrices.value.storage} per GB`
+
+  if (creditUnitPrices.value.bandwidth)
+    features[2] += ` included, then $${creditUnitPrices.value.bandwidth} per GB`
+
+  if (plan.build_time_unit && buildTimeDisplay)
+    features[buildTimeIndex] += ` included, then $${plan.build_time_unit} per hour`
+
+  features.push('Dedicated support')
+  features.push('Custom Domain')
+  features.push('SOC II')
🧹 Nitpick comments (4)
src/services/supabase.ts (1)

390-398: Redundant secondary sort by step_min.

Since the query already filters by .eq('step_min', 0), all results have step_min = 0. The secondary sort comparison (a.step_min ?? 0) - (b.step_min ?? 0) will always evaluate to 0 - 0 = 0, making it a no-op. Consider removing it for clarity.

     const sortedSteps = [...data].sort((a, b) => {
       const aOrgPriority = a.org_id && orgId && a.org_id === orgId ? 0 : 1
       const bOrgPriority = b.org_id && orgId && b.org_id === orgId ? 0 : 1

-      if (aOrgPriority !== bOrgPriority)
-        return aOrgPriority - bOrgPriority
-
-      return (a.step_min ?? 0) - (b.step_min ?? 0)
+      return aOrgPriority - bOrgPriority
     })
src/pages/settings/organization/Usage.vue (1)

218-219: Type assertion as any may mask type issues.

The as any cast on usageDetails suggests a potential type mismatch with what the Map expects. Consider properly typing usageDetails or fixing the return type of getUsage.

src/types/supabase.types.ts (1)

2661-2663: Omit<Database, "__InternalSupabase"> references non-existent key.

Since __InternalSupabase was removed from the Database type (replaced by graphql_public), this Omit is now a no-op. While this doesn't cause errors, it's misleading. Consider updating to reflect the current structure.

-type DatabaseWithoutInternals = Omit<Database, "__InternalSupabase">
+type DatabaseWithoutInternals = Database

Or if the intent was to exclude graphql_public:

-type DatabaseWithoutInternals = Omit<Database, "__InternalSupabase">
+type DatabaseWithoutInternals = Omit<Database, "graphql_public">
supabase/migrations/20251204163538_drop_plans_overage_columns.sql (1)

1-10: Migration is safe to deploy.

No references to the dropped columns (storage_unit, bandwidth_unit, mau_unit, price_m_storage_id, price_m_bandwidth_id) exist in the codebase. The migration properly uses IF EXISTS and is wrapped in a transaction for atomicity.

Consider maintaining a corresponding rollback migration for production safety if reverting this change becomes necessary.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec88c79 and 881ab90.

📒 Files selected for processing (7)
  • src/pages/settings/organization/Plans.vue (5 hunks)
  • src/pages/settings/organization/Usage.vue (5 hunks)
  • src/services/supabase.ts (1 hunks)
  • src/types/supabase.types.ts (12 hunks)
  • supabase/functions/_backend/utils/supabase.types.ts (12 hunks)
  • supabase/migrations/20251204163538_drop_plans_overage_columns.sql (1 hunks)
  • supabase/seed.sql (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/types/supabase.types.ts (1)
supabase/functions/_backend/utils/supabase.types.ts (1)
  • Json (1-7)
supabase/functions/_backend/utils/supabase.types.ts (1)
src/types/supabase.types.ts (1)
  • Json (1-7)
🔇 Additional comments (13)
supabase/seed.sql (1)

61-65: Seed data correctly aligns with the schema migration.

The plan INSERT statements have been properly updated to remove references to the dropped columns while retaining price_m_mau_id and build_time_unit. The data values appear consistent.

src/services/supabase.ts (1)

377-413: Well-structured pricing fetcher with appropriate error handling.

The function correctly prioritizes org-specific pricing over default pricing and gracefully returns an empty object on error, which is appropriate for UI consumption.

src/pages/settings/organization/Plans.vue (1)

146-168: Good use of parallel data loading.

The Promise.all pattern correctly loads credit pricing and plan name concurrently, improving page load performance.

src/pages/settings/organization/Usage.vue (1)

115-119: Good defensive guard in calculatePrice.

The check for unit <= 0 prevents incorrect calculations when pricing data is unavailable or zero, returning 0 instead of potentially negative or NaN values.

src/types/supabase.types.ts (2)

10-34: New graphql_public schema correctly added.

The GraphQL schema addition with the graphql function type is properly structured and follows the expected Supabase pattern.


1210-1267: Plans table type correctly updated - removed unused columns, added version.

The plans table Row/Insert/Update types have been properly updated to remove the dropped columns (storage_unit, bandwidth_unit, mau_unit, price_m_storage_id, price_m_bandwidth_id) and add the new version field.

supabase/functions/_backend/utils/supabase.types.ts (7)

10-33: graphql_public schema typings are well-structured and isolated

The new graphql_public schema block is self-contained, uses the same pattern as other schemas, and does not affect the existing public helpers.


204-233: New app_versions_meta.devices field is typed consistently

Row.devices is non-optional number | null, with Insert/Update making it optional, matching how other nullable numeric columns are modeled in this file.


1210-1268: plans.version column typing looks correct; confirm DB default

Row.version is non-null while Insert/Update make it optional, consistent with other defaulted columns (e.g., timestamps). This assumes the migration defines a NOT NULL column with a server-side default so existing inserts remain valid.

Please confirm the plans.version migration sets an appropriate default to avoid runtime insert errors when version is omitted.


2460-2478: Reset/seed RPC function entries align with existing patterns

Arg optionality and Returns: undefined mirror other maintenance RPC definitions in this type file, so these additions should integrate cleanly with existing RPC usage.


2594-2611: stats_action and usage_mode enum updates are internally consistent

The new ping and backend_refusal literals are correctly added to the stats_action union, and usage_mode’s union matches the intended value set.


2779-2883: Constants extended for graphql_public and refreshed enums stay in sync

Adding Constants.graphql_public.Enums and updating the stats_action and usage_mode arrays keeps the runtime constants aligned with the Database enum definitions, and as const preserves literal types.


758-773: deleted_account.Insert.email now required – correctly aligns with schema

Making email required in Insert is correct: the database schema defines email as NOT NULL. All existing inserts in the codebase already provide this field, so no type-checking failures occur.

Comment on lines 74 to 75
if (plan.build_time_unit && buildTimeDisplay)
features[buildTimeIndex] += ` included, then $${plan.build_time_unit} per hour`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Incorrect value used for build time pricing.

plan.build_time_unit represents the included build time in seconds, not the per-unit price. For consistency with other metrics, this should use creditUnitPrices.value.build_time instead.

-    if (plan.build_time_unit && buildTimeDisplay)
-      features[buildTimeIndex] += ` included, then $${plan.build_time_unit} per hour`
+    if (plan.build_time_unit && buildTimeDisplay && creditUnitPrices.value.build_time)
+      features[buildTimeIndex] += ` included, then $${creditUnitPrices.value.build_time} per minute`

Note: Verify the unit (per hour vs per minute) matches your pricing model in capgo_credits_steps.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/pages/settings/organization/Plans.vue around lines 74-75, the code
appends a price using plan.build_time_unit (which is actually an included build
time in seconds) — replace that with creditUnitPrices.value.build_time so the
per-unit price is used consistently; also ensure the appended text and any
numeric conversion reflect the correct billing interval (per hour vs per minute)
to match capgo_credits_steps (convert seconds to the chosen interval if needed)
and update the template string accordingly.

Comment on lines 80 to 85
const payg_units = {
mau: currentPlan?.mau_unit,
storage: currentPlan?.storage_unit,
bandwidth: currentPlan?.bandwidth_unit,
build_time: currentPlan?.build_time_unit || 0,
mau: creditUnitPrices.value.mau ?? 0,
storage: creditUnitPrices.value.storage ?? 0,
bandwidth: creditUnitPrices.value.bandwidth ?? 0,
build_time: currentPlan?.build_time_unit ?? 0,
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Inconsistent source for build_time pricing.

payg_units.build_time uses currentPlan?.build_time_unit (included seconds), while other metrics use creditUnitPrices. For consistency, this should use creditUnitPrices.value.build_time like the other metrics.

   const payg_units = {
     mau: creditUnitPrices.value.mau ?? 0,
     storage: creditUnitPrices.value.storage ?? 0,
     bandwidth: creditUnitPrices.value.bandwidth ?? 0,
-    build_time: currentPlan?.build_time_unit ?? 0,
+    build_time: creditUnitPrices.value.build_time ?? 0,
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const payg_units = {
mau: currentPlan?.mau_unit,
storage: currentPlan?.storage_unit,
bandwidth: currentPlan?.bandwidth_unit,
build_time: currentPlan?.build_time_unit || 0,
mau: creditUnitPrices.value.mau ?? 0,
storage: creditUnitPrices.value.storage ?? 0,
bandwidth: creditUnitPrices.value.bandwidth ?? 0,
build_time: currentPlan?.build_time_unit ?? 0,
}
const payg_units = {
mau: creditUnitPrices.value.mau ?? 0,
storage: creditUnitPrices.value.storage ?? 0,
bandwidth: creditUnitPrices.value.bandwidth ?? 0,
build_time: creditUnitPrices.value.build_time ?? 0,
}
🤖 Prompt for AI Agents
In src/pages/settings/organization/Usage.vue around lines 80 to 85,
payg_units.build_time is incorrectly sourced from currentPlan?.build_time_unit
while the other metrics use creditUnitPrices; change it to use
creditUnitPrices.value.build_time so build_time pricing is consistent with the
other unit prices (use the same null-coalescing pattern, e.g.,
creditUnitPrices.value.build_time ?? 0).

@riderx
Copy link
Copy Markdown
Member

riderx commented Dec 5, 2025

issue with test to check

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/types/supabase.types.ts (1)

2772-2774: Constants alignment with graphql_public namespace.

This adds the graphql_public section to Constants with an empty Enums object, maintaining consistency with the database type structure. See earlier comment on lines 10-34 regarding the purpose of the graphql_public namespace.

🧹 Nitpick comments (2)
supabase/migrations/20250530233128_base.sql (1)

69-84: Guard non-core extensions to avoid migration failures on hosts that don’t ship them.

CREATE EXTENSION IF NOT EXISTS still errors if the extension isn’t installed. Wrap with availability checks:

DO $$
BEGIN
  IF EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='pgsodium') THEN
    CREATE EXTENSION IF NOT EXISTS pgsodium;
  END IF;
  IF EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='hypopg') THEN
    CREATE EXTENSION IF NOT EXISTS hypopg WITH SCHEMA extensions;
  END IF;
  IF EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='index_advisor') THEN
    CREATE EXTENSION IF NOT EXISTS index_advisor WITH SCHEMA extensions;
  END IF;
  IF EXISTS (SELECT 1 FROM pg_available_extensions WHERE name='plpgsql_check') THEN
    CREATE EXTENSION IF NOT EXISTS plpgsql_check WITH SCHEMA extensions;
  END IF;
END $$;
supabase/functions/_backend/utils/supabase.types.ts (1)

1-2875: Consider eliminating duplicate type definitions across the repository.

supabase/functions/_backend/utils/supabase.types.ts is an exact duplicate of src/types/supabase.types.ts (both 2875 lines, bit-for-bit identical). This creates maintenance friction:

  • Type changes must be manually synchronized between both files
  • Risk of inconsistencies if one file is updated without the other
  • Increased codebase size

Consider consolidating via one of these approaches:

  1. Have backend functions import types directly from src/types/supabase.types.ts
  2. Use a build step to generate the backend copy from a single source
  3. Create a shared types package for both source and backend to depend on
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15a9b06 and 38e952f.

📒 Files selected for processing (5)
  • src/types/supabase.types.ts (7 hunks)
  • supabase/functions/_backend/utils/supabase.types.ts (7 hunks)
  • supabase/migrations/20250530233128_base.sql (4 hunks)
  • supabase/migrations/20251204163538_drop_plans_overage_columns.sql (1 hunks)
  • supabase/seed.sql (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/types/supabase.types.ts (1)
supabase/functions/_backend/utils/supabase.types.ts (1)
  • Json (1-7)
supabase/functions/_backend/utils/supabase.types.ts (1)
src/types/supabase.types.ts (1)
  • Json (1-7)
🔇 Additional comments (6)
supabase/migrations/20251204163538_drop_plans_overage_columns.sql (1)

1-11: Drops look fine, but verify no remaining references (including seeds).

Given seed.sql currently inserts build_time_unit and no migration adds it, align seeds/migrations before running this. Also confirm no functions/views still expect the dropped unit/price_m_* columns.

supabase/migrations/20250530233128_base.sql (1)

3636-3648: Adding devices.id identity: confirm downstream types and no PK assumptions.

  • PK remains (app_id, device_id). Good.
  • Ensure generated Supabase types/ORM models include the new id and no code assumes a surrogate PK. If unused, consider not selecting it to avoid breaking strict mappers.
src/types/supabase.types.ts (4)

2588-2590: LGTM: stats_action enum values updated consistently.

The stats_action enum has been updated with "ping" and "backend_refusal" entries in both the type definition and the Constants array. The changes are consistent across both locations.

Also applies to: 2839-2841


763-763: Email field requirement in deleted_account.Insert aligns with database schema.

The email field is correctly required in the deleted_account.Insert type, matching the database column constraint (NOT NULL). All existing inserts in both SQL migrations and seed data provide the email field, so no code breakage occurs from this requirement.


1210-1263: > Likely an incorrect or invalid review comment.


10-34: The supabase.types.ts file is auto-generated by running supabase gen types typescript. The graphql_public namespace is part of Supabase's standard schema and is included automatically whenever types are regenerated. This is not a manually added addition specific to this PR—it reflects the current state of the Supabase database schema. No action is needed.

Likely an incorrect or invalid review comment.

Comment thread supabase/seed.sql
Comment on lines +61 to 66
INSERT INTO "public"."plans" ("created_at", "updated_at", "name", "description", "price_m", "price_y", "stripe_id", "id", "price_m_id", "price_y_id", "storage", "bandwidth", "mau", "market_desc", "build_time_unit") VALUES
(now(), now(), 'Maker', 'plan.maker.desc', 39, 396, 'prod_LQIs1Yucml9ChU', '440cfd69-0cfd-486e-b59b-cb99f7ae76a0', 'price_1KjSGyGH46eYKnWwL4h14DsK', 'price_1KjSKIGH46eYKnWwFG9u4tNi', 3221225472, 268435456000, 10000, 'Best for small business owners', 3600),
(now(), now(), 'Pay as you go', 'plan.payasyougo.desc', 239, 4799, 'prod_MH5Jh6ajC9e7ZH', '745d7ab3-6cd6-4d65-b257-de6782d5ba50', 'price_1LYX8yGH46eYKnWwzeBjISvW', 'price_1LYX8yGH46eYKnWwzeBjISvW', 12884901888, 3221225472000, 1000000, 'Best for scalling enterprises', 600000),
(now(), now(), 'Solo', 'plan.solo.desc', 14, 146, 'prod_LQIregjtNduh4q', '526e11d8-3c51-4581-ac92-4770c602f47c', 'price_1LVvuZGH46eYKnWwuGKOf4DK', 'price_1LVvuIGH46eYKnWwHMDCrxcH', 1073741824, 13958643712, 1000, 'Best for independent developers', 1800),
(now(), now(), 'Team', 'plan.team.desc', 99, 998, 'prod_LQIugvJcPrxhda', 'abd76414-8f90-49a5-b3a4-8ff4d2e12c77', 'price_1KjSIUGH46eYKnWwWHvg8XYs', 'price_1KjSLlGH46eYKnWwAwMW2wiW', 6442450944, 536870912000, 100000, 'Best for medium enterprises', 18000);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

find supabase -type f -name "*.sql" 2>/dev/null | sort

Repository: Cap-go/capgo

Length of output: 3989


🏁 Script executed:

rg -A 30 "CREATE TABLE.*\"plans\"" supabase/migrations/20250530233128_base.sql

Repository: Cap-go/capgo

Length of output: 1466


🏁 Script executed:

# Check if build_time_unit appears in seed.sql
rg "build_time_unit" supabase/seed.sql

Repository: Cap-go/capgo

Length of output: 366


🏁 Script executed:

# Get exact lines 61-66 with context
sed -n '55,75p' supabase/seed.sql

Repository: Cap-go/capgo

Length of output: 2605


🏁 Script executed:

# View the drop migration
cat supabase/migrations/20251204163538_drop_plans_overage_columns.sql

Repository: Cap-go/capgo

Length of output: 339


Seed/schema mismatch: build_time_unit column doesn't exist in public.plans — seed INSERT will fail.

The build_time_unit column is not defined in the plans table schema (base migration creates plans without it, and the drop migration only removes overage columns). Remove this column from the seed INSERT statement to match the actual schema:

-INSERT INTO "public"."plans" ("created_at", "updated_at", "name", "description", "price_m", "price_y", "stripe_id", "id", "price_m_id", "price_y_id", "storage", "bandwidth", "mau", "market_desc", "build_time_unit") VALUES
-(now(), now(), 'Maker', 'plan.maker.desc', 39, 396, 'prod_LQIs1Yucml9ChU', '440cfd69-0cfd-486e-b59b-cb99f7ae76a0', 'price_1KjSGyGH46eYKnWwL4h14DsK', 'price_1KjSKIGH46eYKnWwFG9u4tNi', 3221225472, 268435456000, 10000, 'Best for small business owners', 3600),
-(now(), now(), 'Pay as you go', 'plan.payasyougo.desc', 239, 4799, 'prod_MH5Jh6ajC9e7ZH', '745d7ab3-6cd6-4d65-b257-de6782d5ba50', 'price_1LYX8yGH46eYKnWwzeBjISvW', 'price_1LYX8yGH46eYKnWwzeBjISvW', 12884901888, 3221225472000, 1000000, 'Best for scalling enterprises', 600000),
-(now(), now(), 'Solo', 'plan.solo.desc', 14, 146, 'prod_LQIregjtNduh4q', '526e11d8-3c51-4581-ac92-4770c602f47c', 'price_1LVvuZGH46eYKnWwuGKOf4DK', 'price_1LVvuIGH46eYKnWwHMDCrxcH', 1073741824, 13958643712, 1000, 'Best for independent developers', 1800),
-(now(), now(), 'Team', 'plan.team.desc', 99, 998, 'prod_LQIugvJcPrxhda', 'abd76414-8f90-49a5-b3a4-8ff4d2e12c77', 'price_1KjSIUGH46eYKnWwWHvg8XYs', 'price_1KjSLlGH46eYKnWwAwMW2wiW', 6442450944, 536870912000, 100000, 'Best for medium enterprises', 18000);
+INSERT INTO "public"."plans" ("created_at", "updated_at", "name", "description", "price_m", "price_y", "stripe_id", "id", "price_m_id", "price_y_id", "storage", "bandwidth", "mau", "market_desc") VALUES
+(now(), now(), 'Maker', 'plan.maker.desc', 39, 396, 'prod_LQIs1Yucml9ChU', '440cfd69-0cfd-486e-b59b-cb99f7ae76a0', 'price_1KjSGyGH46eYKnWwL4h14DsK', 'price_1KjSKIGH46eYKnWwFG9u4tNi', 3221225472, 268435456000, 10000, 'Best for small business owners'),
+(now(), now(), 'Pay as you go', 'plan.payasyougo.desc', 239, 4799, 'prod_MH5Jh6ajC9e7ZH', '745d7ab3-6cd6-4d65-b257-de6782d5ba50', 'price_1LYX8yGH46eYKnWwzeBjISvW', 'price_1LYX8yGH46eYKnWwzeBjISvW', 12884901888, 3221225472000, 1000000, 'Best for scaling enterprises'),
+(now(), now(), 'Solo', 'plan.solo.desc', 14, 146, 'prod_LQIregjtNduh4q', '526e11d8-3c51-4581-ac92-4770c602f47c', 'price_1LVvuZGH46eYKnWwuGKOf4DK', 'price_1LVvuIGH46eYKnWwHMDCrxcH', 1073741824, 13958643712, 1000, 'Best for independent developers'),
+(now(), now(), 'Team', 'plan.team.desc', 99, 998, 'prod_LQIugvJcPrxhda', 'abd76414-8f90-49a5-b3a4-8ff4d2e12c77', 'price_1KjSIUGH46eYKnWwWHvg8XYs', 'price_1KjSLlGH46eYKnWwAwMW2wiW', 6442450944, 536870912000, 100000, 'Best for medium enterprises');

Also fix the typo on line 63: "scalling" → "scaling".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
INSERT INTO "public"."plans" ("created_at", "updated_at", "name", "description", "price_m", "price_y", "stripe_id", "id", "price_m_id", "price_y_id", "storage", "bandwidth", "mau", "market_desc", "build_time_unit") VALUES
(now(), now(), 'Maker', 'plan.maker.desc', 39, 396, 'prod_LQIs1Yucml9ChU', '440cfd69-0cfd-486e-b59b-cb99f7ae76a0', 'price_1KjSGyGH46eYKnWwL4h14DsK', 'price_1KjSKIGH46eYKnWwFG9u4tNi', 3221225472, 268435456000, 10000, 'Best for small business owners', 3600),
(now(), now(), 'Pay as you go', 'plan.payasyougo.desc', 239, 4799, 'prod_MH5Jh6ajC9e7ZH', '745d7ab3-6cd6-4d65-b257-de6782d5ba50', 'price_1LYX8yGH46eYKnWwzeBjISvW', 'price_1LYX8yGH46eYKnWwzeBjISvW', 12884901888, 3221225472000, 1000000, 'Best for scalling enterprises', 600000),
(now(), now(), 'Solo', 'plan.solo.desc', 14, 146, 'prod_LQIregjtNduh4q', '526e11d8-3c51-4581-ac92-4770c602f47c', 'price_1LVvuZGH46eYKnWwuGKOf4DK', 'price_1LVvuIGH46eYKnWwHMDCrxcH', 1073741824, 13958643712, 1000, 'Best for independent developers', 1800),
(now(), now(), 'Team', 'plan.team.desc', 99, 998, 'prod_LQIugvJcPrxhda', 'abd76414-8f90-49a5-b3a4-8ff4d2e12c77', 'price_1KjSIUGH46eYKnWwWHvg8XYs', 'price_1KjSLlGH46eYKnWwAwMW2wiW', 6442450944, 536870912000, 100000, 'Best for medium enterprises', 18000);
INSERT INTO "public"."plans" ("created_at", "updated_at", "name", "description", "price_m", "price_y", "stripe_id", "id", "price_m_id", "price_y_id", "storage", "bandwidth", "mau", "market_desc") VALUES
(now(), now(), 'Maker', 'plan.maker.desc', 39, 396, 'prod_LQIs1Yucml9ChU', '440cfd69-0cfd-486e-b59b-cb99f7ae76a0', 'price_1KjSGyGH46eYKnWwL4h14DsK', 'price_1KjSKIGH46eYKnWwFG9u4tNi', 3221225472, 268435456000, 10000, 'Best for small business owners'),
(now(), now(), 'Pay as you go', 'plan.payasyougo.desc', 239, 4799, 'prod_MH5Jh6ajC9e7ZH', '745d7ab3-6cd6-4d65-b257-de6782d5ba50', 'price_1LYX8yGH46eYKnWwzeBjISvW', 'price_1LYX8yGH46eYKnWwzeBjISvW', 12884901888, 3221225472000, 1000000, 'Best for scaling enterprises'),
(now(), now(), 'Solo', 'plan.solo.desc', 14, 146, 'prod_LQIregjtNduh4q', '526e11d8-3c51-4581-ac92-4770c602f47c', 'price_1LVvuZGH46eYKnWwuGKOf4DK', 'price_1LVvuIGH46eYKnWwHMDCrxcH', 1073741824, 13958643712, 1000, 'Best for independent developers'),
(now(), now(), 'Team', 'plan.team.desc', 99, 998, 'prod_LQIugvJcPrxhda', 'abd76414-8f90-49a5-b3a4-8ff4d2e12c77', 'price_1KjSIUGH46eYKnWwWHvg8XYs', 'price_1KjSLlGH46eYKnWwAwMW2wiW', 6442450944, 536870912000, 100000, 'Best for medium enterprises');
🤖 Prompt for AI Agents
In supabase/seed.sql around lines 61 to 66, the INSERT into public.plans
references a non-existent column build_time_unit which will cause the seed to
fail; remove build_time_unit from the column list and strip the corresponding
trailing value from each VALUES tuple so the number of values matches the table
columns, and also correct the typo on line 63 from "scalling" to "scaling".

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Dec 5, 2025

@riderx riderx merged commit 4139f0b into main Dec 5, 2025
10 of 11 checks passed
@riderx riderx deleted the drop-plans-unused-columns branch December 5, 2025 17:33
@coderabbitai coderabbitai Bot mentioned this pull request Dec 8, 2025
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants