crafting connections in 3D using TypeORM (ORM)

I attempted to construct a database schema involving users, groups, documents, and permissions.

  • Users can be part of multiple groups
  • Groups can have multiple users
  • Users can possess permissions for documents
  • Groups can have permissions for documents
  • Permissions can encompass any type of data, not solely documents

I endeavored to create a simplistic visual representation of this concept

https://i.sstatic.net/5BjXh.png

I initiated the process by designing the entities

User

@Entity('User')
export class UserEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany((type: any) => GroupEntity, (group: GroupEntity) => group.users)
  @JoinTable()
  groups: GroupEntity[];

  @ManyToMany((type: any) => DocumentEntity, (document: DocumentEntity) => document.users)
  @JoinTable()
  documents: DocumentEntity[];
}

Group

@Entity('Group')
export class GroupEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany((type: any) => UserEntity, (user: UserEntity) => user.groups)
  users: UserEntity[];

  @ManyToMany((type: any) => DocumentEntity, (document: DocumentEntity) => document.groups)
  @JoinTable()
  documents: DocumentEntity[];
}

Document

@Entity('Document')
export class DocumentEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany((type: any) => UserEntity, (user: UserEntity) => user.documents)
  users: UserEntity[];

  @ManyToMany((type: any) => GroupEntity, (group: GroupEntity) => group.documents)
  groups: GroupEntity[];
}

Regarding permissions for documents, it's apparent that there is a relational connection among three tables: users/groups, documents, and permissions.

  1. I utilize TypeORM for developing REST APIs with NestJs, but I am uncertain if a permission should be considered an Entity. Since I am structuring REST endpoints, this permission entity would likely serve as a shared entity across various endpoints.

  2. How should I modify my entities to accommodate these permissions?

... perhaps you could propose an improved database design :)

Answer №1

To efficiently handle this situation, it is advised to manually create an entity class called CrossGroupDocumentPermissionEntity. Within this entity class, add a ManyToOne relation for each connection. On the other side, within the Document, Group, and User entities, include a OneToMany relation. For an example of how to implement ManyToMany relations with custom fields, you can refer here.

Edit:

User

@Entity('User')
export class UserEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany((type: any) => GroupEntity, (group: GroupEntity) => group.users)
  @JoinTable()
  groups: GroupEntity[];

  @OneToMany((type: any) => CrossUserDocumentPermissionEntity, (documentPermission: CrossUserDocumentPermissionEntity) => documentPermission.user)
  documentPermissions: CrossUserDocumentPermissionEntity[];
}

Group

@Entity('Group')
export class GroupEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany((type: any) => UserEntity, (user: UserEntity) => user.groups)
  users: UserEntity[];

  @OneToMany((type: any) => CrossGroupDocumentPermissionEntity, (documentPermission: CrossGroupDocumentPermissionEntity) => documentPermission.group)
  documentPermissions: CrossGroupDocumentPermissionEntity[];
}

Permission

@Entity('Permission')
export class PermissionEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @OneToMany((type: any) => CrossUserDocumentPermissionEntity, (userDocument: CrossUserDocumentPermissionEntity) => userDocument.permission)
  usersDocuments: CrossUserDocumentPermissionEntity[];

  @OneToMany((type: any) => CrossGroupDocumentPermissionEntity, (groupDocument: CrossUserDocumentPermissionEntity) => groupDocument.permission)
  GroupDocuments: CrossGroupDocumentPermissionEntity[];
}

Document

@Entity('Document')
export class DocumentEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @OneToMany((type: any) => CrossUserDocumentPermissionEntity, (userPermission: CrossUserDocumentPermissionEntity) => userPermission.document)
  usersPermissions: CrossUserDocumentPermissionEntity[];

  @OneToMany((type: any) => CrossGroupDocumentPermissionEntity, (groupPermission: CrossUserDocumentPermissionEntity) => groupPermission.document)
  GroupPermissions: CrossGroupDocumentPermissionEntity[];
}

Cross_User_Document_Permission

@Entity('Cross_User_Document_Permission')
export class CrossUserDocumentPermissionEntity {
  @PrimaryColumn()
  userId: string;

  @PrimaryColumn()
  permissionId: string;

  @PrimaryColumn()
  documentId: string;

  @ManyToOne((type: any) => UserEntity, (user: UserEntity) => user.documentPermission)
  user: UserEntity;

  @ManyToOne((type: any) => DocumentEntity, (document: DocumentEntity) => document.userPermission)
  document: DocumentEntity;

  @ManyToOne((type: any) => PermissionEntity, (permission: PermissionEntity) => permission.userDocument)
  permission: PermissionEntity;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Searching for a streamlined approach to sending out numerous HTTP requests in a node.js environment

I'm new to the world of JS/node.js after working with .Net. I have an existing Web API host that I want to stress test with different payloads. I am aware of load testing tools available for this purpose, but my focus right now is on finding an effic ...

Is the Positioning of JS Scripts in Pug and Jade Documents Important?

Have you ever wondered why a page loads faster when certain lines are placed at the end of the tag instead of inside it? script(src="/Scripts/jquery.timeago.js") This phenomenon is often seen in code like this: //Jade file with JQuery !!! 5 html(lang=" ...

Creating two separate divs that can scroll independently while also limiting each other's scroll depth can be achieved by utilizing

I am attempting to replicate the unique scrolling feature seen on this particular page. Essentially, there are two columns above the fold that can be scrolled independently, but I want their scroll depths to be linked. When a certain depth is reached whil ...

experiencing difficulties in retrieving the outcome from a sweetalert2 popup

function confirmation() { swal.fire({ title: "Are you absolutely certain?", text: "You are about to permanently delete important files", type: "warning", showCancelButton: true, show ...

JavaScript causing Google custom search to not refresh results when updating search query

I am inputting user IDs into a textbox in my system. Upon submitting the ID, it fetches the name and address of the user and places it in the search box of a GCSE. document.getElementById("gsc-i-id1").setAttribute("value", this.searchqu ...

How can I retrieve values of selected checkboxes using the Express Data API?

I have a scenario where I need to retrieve data from input checkboxes only when the checkbox for my express post function is selected. There are 3 checkboxes with values of 1000, 2000, and 3000 as follows: <input type="checkbox" name=" ...

"Encountering issues with Firebase deployment related to function-builder and handle-builder while working with TypeScript

I encountered 4 errors while executing firebase deploy with firebase cloud functions. The errors are originating from files that I didn't modify. node_modules/firebase-functions/lib/function-builder.d.ts:64:136 - error TS2707: Generic type 'Req ...

In Material-UI, what is the reason behind setting this variable equal to its own value?

Currently, I'm struggling to understand the reasoning behind Material-UI setting a variable equal to itself for its Popover component. Take a look at the snippet of code and pay attention to the two if blocks before the return statement. I'm cu ...

Error message: "An undefined index error occurred during an Ajax call to a

Path: homepage -> initiate ajax request to tester.php on PHP -> receive JSON data back to homepage. I am struggling to resolve this issue. Any help would be appreciated. AJAX Request: $.ajax({ url : "tester.php", ty ...

Tips for accessing JSON values in JavaScript

How can I extract values from a JSON object in JavaScript? Below is the code snippet I've tried: var obj={"0.5":0.009333, "0.21":0.048667,"0.31":0.070667}; var value =0.21; var p=0; for(i=0; i<= obj.length ;i++){ if(value== obj[i]) ...

Ways to enhance the data for my YouTube video uploads version 3

Currently facing an issue where Google has restricted my daily queries to 10,000. I am in search of a solution to adjust my chunksize either up or down. Uncertain about the exact amount to increase or decrease to limit the number of queries per upload, her ...

Adding an image to a server through PHP in the TinyMCE editor

Currently, I am in the process of utilizing TinyMCE text editor for uploading images using PHP and JS database. However, I find myself perplexed when it comes to sending the image to the server. Below is the snippet of the JS code being used: <script ...

Adjust the color of the text as it scrolls by

As I work on developing my website using the Neve Theme on WordPress, I have encountered an issue with customizing the header block. I am using a plugin to set a background color for the header after scrolling 100px down the page, but this makes the text h ...

Supplying information to my ejs template while redirecting

I am currently working on a feature that involves sending data from the login page to the home page when the user is redirected. This data will then be used in the home EJS file. Below is the code snippet I have implemented: module.exports = functio ...

I am having an issue with the npm install command. Each time I try running it, I keep receiving an

After posting the output, I find myself unable to comprehend anything. Can someone please guide me on what steps to take next? npm has issued a warning about an old lockfile and advises that supplemental metadata needs to be fetched from the registry due t ...

How can I access a component variable within a foreach loop in Typescript?

Can anyone please explain how I can access a component variable within a foreach loop? Check out my code on Plunker public exampleVariable:number; test(){ console.log('fired'); var x =[1,2,3,4]; x.forEach(function (e){ th ...

Is there a way to have the submit button show the uploaded file on the same page, without redirecting to a new

My code seems to be malfunctioning and I suspect it's due to some errors. I'm attempting to have the submit button display an image of a molecule using JSmol. Can anyone lend a hand with this? <script> var Molecule = { width: 550, ...

Storing the value of e.currentTarget in a TypeScript variable with a fixed data type

Within my interface, MyObject.type is designated as a type of (constant): 'orange' | 'apple'. However, when attempting to execute: MyObject.type = e.currentTarget.value in the onChange method, an error arises since it could potentially ...

Preventing Users from Accessing a PHP Page: Best Practices

I'm currently focusing on a problem that involves restricting a user from opening a PHP page. The following is my JavaScript code: <script> $('input[id=f1email1]').on('blur', function(){ var k = $('inp ...

How can a new <li> element be created without being influenced by certain CSS styles?

I am attempting to enhance my menubar by adding a signup/login item aligned on the right without affecting the other center-aligned items. Essentially, I have an entry named "Login/Sign Up" that should maintain its own unique style while seamlessly blendin ...