Skip to content

Commit

Permalink
Init paid plans model config (#2275)
Browse files Browse the repository at this point in the history
  • Loading branch information
PopDaph authored Oct 26, 2023
1 parent 8d1bd7e commit ae13d84
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 8 deletions.
2 changes: 2 additions & 0 deletions front/admin/init_plans.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { upsertFreePlans } from "@app/lib/plans/free_plans";
import { upsertProPlans } from "@app/lib/plans/pro_plans";

async function main() {
await upsertFreePlans();
await upsertProPlans();
process.exit(0);
}

Expand Down
5 changes: 5 additions & 0 deletions front/lib/models/plan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class Plan extends Model<

declare code: string; // unique
declare name: string;
declare stripeProductId: string | null;

// workspace limitations
declare maxMessages: number;
Expand Down Expand Up @@ -60,6 +61,10 @@ Plan.init(
type: DataTypes.STRING,
allowNull: false,
},
stripeProductId: {
type: DataTypes.STRING,
allowNull: true,
},
maxMessages: {
type: DataTypes.INTEGER,
allowNull: false,
Expand Down
38 changes: 38 additions & 0 deletions front/lib/plans/enterprise_plans.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Attributes } from "sequelize";

import { Plan } from "@app/lib/models";

export type PlanAttributes = Omit<
Attributes<Plan>,
"id" | "createdAt" | "updatedAt"
>;

/**
* We have 3 categories of plans:
* - Free: plans with no paid subscription.
* - Pro: plans with a paid subscription, not tailored. -> i.e. the same plan is used by all Pro workspaces.
* - Entreprise: plans with a paid subscription, tailored to the needs of the entreprise. -> i.e. we will have one plan per "Entreprise".
*
* This file about Entreprise plans.
* As entreprise plans are custom, we won't create them in this file, but directly from Poké.
*/

/**
* ENT_PLAN_FAKE is not subscribable and is only used to display the Enterprise plan in the UI (hence it's not stored on the db).
*/
export const ENT_PLAN_FAKE_CODE = "ENT_PLAN_FAKE_CODE";
export const ENT_PLAN_FAKE_DATA: PlanAttributes = {
code: ENT_PLAN_FAKE_CODE,
name: "Entreprise",
stripeProductId: null,
maxMessages: -1,
maxUsersInWorkspace: -1,
isSlackbotAllowed: true,
isManagedSlackAllowed: true,
isManagedNotionAllowed: true,
isManagedGoogleDriveAllowed: true,
isManagedGithubAllowed: true,
maxNbStaticDataSources: -1,
maxNbStaticDocuments: -1,
maxSizeStaticDataSources: 2, // 2MB
};
23 changes: 15 additions & 8 deletions front/lib/plans/free_plans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,26 @@ export type PlanAttributes = Omit<
>;

/**
* We have 2 FREE plans:
* - The FREE_TEST plan, a free plan with strong limitations, used until the user subscribes to a paid plan.
* - The FREE_UPGRADED plan, a free plan with no limitations that won't be users for users that are not Dust once we have paid plans.
* We have 3 categories of plans:
* - Free: plans with no paid subscription.
* - Pro: plans with a paid subscription, not tailored. -> i.e. the same plan is used by all Pro workspaces.
* - Entreprise: plans with a paid subscription, tailored to the needs of the entreprise. -> i.e. we will have one plan per "Entreprise".
*
* This file about Free plans.
*/

// Current free plans:
export const FREE_TEST_PLAN_CODE = "FREE_TEST_PLAN";
export const FREE_UPGRADED_PLAN_CODE = "FREE_UPGRADED_PLAN";

/**
* Our TEST plan is our default plan, when no subscription is ON.
* It is the only plan not stored in the database.
* FREE_TEST plan is our default plan: this is the plan used by all workspaces until they subscribe to a plan.
* It is not stored in the database (as we don't create a subsription).
*/
export const FREE_TEST_PLAN_CODE = "FREE_TEST_PLAN";
export const FREE_TEST_PLAN_DATA: PlanAttributes = {
code: FREE_TEST_PLAN_CODE,
name: "Test",
stripeProductId: null,
maxMessages: 100,
maxUsersInWorkspace: 1,
isSlackbotAllowed: false,
Expand All @@ -35,13 +42,13 @@ export const FREE_TEST_PLAN_DATA: PlanAttributes = {

/**
* Other FREE plans are stored in the database.
* We never remove anything from this list, we only add new plans and run a migration to create new subscriptions for them.
* We can update existing plans or add new one but never remove anything from this list.
*/
export const FREE_UPGRADED_PLAN_CODE = "FREE_UPGRADED_PLAN";
const FREE_PLANS_DATA: PlanAttributes[] = [
{
code: FREE_UPGRADED_PLAN_CODE,
name: "Free Trial",
stripeProductId: null,
maxMessages: -1,
maxUsersInWorkspace: -1,
isSlackbotAllowed: true,
Expand Down
79 changes: 79 additions & 0 deletions front/lib/plans/pro_plans.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Attributes } from "sequelize";

import { Plan } from "@app/lib/models";

export type PlanAttributes = Omit<
Attributes<Plan>,
"id" | "createdAt" | "updatedAt"
>;

/**
* We have 3 categories of plans:
* - Free: plans with no paid subscription.
* - Pro: plans with a paid subscription, not tailored. -> i.e. the same plan is used by all Pro workspaces.
* - Entreprise: plans with a paid subscription, tailored to the needs of the entreprise. -> i.e. we will have one plan per "Entreprise".
*
* This file about Pro plans.
*/

// Current pro plans:
export const PRO_PLAN_MAU_29_CODE = "PRO_PLAN_MAU_29";
export const PRO_PLAN_FIXED_1000_CODE = "PRO_PLAN_FIXED_1000";

/**
* Paid plans are stored in the database.
* We can update existing plans or add new one but never remove anything from this list.
* Entreprise custom plans will be created from Poké.
*/
const PRO_PLANS_DATA: PlanAttributes[] = [
{
code: "PRO_PLAN_MAU_29",
name: "Pro",
stripeProductId: "prod_OtB9SOIwFyiQnl",
maxMessages: -1,
maxUsersInWorkspace: 500,
isSlackbotAllowed: true,
isManagedSlackAllowed: true,
isManagedNotionAllowed: true,
isManagedGoogleDriveAllowed: true,
isManagedGithubAllowed: true,
maxNbStaticDataSources: -1,
maxNbStaticDocuments: -1,
maxSizeStaticDataSources: 2, // 2MB
},
{
code: "PRO_PLAN_FIXED_1000",
name: "Pro Fixed",
stripeProductId: "prod_OtBhelMswszehT",
maxMessages: -1,
maxUsersInWorkspace: 50,
isSlackbotAllowed: true,
isManagedSlackAllowed: true,
isManagedNotionAllowed: true,
isManagedGoogleDriveAllowed: true,
isManagedGithubAllowed: true,
maxNbStaticDataSources: -1,
maxNbStaticDocuments: -1,
maxSizeStaticDataSources: 2, // 2MB
},
];

/**
* Function to call when we edit something in FREE_PLANS_DATA to update the database. It will create or update the plans.
*/
export const upsertProPlans = async () => {
for (const planData of PRO_PLANS_DATA) {
const plan = await Plan.findOne({
where: {
code: planData.code,
},
});
if (plan === null) {
await Plan.create(planData);
console.log(`Pro plan ${planData.code} created.`);
} else {
await plan.update(planData);
console.log(`Pro plan ${planData.code} updated.`);
}
}
};

0 comments on commit ae13d84

Please sign in to comment.