DEV Community

Sanatel Consulting
Sanatel Consulting

Posted on

PrimeNG + NestJS = CRM — part 1

We decided to develop a CRM system in-house. During the development process, there were some interesting moments that I will try to describe in several articles. In the articles, I will try to avoid banalities like: downloaded, unpacked, launched, and look, swagger out of the box. There are already a lot of such articles, as well as videos on YouTube. I will try to share just interesting details that I came across during the development process. I will get ahead of myself - the system was configured and launched.

1. Why development, and not buying a ready-made system

For two reasons. Secondly, because purchased systems over time become so overgrown with additional settings that there is little left from the "box". And firstly, because frameworks have rapidly developed into some kind of platforms in which you have to code little.

2. Choosing a framework

I wanted to find a framework that already had all the Boiler code needed for a business application: menus, sections, graphs, users, etc. While searching for such a framework, we noticed the .Net frameworks https://aspnetboilerplate.com and https://abp.io, which already have a lot of things "out of the box". As far as I understand, both frameworks are being developed either by related teams, or even by one team. And the teams are from Turkey. The ASP.NET Boilerplate framework has legacy code from older versions of the .Net Framework. The newer ABP framework does not have legacy, it is on .Net Core. Both frameworks have a decent number of stars on github.

Then I came across an interesting library for the front - PrimeNG, it has three branches, for Angular, for React, for Vue. Each branch has a store with design themes, there are paid themes, there are free themes. Everything looks very beautiful, "out of the box" has everything you need for the front, menu, tabs, buttons, pop-up notifications. PrimeNG is again backed by a team from Turkey, PrimeTek.

As a result, we decided to develop on a bundle of PrimeNG (Angular) + NestJs. Because the front really wants to be on Angular, then there is a desire to save on the expertise of developers, and therefore let both the front and the backend be TypeScript.

The disadvantages of Node.js are known:

  • TypeScript is still an add-on, I consider the lack of data types in JavaScript a disadvantage.
  • The node_modules folder will contain several tens (hundreds) of thousands of files written by no one knows who.
  1. Logging TypeORM queries

To work with the database, the NestJs framework uses TypeORM. The TypeORM library surprised, it handles changes made to the table structure well, replacing column types, even with data in tables. And in order to view the logs of SQL queries generated by TypeORM, you need to add logging parameter:

TypeOrmModule.forRoot({
type: 'mysql', // ...
entities: [ ContactEntity, ],
logging: true, // For logging SQL queries to the console
}),

  1. Generating UUID primary key in TypeORM

Boiler columns in tables that should be in each table by default are the primary key, creation date, update date. If you declare in TypeORM:

export class ContactEntity {
@ApiProperty({description: 'Primary key'})
@PrimaryGeneratedColumn()
id: string;

@ApiProperty({description: 'Creation date'})
@CreateDateColumn()
created: Date;

@ApiProperty({description: 'Update date'})
@UpdateDateColumn()
updated: Date;
}

Then in MySQL database it will turn into in:

CREATE TABLE contacts (
id int(11) NOT NULL AUTO_INCREMENT,
created datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
updated datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY (id)
);

Everything is fine. But for a business application, you want a UUID primary key, not an integer.

And if you declare in TypeORM:

export class ContactEntity {
@ApiProperty({description: 'Primary key'})
@PrimaryGeneratedColumn('uuid')
id: string;

@ApiProperty({description: 'Creation date'})
@CreateDateColumn()
created: Date;

@ApiProperty({description: 'Update date'})
@UpdateDateColumn()
updated: Date;
}

Then in the SQL database it will turn into:

CREATE TABLE contacts (
id varchar(36) NOT NULL,
created datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
updated datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY (id)
);

That is, the primary key is just a string, without auto-generation of the UUID value! At first it seemed strange. But it turned out that in TypeORM it is done this way deliberately, the UUID is generated in the TypeORM code and the insertion of records occurs with the UUID field of the key already filled in. Because in the case of an auto-generated UUID column, for some types of insertion TypeORM would then have to read the insert

Top comments (0)