Below is a proposed solution architecture and a breakdown of implementation tasks to satisfy the requirement of two membership types (Premium and All Access), enforcing same‑domain invitations, and a three‑seat limit for the introductory All Access package.
Summary
We’ll introduce an All Access plan alongside the existing Premium plan, each represented in our system’s pricing/plan model. Invitations will be restricted by parsing the inviter’s email domain and allowing only users from that domain to join (preventing cross‑company sharing)
Auth0 Community
Auth0 Community
. Seat counts will be tracked per company, and for the All Access plan we’ll cap it at three active seats, enforced both in‑app and via Stripe’s per‑seat subscription quantity
Documentation
Stripe
. The All Access plan will be the only pay‑as‑you‑go package ($4,999), implemented as a Stripe subscription with quantity reflecting seats
Documentation
Node.js SaaS Boilerplate with React.js
.
Solution Design
A. Data Modeling & Migrations
Plan Table
Fields: id, name (Premium/AllAccess), price_id (Stripe), max_seats (nullable; set to 3 for All Access, null for Premium).
Company Record
Add email_domain and active_seats counters.
User
Foreign key to company_id; add a plan_id on company to know which plan they’re on.
B. Backend Services & API
Invite Endpoint (POST /companies/:id/invite)
Reads inviter’s domain, validates invitee’s email domain, checks seat availability (for All Access), then enqueues email.
Accept Invite Endpoint (POST /invites/:token/accept)
Verifies domain and seat count again, increments active_seats.
Seat Management
Endpoints or admin actions to free up seats (e.g. when a user is deactivated).
C. Payment Workflow
Stripe Product/Price Setup
Create via Dashboard or API: Price = $4,999, recurring or one‑time.
Subscription Creation
On first seat addition, call Stripe’s Subscription API with initial quantity 1.
Quantity Updates
When seats are added/removed, call stripe.subscriptions.update({ quantity }).
Webhook Handling
Listen for invoice.payment_failed, customer.subscription.updated, etc., to sync on‑chain state.
D. Frontend / UI Changes
Invitation Modal
Disable email input or show inline error if domain mismatch.
Seat Dashboard
Show current seat usage vs. max (e.g. “2 / 3 seats used”).
Billing Settings
Display plan details, next payment date, and seat adjustment controls (updating Stripe).
E. Testing & QA
Unit Tests
Domain parsing and validation logic.
Seat limit guard rails for both invite and accept flows.
Integration Tests
Simulate full invite → accept → seat count → Stripe quantity update.
E2E / UI Tests
Ensure the invite form blocks invalid domains; billing page updates quantities visually.
F. Documentation & Rollout
Developer Docs
Update API docs for new endpoints and data models.
Admin Guide
How to grant Premium vs. how to purchase All Access and manage seats.
Monitoring
Alerts on webhook failures or when a company hits the 3‑seat cap.
By following this design and task breakdown, you’ll ensure that only same‑domain users can join each team, that the All Access package is properly limited to three seats, and that billing aligns seamlessly with seat usage.
Your solution architecture looks comprehensive and well-thought-out. I'll implement a working prototype that demonstrates the core functionality you've described, focusing on the domain-restricted invitations, seat limits, and Stripe integration.
I've created a working prototype that implements the core functionality you described in your solution architecture. Here's a breakdown of what's included:
I've included a Prisma schema file that models the data structure you described, with tables for:
To fully implement this solution in production, you would need to:
The prototype provides a solid foundation that follows your architecture and can be extended with these additional features.
This generation may require the following integrations:
Please make sure to add the following environment variable to your project:
Great! Now that you've added the STRIPE_SECRET_KEY to your Vercel project, the Stripe integration in the code will work properly. Let me explain how the Stripe integration is implemented in the solution:
In the code I provided, the Stripe integration is primarily handled in the lib/actions.ts file:
Stripe Client Initialization:
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", {
apiVersion: "2023-10-16",
});Subscription Creation:
The createSubscription server action creates a new Stripe subscription with the specified plan and seat quantity:
export async function createSubscription(companyId: string, planId: string, seats = 1) {
// Create a Stripe subscription with the specified plan and quantity
const subscription = await stripe.subscriptions.create({
customer: "cus_example", // In production, get this from your database
items: [
{
price: "price_example", // In production, get this from your plan configuration
quantity: seats,
},
],
payment_behavior: "default_incomplete",
expand: ["latest_invoice.payment_intent"],
});
// Return client secret for payment confirmation
// ...
}Updating Subscription Quantity:
The updateSubscriptionQuantity server action updates the seat count in Stripe when users are added or removed:
export async function updateSubscriptionQuantity(subscriptionId: string, quantity: number) {
// Update the subscription quantity in Stripe
const subscription = await stripe.subscriptions.update(subscriptionId, {
items: [
{
id: "si_example", // In production, get this from your database
quantity,
},
],
});
// ...
}To fully implement the Stripe integration for your membership plans:
Create Stripe Products and Prices:
Update the Placeholder Values:
"cus_example" with actual customer IDs from your database"price_example" with your actual Stripe price ID"si_example" with the actual subscription item IDImplement Stripe Webhooks:
/api/webhooks/stripe)customer.subscription.updated, invoice.payment_succeeded, etc.Add Payment UI:
createSubscription to confirm paymentsBefore going to production, you should test your Stripe integration:
Use Stripe Test Mode:
Test Webhook Events:
Test Seat Management:
Would you like me to provide more detailed code for any specific part of the Stripe integration, such as the webhook handler or payment UI?
This generation may require the following integrations: