Stores: subscriptionstore

Manage plans and subscriptions with github.com/dracory/subscriptionstore.

github.com/dracory/subscriptionstore

subscriptionstore provides a complete data layer for plans and subscriptions. It wraps SQL persistence behind interfaces so you can manage billing tiers, trial status, renewals, and custom metadata through a consistent API.


Highlights

  • Plan & subscription entities – fluent getters/setters, metadata helpers, dirty tracking, soft-delete markers, and status helpers.
  • Interface-first design – stores and queries are defined via interfaces for easy testing and extension.
  • Query builders – filter by user, plan, status, date ranges, trial flags, pagination, ordering, and column selections.
  • Metadata support – JSON metas across plans and subscriptions for custom fields (limits, pricing data, flags).
  • Multi-database ready – uses Goqu + shared sb helpers to target SQLite, MySQL, PostgreSQL, etc.

Creating a Store

store, err := subscriptionstore.NewStore(subscriptionstore.NewStoreOptions{
    DB:                   db,
    PlanTableName:        "subscription_plan",
    SubscriptionTableName:"subscription",
    AutomigrateEnabled:   true,
    DebugEnabled:         false,
})
if err != nil {
    log.Fatal(err)
}
  • Automigration creates both plan and subscription tables with indexes.
  • Debug logging prints SQL for troubleshooting.

Working with Plans

plan := subscriptionstore.NewPlan().
    SetName("Pro").
    SetPrice("19.99").
    SetCurrency("USD").
    SetInterval("monthly").
    SetStatus(subscriptionstore.PLAN_STATUS_ACTIVE)

if err := store.PlanCreate(ctx, plan); err != nil {
    log.Fatal(err)
}

plan.SetDescription("Pro tier with advanced analytics")
if err := store.PlanUpdate(ctx, plan); err != nil {
    log.Fatal(err)
}
  • Plans support helper predicates (e.g., IsActive).
  • Metas enable custom limits, features, or entitlements.

Subscriptions

sub := subscriptionstore.NewSubscription().
    SetPlanID(plan.ID()).
    SetUserID(userID).
    SetStatus(subscriptionstore.SUBSCRIPTION_STATUS_ACTIVE).
    SetCurrentPeriodEnd(subscriptionstore.NowPlusInterval("monthly"))

if err := store.SubscriptionCreate(ctx, sub); err != nil {
    log.Fatal(err)
}

subs, err := store.SubscriptionList(ctx, subscriptionstore.NewSubscriptionQuery().
    SetUserID(userID).
    SetStatus(subscriptionstore.SUBSCRIPTION_STATUS_ACTIVE))
  • Track trials (SetTrialEndsAt), cancellation (SetCanceledAt), and auto-renewal metadata.
  • SubscriptionUpdate persists only dirty fields.

Querying

  • PlanQuery filters by status, price range, IDs, name like, etc.
  • SubscriptionQuery filters by user, plan, status, trial status, date ranges, and includes soft-deleted records when requested.
  • Use PlanCount, SubscriptionCount for pagination.

Metadata & Soft Deletion

  • SetMetas, Meta, UpsertMetas attach metadata for usage limits, upgrade prompts, or integration IDs.
  • Soft-delete helpers (PlanSoftDelete, SubscriptionSoftDelete) retain history while hiding from default queries.

  • Design Principles – revisit the shared store architecture.
  • Entities & Interfaces – learn how subscriptionstore leverages dataobject patterns.
  • Testing – repository includes SQLite-backed tests for realistic coverage.
  • Create Your Own Store – extend to billing integrations or custom lifecycle logic.