Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subscription Plan Selection #229

Closed
jpaulet opened this issue Sep 5, 2024 · 3 comments
Closed

Subscription Plan Selection #229

jpaulet opened this issue Sep 5, 2024 · 3 comments
Assignees

Comments

@jpaulet
Copy link
Member

jpaulet commented Sep 5, 2024

To extend the subscription model and premium features into a comprehensive system that controls organizational limits, voting process types, and specific voting features, we need to carefully design both the database schema and the logic for backend checks. Below is a detailed breakdown of how this extended model will work, including the structure for a "subscription" object in the database, how it relates to organizational parameters, and integration with Stripe for payment and plan management.

Extended Subscription Model Structure

1. Subscription Object Structure in the Database
The subscription object will have three main sections: organization, votingTypes, and features. Each section will control different aspects of the SaaS platform based on the subscribed plan.

{
    "plan": "pro",
    "stripePlanId": "plan_xyz123",    // Stripe plan ID for payment and plan management
    "organization": {
        "memberships": 5,     // Maximum number of members or admins
        "subOrgs": 3,         // Maximum number of sub-organizations
        "maxProcesses": 10,   // Maximum number of voting processes
        "max_census_size": 10000,   // Maximum number of voters (census size) for this plan
        "customURL": true     // Whether a custom URL for the voting page is allowed
    },
    "votingTypes": {
        "single": true,                   // Simple single-choice voting allowed
        "multiple": true,               // Multiple-choice voting allowed
        "approval": true,              // Approval voting allowed
        "cumulative": false,         // Cumulative voting not allowed
        "ranked": false,                // Ranked voting not allowed
        "weighted": false             // Weighted voting not allowed
    },
    "features": {
        "personalization": true,         // Voting page customization allowed
        "emailReminder": true,         // Email reminders allowed
        "smsNotification": true,        // SMS notifications allowed
        "whiteLabel": true,                // White-label voting page allowed
        "liveStreaming": false,         // Live results streaming not allowed
        // ... Other feature controls
    }
}

2. Update Organization Object Structure
Each organization object in the database will reference a subscription object and include additional parameters specific to that organization.

{
   "address": "0x...",
   "name": "Test Organization",
   "type": "community",
   "description": "My amazing testing organization",
   "size": 10,
   "color": "#ff0000",
   "logo": "https://[...].png",
   "subdomain": "mysubdomain",
    "timezone": "GMT+2",
    "active": true,
    "parents": [],
    
    //Extra Fields
    "subscriptionPlan": "pro",                        // Current subscribed plan
    "subscriptionId": "sub_xyz123",             // Reference to the subscription object
    "currentMembers": 4,                              // Current number of members/admins
    "currentSubOrgs": 2,                               // Current number of sub-organizations
    "currentProcesses": 8,                             // Current number of active processes
    "currentSMSUsed": 500,                         // Number of SMS notifications used
    "currentEmailRemindersUsed": 3000, // Number of email reminders used
    "currentCensusSize": 8000,                   // Current census size
    "stripeCustomerId": "cus_xyz456",      // Stripe customer ID for billing
    "yearlyConsumedTokens": 1000,
    "monthlyConsumedTokens": 100,
    "created_at": "10-10-2024 10:10:10",
    "subscribed_at": "10-10-2024 10:10:10",  // Date of the first subscription (maybe we don't need to store in the BBDD)
    "renewal_at": "10-10-2025 10:10:10",   // Date of the next renewal period (maybe we don't need to store in the BBDD)
}

Backend Logic for Subscription Checks

The backend needs to perform checks at multiple points to enforce the limits set by the subscription plan. Here's how it would be structured:

1. Check Organizational Limits:

  • Before adding a new member or admin, the backend checks if currentMembers < subscriptions.organization.memberships.
  • Before creating a new sub-organization, check if currentSubOrgs < subscriptions.organization.subOrgs.
  • Before starting or creating a new process, check if currentProcesses < subscriptions.organization.maxProcesses.
  • Check currentCensusSize to enforce voter limits when a new process is created.

2. Check Voting Process Types:

  • When setting up a new voting process, check if the selected votingType (e.g., ranked, cumulative) is allowed under subscriptions.votingTypes.

3. Check Voting Features:
During process configuration, check the desired features (e.g., personalization, emailReminder) against subscriptions.features to ensure they are enabled.

Integration with Stripe for Payment and Plan Management

1. Stripe Plan Integration:

  • Each subscription plan corresponds to a plan in Stripe (e.g., stripePlanId).
  • When an organization subscribes or upgrades, the backend will create or update a subscription in Stripe using the stripeCustomerId and stripePlanId.
  • Stripe webhooks can be used to handle events like subscription renewals, cancellations, or changes. These events can trigger updates to the subscription object and organization object in the database.

2. Syncing Stripe Data with Database:

  • When a payment is successful or a plan is upgraded, the backend updates the organization’s subscription data and reflects the new limits and features.
  • The backend will regularly sync with Stripe to ensure that the subscription data in the database is up to date.
@jpaulet jpaulet mentioned this issue Sep 17, 2024
27 tasks
selankon added a commit to vocdoni/ui-scaffold that referenced this issue Oct 3, 2024
This PR implements some new necessary logic in order to follow new saas requirements for process creation. Related:

vocdoni/interoperability#210
vocdoni/interoperability#229

- Adds a footer on process creation
- Adds a store draft button
- Implement new steps when is saas
- Add saas extra features on the form 
- Mock `useAccountPlan`, simulating a call that gives for an organization which features a plan has activated.
- Add some minimum styles to try it easier

## Important!

This PR **does not** implement:

- New styles
- Some buttons logics (for example save draft or upgrade plan)
- New modals
- Logic to store the election on the saas backend (this need some meetings). For now, the SDK and the remote signer are able to create an election on the backend as before.
emmdim added a commit to vocdoni/saas-backend that referenced this issue Nov 12, 2024
* Upgrade Github CI workflows
* Adds plan types and db setters/getters
* Enables reading plan from a json file in the root folder and update any previous subscriptions existing in the DB
* Emembeded plans json in `assets/plans.json`
* Adds `GET /plans` and  `GET /plans/{planID}`
* Implements default subscription plan
* Implements `GET /organizations/{address}/subscription`
* Implements first version of stripe webhook handler that updates subscription
* Adds flags "stripeApiSecret" and "stripeWebhookSecret"
* Makes user phone Mongo Index a sparse index, as way to accept null values
* Creates subscriptions package responsible for checking user permissions for Transactions
* Implements initial version subscriiption permission, using the censussize
* Updates Docs
* Allows only org admins to read organization subscription info
* Updates stripe API and subscription IDs
* Updates go packages

More info on:
#17 (comment)
vocdoni/interoperability#229
@jpaulet jpaulet added this to the SaaS Soft Launch milestone Dec 10, 2024
@jpaulet
Copy link
Member Author

jpaulet commented Jan 7, 2025

Right now we cannot upgrade a plan (only the tier). We should look in the dashboard how to manage this upgrade flow.

Also, when canceling the subscription, the organization don't show any subscription. We should show take a look how to do the cancel/downgrade (show the current plan until the plan subscription ends, even when canceling) or show the Free plan subscription.

@jpaulet
Copy link
Member Author

jpaulet commented Jan 7, 2025

To ensure the organization can perform the desired action, the backend should implement the following checks and controls. These checks can be categorized into basic eligibility, feature-specific, and quota-related validations:

1. Subscription and Plan Validations

Subscription Status:

  • Verify the organization has an active subscription.
  • Check if the subscription is not expired (compare the current date with the endDate in the subscription record).

Plan-Specific Features:

  • Confirm the requested action is allowed under the organization's subscription plan.For example, if the plan allows ranked-choice voting or custom branding, ensure the requested feature matches the allowed capabilities.

Quota Limitations:

  • Verify that the organization has not exceeded any applicable quotas:
  • Maximum census size: Check the number of voters in the draft or election against the limit for the subscription plan.
  • Number of ongoing elections: Ensure the organization has not exceeded the allowed number of active elections under their plan.
  • Monthly/annual limits: Track actions such as the number of elections created or notifications sent, ensuring these are within the plan's allowance.

Add-On Features:

  • If certain features are pay-per-use or require separate purchase (e.g., advanced reporting, SMS notifications), confirm the feature is enabled or the organization has sufficient credits.

2. Role-Based Access Control (RBAC)

Admin Permissions:

  • Verify the requesting user has the necessary role (e.g., "Admin" or "Election Manager") to perform the action.
  • Check if the role explicitly grants access to manage specific resources (e.g., create/delete elections, manage census, change organization settings).

Scoped Permissions:

  • For organizations with sub-organizations, confirm the admin has permissions for the specific sub-organization they are managing.
  • Enforce separation of concerns by limiting access to only the resources within their scope.

3. Resource Ownership and Availability

Organization Ownership:

  • Validate that the resource being managed (e.g., draft, election, census) belongs to the requesting organization.

@jpaulet jpaulet removed this from the SaaS Soft Launch milestone Jan 22, 2025
@jpaulet
Copy link
Member Author

jpaulet commented Feb 4, 2025

Closing those 3 related issues:

#229
#227
#240

For now it seems to work properly. If we find any bug we will open an specific task for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants