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

feat: initial spike on referrals service #1

Merged
merged 12 commits into from
Nov 25, 2024
Merged

feat: initial spike on referrals service #1

merged 12 commits into from
Nov 25, 2024

Conversation

travis
Copy link
Member

@travis travis commented Nov 8, 2024

extracted from original implementation in storacha/console#142

This is a very simple REST service built as a Cloudflare worker. I've extracted it from its original implementation because I need to to be a scheduler as well, and that isn't well supported by the next-on-pages deployment style we're using in Next.js.

Users can create "refcodes" by email, look up "refcodes" and "referredby" by email and look up "referrals" by refcode. There is no authorization - this allows the service to work for unauthenticated users, but does mean that anyone can look up refcodes, referrals and referredBy for any email address - we only ever leak lists of refcodes and metadata about them, so I don't think this is too serious a leak, and some level of anonymous interaction is required to meet product requirements, but I do think we should move some of this into an authenticated context (ie, behind UCAN invocations) if we decide to keep scaling this functionality out.

Referral System Database Design

Two tables are used: users and referrals. users is used to store refcodes for users (identified by email address). referrals is used to record the refcode used by a user (identified by email address) during signup. Separate tables are used to avoid mutating rows in the database - a simple, immutable system is generally easier to maintain and reason about and while immutability of database tables isn't a hard requirement, it is a property this design strives to maintain.

Operational Notes

We also introduce a set of scripts prefixed with db:local that make it relatively simple to maintain a local D1 database for development.

TODO

  • add GitHub workflow files to push to Cloudflare
  • configure production (and staging?) environment(s)
  • finish "credits and conversions" cronjob

extracted from original implementation in storacha/console#142
Copy link
Member

@alanshaw alanshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the plan for what happens when a user actually logs in and selects a payment plan? Where do they add the refcode? How do we verify the refcode is correct and apply the discount?

I'm concerned that this actually needs to be integrated with w3infra rather than a separate thing...

refcode TEXT UNIQUE,
referred_at DATETIME DEFAULT CURRENT_TIMESTAMP,
selected_plan TEXT,
rewarded BOOLEAN DEFAULT false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work - is there some external process that's updating it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep exactly - I have the beginnings of a cronjob in this PR that will go look at Stripe and update these referrals after we've granted the referrer credits.

@travis
Copy link
Member Author

travis commented Nov 22, 2024

ah right sorry, should have documented this better:

I don't understand the plan for what happens when a user actually logs in and selects a payment plan?

We're using Stripe "Free Trials" (particularly for their handling of local regulatory issues around "free trials") to give people a discount. This means that all we need to do to give them a discount is to show them a different pricing table with free trials enabled

Where do they add the refcode?

It's attached to the referral URL and we grab it from there. I'm also going to add a form on the pricing page that lets them manually enter a code.

How do we verify the refcode is correct and apply the discount?

At the moment we don't verify the refcode is correct, but we can check it and probably should once we add a form on the pricing page. The thing is, if a user wants to generate a refcode they can just go use a fake email address to do that, so checking doesn't really improve our security posture at all, it just makes it a tiny bit harder to get a free trial in this case. From a user experience perspective I think it's weird to just let people type anything into the form on the pricing page, so I will definitely check it there, but I'm not sure it provides much tangible benefit otherwise.

One thing we could do in the short term is make refcode a foreign key in the referrals field to prevent people from creating referrals with invalid refcodes. We already only show the free trial UI to users with an actual "referral" in the DB, so this would just work as expected once we made the DB change (and probably a corresponding API-level change to get the error codes right)

@travis
Copy link
Member Author

travis commented Nov 25, 2024

I'm going to merge this to get it to staging so we can test the other two pieces of this, but I would like to come back to this review before we ship to prod!

@travis travis merged commit e547796 into main Nov 25, 2024
1 check passed
travis added a commit to storacha/console that referenced this pull request Dec 3, 2024
### Summary

This PR spikes out a referral system that stores data in Cloudflare's
D1. It allows anonymous or logged-in users to create referral codes
associated with their email addresses, and records the referral code a
user used to sign up for an account. It does not implement the discounts
and other rewards associated with the referral system - these are
expected to be handled manually in the first released version and
implemented as automated systems later, so are a non-goal of this PR.

### Referrals service

The referrals service has been extracted to its own worker:

storacha/referrals-service#1

### User Experience

The UX is just about dialed in - need to do a pass on the copy and some
minor layout stuff, but if you have any thoughts on the big picture now
is a great time to chime in!

<img width="1626" alt="Screenshot 2024-11-05 at 4 01 18 PM"
src="https://github.com/user-attachments/assets/cf1fb92d-94fa-4a27-a751-310dd9088cd7">
<img width="1223" alt="Screenshot 2024-11-05 at 4 00 10 PM"
src="https://github.com/user-attachments/assets/5d0ddc1c-53bc-4c7c-9c7a-8f15d65ee7c1">
<img width="1222" alt="Screenshot 2024-11-05 at 4 00 20 PM"
src="https://github.com/user-attachments/assets/a637bb4f-09d5-4959-af92-21a2eea2affc">

<img width="1414" alt="Screenshot 2024-11-05 at 5 57 42 PM"
src="https://github.com/user-attachments/assets/bbe765f4-ef09-4d54-a1f1-588e50d7524c">

---------

Co-authored-by: Vicente Olmedo <vicente.olmedo@gmail.com>
fforbeck pushed a commit to storacha/upload-service that referenced this pull request Feb 5, 2025
### Summary

This PR spikes out a referral system that stores data in Cloudflare's
D1. It allows anonymous or logged-in users to create referral codes
associated with their email addresses, and records the referral code a
user used to sign up for an account. It does not implement the discounts
and other rewards associated with the referral system - these are
expected to be handled manually in the first released version and
implemented as automated systems later, so are a non-goal of this PR.

### Referrals service

The referrals service has been extracted to its own worker:

storacha/referrals-service#1

### User Experience

The UX is just about dialed in - need to do a pass on the copy and some
minor layout stuff, but if you have any thoughts on the big picture now
is a great time to chime in!

<img width="1626" alt="Screenshot 2024-11-05 at 4 01 18 PM"
src="https://github.com/user-attachments/assets/cf1fb92d-94fa-4a27-a751-310dd9088cd7">
<img width="1223" alt="Screenshot 2024-11-05 at 4 00 10 PM"
src="https://github.com/user-attachments/assets/5d0ddc1c-53bc-4c7c-9c7a-8f15d65ee7c1">
<img width="1222" alt="Screenshot 2024-11-05 at 4 00 20 PM"
src="https://github.com/user-attachments/assets/a637bb4f-09d5-4959-af92-21a2eea2affc">

<img width="1414" alt="Screenshot 2024-11-05 at 5 57 42 PM"
src="https://github.com/user-attachments/assets/bbe765f4-ef09-4d54-a1f1-588e50d7524c">

---------

Co-authored-by: Vicente Olmedo <vicente.olmedo@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants