Added backend limits

This commit is contained in:
blaisadmin
2026-05-30 15:43:38 -04:00
parent c6dc5b22b8
commit 505a9b8496
2 changed files with 46 additions and 8 deletions
+38
View File
@@ -94,6 +94,7 @@ import {
getMembershipForUser, getMembershipForUser,
getNextWorkspaceId, getNextWorkspaceId,
getWorkspaceById, getWorkspaceById,
getWorkspaceBirdCount,
getWorkspaceTotalBirdCount, getWorkspaceTotalBirdCount,
listOwnedWorkspacesByOwnerEmail, listOwnedWorkspacesByOwnerEmail,
listRescueWorkspacesForAdmin, listRescueWorkspacesForAdmin,
@@ -951,6 +952,26 @@ const subscriptionAllowsWrite = (workspace: WorkspaceRow) => {
return workspace.subscription_status === 'active' || workspace.subscription_status === 'trialing'; return workspace.subscription_status === 'active' || workspace.subscription_status === 'trialing';
}; };
const getBillingPlanBirdLimit = (billingPlan: BillingPlan) => {
if (billingPlan === 'rescue_free') {
return null;
}
if (billingPlan === 'household_basic') {
return 4;
}
if (billingPlan === 'household_plus') {
return 10;
}
if (billingPlan === 'household_macaw') {
return 16;
}
return null;
};
const mapStripeSubscriptionStatus = (status: Stripe.Subscription.Status): SubscriptionStatus => { const mapStripeSubscriptionStatus = (status: Stripe.Subscription.Status): SubscriptionStatus => {
if (status === 'active' || status === 'trialing' || status === 'past_due' || status === 'canceled' || status === 'unpaid') { if (status === 'active' || status === 'trialing' || status === 'past_due' || status === 'canceled' || status === 'unpaid') {
return status; return status;
@@ -3118,6 +3139,23 @@ app.post('/api/birds', requireAuth, requireWriteAccess, requireWorkspaceRole(['o
let uploadedObjectKeyToCleanup: string | null = null; let uploadedObjectKeyToCleanup: string | null = null;
try { try {
const birdLimit = getBillingPlanBirdLimit(req.auth!.workspace.billing_plan);
if (birdLimit !== null) {
const currentBirdCount = await getWorkspaceBirdCount(req.auth!.workspace.id);
if (currentBirdCount >= birdLimit) {
res.status(409).json({
error: 'This flock has reached the bird limit for the selected plan. Upgrade the flock subscription or memorialize a bird before adding another.',
code: 'billing_plan_bird_limit_reached',
birdLimit,
currentBirdCount,
billingPlan: req.auth!.workspace.billing_plan,
});
return;
}
}
const birdId = crypto.randomUUID(); const birdId = crypto.randomUUID();
const photoStorage = await resolveBirdPhotoStorage({ const photoStorage = await resolveBirdPhotoStorage({
birdId, birdId,
+8 -8
View File
@@ -1012,7 +1012,7 @@ const formatBillingPlanCapacity = (billingPlan: BillingPlan) => {
} }
if (billingPlan === 'household_plus') { if (billingPlan === 'household_plus') {
return 'Permits 5 to 9 birds in the flock.'; return 'Permits 5 to 10 birds in the flock.';
} }
if (billingPlan === 'household_macaw') { if (billingPlan === 'household_macaw') {
@@ -1024,11 +1024,11 @@ const formatBillingPlanCapacity = (billingPlan: BillingPlan) => {
const formatBillingPlanDropdownLabel = (billingPlan: HouseholdBillingPlan) => { const formatBillingPlanDropdownLabel = (billingPlan: HouseholdBillingPlan) => {
if (billingPlan === 'household_basic') { if (billingPlan === 'household_basic') {
return 'Conure (4 birds)'; return 'Conure (up to 4 birds)';
} }
if (billingPlan === 'household_plus') { if (billingPlan === 'household_plus') {
return 'Indian Ringneck (5-9 birds)'; return 'Indian Ringneck (5-10 birds)';
} }
if (billingPlan === 'household_macaw') { if (billingPlan === 'household_macaw') {
@@ -1066,7 +1066,7 @@ const formatBillingPlanBirdLimit = (billingPlan: BillingPlan) => {
} }
if (billingPlan === 'household_plus') { if (billingPlan === 'household_plus') {
return '9'; return '10';
} }
if (billingPlan === 'household_macaw') { if (billingPlan === 'household_macaw') {
@@ -6451,8 +6451,8 @@ function App() {
}) })
} }
> >
<option value="household_basic">Conure (4 birds)</option> <option value="household_basic">Conure (up to 4 birds)</option>
<option value="household_plus">Indian Ringneck (5-9 birds)</option> <option value="household_plus">Indian Ringneck (5-10 birds)</option>
<option value="household_macaw">African Grey (11-16 birds)</option> <option value="household_macaw">African Grey (11-16 birds)</option>
<option value="household_hyacinth_macaw">Hyacinth Macaw (17+)</option> <option value="household_hyacinth_macaw">Hyacinth Macaw (17+)</option>
</select> </select>
@@ -6590,8 +6590,8 @@ function App() {
}) })
} }
> >
<option value="household_basic">Conure (4 birds)</option> <option value="household_basic">Conure (up to 4 birds)</option>
<option value="household_plus">Indian Ringneck (5-9 birds)</option> <option value="household_plus">Indian Ringneck (5-10 birds)</option>
<option value="household_macaw">African Grey (11-16 birds)</option> <option value="household_macaw">African Grey (11-16 birds)</option>
<option value="household_hyacinth_macaw">Hyacinth Macaw (17+)</option> <option value="household_hyacinth_macaw">Hyacinth Macaw (17+)</option>
</select> </select>