Collection setup for a basic SaaS using stripe

I’m setting up a basic SaaS. This will be a node.js app backed by mongoDB/graphql.

I’m just looking for some ideas on setting up my collections/types. How have you done it in the past? Anything you didn’t track that you wished you tracked? Anything you tracked that was a waste of time tracking? Any good naming conventions for collections? Do you store the subscription status on the a User object? How many webhook endpoints did you create for stripe to talk to? Looking for tips along those lines.

My app will start with just one basic subscription, but could move to a three tiered approach in the future.

1 Like

We track everything - its invaluable for debugging:

  • invoices
  • subscriptions
  • log every webhook stripe sends us

we set up a single webhook that receives every event from stripe and processes it accordingly. There’s no real difference between a single subscription and multiple tiers of subscriptions, beyond your application logic of what to do in that scenario. e.g., you may grant different permissions based on different product ID’s from stripe.

We track the customer object on the user, but the subscription object in its own collection. This allows a user to transfer a subscription to another user (which is critical for us as organisations pay for a subscription, not users). If you have a 1:1 mapping of users to subscriptions, you could track subscriptions on the user.

Just be weary of how much data you are storing on the Meteor.users collection. If you store transaction logs on the user object then it will grow indefinitely as long as the user keeps resubscribing.

Many meteor packages, including some core packages, call Meteor.user() or Meteor.users.find/findOne() to get the full user object even if they don’t need all of it. E.g. Meteor.user().profile.name on the server fetches the full user object from the db. Very wasteful. The accounts package does something similar on every user log in/out.

See my bug report here (unlikely to be fixed) and another feature suggestion here.

I didn’t realise this until it was too late: one of my app logs every user’s interaction and stores it on the user object - which is the logical (and recommended) place for it. Every users object quickly became huge and the db bandwidth was unnecessarily large and slow.

1 Like

That section definitely needs editing. Can you make a pull request with the same warning you’ve posted here?

1 Like

I would rather create a PR to fix the underlying issue, but would it have any chance of being merged? I’ve done it myself with my own forked accounts-base package.

There are many internal fixes which are trivial and non-breaking. The only real problem is with the login/out callbacks where it’s not known which fields are required by each callback. With my fix I’ve introduced my own Accounts.callbackFields object so that the login/out callbacks only fetch a limited set of fields. A better solution would be for the callback registration to specify which fields are required. Either way this is introducing new public API which is unlikely to be accepted for what is considered to be an edge case (I see my bug as recently been labelled ‘Impact:few’ which I disagree with - who doesn’t store extra data on the user object?)