Hello, hope you are doing great, I have a question regarding how to setup an app for company accounts rather than users, I been doing everything included in the learn plasmic page, i’ve setup the data base on supabase, but I could not find any references or projects that explain this, I assume the user rules are meant for this exact use case but again the information available does not provide use cases, examples, best practices, etc etc.
What is the data base structure I should use if my app will be for companies with multiple users, should the user id be the company id ? or if the company id is different from the user id, If I create dynamic pages based on the company ID, how will plasmic verify the user is in the company without having to add both the user id and company id to the URLs, I’m looking for best practices all over plasmic documentation but there is nothing. the groups feature is very confusing not sure if thats it.
also is there a way to add company properties to the variables instead of user properties, also there are roles for users, which i assume are roles within the company, but what If a user uses our app to be a staff user in one company and admin in another company like in shopify for example. I’m just really really confused with this.
For reference here is the data structure I plan to use in the database and urls.
Column 1 | Column 2 | Column 3 | Column 4 |
---|---|---|---|
Section Title | Field | Type | Description |
Companies Table | company_id | UUID | Unique identifier for the company |
- | name | Text | Company name (may differ from username) |
- | company_username | Text | URL-friendly version of the company name (unique) |
- | created_at | Timestamp | Timestamp of when the company was created |
- | updated_at | Timestamp | Timestamp of last update on company information |
URL Structure | /{company_username}/ | - | Base URL for company-specific actions |
- | /{company_username}/quotas/ | - | Quota settings for a specific company |
- | /{company_username}/users/ | - | View all users in the company |
- | /{company_username}/templates/ | - | View all templates for the company |
- | /{company_username}/files/ | - | View all files for the company |
- | /{company_username}/files/{file_slug}/ | - | Specific file details |
Users Table | user_id | UUID | Unique identifier for the user |
- | Text | User’s email address (unique) | |
- | password_hash | Text | Hashed password for user authentication |
- | profile_picture | Text | URL to the user’s profile picture |
- | first_name | Text | User’s first name |
- | last_name | Text | User’s last name |
- | role | JSON | Object storing roles by company ID (e.g., {company_id: role}) |
- | created_at | Timestamp | Timestamp of user account creation |
URL Structure | /{company_username}/users/{user_id}/ | - | Specific user details in the company |
- | /{user_id}/ | - | Access user profile |
- | /{user_id}/settings/ | - | User account settings |
Files Table | file_id | UUID | Unique identifier for the file |
- | company_id | Foreign Key | Linked to companies.company_id |
- | file_name | Text | Original name of the file |
- | file_type | Enum | Type of file (e.g., 3D Model, Video) |
- | file_url | Text | Path to the file in Supabase storage |
- | thumbnail_url | Text | Path to the auto-generated thumbnail |
- | uploaded_at | Timestamp | Timestamp of when the file was uploaded |
- | campaign_ids | JSON | Array of campaign IDs where the file has been used |
URL Structure | /{company_username}/files/{file_slug}/ | - | Specific file details |
- | /{company_username}/files/ | - | All files for the company |
Templates Table | template_id | UUID | Unique identifier for the template |
- | company_id | Foreign Key | Linked to companies.company_id |
- | title | Text | Name of the template |
- | campaign_data | JSON | JSON object containing all necessary data to recreate the campaign |
- | created_at | Timestamp | Timestamp of when the template was created |
URL Structure | /{company_username}/templates/{template_slug}/ | - | Specific template details |
- | /{company_username}/templates/ | - | All templates for the company |
<table>
<tr>
<th colspan="3">Companies Table</th>
</tr>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>company_id</td>
<td>UUID</td>
<td>Unique identifier for the company</td>
</tr>
<tr>
<td>name</td>
<td>Text</td>
<td>Company name (may differ from username)</td>
</tr>
<tr>
<td>company_username</td>
<td>Text</td>
<td>URL-friendly version of the company name (unique)</td>
</tr>
<tr>
<td>created_at</td>
<td>Timestamp</td>
<td>Timestamp of when the company was created</td>
</tr>
<tr>
<td>updated_at</td>
<td>Timestamp</td>
<td>Timestamp of last update on company information</td>
</tr>
<tr>
<th colspan="3">URL Structure</th>
</tr>
<tr>
<td>/{company_username}/</td>
<td colspan="2">Base URL for company-specific actions</td>
</tr>
<tr>
<td>/{company_username}/quotas/</td>
<td colspan="2">Quota settings for a specific company</td>
</tr>
<tr>
<td>/{company_username}/users/</td>
<td colspan="2">View all users in the company</td>
</tr>
<tr>
<td>/{company_username}/templates/</td>
<td colspan="2">View all templates for the company</td>
</tr>
<tr>
<td>/{company_username}/files/</td>
<td colspan="2">View all files for the company</td>
</tr>
<tr>
<td>/{company_username}/files/{file_slug}/</td>
<td colspan="2">Specific file details</td>
</tr>
<tr>
<th colspan="3">Users Table</th>
</tr>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>user_id</td>
<td>UUID</td>
<td>Unique identifier for the user</td>
</tr>
<tr>
<td>email</td>
<td>Text</td>
<td>User's email address (unique)</td>
</tr>
<tr>
<td>password_hash</td>
<td>Text</td>
<td>Hashed password for user authentication</td>
</tr>
<tr>
<td>profile_picture</td>
<td>Text</td>
<td>URL to the user's profile picture</td>
</tr>
<tr>
<td>first_name</td>
<td>Text</td>
<td>User's first name</td>
</tr>
<tr>
<td>last_name</td>
<td>Text</td>
<td>User's last name</td>
</tr>
<tr>
<td>role</td>
<td>JSON</td>
<td>Object storing roles by company ID (e.g., {"company_id": "role"})</td>
</tr>
<tr>
<td>created_at</td>
<td>Timestamp</td>
<td>Timestamp of user account creation</td>
</tr>
<tr>
<td>updated_at</td>
<td>Timestamp</td>
<td>Timestamp of last update on user information</td>
</tr>
<tr>
<th colspan="3">URL Structure</th>
</tr>
<tr>
<td>/{company_username}/users/{user_id}/</td>
<td colspan="2">Specific user details in the company</td>
</tr>
<tr>
<td>/{user_id}/</td>
<td colspan="2">Access user profile</td>
</tr>
<tr>
<td>/{user_id}/settings/</td>
<td colspan="2">User account settings</td>
</tr>
<tr>
<th colspan="3">Files Table</th>
</tr>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>file_id</td>
<td>UUID</td>
<td>Unique identifier for the file</td>
</tr>
<tr>
<td>company_id</td>
<td>Foreign Key</td>
<td>Linked to companies.company_id</td>
</tr>
<tr>
<td>file_name</td>
<td>Text</td>
<td>Original name of the file</td>
</tr>
<tr>
<td>file_type</td>
<td>Enum</td>
<td>Type of file (e.g., 3D Model, Video)</td>
</tr>
<tr>
<td>file_url</td>
<td>Text</td>
<td>Path to the file in Supabase storage</td>
</tr>
<tr>
<td>thumbnail_url</td>
<td>Text</td>
<td>Path to the auto-generated thumbnail</td>
</tr>
<tr>
<td>uploaded_at</td>
<td>Timestamp</td>
<td>Timestamp of when the file was uploaded</td>
</tr>
<tr>
<td>campaign_ids</td>
<td>JSON</td>
<td>Array of campaign IDs where the file has been used</td>
</tr>
<tr>
<td>is_saved</td>
<td>Boolean</td>
<td>Whether the file is saved in "My Files" (true/false)</td>
</tr>
<tr>
<th colspan="3">URL Structure</th>
</tr>
<tr>
<td>/{company_username}/files/{file_slug}/</td>
<td colspan="2">Specific file details</td>
</tr>
<tr>
<td>/{company_username}/files/</td>
<td colspan="2">All files for the company</td>
</tr>
<tr>
<th colspan="3">Templates Table</th>
</tr>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>template_id</td>
<td>UUID</td>
<td>Unique identifier for the template</td>
</tr>
<tr>
<td>company_id</td>
<td>Foreign Key</td>
<td>Linked to companies.company_id</td>
</tr>
<tr>
<td>title</td>
<td>Text</td>
<td>Name of the template</td>
</tr>
<tr>
<td>campaign_data</td>
<td>JSON</td>
<td>JSON object containing all necessary data to recreate the campaign</td>
</tr>
<tr>
<td>created_at</td>
<td>Timestamp</td>
<td>Timestamp of when the template was created</td>
</tr>
<tr>
<td>updated_at</td>
<td>Timestamp</td>
<td>Timestamp of last update on the template</td>
</tr>
<tr>
<th colspan="3">URL Structure</th>
</tr>
<tr>
<td>/{company_username}/templates/{template_slug}/</td>
<td colspan="2">Specific template details</td>
</tr>
<tr>
<td>/{company_username}/templates/</td>
<td colspan="2">View all templates for the company</td>
</tr>
<tr>
<th colspan="3">Quotas Table</th>
</tr>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>company_id</td>
<td>Foreign Key</td>
<td>Linked to companies.company_id</td>
</tr>
<tr>
<td>campaign_limit</td>
<td>Integer</td>
<td>Maximum number of campaigns a company can create</td>
</tr>
<tr>
<td>view_limit</
Thanks.