twenty icon indicating copy to clipboard operation
twenty copied to clipboard

Provide a demo environment

Open FelixMalfait opened this issue 1 year ago • 17 comments

Scope & Context

We don't really have a good way to demo the app for someone who wouldn't want to signup. We need better seeding data and a way to reset automatically the content if it's modified.

Periodic reset endpoint

Create an env variable DEMO_WORKSPACES which will hold an an array of ids. Create a new mutation ResetDemo on the API that takes an id as parameters. We'll setup a service like uptimerobot to update this frequently. That operation should:

  • check it's really a demo account, as per the env variable
  • the if check is ok:
    • clear existing people, companies, opportunities, ...
    • create new ones from seed files

Then, on the backend, prevent the following actions from being executed if the workspace is in DEMO_WORKSPACES:

  • Creating an API Key
  • Deleting an API Key
  • Deleting the Workspace
  • Inviting a member

Improve seed data

We already have 2 ways to generate seed data: (1) files in database/seeds/ which contains seed data for a dev environment. Maybe in the future can me improved to be generated with a library like faker (2) files in src/core/{object}/seed-date/{object}.json those are just a few items, they are real people/companies and are meant to avoid throwing people into an empty workspace. It's just a few items that are meant to look nice and be deleted when you start using the CRM.

We need to create a third dataset, that will be very similar to (2), i.e. nice looking/real companies, but with a lot more records (500 companies + 500 people + 100 opportunities would be nice) I recommend created a second .json file and using ChatGPT Code Interpreter to generate these files. We want these companies to feel relatable so maybe use a list of S&P 500 Companies or something like that as an initial input in ChatGPT Code Interpreter. They shouldn't be fake companies.

Pre-fill sign-in

There is already an environment variable to pre-fill the login form. It's helpful to pre-fill the login on non-production environment but doesn't help us in the production environment. We would need to be able to overwrite isSignInPrefilled based on a url parameter. e.g. app.twenty.com?demo=true or any other similar suitable format

FelixMalfait avatar Oct 24 '23 07:10 FelixMalfait

@khakimov are you working on the reset endpoint also? if not I can take it

alfredlouisw8 avatar Nov 05 '23 14:11 alfredlouisw8

@khakimov are you working on the reset endpoint also? if not I can take it

I’m wrestling with seed data for pipelines at the moment, please go ahead and implement reset endpoints. I wrote some basics to handle the reset on graphql, I could share it with you if needed (over discord?)

khakimov avatar Nov 05 '23 15:11 khakimov

Updated script for seeding pipeline data. It fetches all companies associated with a specific workspace, randomly assigns a pipeline stage (pre-set too) to each company, and creates a new record in the 'pipelineProgress' table. image

@FelixMalfait shall we define a demo workspaceId and hardcode it, should it be different from the current default workspaceId? (twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419)

khakimov avatar Nov 08 '23 03:11 khakimov

Nice work @khakimov! I think you should create a DEMO_WORKSPACES environment variable as briefly mentioned in the issue, that way we don't hardcode the id in the code. I'm not sure there is a big use case for having an array instead of a single workspace but it probably doesn't cost much to make it an array an then we can provision as many separate demo environments as we want

FelixMalfait avatar Nov 08 '23 09:11 FelixMalfait

Merged yesterday https://github.com/twentyhq/twenty/pull/2307/

added command workspace:seed:demo which takes DEMO_WORKSPACE_IDS from .env and creates workspace with seed data ( 600 companies, 1200 people, 50 opportunities ).

Now will work on preventing the following actions from being executed if the workspace is in DEMO_WORKSPACES:

  • Creating an API Key
  • Deleting an API Key
  • Deleting the Workspace
  • Inviting a member

khakimov avatar Dec 03 '23 07:12 khakimov

Nice work @khakimov!!! I think images got put in the job title field? Screenshot 2023-12-03 at 11 44 29

FelixMalfait avatar Dec 03 '23 10:12 FelixMalfait

Actually it's not the only field that got mixed up. Email, address, Linkedin, etc. seems to be mixed up too Screenshot 2023-12-03 at 11 53 41

FelixMalfait avatar Dec 03 '23 10:12 FelixMalfait

Actually it's not the only field that got mixed up. Email, address, Linkedin, etc. seems to be mixed up too Screenshot 2023-12-03 at 11 53 41

Oops, will look into it.

khakimov avatar Dec 03 '23 12:12 khakimov

@FelixMalfait PR fix here https://github.com/twentyhq/twenty/pull/2842 Looks better!

CleanShot 2566-12-05 at 16 35 25@2x

khakimov avatar Dec 05 '23 09:12 khakimov

Nice @khakimov!

FelixMalfait avatar Dec 05 '23 09:12 FelixMalfait

Related to preventing "Deleting the Workspace" and others, on backend:

    const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds();
    // Check if the id is in the list of demo workspaceIds
    if (demoWorkspaceIds.includes(id)) {
      throw new Error('Cannot delete a demo workspace.');
    }

is it enough to show this message or to avoid showing anything better?

CleanShot 2566-12-05 at 17 19 23@2x

khakimov avatar Dec 05 '23 10:12 khakimov

@khakimov We would actually need to disable features on the backend. To do that, you'll need to pass the information "is this workspace a demo workspace" to the frontend. Right now we have different ways of doing it:

  1. ClientConfig: this is a server level configuration that's returned to the FE. This ClientConfig is not tied to the current workspace but we could send the demoWorkspaceIds through it, create an util or a hook in FE to check if currentWorkspace.id is in clientConfig.demoWorkspaceIds
  2. FeatureFlags: we have just introduce FeatureFlags. There is postgres table named "core.featureFlag". This is attaching a featureFlag array to the currentWorkspace (which is already there in the FE). Search IS_RELATION_FIELD_TYPE_ENABLED in the code to see how we use it
  3. currentWorkspace custom resolver: we could create a isDemo custom resolver that would add a isDemo field to currentWorkspace. I think this is overkill and this pattern will not scale as the project grows

I would go with option 2) which seems the cleaner

charlesBochet avatar Dec 05 '23 13:12 charlesBochet

@khakimov After a discussion with @FelixMalfait, we actually think that we don't want to bother the frontend with this logic. So, what we need is to show this backend error to the FE. This should be done using the Snackbar component. However, this is out of scope for your ticket (we already have ticket this week to work on FE errors display).

So long story short, it's fine to block it the way you are blocking it :)

charlesBochet avatar Dec 05 '23 13:12 charlesBochet

@khakimov are you still working on this? Obviously the day after we shipped the demo account someone had already deleted the workspace haha https://discord.com/channels/1130383047699738754/1130383048173682821/1186340133033758811 If you have ongoing work we should take over let us know, we should probably prioritize this soon!

Thanks

FelixMalfait avatar Dec 18 '23 16:12 FelixMalfait

While restoring the workspace by running the command again, I have noticed that as the users themselves were not deleted (only workspace + workspace member), the user was not re-attached to the demo workspace Also the subscription status of the workspace was set to incomplete (default) and not to active

charlesBochet avatar Dec 18 '23 20:12 charlesBochet

ah, here is fix above.

apikey related stuff isn't as critical, hopefully will figure out soon direction of implementation (have a thread in discord) 🙏

khakimov avatar Dec 19 '23 03:12 khakimov

@khakimov We also have the issue with "Delete account" button which is deleting the workspaceMember (through flexible schema). It raises the same question as the API key above.

Can we hide the button on the FE for now?

charlesBochet avatar Dec 25 '23 18:12 charlesBochet