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: detect and upgrade users with missing metadata #18

Merged
merged 6 commits into from
Aug 29, 2024

Conversation

codeincontext
Copy link
Collaborator

@codeincontext codeincontext commented Aug 28, 2024

Description

Existing users were onboarded without us recording their region, which we need to determine their demo status. This PR takes these legacy users through a quick onboarding just to record the region and demo status

It's also a good opportunity to namespace the public metadata to the labs prefix. Existing users will already be migrated to this structure with a script

  • Metadata structure
    • Move public user metadata to publicMetadata.labs
    • Add isOnboarded to public metadata
  • Middleware
    • Add isOnboarded and isDemoUser to Clerk session claims to avoid server round trip
    • Detect users without isOnboarded session claim and redirect to /onboarding
    • Allow routes required for onboarding if the user needs to onboard
    • Dev: Allow routes with x-dev-preload even if they're protected
  • Onboarding backend
    • Split demo user setup to new tRPC endpoint
  • Onboarding frontend
    • Extract current onboarding form to a new AcceptTermsForm component
    • Check user metadata for isOnboarded
      • Show AcceptTermsForm if not onboarded
      • Just update demo status if already onboarded
    • Regenerate token on completion to update claims

How to test

  1. Create or modify a test user with the following public metadata: { "labs": { "isOnboarded": true } }
  2. Log in with that user at https://oak-ai-lesson-assistant-k3tc8h51r.vercel-preview.thenational.academy
  3. You go through a quick onboarding state before landing on the homepage
  4. You have been assigned a demo status in your public metadata
  5. You can see this demo status on /aila

Screenshots

Current onboarding form. This shouls stay the same for new users
CleanShot 2024-08-28 at 13 40 36@2x

For legacy users without demo status

CleanShot 2024-08-28 at 13 42 34@2x

Checklist

  • Manually tested across browsers / devices
  • Considered impact on accessibility
  • Does this PR update a package with a breaking change

Copy link

vercel bot commented Aug 28, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
oak-ai-lesson-assistant ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 29, 2024 1:45pm

Copy link

github-actions bot commented Aug 28, 2024

Playwright e2e tests

Job summary

Download report

To view traces locally, unzip the report and run:

npx playwright show-report ~/Downloads/playwright-report

Copy link
Collaborator

@mantagen mantagen left a comment

Choose a reason for hiding this comment

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

LGTM! Few comments

apps/nextjs/src/middlewares/auth.middleware.ts Outdated Show resolved Hide resolved
const setDemoStatus = trpc.auth.setDemoStatus.useMutation();

const userHasAlreadyAcceptedTerms =
user?.publicMetadata?.["labs"]?.["isOnboarded"];
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this a TS complaint that the keys might not exist?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah. It's a slightly hokey way to wait for user to have loaded and then dig into those fields if they don't exist. publicMetadata is unknown here, so we have to access them as fields rather than properties

const userHasAlreadyAcceptedTerms =
user?.publicMetadata?.["labs"]?.["isOnboarded"];

// Edge case: Legacy users have already accepted terms but don't have a demo status
Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry being a bit slow here -- where's the condition that they don't have a demo status?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah just seen -- user won't land on this page otherwise

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The case is any user who signed up before started capturing the demo status. Unless we can find a sensible representation of their region (maybe posthog?), our only option is to wait until they come back online to set it

We're soon going to have users landing on labs from OWA who don't have all of our metadata, so this concept of upgrading metadata will likely come in useful anyway

apps/nextjs/src/components/Onboarding/AcceptTermsForm.tsx Outdated Show resolved Hide resolved
packages/api/src/router/auth.ts Outdated Show resolved Hide resolved
packages/core/src/models/demoUsers.ts Show resolved Hide resolved
Copy link
Contributor

@stefl stefl left a comment

Choose a reason for hiding this comment

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

Just a couple of questions and spotted some copy issues

if (!demoUsers.isDemoStatusSet(user)) {
return false;
}
const isDemoUser = Boolean(user.publicMetadata.labs.isDemoUser ?? "true");
Copy link
Contributor

Choose a reason for hiding this comment

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

does this need to be publicMetadata.labs?.isDemoUser or is this safe at this point?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The type of isDemoStatusSet is

  isDemoStatusSet(user: LabsUser): user is UserWithDemoStatus

So that's already asserted here!

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess my concern is that we might be trusting what is coming through here, and it might be correct in the types, but I'm not sure we validate the actual data from Clerk?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Do you mean that isDemoStatusSet could be accidentally sanitising incorrect data with a correct type?

Here's the definition:

  isDemoStatusSet(user: LabsUser): user is UserWithDemoStatus {
    const labsMetadata = user.publicMetadata.labs || {};
    return "isDemoUser" in labsMetadata && labsMetadata.isDemoUser !== null;
  }

apps/nextjs/src/app/onboarding/onboarding.tsx Outdated Show resolved Hide resolved
apps/nextjs/src/app/onboarding/page.tsx Outdated Show resolved Hide resolved
apps/nextjs/src/components/Onboarding/AcceptTermsForm.tsx Outdated Show resolved Hide resolved
<OakSpan>
Keep me updated with latest Oak AI experiments, resources and
other helpful content by email. You can unsubscribe at any time.
See our{" "}
Copy link
Contributor

Choose a reason for hiding this comment

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

The language here shifts from "me" - the user to "our" - Oak. Should this be "the"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This isn't new copy, but you are right that the grammar isn't quite right

The previous sentence has already switched to "You", so I don't think it's as bad as it looks at first glance

That said, "Keep me updated with latest Oak AI experiments" seems to be missing a "the"?

apps/nextjs/src/components/Onboarding/AcceptTermsForm.tsx Outdated Show resolved Hide resolved
apps/nextjs/src/hooks/useClerkDemoMetadata.ts Show resolved Hide resolved
Copy link

@codeincontext codeincontext merged commit e2b8fcc into main Aug 29, 2024
12 checks passed
@codeincontext codeincontext deleted the feat/onboarding-metadata-upgrades branch August 29, 2024 13:56
@oak-machine-user
Copy link
Collaborator

🎉 This PR is included in version 1.3.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants