diff --git a/src/app.module.ts b/src/app.module.ts index e125c07..36b03d4 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -7,12 +7,14 @@ import { AppService } from './app.service'; import { dataSourceOptions } from './appDataSource'; import { EntryModule } from './entries/entries.module'; import { DataSource, EntityManager } from 'typeorm'; +import { UsersModule } from './users/users.module'; @Module({ imports: [ ConfigModule.forRoot(), TypeOrmModule.forRoot(dataSourceOptions), - EntryModule + EntryModule, + UsersModule, ], controllers: [AppController], providers: [AppService], diff --git a/src/appDataSource.ts b/src/appDataSource.ts index ab2f974..ad436c5 100644 --- a/src/appDataSource.ts +++ b/src/appDataSource.ts @@ -1,18 +1,24 @@ -import { DataSource, DataSourceOptions } from "typeorm"; -import { Entry } from "./entries/entries.entity"; -import { Initial1770020781006 } from "./migrations/1770020781006-initial"; -import { AddCreateUpdateDeleteColsAndRenameSourceToSourceText1770067407619 } from "./migrations/1770067407619-add_create_update_delete_cols_and_rename_source_to_sourceText"; +import { DataSource, DataSourceOptions } from 'typeorm'; +import { Entry } from './entries/entries.entity'; +import { Initial1770020781006 } from './migrations/1770020781006-initial'; +import { AddCreateUpdateDeleteColsAndRenameSourceToSourceText1770067407619 } from './migrations/1770067407619-add_create_update_delete_cols_and_rename_source_to_sourceText'; +import { User } from './users/users.entity'; +import { AddUserEntity1770147074119 } from './migrations/1770147074119-add_user_entity'; export const dataSourceOptions: DataSourceOptions = { - type: "postgres", - host: process.env.DB_HOST, - port: parseInt(process.env.DB_PORT as string, 10) || 5432, - username: process.env.DB_USERNAME, - password: process.env.DB_PASSWORD, - database: process.env.DB_NAME, - entities: [Entry], - migrations: [Initial1770020781006, AddCreateUpdateDeleteColsAndRenameSourceToSourceText1770067407619], - synchronize: false, -} + type: 'postgres', + host: process.env.DB_HOST, + port: parseInt(process.env.DB_PORT as string, 10) || 5432, + username: process.env.DB_USERNAME, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + entities: [Entry, User], + migrations: [ + Initial1770020781006, + AddCreateUpdateDeleteColsAndRenameSourceToSourceText1770067407619, + AddUserEntity1770147074119 + ], + synchronize: false, +}; -export const appDataSource = new DataSource(dataSourceOptions) \ No newline at end of file +export const appDataSource = new DataSource(dataSourceOptions); diff --git a/src/entries/entries.controller.ts b/src/entries/entries.controller.ts index 9fc289e..a4b6c61 100644 --- a/src/entries/entries.controller.ts +++ b/src/entries/entries.controller.ts @@ -1,50 +1,60 @@ -import { Body, Controller, Delete, Get, Inject, Param, Post, Put } from '@nestjs/common'; +import { + Body, + Controller, + Delete, + Get, + Inject, + Param, + Post, + Put, +} from '@nestjs/common'; import { EntryService } from './entries.service'; import { EntryDTO } from './entries.dto'; import { Entry } from './entries.entity'; @Controller('entries') export class EntriesController { - constructor( - @Inject(EntryService) - private readonly entryService: EntryService - ) {} + constructor( + @Inject(EntryService) + private readonly entryService: EntryService, + ) {} + @Post() + async saveEntry(@Body() entry: EntryDTO): Promise { + return (await this.entryService.save(entry)).uuid; + } - @Post() - async saveEntry(@Body() entry: EntryDTO): Promise { - return (await this.entryService.save(entry)).uuid - } + @Put(':uuid') + async updateEntry( + @Param('uuid') uuid: string, + @Body() entry: EntryDTO, + ): Promise { + return (await this.entryService.updateByUuid(uuid, entry)).uuid; + } - @Put(":uuid") - async updateEntry(@Param("uuid") uuid: string, @Body() entry: EntryDTO): Promise { - return (await this.entryService.updateByUuid(uuid, entry)).uuid - } + @Get() + async findAll(): Promise { + const entries = await this.entryService.findAll(); + return entries.sort((a, b) => { + return ( + new Date(b.created_at as Date).getTime() - + new Date(a.created_at as Date).getTime() + ); + }); + } - @Get() - async findAll(): Promise - { - const entries = await this.entryService.findAll() - return entries.sort((a, b) => { - return ( - new Date(b.created_at as Date).getTime() - new Date(a.created_at as Date).getTime() - ) - }) - } + @Get(':uuid') + async findOneByUuid(@Param('uuid') uuid: string): Promise { + return await this.entryService.findOneByUuid(uuid); + } - @Get(":uuid") - async findOneByUuid(@Param("uuid") uuid: string): Promise { - return await this.entryService.findOneByUuid(uuid) - } + @Delete(':uuid') + async softDelete(@Param('uuid') uuid: string): Promise { + await this.entryService.softDeleteByUuid(uuid); + } - @Delete(":uuid") - async softDelete(@Param("uuid") uuid: string): Promise - { - await this.entryService.softDeleteByUuid(uuid) - } - - @Put("/restore/:uuid") - async restoreSoftDeleted(@Param("uuid") uuid: string): Promise { - return await this.entryService.restoreDeletedByUuid(uuid) - } + @Put('/restore/:uuid') + async restoreSoftDeleted(@Param('uuid') uuid: string): Promise { + return await this.entryService.restoreDeletedByUuid(uuid); + } } diff --git a/src/entries/entries.dto.ts b/src/entries/entries.dto.ts index 64ecf54..464f5ec 100644 --- a/src/entries/entries.dto.ts +++ b/src/entries/entries.dto.ts @@ -1,8 +1,8 @@ -import { Entry } from "./entries.entity"; +import { Entry } from './entries.entity'; export class EntryDTO implements Partial { - title?: string; - description?: string; - sourceText?: string; - sourceUrl?: string; -} \ No newline at end of file + title?: string; + description?: string; + sourceText?: string; + sourceUrl?: string; +} diff --git a/src/entries/entries.entity.ts b/src/entries/entries.entity.ts index 1f476f9..2cba49e 100644 --- a/src/entries/entries.entity.ts +++ b/src/entries/entries.entity.ts @@ -1,32 +1,40 @@ -import { Column, CreateDateColumn, DeleteDateColumn, Entity, Generated, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm"; +import { + Column, + CreateDateColumn, + DeleteDateColumn, + Entity, + Generated, + PrimaryGeneratedColumn, + UpdateDateColumn, +} from 'typeorm'; -@Entity({ name: "entries"}) +@Entity({ name: 'entries' }) export class Entry { - @Column() - @Generated("uuid") - uuid?: string; + @Column() + @Generated('uuid') + uuid?: string; - @PrimaryGeneratedColumn("increment") - id?: number; + @PrimaryGeneratedColumn('increment') + id?: number; - @Column({ type: String, default: "" }) - title?: string; + @Column({ type: String, default: '' }) + title?: string; - @Column({ type: String, default: "" }) - description?: string; - - @Column({ type: String, default: "" }) - sourceText?: string; - - @Column({ type: String, default: "" }) - sourceUrl?: string; + @Column({ type: String, default: '' }) + description?: string; - @CreateDateColumn() - created_at?: Date; + @Column({ type: String, default: '' }) + sourceText?: string; - @UpdateDateColumn() - updated_at?: Date; + @Column({ type: String, default: '' }) + sourceUrl?: string; - @DeleteDateColumn() - deleted_at?: Date; -} \ No newline at end of file + @CreateDateColumn() + created_at?: Date; + + @UpdateDateColumn() + updated_at?: Date; + + @DeleteDateColumn() + deleted_at?: Date; +} diff --git a/src/entries/entries.module.ts b/src/entries/entries.module.ts index ae1d546..2125f7a 100644 --- a/src/entries/entries.module.ts +++ b/src/entries/entries.module.ts @@ -1,15 +1,13 @@ -import { Module } from "@nestjs/common"; -import { TypeOrmModule } from "@nestjs/typeorm"; -import { Entry } from "./entries.entity"; -import { EntryService } from "./entries.service"; -import { EntriesController } from "./entries.controller"; +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Entry } from './entries.entity'; +import { EntryService } from './entries.service'; +import { EntriesController } from './entries.controller'; @Module({ - imports: [ - TypeOrmModule.forFeature([Entry]), - ], - exports: [EntryService], - providers: [EntryService], - controllers: [EntriesController], + imports: [TypeOrmModule.forFeature([Entry])], + exports: [EntryService], + providers: [EntryService], + controllers: [EntriesController], }) -export class EntryModule {} \ No newline at end of file +export class EntryModule {} diff --git a/src/entries/entries.service.ts b/src/entries/entries.service.ts index a78d1dc..53bed95 100644 --- a/src/entries/entries.service.ts +++ b/src/entries/entries.service.ts @@ -1,85 +1,85 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { InjectRepository } from "@nestjs/typeorm"; -import { Entry } from "./entries.entity"; -import { Repository } from "typeorm"; -import { EntryDTO } from "./entries.dto"; -import EntryNotFoundException from "./exceptions/entryNotFound.exception"; +import { Injectable, Logger } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Entry } from './entries.entity'; +import { Repository } from 'typeorm'; +import { EntryDTO } from './entries.dto'; +import EntryNotFoundException from './exceptions/entryNotFound.exception'; @Injectable() export class EntryService { - constructor( - @InjectRepository(Entry) - private entryRepository: Repository - ) {} - private readonly logger = new Logger(EntryService.name) + constructor( + @InjectRepository(Entry) + private entryRepository: Repository, + ) {} + private readonly logger = new Logger(EntryService.name); - async save(data: EntryDTO): Promise { - this.logger.log("Creating entry") - const lEntry = new Entry(); - lEntry.description = data.description - lEntry.sourceText = data.sourceText - lEntry.sourceUrl = data.sourceUrl - lEntry.title = data.title - await this.entryRepository.save(lEntry) - return lEntry - } + async save(data: EntryDTO): Promise { + this.logger.log('Creating entry'); + const lEntry = new Entry(); + lEntry.description = data.description; + lEntry.sourceText = data.sourceText; + lEntry.sourceUrl = data.sourceUrl; + lEntry.title = data.title; + await this.entryRepository.save(lEntry); + return lEntry; + } - async updateByUuid(uuid: string, data: EntryDTO): Promise { - this.logger.log(`Updating entry with UUID ${uuid}`) - const oldEntry = await this.entryRepository.findOneBy({ uuid: uuid}) - if (!oldEntry) { - throw new EntryNotFoundException(uuid) - } else { - const lEntry = new Entry(); - // `id` is the primary key - lEntry.id = oldEntry.id - // These options can be updated - lEntry.description = data.description - lEntry.sourceText = data.sourceText - lEntry.sourceUrl = data.sourceUrl - lEntry.title = data.title - await this.entryRepository.save(lEntry) - return lEntry - } - } - - async findOneByUuid(uuid: string): Promise { - this.logger.log(`Returning entry with UUID ${uuid}`) - return this.entryRepository.findOneByOrFail({uuid: uuid}) + async updateByUuid(uuid: string, data: EntryDTO): Promise { + this.logger.log(`Updating entry with UUID ${uuid}`); + const oldEntry = await this.entryRepository.findOneBy({ uuid: uuid }); + if (!oldEntry) { + throw new EntryNotFoundException(uuid); + } else { + const lEntry = new Entry(); + // `id` is the primary key + lEntry.id = oldEntry.id; + // These options can be updated + lEntry.description = data.description; + lEntry.sourceText = data.sourceText; + lEntry.sourceUrl = data.sourceUrl; + lEntry.title = data.title; + await this.entryRepository.save(lEntry); + return lEntry; } + } - async findAll(): Promise { - this.logger.log("Returning all entries") - return this.entryRepository.find() - } + async findOneByUuid(uuid: string): Promise { + this.logger.log(`Returning entry with UUID ${uuid}`); + return this.entryRepository.findOneByOrFail({ uuid: uuid }); + } - async findAllAndDeleted(): Promise { - this.logger.log("Returning all entries, active and deleted") - return this.entryRepository.find({ withDeleted: true }) - } + async findAll(): Promise { + this.logger.log('Returning all entries'); + return this.entryRepository.find(); + } - async softDeleteByUuid(uuid: string): Promise { - this.logger.log(`Soft deleting entry with UUID ${uuid}`) - const deleteResponse = await this.entryRepository.softDelete({ - uuid: uuid - }) - if (!deleteResponse.affected) { - throw new EntryNotFoundException(uuid) - } - } + async findAllAndDeleted(): Promise { + this.logger.log('Returning all entries, active and deleted'); + return this.entryRepository.find({ withDeleted: true }); + } - async restoreDeletedByUuid(uuid: string): Promise { - this.logger.log(`Restoring entry with UUID ${uuid}`) - const restoreResponse = await this.entryRepository.restore({ - uuid: uuid - }) - - if (!restoreResponse.affected) { - throw new EntryNotFoundException(uuid) - } else { - return this.entryRepository.findOneByOrFail({ - uuid: uuid - }) - } + async softDeleteByUuid(uuid: string): Promise { + this.logger.log(`Soft deleting entry with UUID ${uuid}`); + const deleteResponse = await this.entryRepository.softDelete({ + uuid: uuid, + }); + if (!deleteResponse.affected) { + throw new EntryNotFoundException(uuid); } -} \ No newline at end of file + } + + async restoreDeletedByUuid(uuid: string): Promise { + this.logger.log(`Restoring entry with UUID ${uuid}`); + const restoreResponse = await this.entryRepository.restore({ + uuid: uuid, + }); + + if (!restoreResponse.affected) { + throw new EntryNotFoundException(uuid); + } else { + return this.entryRepository.findOneByOrFail({ + uuid: uuid, + }); + } + } +} diff --git a/src/entries/exceptions/entryNotFound.exception.ts b/src/entries/exceptions/entryNotFound.exception.ts index 919996e..7dcf2a0 100644 --- a/src/entries/exceptions/entryNotFound.exception.ts +++ b/src/entries/exceptions/entryNotFound.exception.ts @@ -1,9 +1,9 @@ -import { NotFoundException } from "@nestjs/common"; +import { NotFoundException } from '@nestjs/common'; class EntryNotFoundException extends NotFoundException { - constructor(uuid: string) { - super(`Entry with UUID ${uuid} not found`) - } + constructor(uuid: string) { + super(`Entry with UUID ${uuid} not found`); + } } -export default EntryNotFoundException \ No newline at end of file +export default EntryNotFoundException; diff --git a/src/migrations/1770020781006-initial.ts b/src/migrations/1770020781006-initial.ts index e9d6ea5..2b46ac1 100644 --- a/src/migrations/1770020781006-initial.ts +++ b/src/migrations/1770020781006-initial.ts @@ -1,14 +1,15 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class Initial1770020781006 implements MigrationInterface { - name = 'Initial1770020781006' + name = 'Initial1770020781006'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "entries" ("uuid" uuid NOT NULL DEFAULT uuid_generate_v4(), "id" SERIAL NOT NULL, "title" character varying NOT NULL DEFAULT '', "description" character varying NOT NULL DEFAULT '', "source" character varying NOT NULL DEFAULT '', "sourceUrl" character varying NOT NULL DEFAULT '', CONSTRAINT "PK_8640855ae82083455cbb806173d" PRIMARY KEY ("id"))`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP TABLE "entries"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "entries" ("uuid" uuid NOT NULL DEFAULT uuid_generate_v4(), "id" SERIAL NOT NULL, "title" character varying NOT NULL DEFAULT '', "description" character varying NOT NULL DEFAULT '', "source" character varying NOT NULL DEFAULT '', "sourceUrl" character varying NOT NULL DEFAULT '', CONSTRAINT "PK_8640855ae82083455cbb806173d" PRIMARY KEY ("id"))`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE "entries"`); + } } diff --git a/src/migrations/1770067407619-add_create_update_delete_cols_and_rename_source_to_sourceText.ts b/src/migrations/1770067407619-add_create_update_delete_cols_and_rename_source_to_sourceText.ts index 94c76ce..e3c1185 100644 --- a/src/migrations/1770067407619-add_create_update_delete_cols_and_rename_source_to_sourceText.ts +++ b/src/migrations/1770067407619-add_create_update_delete_cols_and_rename_source_to_sourceText.ts @@ -1,22 +1,29 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCreateUpdateDeleteColsAndRenameSourceToSourceText1770067407619 implements MigrationInterface { - name = 'AddCreateUpdateDeleteColsAndRenameSourceToSourceText1770067407619' + name = 'AddCreateUpdateDeleteColsAndRenameSourceToSourceText1770067407619'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "entries" DROP COLUMN "source"`); - await queryRunner.query(`ALTER TABLE "entries" ADD "sourceText" character varying NOT NULL DEFAULT ''`); - await queryRunner.query(`ALTER TABLE "entries" ADD "created_at" TIMESTAMP NOT NULL DEFAULT now()`); - await queryRunner.query(`ALTER TABLE "entries" ADD "updated_at" TIMESTAMP NOT NULL DEFAULT now()`); - await queryRunner.query(`ALTER TABLE "entries" ADD "deleted_at" TIMESTAMP`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "entries" DROP COLUMN "deleted_at"`); - await queryRunner.query(`ALTER TABLE "entries" DROP COLUMN "updated_at"`); - await queryRunner.query(`ALTER TABLE "entries" DROP COLUMN "created_at"`); - await queryRunner.query(`ALTER TABLE "entries" DROP COLUMN "sourceText"`); - await queryRunner.query(`ALTER TABLE "entries" ADD "source" character varying NOT NULL DEFAULT ''`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "entries" DROP COLUMN "source"`); + await queryRunner.query( + `ALTER TABLE "entries" ADD "sourceText" character varying NOT NULL DEFAULT ''`, + ); + await queryRunner.query( + `ALTER TABLE "entries" ADD "created_at" TIMESTAMP NOT NULL DEFAULT now()`, + ); + await queryRunner.query( + `ALTER TABLE "entries" ADD "updated_at" TIMESTAMP NOT NULL DEFAULT now()`, + ); + await queryRunner.query(`ALTER TABLE "entries" ADD "deleted_at" TIMESTAMP`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "entries" DROP COLUMN "deleted_at"`); + await queryRunner.query(`ALTER TABLE "entries" DROP COLUMN "updated_at"`); + await queryRunner.query(`ALTER TABLE "entries" DROP COLUMN "created_at"`); + await queryRunner.query(`ALTER TABLE "entries" DROP COLUMN "sourceText"`); + await queryRunner.query( + `ALTER TABLE "entries" ADD "source" character varying NOT NULL DEFAULT ''`, + ); + } } diff --git a/src/migrations/1770147074119-add_user_entity.ts b/src/migrations/1770147074119-add_user_entity.ts new file mode 100644 index 0000000..f6a5709 --- /dev/null +++ b/src/migrations/1770147074119-add_user_entity.ts @@ -0,0 +1,15 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddUserEntity1770147074119 implements MigrationInterface { + name = 'AddUserEntity1770147074119'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "users" ("uuid" uuid NOT NULL DEFAULT uuid_generate_v4(), "id" SERIAL NOT NULL, "username" character varying NOT NULL DEFAULT '', "email" character varying NOT NULL DEFAULT '', "firstName" character varying NOT NULL DEFAULT '', "lastName" character varying NOT NULL DEFAULT '', "isAdmin" boolean NOT NULL DEFAULT false, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "updated_at" TIMESTAMP NOT NULL DEFAULT now(), "deleted_at" TIMESTAMP, CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id"))`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE "users"`); + } +} diff --git a/src/users/users.controller.spec.ts b/src/users/users.controller.spec.ts new file mode 100644 index 0000000..3e27c39 --- /dev/null +++ b/src/users/users.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { UsersController } from './users.controller'; + +describe('UsersController', () => { + let controller: UsersController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [UsersController], + }).compile(); + + controller = module.get(UsersController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts new file mode 100644 index 0000000..f06c942 --- /dev/null +++ b/src/users/users.controller.ts @@ -0,0 +1,22 @@ +import { Controller, Inject } from '@nestjs/common'; +import { UserService } from './users.service'; + +@Controller('users') +export class UsersController { + constructor( + @Inject(UserService) + private readonly userService: UserService, + ) {} + + // TODO: POST: save (create new) user + + // TODO: PUT: update user by UUID + + // TODO: GET: find all users + + // TODO: GET: find user by UUID + + // TODO: DELETE: soft delete user + + // TODO: PUT: restore soft deleted user +} diff --git a/src/users/users.dto.ts b/src/users/users.dto.ts new file mode 100644 index 0000000..cf2e38f --- /dev/null +++ b/src/users/users.dto.ts @@ -0,0 +1,9 @@ +import { User } from './users.entity'; + +export class UserDTO implements Partial { + email?: string; + firstName?: string; + isAdmin?: boolean; + lastName?: string; + username?: string; +} diff --git a/src/users/users.entity.ts b/src/users/users.entity.ts new file mode 100644 index 0000000..9faf151 --- /dev/null +++ b/src/users/users.entity.ts @@ -0,0 +1,43 @@ +import { + Column, + CreateDateColumn, + DeleteDateColumn, + Entity, + Generated, + PrimaryGeneratedColumn, + UpdateDateColumn, +} from 'typeorm'; + +@Entity({ name: 'users' }) +export class User { + @Column() + @Generated('uuid') + uuid?: string; + + @PrimaryGeneratedColumn('increment') + id?: number; + + @Column({ type: String, default: '' }) + username?: string; + + @Column({ type: String, default: '' }) + email?: string; + + @Column({ type: String, default: '' }) + firstName?: string; + + @Column({ type: String, default: '' }) + lastName?: string; + + @Column({ type: Boolean, default: false }) + isAdmin?: boolean; + + @CreateDateColumn() + created_at?: Date; + + @UpdateDateColumn() + updated_at?: Date; + + @DeleteDateColumn() + deleted_at?: Date; +} diff --git a/src/users/users.module.ts b/src/users/users.module.ts new file mode 100644 index 0000000..9bdf27a --- /dev/null +++ b/src/users/users.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { User } from './users.entity'; +import { UserService } from './users.service'; +import { UsersController } from './users.controller'; + +@Module({ + imports: [TypeOrmModule.forFeature([User])], + exports: [UserService], + providers: [UserService], + controllers: [UsersController], +}) +export class UsersModule {} diff --git a/src/users/users.service.ts b/src/users/users.service.ts new file mode 100644 index 0000000..6d06498 --- /dev/null +++ b/src/users/users.service.ts @@ -0,0 +1,27 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { User } from './users.entity'; +import { Repository } from 'typeorm'; + +@Injectable() +export class UserService { + constructor( + @InjectRepository(User) + private userRepository: Repository, + ) {} + private readonly logger = new Logger(UserService.name); + + // TODO: save (create new) + + // TODO: update by UUID + + // TODO: find one by UUID + + // TODO: find all + + // TODO: find all and deleted + + // TODO: soft delete + + // TODO: restore soft deleted by UUID +}