Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ next-env.d.ts
# Docker
postgres_data/
.env*.local

#agent
.agent
.agents
.qwen
37 changes: 32 additions & 5 deletions app/(login)/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
import { comparePasswords, hashPassword, setSession } from '@/lib/auth/session';
import { redirect } from 'next/navigation';
import { cookies } from 'next/headers';
import { createCheckoutSession } from '@/lib/payments/stripe';
import { createCheckoutSession, stripe } from '@/lib/payments/stripe';
import { getUser, getUserWithTeam } from '@/lib/db/queries';
import {
validatedAction,
Expand Down Expand Up @@ -323,14 +323,41 @@ export const deleteAccount = validatedActionWithUser(
.where(eq(users.id, user.id));

if (userWithTeam?.teamId) {
await db
.delete(teamMembers)
const owners = await db
.select({ count: sql<number>`count(*)` })
.from(teamMembers)
.where(
and(
eq(teamMembers.userId, user.id),
eq(teamMembers.teamId, userWithTeam.teamId)
eq(teamMembers.teamId, userWithTeam.teamId),
eq(teamMembers.role, 'owner')
)
);

if (owners[0].count === 1 && userWithTeam.role === 'owner') {
const team = await db
.select()
.from(teams)
.where(eq(teams.id, userWithTeam.teamId))
.limit(1);

if (team.length > 0 && team[0].stripeSubscriptionId) {
await stripe.subscriptions.cancel(team[0].stripeSubscriptionId);
Comment thread
mohamed-benoughidene marked this conversation as resolved.
Outdated
}

await db.delete(teamMembers).where(eq(teamMembers.teamId, userWithTeam.teamId));
await db.delete(activityLogs).where(eq(activityLogs.teamId, userWithTeam.teamId));
await db.delete(invitations).where(eq(invitations.teamId, userWithTeam.teamId));
await db.delete(teams).where(eq(teams.id, userWithTeam.teamId));
} else {
await db
.delete(teamMembers)
.where(
and(
eq(teamMembers.userId, user.id),
eq(teamMembers.teamId, userWithTeam.teamId)
)
);
}
}

(await cookies()).delete('session');
Expand Down
10 changes: 5 additions & 5 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ export const viewport: Viewport = {

const manrope = Manrope({ subsets: ['latin'] });

export default function RootLayout({
export default async function RootLayout({
children
}: {
children: React.ReactNode;
}) {
const [user, team] = await Promise.all([getUser(), getTeamForUser()]);

return (
<html
lang="en"
Expand All @@ -29,10 +31,8 @@ export default function RootLayout({
<SWRConfig
value={{
fallback: {
// We do NOT await here
// Only components that read this data will suspend
'/api/user': getUser(),
'/api/team': getTeamForUser()
'/api/user': user,
'/api/team': team
}
}}
>
Expand Down
3 changes: 2 additions & 1 deletion lib/db/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ export async function getUserWithTeam(userId: number) {
const result = await db
.select({
user: users,
teamId: teamMembers.teamId
teamId: teamMembers.teamId,
role: teamMembers.role
})
.from(users)
.leftJoin(teamMembers, eq(users.id, teamMembers.userId))
Expand Down
4 changes: 2 additions & 2 deletions lib/db/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async function createStripeProducts() {
currency: 'usd',
recurring: {
interval: 'month',
trial_period_days: 7,
trial_period_days: 14,
},
});

Expand All @@ -32,7 +32,7 @@ async function createStripeProducts() {
currency: 'usd',
recurring: {
interval: 'month',
trial_period_days: 7,
trial_period_days: 14,
},
});

Expand Down
2 changes: 1 addition & 1 deletion lib/payments/stripe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from '@/lib/db/queries';

export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: '2025-04-30.basil'
apiVersion: '2025-08-27.basil'
});

export async function createCheckoutSession({
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"baseUrl": ".",
"plugins": [
Expand Down