feat(billing): integrate Stripe for subscription management and billing access

- Added billing-related fields to the User model in the database.
- Implemented functions for managing billing access, including trial periods and subscription statuses.
- Created new billing utility functions for Stripe integration.
- Updated onboarding page to include billing overview and workspace creation eligibility.
- Enhanced route access checks to require billing access for certain actions.
- Implemented cleanup scripts for expired billing workspaces and associated media.
- Updated header component to conditionally show app navigation based on billing access.
- Added new migrations for billing-related database changes.
This commit is contained in:
Yusuf İpek
2026-04-08 17:50:40 +03:00
parent 8db7a031e6
commit 6f22b0bf8b
45 changed files with 1859 additions and 218 deletions
@@ -4,7 +4,7 @@ import {
ArrowLeft,
} from 'lucide-react';
import { GuestGate } from '@/components/guest-gate';
import { auth } from '@/lib/auth';
import { auth, checkProjectAccess } from '@/lib/auth';
import { db } from '@/lib/db';
import { ProjectContentClient } from './project-content-client';
@@ -65,6 +65,8 @@ export default async function ProjectPage({ params, searchParams }: ProjectPageP
notFound();
}
const access = await checkProjectAccess(project, session?.user?.id);
// Check access
const isOwner = session?.user?.id === project.ownerId;
const isMember = project.members.length > 0;
@@ -92,7 +94,7 @@ export default async function ProjectPage({ params, searchParams }: ProjectPageP
}
}
if (!isOwner && !isMember && !isPublic && !isWorkspaceMember) {
if (!access.hasAccess || (!isOwner && !isMember && !isPublic && !isWorkspaceMember)) {
if (!session?.user?.id) {
redirect('/login');
}
@@ -139,7 +141,7 @@ export default async function ProjectPage({ params, searchParams }: ProjectPageP
};
});
const canEdit = isOwner || project.members[0]?.role === 'ADMIN' || workspaceRole === 'OWNER' || workspaceRole === 'ADMIN';
const canEdit = access.canEdit && (isOwner || project.members[0]?.role === 'ADMIN' || workspaceRole === 'OWNER' || workspaceRole === 'ADMIN');
const isAuthenticated = !!session?.user?.id;
const projectData = {