mirror of
https://github.com/warmbly/warmbly.git
synced 2026-09-12 08:04:41 +00:00
150 lines
5.1 KiB
Go
150 lines
5.1 KiB
Go
package seed
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
func intPtr(v int) *int { return &v }
|
|
|
|
// seedDurations inserts the duration rows our seeded plans reference. The
|
|
// migration that adds the durations table doesn't seed it, so we do it here
|
|
// to keep the seed self-contained.
|
|
func seedDurations(ctx context.Context, pool *pgxpool.Pool, _ *Result) error {
|
|
rows := []struct {
|
|
id string
|
|
title string
|
|
}{
|
|
{DurationMonthID.String(), "month"},
|
|
{DurationYearID.String(), "year"},
|
|
{DurationLifetimeID.String(), "lifetime"},
|
|
}
|
|
for _, r := range rows {
|
|
_, err := pool.Exec(ctx, `
|
|
INSERT INTO durations (id, title) VALUES ($1, $2)
|
|
ON CONFLICT (id) DO NOTHING
|
|
`, r.id, r.title)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func seedPlans(ctx context.Context, pool *pgxpool.Pool, r *Result) error {
|
|
type plan struct {
|
|
id uuid.UUID
|
|
name string
|
|
maxContacts int64
|
|
dailyEmails int
|
|
ai bool
|
|
accountLimit int
|
|
price float64
|
|
discounted float64
|
|
duration uuid.UUID
|
|
savings int
|
|
public bool
|
|
dedicatedWorkers int
|
|
dailyCampaignLimit *int
|
|
maxCampaigns *int
|
|
maxActiveCampaigns *int
|
|
maxTeamMembers *int
|
|
maxEmailAccounts *int
|
|
monthlyCredits int
|
|
}
|
|
|
|
plans := []plan{
|
|
{
|
|
id: PlanFreeTrialID, name: "Free Trial", maxContacts: 100, dailyEmails: 20,
|
|
ai: false, accountLimit: 2, price: 0, discounted: 0,
|
|
duration: DurationMonthID, savings: 0, public: false,
|
|
dedicatedWorkers: 0, dailyCampaignLimit: intPtr(20),
|
|
maxCampaigns: intPtr(2), maxActiveCampaigns: intPtr(1),
|
|
maxTeamMembers: intPtr(1), maxEmailAccounts: intPtr(2),
|
|
monthlyCredits: 50,
|
|
},
|
|
// Paid plans mirror the pricing page: mailboxes are unlimited on every
|
|
// one (max_email_accounts nil, the fair-use allowance derives from the
|
|
// daily sends), and the daily sends are the marketed numbers.
|
|
{
|
|
id: PlanStarterID, name: "Starter", maxContacts: 1_000, dailyEmails: 150,
|
|
ai: false, accountLimit: 0, price: 29, discounted: 29,
|
|
duration: DurationMonthID, savings: 0, public: true,
|
|
dedicatedWorkers: 0, dailyCampaignLimit: intPtr(150),
|
|
maxCampaigns: intPtr(5), maxActiveCampaigns: intPtr(2),
|
|
maxTeamMembers: intPtr(2), maxEmailAccounts: nil,
|
|
monthlyCredits: 250,
|
|
},
|
|
{
|
|
id: PlanProMonthlyID, name: "Grow", maxContacts: 25_000, dailyEmails: 3_000,
|
|
ai: true, accountLimit: 0, price: 89, discounted: 89,
|
|
duration: DurationMonthID, savings: 0, public: true,
|
|
dedicatedWorkers: 0, dailyCampaignLimit: intPtr(3_000),
|
|
maxCampaigns: intPtr(50), maxActiveCampaigns: intPtr(20),
|
|
maxTeamMembers: intPtr(10), maxEmailAccounts: nil,
|
|
monthlyCredits: 2_000,
|
|
},
|
|
{
|
|
id: PlanProYearlyID, name: "Grow (Annual)", maxContacts: 25_000, dailyEmails: 3_000,
|
|
ai: true, accountLimit: 0, price: 1068, discounted: 852,
|
|
duration: DurationYearID, savings: 20, public: true,
|
|
dedicatedWorkers: 0, dailyCampaignLimit: intPtr(3_000),
|
|
maxCampaigns: intPtr(50), maxActiveCampaigns: intPtr(20),
|
|
maxTeamMembers: intPtr(10), maxEmailAccounts: nil,
|
|
monthlyCredits: 2_000,
|
|
},
|
|
{
|
|
id: PlanEnterpriseID, name: "Business", maxContacts: 1_000_000, dailyEmails: 15_000,
|
|
ai: true, accountLimit: 0, price: 329, discounted: 329,
|
|
duration: DurationMonthID, savings: 0, public: true,
|
|
dedicatedWorkers: 1, dailyCampaignLimit: intPtr(15_000),
|
|
maxCampaigns: nil, maxActiveCampaigns: nil,
|
|
maxTeamMembers: nil, maxEmailAccounts: nil,
|
|
monthlyCredits: 25_000,
|
|
},
|
|
}
|
|
|
|
for _, p := range plans {
|
|
_, err := pool.Exec(ctx, `
|
|
INSERT INTO plans (
|
|
id, name, max_contacts, daily_emails, ai_generation, account_limit,
|
|
price, discounted_price, duration_id, savings, public,
|
|
dedicated_workers, daily_campaign_limit,
|
|
max_campaigns, max_active_campaigns, max_team_members, max_email_accounts,
|
|
monthly_credits
|
|
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18)
|
|
ON CONFLICT (id) DO UPDATE SET
|
|
name = EXCLUDED.name,
|
|
max_contacts = EXCLUDED.max_contacts,
|
|
daily_emails = EXCLUDED.daily_emails,
|
|
ai_generation = EXCLUDED.ai_generation,
|
|
account_limit = EXCLUDED.account_limit,
|
|
price = EXCLUDED.price,
|
|
discounted_price = EXCLUDED.discounted_price,
|
|
duration_id = EXCLUDED.duration_id,
|
|
savings = EXCLUDED.savings,
|
|
public = EXCLUDED.public,
|
|
dedicated_workers = EXCLUDED.dedicated_workers,
|
|
daily_campaign_limit = EXCLUDED.daily_campaign_limit,
|
|
max_campaigns = EXCLUDED.max_campaigns,
|
|
max_active_campaigns = EXCLUDED.max_active_campaigns,
|
|
max_team_members = EXCLUDED.max_team_members,
|
|
max_email_accounts = EXCLUDED.max_email_accounts,
|
|
monthly_credits = EXCLUDED.monthly_credits,
|
|
updated_at = NOW()
|
|
`,
|
|
p.id, p.name, p.maxContacts, p.dailyEmails, p.ai, p.accountLimit,
|
|
p.price, p.discounted, p.duration, p.savings, p.public,
|
|
p.dedicatedWorkers, p.dailyCampaignLimit,
|
|
p.maxCampaigns, p.maxActiveCampaigns, p.maxTeamMembers, p.maxEmailAccounts,
|
|
p.monthlyCredits,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|