Skip to content

Commit 2ecd51e

Browse files
authored
Merge pull request #1056 from trycompai/main
[comp] Production Deploy
2 parents 390ca4f + 985628e commit 2ecd51e

File tree

17 files changed

+799
-332
lines changed

17 files changed

+799
-332
lines changed
File renamed without changes.

.github/workflows/e2e-tests.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ jobs:
289289
run: |
290290
cd apps/app
291291
echo "Starting E2E tests for ${{ matrix.project }} with 2 workers..."
292-
bunx playwright test --project=${{ matrix.project }} --reporter=list
292+
bunx playwright test --project=${{ matrix.project }}
293293
env:
294294
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_db
295295
NEXTAUTH_URL: http://localhost:3000
@@ -318,11 +318,11 @@ jobs:
318318
echo "" >> $GITHUB_STEP_SUMMARY
319319
320320
# Check if test results exist
321-
if [ -f "test-results/.last-run.json" ]; then
321+
if [ -f "test-results/results.json" ]; then
322322
# Parse test results
323-
TOTAL=$(jq '.suites | map(.specs | length) | add' test-results/.last-run.json 2>/dev/null || echo "0")
324-
PASSED=$(jq '.suites | map(.specs | map(select(.ok == true)) | length) | add' test-results/.last-run.json 2>/dev/null || echo "0")
325-
FAILED=$(jq '.suites | map(.specs | map(select(.ok == false)) | length) | add' test-results/.last-run.json 2>/dev/null || echo "0")
323+
TOTAL=$(jq '.suites | map(.specs | length) | add' test-results/results.json 2>/dev/null || echo "0")
324+
PASSED=$(jq '.suites | map(.specs | map(select(.ok == true)) | length) | add' test-results/results.json 2>/dev/null || echo "0")
325+
FAILED=$(jq '.suites | map(.specs | map(select(.ok == false)) | length) | add' test-results/results.json 2>/dev/null || echo "0")
326326
327327
# Add summary stats
328328
echo "### 📊 Summary" >> $GITHUB_STEP_SUMMARY
@@ -337,7 +337,7 @@ jobs:
337337
echo "" >> $GITHUB_STEP_SUMMARY
338338
339339
# List failed tests
340-
jq -r '.suites[] | .specs[] | select(.ok == false) | "- **\(.title)** in `\(.file)`"' test-results/.last-run.json 2>/dev/null >> $GITHUB_STEP_SUMMARY || true
340+
jq -r '.suites[] | .specs[] | select(.ok == false) | "- **\(.title)** in `\(.file)`"' test-results/results.json 2>/dev/null >> $GITHUB_STEP_SUMMARY || true
341341
echo "" >> $GITHUB_STEP_SUMMARY
342342
fi
343343
else

apps/app/src/actions/organization/choose-self-serve.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const chooseSelfServeAction = authWithOrgAccessClient
3030
id: organizationId,
3131
},
3232
data: {
33-
subscriptionType: 'SELF_SERVE',
33+
subscriptionType: 'FREE',
3434
},
3535
});
3636

apps/app/src/actions/stripe/fetch-price-details.ts

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,24 @@ type PriceDetails = {
1414
};
1515

1616
export type CachedPrices = {
17-
monthlyPrice: PriceDetails | null;
18-
yearlyPrice: PriceDetails | null;
17+
managedMonthlyPrice: PriceDetails | null;
18+
managedYearlyPrice: PriceDetails | null;
19+
starterMonthlyPrice: PriceDetails | null;
20+
starterYearlyPrice: PriceDetails | null;
1921
fetchedAt: number;
2022
};
2123

2224
const CACHE_DURATION = 30 * 60; // 30 minutes in seconds
2325

2426
export async function fetchStripePriceDetails(): Promise<CachedPrices> {
2527
// Fetch from Stripe
26-
const monthlyPriceId = env.NEXT_PUBLIC_STRIPE_SUBSCRIPTION_MANAGED_MONTHLY_PRICE_ID;
27-
const yearlyPriceId = env.NEXT_PUBLIC_STRIPE_SUBSCRIPTION_MANAGED_YEARLY_PRICE_ID;
28+
const managedMonthlyPriceId = env.NEXT_PUBLIC_STRIPE_SUBSCRIPTION_MANAGED_MONTHLY_PRICE_ID;
29+
const managedYearlyPriceId = env.NEXT_PUBLIC_STRIPE_SUBSCRIPTION_MANAGED_YEARLY_PRICE_ID;
30+
const starterMonthlyPriceId = env.NEXT_PUBLIC_STRIPE_SUBSCRIPTION_STARTER_MONTHLY_PRICE_ID;
31+
const starterYearlyPriceId = env.NEXT_PUBLIC_STRIPE_SUBSCRIPTION_STARTER_YEARLY_PRICE_ID;
2832

2933
// Create a unique cache key that includes the price IDs
30-
const cacheKey = `stripe:managed-prices:${monthlyPriceId || 'none'}:${yearlyPriceId || 'none'}`;
34+
const cacheKey = `stripe:all-prices:${managedMonthlyPriceId || 'none'}:${managedYearlyPriceId || 'none'}:${starterMonthlyPriceId || 'none'}:${starterYearlyPriceId || 'none'}`;
3135

3236
try {
3337
// Check cache first
@@ -39,17 +43,19 @@ export async function fetchStripePriceDetails(): Promise<CachedPrices> {
3943
console.error('[STRIPE] Error reading from cache:', error);
4044
}
4145

42-
let monthlyPrice: PriceDetails | null = null;
43-
let yearlyPrice: PriceDetails | null = null;
46+
let managedMonthlyPrice: PriceDetails | null = null;
47+
let managedYearlyPrice: PriceDetails | null = null;
48+
let starterMonthlyPrice: PriceDetails | null = null;
49+
let starterYearlyPrice: PriceDetails | null = null;
4450

4551
try {
46-
// Fetch monthly price if ID exists
47-
if (monthlyPriceId) {
48-
const price = await stripe.prices.retrieve(monthlyPriceId, {
52+
// Fetch managed monthly price if ID exists
53+
if (managedMonthlyPriceId) {
54+
const price = await stripe.prices.retrieve(managedMonthlyPriceId, {
4955
expand: ['product'],
5056
});
5157

52-
monthlyPrice = {
58+
managedMonthlyPrice = {
5359
id: price.id,
5460
unitAmount: price.unit_amount,
5561
currency: price.currency,
@@ -61,13 +67,49 @@ export async function fetchStripePriceDetails(): Promise<CachedPrices> {
6167
};
6268
}
6369

64-
// Fetch yearly price if ID exists
65-
if (yearlyPriceId) {
66-
const price = await stripe.prices.retrieve(yearlyPriceId, {
70+
// Fetch managed yearly price if ID exists
71+
if (managedYearlyPriceId) {
72+
const price = await stripe.prices.retrieve(managedYearlyPriceId, {
6773
expand: ['product'],
6874
});
6975

70-
yearlyPrice = {
76+
managedYearlyPrice = {
77+
id: price.id,
78+
unitAmount: price.unit_amount,
79+
currency: price.currency,
80+
interval: price.recurring?.interval ?? null,
81+
productName:
82+
price.product && typeof price.product === 'object' && !price.product.deleted
83+
? price.product.name
84+
: null,
85+
};
86+
}
87+
88+
// Fetch starter monthly price if ID exists
89+
if (starterMonthlyPriceId) {
90+
const price = await stripe.prices.retrieve(starterMonthlyPriceId, {
91+
expand: ['product'],
92+
});
93+
94+
starterMonthlyPrice = {
95+
id: price.id,
96+
unitAmount: price.unit_amount,
97+
currency: price.currency,
98+
interval: price.recurring?.interval ?? null,
99+
productName:
100+
price.product && typeof price.product === 'object' && !price.product.deleted
101+
? price.product.name
102+
: null,
103+
};
104+
}
105+
106+
// Fetch starter yearly price if ID exists
107+
if (starterYearlyPriceId) {
108+
const price = await stripe.prices.retrieve(starterYearlyPriceId, {
109+
expand: ['product'],
110+
});
111+
112+
starterYearlyPrice = {
71113
id: price.id,
72114
unitAmount: price.unit_amount,
73115
currency: price.currency,
@@ -83,8 +125,10 @@ export async function fetchStripePriceDetails(): Promise<CachedPrices> {
83125
}
84126

85127
const priceData: CachedPrices = {
86-
monthlyPrice,
87-
yearlyPrice,
128+
managedMonthlyPrice,
129+
managedYearlyPrice,
130+
starterMonthlyPrice,
131+
starterYearlyPrice,
88132
fetchedAt: Date.now(),
89133
};
90134

apps/app/src/app/(app)/[orgId]/settings/billing/cancel-subscription-dialog.tsx

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ interface CancelSubscriptionDialogProps {
1717
onConfirm: () => void;
1818
isLoading?: boolean;
1919
currentPeriodEnd?: number;
20+
isTrialing?: boolean;
2021
}
2122

2223
export function CancelSubscriptionDialog({
@@ -25,6 +26,7 @@ export function CancelSubscriptionDialog({
2526
onConfirm,
2627
isLoading = false,
2728
currentPeriodEnd,
29+
isTrialing = false,
2830
}: CancelSubscriptionDialogProps) {
2931
const formattedDate = currentPeriodEnd
3032
? new Date(currentPeriodEnd * 1000).toLocaleDateString('en-US', {
@@ -38,24 +40,32 @@ export function CancelSubscriptionDialog({
3840
<Dialog open={open} onOpenChange={onOpenChange}>
3941
<DialogContent>
4042
<DialogHeader>
41-
<DialogTitle>Cancel Subscription</DialogTitle>
43+
<DialogTitle>Cancel {isTrialing ? 'Trial' : 'Subscription'}</DialogTitle>
4244
<DialogDescription className="space-y-3 pt-3">
43-
<p>Are you sure you want to cancel your subscription?</p>
44-
{formattedDate && (
45+
<p>Are you sure you want to cancel your {isTrialing ? 'trial' : 'subscription'}?</p>
46+
{isTrialing ? (
4547
<p className="text-sm">
46-
Your subscription will remain active until{' '}
47-
<span className="font-medium">{formattedDate}</span>. You can resume your
48-
subscription at any time before this date.
48+
If you cancel now, you'll lose access immediately. You can always start a new
49+
subscription later, but you won't get another free trial.
4950
</p>
51+
) : (
52+
formattedDate && (
53+
<p className="text-sm">
54+
Your subscription will remain active until{' '}
55+
<span className="font-medium">{formattedDate}</span>. You can resume your
56+
subscription at any time before this date.
57+
</p>
58+
)
5059
)}
5160
<p className="text-sm text-muted-foreground">
52-
You'll lose access to all premium features after your current billing period ends.
61+
You'll lose access to all premium features{' '}
62+
{isTrialing ? 'immediately' : 'after your current billing period ends'}.
5363
</p>
5464
</DialogDescription>
5565
</DialogHeader>
5666
<DialogFooter className="gap-2">
5767
<Button variant="ghost" onClick={() => onOpenChange(false)} disabled={isLoading}>
58-
Keep Subscription
68+
Keep {isTrialing ? 'Trial' : 'Subscription'}
5969
</Button>
6070
<Button
6171
variant="destructive"
@@ -65,7 +75,7 @@ export function CancelSubscriptionDialog({
6575
disabled={isLoading}
6676
>
6777
{isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
68-
Cancel Subscription
78+
Cancel {isTrialing ? 'Trial' : 'Subscription'}
6979
</Button>
7080
</DialogFooter>
7181
</DialogContent>

0 commit comments

Comments
 (0)