Skip to content

Commit fa68e26

Browse files
AzizX-coderclaude
andcommitted
feat(supabase): complete production schema + raise prices
supabase/schema.sql — one idempotent file to set up the whole backend, replacing the partial 001/002 migrations: - plans table: source of truth for tiers, pricing & limits - profiles: SECURITY FIX — old RLS let a user run `update profiles set plan='max'` and self-grant a paid plan. A before-update trigger now reverts plan / stripe / subscription / ai_credits columns unless the caller is the service_role. - all sync tables: notes, tasks, task_lists, events (existing) PLUS code_snippets, ai_conversations, ai_messages, memories, timer_sessions, voice_recordings (metadata; blob -> storage) - collaboration: workspaces, workspace_members, workspace_invites, accept_workspace_invite(), and is_workspace_member / can_edit_workspace / is_workspace_owner SECURITY DEFINER helpers (avoids the self-referential-RLS recursion footgun) - content tables gain an optional workspace_id with RLS that grants members read and editors write - billing_events: idempotent Stripe webhook audit log (RLS denies all -> service_role only) - ai_usage: per-call metering for credit limits / abuse detection - realtime publication for the collaborative tables - storage buckets (vault, voice, avatars) with per-user path RLS Pricing raised: Pro $8 -> $12/mo, Max $18 -> $29/mo, with annual options ($120 / $290). PricingPage feature lists reworked to justify it (real- time collaboration on Pro, team workspaces on Max). usePlanLimits.ts kept in sync with the plans table (adds price + collaboration fields). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 6fcecce commit fa68e26

5 files changed

Lines changed: 618 additions & 139 deletions

File tree

src/features/pricing/PricingPage.tsx

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const PLANS = [
99
name: "Free",
1010
price: "$0",
1111
period: "forever",
12+
note: "",
1213
icon: <Sparkles size={20} className="text-text-tertiary" />,
1314
color: "border-border/30",
1415
badge: "",
@@ -27,17 +28,18 @@ const PLANS = [
2728
{
2829
id: "pro",
2930
name: "Pro",
30-
price: "$8",
31+
price: "$12",
3132
period: "/ month",
33+
note: "or $120 / year — save 17%",
3234
icon: <Crown size={20} className="text-amber-400" />,
3335
color: "border-amber-400/40 ring-1 ring-amber-400/20",
3436
badge: "Most Popular",
3537
features: [
36-
"Unlimited notes, tasks & flows",
37-
"Unlimited Kanban boards",
38-
"Cloud sync across devices",
39-
"Public note sharing",
40-
"Cloud Vault (5GB)",
38+
"Unlimited notes, tasks, boards & flows",
39+
"Cloud sync across all your devices",
40+
"Real-time collaboration — up to 3 people",
41+
"Public note sharing with links",
42+
"5 GB encrypted Cloud Vault",
4143
"500 AI credits / month",
4244
"Priority support",
4345
],
@@ -47,18 +49,19 @@ const PLANS = [
4749
{
4850
id: "max",
4951
name: "Max",
50-
price: "$18",
52+
price: "$29",
5153
period: "/ month",
54+
note: "or $290 / year — save 17%",
5255
icon: <Zap size={20} className="text-purple-400" />,
5356
color: "border-purple-400/40",
5457
badge: "",
5558
features: [
5659
"Everything in Pro",
57-
"20GB Cloud Vault",
60+
"Team workspaces — up to 10 people",
61+
"20 GB encrypted Cloud Vault",
5862
"Unlimited AI credits",
59-
"Advanced AI features",
63+
"Advanced AI models",
6064
"Early access to new features",
61-
"Team collaboration (coming soon)",
6265
"Dedicated support",
6366
],
6467
cta: "Upgrade to Max",
@@ -137,8 +140,13 @@ export function PricingPage() {
137140

138141
{/* Price */}
139142
<div className="mb-5">
140-
<span className="text-[36px] font-black text-text-primary">{plan.price}</span>
141-
<span className="text-[13px] text-text-tertiary ml-1">{plan.period}</span>
143+
<div>
144+
<span className="text-[36px] font-black text-text-primary">{plan.price}</span>
145+
<span className="text-[13px] text-text-tertiary ml-1">{plan.period}</span>
146+
</div>
147+
{plan.note && (
148+
<p className="text-[11px] text-text-tertiary mt-1">{plan.note}</p>
149+
)}
142150
</div>
143151

144152
{/* Features */}

src/hooks/usePlanLimits.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,47 @@
11
import { useProfile } from "./useProfile";
22

3+
// Keep in sync with the `plans` table in supabase/schema.sql.
34
export const PLAN_LIMITS = {
45
free: {
6+
priceMonthly: 0,
7+
priceYearly: 0,
58
maxNotes: 50,
69
maxBoards: 3,
710
maxFlows: 10,
811
maxVaultMB: 0,
912
canShare: false,
1013
canCloudSync: false,
1114
canUseCloudVault: false,
15+
canCollaborate: false,
16+
maxWorkspaceMembers: 1,
1217
aiCreditsPerMonth: 20,
1318
},
1419
pro: {
20+
priceMonthly: 12,
21+
priceYearly: 120,
1522
maxNotes: Infinity,
1623
maxBoards: Infinity,
1724
maxFlows: Infinity,
1825
maxVaultMB: 5000,
1926
canShare: true,
2027
canCloudSync: true,
2128
canUseCloudVault: true,
29+
canCollaborate: true,
30+
maxWorkspaceMembers: 3,
2231
aiCreditsPerMonth: 500,
2332
},
2433
max: {
34+
priceMonthly: 29,
35+
priceYearly: 290,
2536
maxNotes: Infinity,
2637
maxBoards: Infinity,
2738
maxFlows: Infinity,
2839
maxVaultMB: 20000,
2940
canShare: true,
3041
canCloudSync: true,
3142
canUseCloudVault: true,
43+
canCollaborate: true,
44+
maxWorkspaceMembers: 10,
3245
aiCreditsPerMonth: Infinity,
3346
},
3447
} as const;

supabase/migrations/001_profiles.sql

Lines changed: 0 additions & 54 deletions
This file was deleted.

supabase/migrations/002_sync_tables.sql

Lines changed: 0 additions & 73 deletions
This file was deleted.

0 commit comments

Comments
 (0)