From a1bd6ff93928f72e41662b6f73bebda1788f120e Mon Sep 17 00:00:00 2001 From: Artem-Darius Atlas Date: Wed, 28 Jun 2023 22:53:13 +0300 Subject: [PATCH] feat: add user data service --- apps/auth-e2e/.eslintrc.json | 10 + apps/auth-e2e/jest.config.ts | 19 ++ apps/auth-e2e/project.json | 22 ++ apps/auth-e2e/src/auth/auth.spec.ts | 10 + apps/auth-e2e/src/support/global-setup.ts | 10 + apps/auth-e2e/src/support/global-teardown.ts | 7 + apps/auth-e2e/src/support/test-setup.ts | 10 + apps/auth-e2e/tsconfig.json | 13 + apps/auth-e2e/tsconfig.spec.json | 9 + apps/auth/.eslintrc.json | 18 ++ apps/auth/jest.config.ts | 11 + apps/auth/project.json | 64 +++++ apps/auth/src/app/app.controller.spec.ts | 22 ++ apps/auth/src/app/app.controller.ts | 13 + apps/auth/src/app/app.module.ts | 11 + apps/auth/src/app/app.service.spec.ts | 21 ++ apps/auth/src/app/app.service.ts | 8 + apps/auth/src/assets/.gitkeep | 0 apps/auth/src/main.ts | 22 ++ apps/auth/tsconfig.app.json | 12 + apps/auth/tsconfig.json | 16 ++ apps/auth/tsconfig.spec.json | 14 ++ apps/auth/webpack.config.js | 8 + apps/frontend/src/assets/CTF.jpg | Bin 0 -> 119264 bytes apps/user-data-e2e/.eslintrc.json | 10 + apps/user-data-e2e/jest.config.ts | 19 ++ apps/user-data-e2e/project.json | 22 ++ .../user-data-e2e/src/support/global-setup.ts | 10 + .../src/support/global-teardown.ts | 7 + apps/user-data-e2e/src/support/test-setup.ts | 10 + .../src/user-data/user-data.spec.ts | 10 + apps/user-data-e2e/tsconfig.json | 13 + apps/user-data-e2e/tsconfig.spec.json | 9 + apps/user-data/.ASC_MANIFEST | 13 + apps/user-data/.env.example | 8 + apps/user-data/.eslintrc.json | 18 ++ apps/user-data/.gitignore | 3 + apps/user-data/Dockerfile | 32 +++ apps/user-data/LICENSE | 11 + apps/user-data/jest.config.ts | 11 + apps/user-data/prisma/schema.prisma | 53 +++++ apps/user-data/project.json | 64 +++++ apps/user-data/serving/.gitignore | 225 ++++++++++++++++++ apps/user-data/serving/database.env.example | 3 + apps/user-data/serving/docker-compose.yaml | 34 +++ apps/user-data/src/app/app.controller.spec.ts | 22 ++ apps/user-data/src/app/app.controller.ts | 13 + apps/user-data/src/app/app.module.ts | 14 ++ .../src/app/service/app.service.spec.ts | 21 ++ apps/user-data/src/app/service/app.service.ts | 8 + apps/user-data/src/assets/.gitkeep | 0 .../src/email/email.controller.spec.ts | 18 ++ apps/user-data/src/email/email.controller.ts | 53 +++++ apps/user-data/src/email/email.module.ts | 12 + .../src/email/service/email.service.spec.ts | 18 ++ .../src/email/service/email.service.ts | 62 +++++ apps/user-data/src/main.ts | 22 ++ .../phone-number.controller.spec.ts | 18 ++ .../phone-number/phone-number.controller.ts | 53 +++++ .../src/phone-number/phone-number.module.ts | 12 + .../service/phone-number.service.spec.ts | 18 ++ .../service/phone-number.service.ts | 62 +++++ .../prisma/error/record-not-found.error.ts | 1 + .../error/unique-constraint-failed.error.ts | 1 + .../interceptor/prisma-error.interceptor.ts | 26 ++ apps/user-data/src/prisma/prisma.module.ts | 10 + .../src/prisma/service/prisma.service.spec.ts | 18 ++ .../src/prisma/service/prisma.service.ts | 15 ++ .../src/user/service/user.service.spec.ts | 18 ++ .../src/user/service/user.service.ts | 62 +++++ .../src/user/user.controller.spec.ts | 18 ++ apps/user-data/src/user/user.controller.ts | 53 +++++ apps/user-data/src/user/user.module.ts | 12 + apps/user-data/tsconfig.app.json | 12 + apps/user-data/tsconfig.json | 31 +++ apps/user-data/tsconfig.spec.json | 14 ++ apps/user-data/webpack.config.js | 8 + docker-compose.yml | 47 ++++ package-lock.json | 51 ++++ package.json | 2 + 80 files changed, 1760 insertions(+) create mode 100644 apps/auth-e2e/.eslintrc.json create mode 100644 apps/auth-e2e/jest.config.ts create mode 100644 apps/auth-e2e/project.json create mode 100644 apps/auth-e2e/src/auth/auth.spec.ts create mode 100644 apps/auth-e2e/src/support/global-setup.ts create mode 100644 apps/auth-e2e/src/support/global-teardown.ts create mode 100644 apps/auth-e2e/src/support/test-setup.ts create mode 100644 apps/auth-e2e/tsconfig.json create mode 100644 apps/auth-e2e/tsconfig.spec.json create mode 100644 apps/auth/.eslintrc.json create mode 100644 apps/auth/jest.config.ts create mode 100644 apps/auth/project.json create mode 100644 apps/auth/src/app/app.controller.spec.ts create mode 100644 apps/auth/src/app/app.controller.ts create mode 100644 apps/auth/src/app/app.module.ts create mode 100644 apps/auth/src/app/app.service.spec.ts create mode 100644 apps/auth/src/app/app.service.ts create mode 100644 apps/auth/src/assets/.gitkeep create mode 100644 apps/auth/src/main.ts create mode 100644 apps/auth/tsconfig.app.json create mode 100644 apps/auth/tsconfig.json create mode 100644 apps/auth/tsconfig.spec.json create mode 100644 apps/auth/webpack.config.js create mode 100644 apps/frontend/src/assets/CTF.jpg create mode 100644 apps/user-data-e2e/.eslintrc.json create mode 100644 apps/user-data-e2e/jest.config.ts create mode 100644 apps/user-data-e2e/project.json create mode 100644 apps/user-data-e2e/src/support/global-setup.ts create mode 100644 apps/user-data-e2e/src/support/global-teardown.ts create mode 100644 apps/user-data-e2e/src/support/test-setup.ts create mode 100644 apps/user-data-e2e/src/user-data/user-data.spec.ts create mode 100644 apps/user-data-e2e/tsconfig.json create mode 100644 apps/user-data-e2e/tsconfig.spec.json create mode 100644 apps/user-data/.ASC_MANIFEST create mode 100644 apps/user-data/.env.example create mode 100644 apps/user-data/.eslintrc.json create mode 100644 apps/user-data/.gitignore create mode 100644 apps/user-data/Dockerfile create mode 100644 apps/user-data/LICENSE create mode 100644 apps/user-data/jest.config.ts create mode 100644 apps/user-data/prisma/schema.prisma create mode 100644 apps/user-data/project.json create mode 100644 apps/user-data/serving/.gitignore create mode 100644 apps/user-data/serving/database.env.example create mode 100644 apps/user-data/serving/docker-compose.yaml create mode 100644 apps/user-data/src/app/app.controller.spec.ts create mode 100644 apps/user-data/src/app/app.controller.ts create mode 100644 apps/user-data/src/app/app.module.ts create mode 100644 apps/user-data/src/app/service/app.service.spec.ts create mode 100644 apps/user-data/src/app/service/app.service.ts create mode 100644 apps/user-data/src/assets/.gitkeep create mode 100644 apps/user-data/src/email/email.controller.spec.ts create mode 100644 apps/user-data/src/email/email.controller.ts create mode 100644 apps/user-data/src/email/email.module.ts create mode 100644 apps/user-data/src/email/service/email.service.spec.ts create mode 100644 apps/user-data/src/email/service/email.service.ts create mode 100644 apps/user-data/src/main.ts create mode 100644 apps/user-data/src/phone-number/phone-number.controller.spec.ts create mode 100644 apps/user-data/src/phone-number/phone-number.controller.ts create mode 100644 apps/user-data/src/phone-number/phone-number.module.ts create mode 100644 apps/user-data/src/phone-number/service/phone-number.service.spec.ts create mode 100644 apps/user-data/src/phone-number/service/phone-number.service.ts create mode 100644 apps/user-data/src/prisma/error/record-not-found.error.ts create mode 100644 apps/user-data/src/prisma/error/unique-constraint-failed.error.ts create mode 100644 apps/user-data/src/prisma/interceptor/prisma-error.interceptor.ts create mode 100644 apps/user-data/src/prisma/prisma.module.ts create mode 100644 apps/user-data/src/prisma/service/prisma.service.spec.ts create mode 100644 apps/user-data/src/prisma/service/prisma.service.ts create mode 100644 apps/user-data/src/user/service/user.service.spec.ts create mode 100644 apps/user-data/src/user/service/user.service.ts create mode 100644 apps/user-data/src/user/user.controller.spec.ts create mode 100644 apps/user-data/src/user/user.controller.ts create mode 100644 apps/user-data/src/user/user.module.ts create mode 100644 apps/user-data/tsconfig.app.json create mode 100644 apps/user-data/tsconfig.json create mode 100644 apps/user-data/tsconfig.spec.json create mode 100644 apps/user-data/webpack.config.js diff --git a/apps/auth-e2e/.eslintrc.json b/apps/auth-e2e/.eslintrc.json new file mode 100644 index 0000000..8852e20 --- /dev/null +++ b/apps/auth-e2e/.eslintrc.json @@ -0,0 +1,10 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/apps/auth-e2e/jest.config.ts b/apps/auth-e2e/jest.config.ts new file mode 100644 index 0000000..750cb86 --- /dev/null +++ b/apps/auth-e2e/jest.config.ts @@ -0,0 +1,19 @@ +/* eslint-disable */ +export default { + displayName: 'auth-e2e', + preset: '../../jest.preset.js', + globalSetup: '/src/support/global-setup.ts', + globalTeardown: '/src/support/global-teardown.ts', + setupFiles: ['/src/support/test-setup.ts'], + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': [ + 'ts-jest', + { + tsconfig: '/tsconfig.spec.json', + }, + ], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/auth-e2e', +}; diff --git a/apps/auth-e2e/project.json b/apps/auth-e2e/project.json new file mode 100644 index 0000000..bcf1d3a --- /dev/null +++ b/apps/auth-e2e/project.json @@ -0,0 +1,22 @@ +{ + "name": "auth-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "implicitDependencies": ["auth"], + "targets": { + "e2e": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{e2eProjectRoot}"], + "options": { + "jestConfig": "apps/auth-e2e/jest.config.ts", + "passWithNoTests": true + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/auth-e2e/**/*.{js,ts}"] + } + } + } +} diff --git a/apps/auth-e2e/src/auth/auth.spec.ts b/apps/auth-e2e/src/auth/auth.spec.ts new file mode 100644 index 0000000..e8ac2a6 --- /dev/null +++ b/apps/auth-e2e/src/auth/auth.spec.ts @@ -0,0 +1,10 @@ +import axios from 'axios'; + +describe('GET /api', () => { + it('should return a message', async () => { + const res = await axios.get(`/api`); + + expect(res.status).toBe(200); + expect(res.data).toEqual({ message: 'Hello API' }); + }); +}); diff --git a/apps/auth-e2e/src/support/global-setup.ts b/apps/auth-e2e/src/support/global-setup.ts new file mode 100644 index 0000000..c1f5144 --- /dev/null +++ b/apps/auth-e2e/src/support/global-setup.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ +var __TEARDOWN_MESSAGE__: string; + +module.exports = async function () { + // Start services that that the app needs to run (e.g. database, docker-compose, etc.). + console.log('\nSetting up...\n'); + + // Hint: Use `globalThis` to pass variables to global teardown. + globalThis.__TEARDOWN_MESSAGE__ = '\nTearing down...\n'; +}; diff --git a/apps/auth-e2e/src/support/global-teardown.ts b/apps/auth-e2e/src/support/global-teardown.ts new file mode 100644 index 0000000..32ea345 --- /dev/null +++ b/apps/auth-e2e/src/support/global-teardown.ts @@ -0,0 +1,7 @@ +/* eslint-disable */ + +module.exports = async function () { + // Put clean up logic here (e.g. stopping services, docker-compose, etc.). + // Hint: `globalThis` is shared between setup and teardown. + console.log(globalThis.__TEARDOWN_MESSAGE__); +}; diff --git a/apps/auth-e2e/src/support/test-setup.ts b/apps/auth-e2e/src/support/test-setup.ts new file mode 100644 index 0000000..07f2870 --- /dev/null +++ b/apps/auth-e2e/src/support/test-setup.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ + +import axios from 'axios'; + +module.exports = async function () { + // Configure axios for tests to use. + const host = process.env.HOST ?? 'localhost'; + const port = process.env.PORT ?? '3000'; + axios.defaults.baseURL = `http://${host}:${port}`; +}; diff --git a/apps/auth-e2e/tsconfig.json b/apps/auth-e2e/tsconfig.json new file mode 100644 index 0000000..ed633e1 --- /dev/null +++ b/apps/auth-e2e/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/apps/auth-e2e/tsconfig.spec.json b/apps/auth-e2e/tsconfig.spec.json new file mode 100644 index 0000000..d7f9cf2 --- /dev/null +++ b/apps/auth-e2e/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": ["jest.config.ts", "src/**/*.ts"] +} diff --git a/apps/auth/.eslintrc.json b/apps/auth/.eslintrc.json new file mode 100644 index 0000000..9d9c0db --- /dev/null +++ b/apps/auth/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/apps/auth/jest.config.ts b/apps/auth/jest.config.ts new file mode 100644 index 0000000..b4b7e15 --- /dev/null +++ b/apps/auth/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'auth', + preset: '../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/apps/auth', +}; diff --git a/apps/auth/project.json b/apps/auth/project.json new file mode 100644 index 0000000..76da07a --- /dev/null +++ b/apps/auth/project.json @@ -0,0 +1,64 @@ +{ + "name": "auth", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/auth/src", + "projectType": "application", + "targets": { + "build": { + "executor": "@nx/webpack:webpack", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "production", + "options": { + "target": "node", + "compiler": "tsc", + "outputPath": "dist/apps/auth", + "main": "apps/auth/src/main.ts", + "tsConfig": "apps/auth/tsconfig.app.json", + "assets": ["apps/auth/src/assets"], + "isolatedConfig": true, + "webpackConfig": "apps/auth/webpack.config.js" + }, + "configurations": { + "development": {}, + "production": {} + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "auth:build" + }, + "configurations": { + "development": { + "buildTarget": "auth:build:development" + }, + "production": { + "buildTarget": "auth:build:production" + } + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/auth/**/*.ts"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "apps/auth/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + } + }, + "tags": [] +} diff --git a/apps/auth/src/app/app.controller.spec.ts b/apps/auth/src/app/app.controller.spec.ts new file mode 100644 index 0000000..de8007e --- /dev/null +++ b/apps/auth/src/app/app.controller.spec.ts @@ -0,0 +1,22 @@ +import { Test, TestingModule } from '@nestjs/testing'; + +import { AppController } from './app.controller'; +import { AppService } from './app.service'; + +describe('AppController', () => { + let app: TestingModule; + + beforeAll(async () => { + app = await Test.createTestingModule({ + controllers: [AppController], + providers: [AppService], + }).compile(); + }); + + describe('getData', () => { + it('should return "Hello API"', () => { + const appController = app.get(AppController); + expect(appController.getData()).toEqual({ message: 'Hello API' }); + }); + }); +}); diff --git a/apps/auth/src/app/app.controller.ts b/apps/auth/src/app/app.controller.ts new file mode 100644 index 0000000..dff210a --- /dev/null +++ b/apps/auth/src/app/app.controller.ts @@ -0,0 +1,13 @@ +import { Controller, Get } from '@nestjs/common'; + +import { AppService } from './app.service'; + +@Controller() +export class AppController { + constructor(private readonly appService: AppService) {} + + @Get() + getData() { + return this.appService.getData(); + } +} diff --git a/apps/auth/src/app/app.module.ts b/apps/auth/src/app/app.module.ts new file mode 100644 index 0000000..6a9bc16 --- /dev/null +++ b/apps/auth/src/app/app.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; + +import { AppController } from './app.controller'; +import { AppService } from './app.service'; + +@Module({ + imports: [], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} diff --git a/apps/auth/src/app/app.service.spec.ts b/apps/auth/src/app/app.service.spec.ts new file mode 100644 index 0000000..42cf0a2 --- /dev/null +++ b/apps/auth/src/app/app.service.spec.ts @@ -0,0 +1,21 @@ +import { Test } from '@nestjs/testing'; + +import { AppService } from './app.service'; + +describe('AppService', () => { + let service: AppService; + + beforeAll(async () => { + const app = await Test.createTestingModule({ + providers: [AppService], + }).compile(); + + service = app.get(AppService); + }); + + describe('getData', () => { + it('should return "Hello API"', () => { + expect(service.getData()).toEqual({ message: 'Hello API' }); + }); + }); +}); diff --git a/apps/auth/src/app/app.service.ts b/apps/auth/src/app/app.service.ts new file mode 100644 index 0000000..cd8cede --- /dev/null +++ b/apps/auth/src/app/app.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AppService { + getData(): { message: string } { + return { message: 'Hello API' }; + } +} diff --git a/apps/auth/src/assets/.gitkeep b/apps/auth/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/auth/src/main.ts b/apps/auth/src/main.ts new file mode 100644 index 0000000..a124382 --- /dev/null +++ b/apps/auth/src/main.ts @@ -0,0 +1,22 @@ +/** + * This is not a production server yet! + * This is only a minimal backend to get started. + */ + +import { Logger } from '@nestjs/common'; +import { NestFactory } from '@nestjs/core'; + +import { AppModule } from './app/app.module'; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + const globalPrefix = 'api'; + app.setGlobalPrefix(globalPrefix); + const port = process.env.PORT || 3000; + await app.listen(port); + Logger.log( + `πŸš€ Application is running on: http://localhost:${port}/${globalPrefix}` + ); +} + +bootstrap(); diff --git a/apps/auth/tsconfig.app.json b/apps/auth/tsconfig.app.json new file mode 100644 index 0000000..a2ce765 --- /dev/null +++ b/apps/auth/tsconfig.app.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["node"], + "emitDecoratorMetadata": true, + "target": "es2021" + }, + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/apps/auth/tsconfig.json b/apps/auth/tsconfig.json new file mode 100644 index 0000000..c1e2dd4 --- /dev/null +++ b/apps/auth/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/apps/auth/tsconfig.spec.json b/apps/auth/tsconfig.spec.json new file mode 100644 index 0000000..9b2a121 --- /dev/null +++ b/apps/auth/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/auth/webpack.config.js b/apps/auth/webpack.config.js new file mode 100644 index 0000000..81db92b --- /dev/null +++ b/apps/auth/webpack.config.js @@ -0,0 +1,8 @@ +const { composePlugins, withNx } = require('@nx/webpack'); + +// Nx plugins for webpack. +module.exports = composePlugins(withNx(), (config) => { + // Update the webpack config as needed here. + // e.g. `config.plugins.push(new MyPlugin())` + return config; +}); diff --git a/apps/frontend/src/assets/CTF.jpg b/apps/frontend/src/assets/CTF.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0801447d53f7f8e7c28df420f8743c76bb4efcde GIT binary patch literal 119264 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⪰3;6sX?NDg%V;`Qp~C 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%0A~5G*ST{rLnS!^Xk){ekbpajU55|5{V7H8$5s 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/src/support/global-setup.ts', + globalTeardown: '/src/support/global-teardown.ts', + setupFiles: ['/src/support/test-setup.ts'], + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': [ + 'ts-jest', + { + tsconfig: '/tsconfig.spec.json', + }, + ], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/user-data-e2e', +}; diff --git a/apps/user-data-e2e/project.json b/apps/user-data-e2e/project.json new file mode 100644 index 0000000..840891a --- /dev/null +++ b/apps/user-data-e2e/project.json @@ -0,0 +1,22 @@ +{ + "name": "user-data-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "implicitDependencies": ["user-data"], + "targets": { + "e2e": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{e2eProjectRoot}"], + "options": { + "jestConfig": "apps/user-data-e2e/jest.config.ts", + "passWithNoTests": true + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/user-data-e2e/**/*.{js,ts}"] + } + } + } +} diff --git a/apps/user-data-e2e/src/support/global-setup.ts b/apps/user-data-e2e/src/support/global-setup.ts new file mode 100644 index 0000000..c1f5144 --- /dev/null +++ b/apps/user-data-e2e/src/support/global-setup.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ +var __TEARDOWN_MESSAGE__: string; + +module.exports = async function () { + // Start services that that the app needs to run (e.g. database, docker-compose, etc.). + console.log('\nSetting up...\n'); + + // Hint: Use `globalThis` to pass variables to global teardown. + globalThis.__TEARDOWN_MESSAGE__ = '\nTearing down...\n'; +}; diff --git a/apps/user-data-e2e/src/support/global-teardown.ts b/apps/user-data-e2e/src/support/global-teardown.ts new file mode 100644 index 0000000..32ea345 --- /dev/null +++ b/apps/user-data-e2e/src/support/global-teardown.ts @@ -0,0 +1,7 @@ +/* eslint-disable */ + +module.exports = async function () { + // Put clean up logic here (e.g. stopping services, docker-compose, etc.). + // Hint: `globalThis` is shared between setup and teardown. + console.log(globalThis.__TEARDOWN_MESSAGE__); +}; diff --git a/apps/user-data-e2e/src/support/test-setup.ts b/apps/user-data-e2e/src/support/test-setup.ts new file mode 100644 index 0000000..07f2870 --- /dev/null +++ b/apps/user-data-e2e/src/support/test-setup.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ + +import axios from 'axios'; + +module.exports = async function () { + // Configure axios for tests to use. + const host = process.env.HOST ?? 'localhost'; + const port = process.env.PORT ?? '3000'; + axios.defaults.baseURL = `http://${host}:${port}`; +}; diff --git a/apps/user-data-e2e/src/user-data/user-data.spec.ts b/apps/user-data-e2e/src/user-data/user-data.spec.ts new file mode 100644 index 0000000..e8ac2a6 --- /dev/null +++ b/apps/user-data-e2e/src/user-data/user-data.spec.ts @@ -0,0 +1,10 @@ +import axios from 'axios'; + +describe('GET /api', () => { + it('should return a message', async () => { + const res = await axios.get(`/api`); + + expect(res.status).toBe(200); + expect(res.data).toEqual({ message: 'Hello API' }); + }); +}); diff --git a/apps/user-data-e2e/tsconfig.json b/apps/user-data-e2e/tsconfig.json new file mode 100644 index 0000000..ed633e1 --- /dev/null +++ b/apps/user-data-e2e/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/apps/user-data-e2e/tsconfig.spec.json b/apps/user-data-e2e/tsconfig.spec.json new file mode 100644 index 0000000..d7f9cf2 --- /dev/null +++ b/apps/user-data-e2e/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": ["jest.config.ts", "src/**/*.ts"] +} diff --git a/apps/user-data/.ASC_MANIFEST b/apps/user-data/.ASC_MANIFEST new file mode 100644 index 0000000..63abe52 --- /dev/null +++ b/apps/user-data/.ASC_MANIFEST @@ -0,0 +1,13 @@ +$$ +@version: 0.1.0; +@scuuid: 27895030-15ec-11ee-be56-0242ac120002; +@type: service; +@platform: nestjs; +@license: BSD-3-Clause; +@owner: artem-darius weber; +@author: ; +@title: user-data; +@desc: ; +@rp: kubsu it lab; +@vr: 7093; +$$ diff --git a/apps/user-data/.env.example b/apps/user-data/.env.example new file mode 100644 index 0000000..6c89035 --- /dev/null +++ b/apps/user-data/.env.example @@ -0,0 +1,8 @@ +# Environment variables declared in this file are automatically made available to Prisma. +# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema + +# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. +# See the documentation for all the connection string options: https://pris.ly/d/connection-strings + +DATABASE_URL=postgresql://postgres:postgres@sc-user-data-database/sc-user-data +PORT=3002 diff --git a/apps/user-data/.eslintrc.json b/apps/user-data/.eslintrc.json new file mode 100644 index 0000000..9d9c0db --- /dev/null +++ b/apps/user-data/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/apps/user-data/.gitignore b/apps/user-data/.gitignore new file mode 100644 index 0000000..11ddd8d --- /dev/null +++ b/apps/user-data/.gitignore @@ -0,0 +1,3 @@ +node_modules +# Keep environment variables out of version control +.env diff --git a/apps/user-data/Dockerfile b/apps/user-data/Dockerfile new file mode 100644 index 0000000..f0b43cf --- /dev/null +++ b/apps/user-data/Dockerfile @@ -0,0 +1,32 @@ +# syntax=docker/dockerfile:1 +FROM node:18 + +WORKDIR /app + +COPY --chown=node:node . . + +RUN rm -f *.env *.env.* + +RUN apt-get update -y && apt-get install -y dumb-init + +RUN npm install + +ENV NODE_ENV=production + +RUN npm run prefullbuild && npm run prebuild && npm run build + +RUN mkdir temp temp/.prisma temp/@prisma temp/prisma && cp -r ./node_modules/.prisma/* ./temp/.prisma/ && cp -r ./node_modules/@prisma/* ./temp/@prisma/ && cp -r ./node_modules/prisma/* ./temp/prisma/ + +RUN rm -rdf node_modules + +RUN npm install --production + +RUN cp -r ./temp/* ./node_modules/ && rm -rdf temp + +RUN ls | grep -v node_modules | grep -v dist | xargs rm -rfv + +RUN cp -r ./dist/* ./ && rm -rdf dist + +USER node + +CMD ["dumb-init", "node", "./main.js"] diff --git a/apps/user-data/LICENSE b/apps/user-data/LICENSE new file mode 100644 index 0000000..d62cc9d --- /dev/null +++ b/apps/user-data/LICENSE @@ -0,0 +1,11 @@ +Copyright 2023 SC (DJEEFT) Β© + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS β€œAS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/apps/user-data/jest.config.ts b/apps/user-data/jest.config.ts new file mode 100644 index 0000000..98babab --- /dev/null +++ b/apps/user-data/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'user-data', + preset: '../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/apps/user-data', +}; diff --git a/apps/user-data/prisma/schema.prisma b/apps/user-data/prisma/schema.prisma new file mode 100644 index 0000000..4b6ad66 --- /dev/null +++ b/apps/user-data/prisma/schema.prisma @@ -0,0 +1,53 @@ +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" +} + +model User { + uuid String @id @default(uuid()) @db.Uuid + + email Email? @relation("mainEmail") + phoneNumber PhoneNumber? @relation("mainPhoneNumber") + + reserveEmails Email[] @relation("reserveEmails") + reservePhoneNumbers PhoneNumber[] @relation("reservePhoneNumbers") + + extendedData Json @default("{}") @db.JsonB + + createdAt DateTime @db.Timestamp(3) + updatedAt DateTime @db.Timestamp(3) +} + +model Email { + uuid String @id @default(uuid()) @db.Uuid + + email String @unique @db.VarChar(256) + + userUuid String? @unique @db.Uuid + user User? @relation("mainEmail", fields: [userUuid], references: [uuid]) + + userUuidReserve String? @db.Uuid + userReserve User? @relation("reserveEmails", fields: [userUuidReserve], references: [uuid]) + + createdAt DateTime @db.Timestamp(3) + updatedAt DateTime @db.Timestamp(3) +} + +model PhoneNumber { + uuid String @id @default(uuid()) @db.Uuid + + phoneNumber String @unique @db.VarChar(20) + + userUuid String? @unique @db.Uuid + user User? @relation("mainPhoneNumber", fields: [userUuid], references: [uuid]) + + userUuidReserve String? @db.Uuid + userReserve User? @relation("reservePhoneNumbers", fields: [userUuidReserve], references: [uuid]) + + createdAt DateTime @db.Timestamp(3) + updatedAt DateTime @db.Timestamp(3) +} diff --git a/apps/user-data/project.json b/apps/user-data/project.json new file mode 100644 index 0000000..d34fe8e --- /dev/null +++ b/apps/user-data/project.json @@ -0,0 +1,64 @@ +{ + "name": "user-data", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/user-data/src", + "projectType": "application", + "targets": { + "build": { + "executor": "@nx/webpack:webpack", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "production", + "options": { + "target": "node", + "compiler": "tsc", + "outputPath": "dist/apps/user-data", + "main": "apps/user-data/src/main.ts", + "tsConfig": "apps/user-data/tsconfig.app.json", + "assets": ["apps/user-data/src/assets"], + "isolatedConfig": true, + "webpackConfig": "apps/user-data/webpack.config.js" + }, + "configurations": { + "development": {}, + "production": {} + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "user-data:build" + }, + "configurations": { + "development": { + "buildTarget": "user-data:build:development" + }, + "production": { + "buildTarget": "user-data:build:production" + } + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/user-data/**/*.ts"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "apps/user-data/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + } + }, + "tags": [] +} diff --git a/apps/user-data/serving/.gitignore b/apps/user-data/serving/.gitignore new file mode 100644 index 0000000..7278035 --- /dev/null +++ b/apps/user-data/serving/.gitignore @@ -0,0 +1,225 @@ +*.env +.idea + +### NotepadPP template +# Notepad++ backups # +*.bak + +### VisualStudioCode template +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Xcode template +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +build/ +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 + +## Gcc Patch +/*.gcno + +### Linux template +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### Kate template +# Swap Files # +.*.kate-swp +.swp.* + +### Windows template +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### macOS template +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### SublimeText template +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json +sftp-config-alt*.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings diff --git a/apps/user-data/serving/database.env.example b/apps/user-data/serving/database.env.example new file mode 100644 index 0000000..c44f3ae --- /dev/null +++ b/apps/user-data/serving/database.env.example @@ -0,0 +1,3 @@ +POSTGRES_DB=sc-user-data +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres diff --git a/apps/user-data/serving/docker-compose.yaml b/apps/user-data/serving/docker-compose.yaml new file mode 100644 index 0000000..0e8a651 --- /dev/null +++ b/apps/user-data/serving/docker-compose.yaml @@ -0,0 +1,34 @@ +version: "3.9" + +services: + user-data-database: + image: postgres:latest + container_name: user-data-database + restart: always + networks: + - user-data + volumes: + - user-data-database:/var/lib/postgresql + env_file: + - ./database.env + user-data-database-admin: + container_name: user-data-database-admin + image: bitnami/phppgadmin:latest + restart: always + networks: + - user-data + depends_on: + - user-data-database + environment: + - DATABASE_HOST=user-data-database + ports: + - "8083:8080" + +networks: + user-data: + name: user-data + driver: bridge + +volumes: + user-data-database: + driver: local diff --git a/apps/user-data/src/app/app.controller.spec.ts b/apps/user-data/src/app/app.controller.spec.ts new file mode 100644 index 0000000..a6e8d35 --- /dev/null +++ b/apps/user-data/src/app/app.controller.spec.ts @@ -0,0 +1,22 @@ +import { Test, TestingModule } from '@nestjs/testing'; + +import { AppController } from './app.controller'; +import { AppService } from './service/app.service'; + +describe('AppController', () => { + let app: TestingModule; + + beforeAll(async () => { + app = await Test.createTestingModule({ + controllers: [AppController], + providers: [AppService], + }).compile(); + }); + + describe('getData', () => { + it('should return "Hello API"', () => { + const appController = app.get(AppController); + expect(appController.getData()).toEqual({ message: 'Hello API' }); + }); + }); +}); diff --git a/apps/user-data/src/app/app.controller.ts b/apps/user-data/src/app/app.controller.ts new file mode 100644 index 0000000..0c6a72d --- /dev/null +++ b/apps/user-data/src/app/app.controller.ts @@ -0,0 +1,13 @@ +import { Controller, Get } from '@nestjs/common'; + +import { AppService } from './service/app.service'; + +@Controller() +export class AppController { + constructor(private readonly appService: AppService) {} + + @Get() + getData() { + return this.appService.getData(); + } +} diff --git a/apps/user-data/src/app/app.module.ts b/apps/user-data/src/app/app.module.ts new file mode 100644 index 0000000..e8f09b7 --- /dev/null +++ b/apps/user-data/src/app/app.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common'; + +import { AppController } from './app.controller'; +import { AppService } from './service/app.service'; +import { UserModule } from "../user/user.module"; +import { EmailModule } from "../email/email.module"; +import { PhoneNumberModule } from "../phone-number/phone-number.module"; + +@Module({ + imports: [UserModule, EmailModule, PhoneNumberModule], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} diff --git a/apps/user-data/src/app/service/app.service.spec.ts b/apps/user-data/src/app/service/app.service.spec.ts new file mode 100644 index 0000000..42cf0a2 --- /dev/null +++ b/apps/user-data/src/app/service/app.service.spec.ts @@ -0,0 +1,21 @@ +import { Test } from '@nestjs/testing'; + +import { AppService } from './app.service'; + +describe('AppService', () => { + let service: AppService; + + beforeAll(async () => { + const app = await Test.createTestingModule({ + providers: [AppService], + }).compile(); + + service = app.get(AppService); + }); + + describe('getData', () => { + it('should return "Hello API"', () => { + expect(service.getData()).toEqual({ message: 'Hello API' }); + }); + }); +}); diff --git a/apps/user-data/src/app/service/app.service.ts b/apps/user-data/src/app/service/app.service.ts new file mode 100644 index 0000000..cd8cede --- /dev/null +++ b/apps/user-data/src/app/service/app.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AppService { + getData(): { message: string } { + return { message: 'Hello API' }; + } +} diff --git a/apps/user-data/src/assets/.gitkeep b/apps/user-data/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/user-data/src/email/email.controller.spec.ts b/apps/user-data/src/email/email.controller.spec.ts new file mode 100644 index 0000000..9470aa8 --- /dev/null +++ b/apps/user-data/src/email/email.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { EmailController } from './email.controller'; + +describe('EmailController', () => { + let controller: EmailController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [EmailController], + }).compile(); + + controller = module.get(EmailController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/apps/user-data/src/email/email.controller.ts b/apps/user-data/src/email/email.controller.ts new file mode 100644 index 0000000..f4dade4 --- /dev/null +++ b/apps/user-data/src/email/email.controller.ts @@ -0,0 +1,53 @@ +import { Body, Controller, HttpCode, Inject, Post, UseInterceptors } from "@nestjs/common"; +import { Prisma, Email } from "@prisma/client"; +import { EmailService } from "./service/email.service"; +import { PrismaErrorInterceptor } from "../prisma/interceptor/prisma-error.interceptor"; + +@Controller("email") +@UseInterceptors(PrismaErrorInterceptor) +export class EmailController { + constructor(@Inject(EmailService) private email: EmailService) { + } + + @Post("find/unique") + @HttpCode(200) + async FindUnique(@Body() emailFindUniqueArgs: Prisma.EmailFindUniqueArgs): Promise | null> { + return await this.email.FindUnique(emailFindUniqueArgs); + } + + @Post("find/first") + @HttpCode(200) + async FindFirst(@Body() emailFindFirstArgs: Prisma.EmailFindFirstArgs): Promise | null> { + return await this.email.FindFirst(emailFindFirstArgs); + } + + @Post("find/many") + @HttpCode(200) + async FindMany(@Body() emailFindManyArgs: Prisma.EmailFindManyArgs): Promise[]> { + return await this.email.FindMany(emailFindManyArgs); + } + + @Post("update") + @HttpCode(200) + async Update(@Body() emailUpdateArgs: Prisma.EmailUpdateArgs): Promise> { + return await this.email.Update(emailUpdateArgs); + } + + @Post("count") + @HttpCode(200) + async Count(@Body() emailCountArgs: Prisma.EmailCountArgs): Promise { + return await this.email.Count(emailCountArgs); + } + + @Post("create") + @HttpCode(200) + async Create(@Body() emailCreateArgs: Prisma.EmailCreateArgs): Promise> { + return await this.email.Create(emailCreateArgs); + } + + @Post("delete") + @HttpCode(200) + async Delete(@Body() emailDeleteArgs: Prisma.EmailDeleteArgs): Promise> { + return await this.email.Delete(emailDeleteArgs); + } +} diff --git a/apps/user-data/src/email/email.module.ts b/apps/user-data/src/email/email.module.ts new file mode 100644 index 0000000..693fee6 --- /dev/null +++ b/apps/user-data/src/email/email.module.ts @@ -0,0 +1,12 @@ +import { Module } from "@nestjs/common"; +import { EmailController } from "./email.controller"; +import { EmailService } from "./service/email.service"; +import { PrismaModule } from "../prisma/prisma.module"; + +@Module({ + imports: [PrismaModule], + controllers: [EmailController], + providers: [EmailService] +}) +export class EmailModule { +} diff --git a/apps/user-data/src/email/service/email.service.spec.ts b/apps/user-data/src/email/service/email.service.spec.ts new file mode 100644 index 0000000..27719da --- /dev/null +++ b/apps/user-data/src/email/service/email.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { EmailService } from './email.service'; + +describe('EmailService', () => { + let service: EmailService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [EmailService], + }).compile(); + + service = module.get(EmailService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/user-data/src/email/service/email.service.ts b/apps/user-data/src/email/service/email.service.ts new file mode 100644 index 0000000..b64799c --- /dev/null +++ b/apps/user-data/src/email/service/email.service.ts @@ -0,0 +1,62 @@ +import { Inject, Injectable } from "@nestjs/common"; +import { PrismaService } from '../../prisma/service/prisma.service'; +import { Email, Prisma } from "@prisma/client"; +import { PrismaClientKnownRequestError } from "@prisma/client/runtime"; +import { UniqueConstraintFailedError } from "../../prisma/error/unique-constraint-failed.error"; +import { RecordNotFoundError } from "../../prisma/error/record-not-found.error"; + +@Injectable() +export class EmailService { + constructor(@Inject(PrismaService) private prisma: PrismaService) { + } + + async FindUnique(emailFindUniqueArgs: Prisma.EmailFindUniqueArgs): Promise | null> { + return await this.prisma.email.findUnique(emailFindUniqueArgs); + } + + async FindFirst(emailFindFirstArgs: Prisma.EmailFindFirstArgs): Promise | null> { + return await this.prisma.email.findFirst(emailFindFirstArgs); + } + + async FindMany(emailFindManyArgs: Prisma.EmailFindManyArgs): Promise[]> { + return await this.prisma.email.findMany(emailFindManyArgs); + } + + async Update(emailUpdateArgs: Prisma.EmailUpdateArgs): Promise> { + try { + return await this.prisma.email.update(emailUpdateArgs); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError) { + if (e.code === "P2025") throw new RecordNotFoundError("Record to update not found."); + if (e.code === "P2002") throw new UniqueConstraintFailedError("Unique constant failed"); + } + throw e; + } + } + + async Count(emailCountArgs: Prisma.EmailCountArgs): Promise { + return await this.prisma.email.count(emailCountArgs); + } + + async Create(emailCreateArgs: Prisma.EmailCreateArgs): Promise> { + try { + return await this.prisma.email.create(emailCreateArgs); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError) { + if (e.code === "P2002") throw new UniqueConstraintFailedError("Unique constant failed"); + } + throw e; + } + } + + async Delete(emailDeleteArgs: Prisma.EmailDeleteArgs): Promise> { + try { + return await this.prisma.email.delete(emailDeleteArgs); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError) { + if (e.code === "P2025") throw new RecordNotFoundError("Record to delete not found."); + } + throw e; + } + } +} diff --git a/apps/user-data/src/main.ts b/apps/user-data/src/main.ts new file mode 100644 index 0000000..5794fe8 --- /dev/null +++ b/apps/user-data/src/main.ts @@ -0,0 +1,22 @@ +/** + * This is not a production server yet! + * This is only a minimal backend to get started. + */ + +import { Logger } from '@nestjs/common'; +import { NestFactory } from '@nestjs/core'; + +import { AppModule } from './app/app.module'; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + const globalPrefix = 'api'; + app.setGlobalPrefix(globalPrefix); + const port = process.env.PORT || 3002; + await app.listen(port); + Logger.log( + `πŸš€ User Data Application is running on: http://localhost:${port}/${globalPrefix}` + ); +} + +bootstrap(); diff --git a/apps/user-data/src/phone-number/phone-number.controller.spec.ts b/apps/user-data/src/phone-number/phone-number.controller.spec.ts new file mode 100644 index 0000000..ed89b8a --- /dev/null +++ b/apps/user-data/src/phone-number/phone-number.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PhoneNumberController } from './phone-number.controller'; + +describe('PhoneNumberController', () => { + let controller: PhoneNumberController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [PhoneNumberController], + }).compile(); + + controller = module.get(PhoneNumberController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/apps/user-data/src/phone-number/phone-number.controller.ts b/apps/user-data/src/phone-number/phone-number.controller.ts new file mode 100644 index 0000000..a4fae62 --- /dev/null +++ b/apps/user-data/src/phone-number/phone-number.controller.ts @@ -0,0 +1,53 @@ +import { Body, Controller, HttpCode, Inject, Post, UseInterceptors } from "@nestjs/common"; +import { PhoneNumber, Prisma } from "@prisma/client"; +import { PhoneNumberService } from "./service/phone-number.service"; +import { PrismaErrorInterceptor } from "../prisma/interceptor/prisma-error.interceptor"; + +@Controller("phoneNumber") +@UseInterceptors(PrismaErrorInterceptor) +export class PhoneNumberController { + constructor(@Inject(PhoneNumberService) private phoneNumber: PhoneNumberService) { + } + + @Post("find/unique") + @HttpCode(200) + async FindUnique(@Body() phoneNumberFindUniqueArgs: Prisma.PhoneNumberFindUniqueArgs): Promise | null> { + return await this.phoneNumber.FindUnique(phoneNumberFindUniqueArgs); + } + + @Post("find/first") + @HttpCode(200) + async FindFirst(@Body() phoneNumberFindFirstArgs: Prisma.PhoneNumberFindFirstArgs): Promise | null> { + return await this.phoneNumber.FindFirst(phoneNumberFindFirstArgs); + } + + @Post("find/many") + @HttpCode(200) + async FindMany(@Body() phoneNumberFindManyArgs: Prisma.PhoneNumberFindManyArgs): Promise[]> { + return await this.phoneNumber.FindMany(phoneNumberFindManyArgs); + } + + @Post("update") + @HttpCode(200) + async Update(@Body() phoneNumberUpdateArgs: Prisma.PhoneNumberUpdateArgs): Promise> { + return await this.phoneNumber.Update(phoneNumberUpdateArgs); + } + + @Post("count") + @HttpCode(200) + async Count(@Body() phoneNumberCountArgs: Prisma.PhoneNumberCountArgs): Promise { + return await this.phoneNumber.Count(phoneNumberCountArgs); + } + + @Post("create") + @HttpCode(200) + async Create(@Body() phoneNumberCreateArgs: Prisma.PhoneNumberCreateArgs): Promise> { + return await this.phoneNumber.Create(phoneNumberCreateArgs); + } + + @Post("delete") + @HttpCode(200) + async Delete(@Body() phoneNumberDeleteArgs: Prisma.PhoneNumberDeleteArgs): Promise> { + return await this.phoneNumber.Delete(phoneNumberDeleteArgs); + } +} diff --git a/apps/user-data/src/phone-number/phone-number.module.ts b/apps/user-data/src/phone-number/phone-number.module.ts new file mode 100644 index 0000000..4a8e411 --- /dev/null +++ b/apps/user-data/src/phone-number/phone-number.module.ts @@ -0,0 +1,12 @@ +import { Module } from "@nestjs/common"; +import { PhoneNumberController } from "./phone-number.controller"; +import { PhoneNumberService } from "./service/phone-number.service"; +import { PrismaModule } from "../prisma/prisma.module"; + +@Module({ + imports: [PrismaModule], + controllers: [PhoneNumberController], + providers: [PhoneNumberService] +}) +export class PhoneNumberModule { +} diff --git a/apps/user-data/src/phone-number/service/phone-number.service.spec.ts b/apps/user-data/src/phone-number/service/phone-number.service.spec.ts new file mode 100644 index 0000000..9b49efb --- /dev/null +++ b/apps/user-data/src/phone-number/service/phone-number.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PhoneNumberService } from './phone-number.service'; + +describe('PhoneNumberService', () => { + let service: PhoneNumberService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [PhoneNumberService], + }).compile(); + + service = module.get(PhoneNumberService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/user-data/src/phone-number/service/phone-number.service.ts b/apps/user-data/src/phone-number/service/phone-number.service.ts new file mode 100644 index 0000000..150bf3d --- /dev/null +++ b/apps/user-data/src/phone-number/service/phone-number.service.ts @@ -0,0 +1,62 @@ +import { Inject, Injectable } from "@nestjs/common"; +import { PrismaService } from "../../prisma/service/prisma.service"; +import { PhoneNumber, Prisma } from "@prisma/client"; +import { PrismaClientKnownRequestError } from "@prisma/client/runtime"; +import { UniqueConstraintFailedError } from "../../prisma/error/unique-constraint-failed.error"; +import { RecordNotFoundError } from "../../prisma/error/record-not-found.error"; + +@Injectable() +export class PhoneNumberService { + constructor(@Inject(PrismaService) private prisma: PrismaService) { + } + + async FindUnique(phoneNumberFindUniqueArgs: Prisma.PhoneNumberFindUniqueArgs): Promise | null> { + return await this.prisma.phoneNumber.findUnique(phoneNumberFindUniqueArgs); + } + + async FindFirst(phoneNumberFindFirstArgs: Prisma.PhoneNumberFindFirstArgs): Promise | null> { + return await this.prisma.phoneNumber.findFirst(phoneNumberFindFirstArgs); + } + + async FindMany(phoneNumberFindManyArgs: Prisma.PhoneNumberFindManyArgs): Promise[]> { + return await this.prisma.phoneNumber.findMany(phoneNumberFindManyArgs); + } + + async Update(phoneNumberUpdateArgs: Prisma.PhoneNumberUpdateArgs): Promise> { + try { + return await this.prisma.phoneNumber.update(phoneNumberUpdateArgs); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError) { + if (e.code === "P2025") throw new RecordNotFoundError("Record to update not found."); + if (e.code === "P2002") throw new UniqueConstraintFailedError("Unique constant failed"); + } + throw e; + } + } + + async Count(phoneNumberCountArgs: Prisma.PhoneNumberCountArgs): Promise { + return await this.prisma.phoneNumber.count(phoneNumberCountArgs); + } + + async Create(phoneNumberCreateArgs: Prisma.PhoneNumberCreateArgs): Promise> { + try { + return await this.prisma.phoneNumber.create(phoneNumberCreateArgs); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError) { + if (e.code === "P2002") throw new UniqueConstraintFailedError("Unique constant failed"); + } + throw e; + } + } + + async Delete(phoneNumberDeleteArgs: Prisma.PhoneNumberDeleteArgs): Promise> { + try { + return await this.prisma.phoneNumber.delete(phoneNumberDeleteArgs); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError) { + if (e.code === "P2025") throw new RecordNotFoundError("Record to delete not found."); + } + throw e; + } + } +} diff --git a/apps/user-data/src/prisma/error/record-not-found.error.ts b/apps/user-data/src/prisma/error/record-not-found.error.ts new file mode 100644 index 0000000..e1c9cb1 --- /dev/null +++ b/apps/user-data/src/prisma/error/record-not-found.error.ts @@ -0,0 +1 @@ +export class RecordNotFoundError extends Error {} diff --git a/apps/user-data/src/prisma/error/unique-constraint-failed.error.ts b/apps/user-data/src/prisma/error/unique-constraint-failed.error.ts new file mode 100644 index 0000000..647b582 --- /dev/null +++ b/apps/user-data/src/prisma/error/unique-constraint-failed.error.ts @@ -0,0 +1 @@ +export class UniqueConstraintFailedError extends Error {} diff --git a/apps/user-data/src/prisma/interceptor/prisma-error.interceptor.ts b/apps/user-data/src/prisma/interceptor/prisma-error.interceptor.ts new file mode 100644 index 0000000..7ad4b9a --- /dev/null +++ b/apps/user-data/src/prisma/interceptor/prisma-error.interceptor.ts @@ -0,0 +1,26 @@ +import { + CallHandler, + ConflictException, + ExecutionContext, + Injectable, + NestInterceptor, + NotFoundException +} from "@nestjs/common"; +import { catchError, Observable } from "rxjs"; +import { RecordNotFoundError } from "../error/record-not-found.error"; +import { UniqueConstraintFailedError } from "../error/unique-constraint-failed.error"; + +@Injectable() +export class PrismaErrorInterceptor implements NestInterceptor { + intercept(context: ExecutionContext, next: CallHandler): Observable { + return next + .handle() + .pipe( + catchError(err => { + if (err instanceof RecordNotFoundError) throw new NotFoundException(err.message); + if (err instanceof UniqueConstraintFailedError) throw new ConflictException(err.message); + throw err; + }) + ); + } +} diff --git a/apps/user-data/src/prisma/prisma.module.ts b/apps/user-data/src/prisma/prisma.module.ts new file mode 100644 index 0000000..44400fd --- /dev/null +++ b/apps/user-data/src/prisma/prisma.module.ts @@ -0,0 +1,10 @@ +import { Global, Module } from "@nestjs/common"; +import { PrismaService } from "./service/prisma.service"; + +@Global() +@Module({ + providers: [PrismaService], + exports: [PrismaService] +}) +export class PrismaModule { +} diff --git a/apps/user-data/src/prisma/service/prisma.service.spec.ts b/apps/user-data/src/prisma/service/prisma.service.spec.ts new file mode 100644 index 0000000..a68cb9e --- /dev/null +++ b/apps/user-data/src/prisma/service/prisma.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PrismaService } from './prisma.service'; + +describe('PrismaService', () => { + let service: PrismaService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [PrismaService], + }).compile(); + + service = module.get(PrismaService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/user-data/src/prisma/service/prisma.service.ts b/apps/user-data/src/prisma/service/prisma.service.ts new file mode 100644 index 0000000..aaa764a --- /dev/null +++ b/apps/user-data/src/prisma/service/prisma.service.ts @@ -0,0 +1,15 @@ +import { INestApplication, Injectable, OnModuleInit } from "@nestjs/common"; +import { PrismaClient } from "@prisma/client"; + +@Injectable() +export class PrismaService extends PrismaClient implements OnModuleInit { + async onModuleInit() { + await this.$connect(); + } + + async enableShutdownHooks(app: INestApplication) { + this.$on("beforeExit", async () => { + await app.close(); + }); + } +} diff --git a/apps/user-data/src/user/service/user.service.spec.ts b/apps/user-data/src/user/service/user.service.spec.ts new file mode 100644 index 0000000..873de8a --- /dev/null +++ b/apps/user-data/src/user/service/user.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { UserService } from './user.service'; + +describe('UserService', () => { + let service: UserService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [UserService], + }).compile(); + + service = module.get(UserService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/user-data/src/user/service/user.service.ts b/apps/user-data/src/user/service/user.service.ts new file mode 100644 index 0000000..413d64a --- /dev/null +++ b/apps/user-data/src/user/service/user.service.ts @@ -0,0 +1,62 @@ +import { Inject, Injectable } from "@nestjs/common"; +import { PrismaService } from "../../prisma/service/prisma.service"; +import { Prisma, User } from "@prisma/client"; +import { PrismaClientKnownRequestError } from "@prisma/client/runtime"; +import { UniqueConstraintFailedError } from "../../prisma/error/unique-constraint-failed.error"; +import { RecordNotFoundError } from "../../prisma/error/record-not-found.error"; + +@Injectable() +export class UserService { + constructor(@Inject(PrismaService) private prisma: PrismaService) { + } + + async FindUnique(userFindUniqueArgs: Prisma.UserFindUniqueArgs): Promise | null> { + return await this.prisma.user.findUnique(userFindUniqueArgs); + } + + async FindFirst(userFindFirstArgs: Prisma.UserFindFirstArgs): Promise | null> { + return await this.prisma.user.findFirst(userFindFirstArgs); + } + + async FindMany(userFindManyArgs: Prisma.UserFindManyArgs): Promise[]> { + return await this.prisma.user.findMany(userFindManyArgs); + } + + async Update(userUpdateArgs: Prisma.UserUpdateArgs): Promise> { + try { + return await this.prisma.user.update(userUpdateArgs); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError) { + if (e.code === "P2025") throw new RecordNotFoundError("Record to update not found."); + if (e.code === "P2002") throw new UniqueConstraintFailedError("Unique constant failed"); + } + throw e; + } + } + + async Count(userCountArgs: Prisma.UserCountArgs): Promise { + return await this.prisma.user.count(userCountArgs); + } + + async Create(userCreateArgs: Prisma.UserCreateArgs): Promise> { + try { + return await this.prisma.user.create(userCreateArgs); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError) { + if (e.code === "P2002") throw new UniqueConstraintFailedError("Unique constant failed"); + } + throw e; + } + } + + async Delete(userDeleteArgs: Prisma.UserDeleteArgs): Promise> { + try { + return await this.prisma.user.delete(userDeleteArgs); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError) { + if (e.code === "P2025") throw new RecordNotFoundError("Record to delete not found."); + } + throw e; + } + } +} diff --git a/apps/user-data/src/user/user.controller.spec.ts b/apps/user-data/src/user/user.controller.spec.ts new file mode 100644 index 0000000..7057a1a --- /dev/null +++ b/apps/user-data/src/user/user.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { UserController } from './user.controller'; + +describe('UserController', () => { + let controller: UserController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [UserController], + }).compile(); + + controller = module.get(UserController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/apps/user-data/src/user/user.controller.ts b/apps/user-data/src/user/user.controller.ts new file mode 100644 index 0000000..66dbd28 --- /dev/null +++ b/apps/user-data/src/user/user.controller.ts @@ -0,0 +1,53 @@ +import { Body, Controller, HttpCode, Inject, Post, UseInterceptors } from "@nestjs/common"; +import { Prisma, User } from "@prisma/client"; +import { UserService } from "./service/user.service"; +import { PrismaErrorInterceptor } from "../prisma/interceptor/prisma-error.interceptor"; + +@Controller("user") +@UseInterceptors(PrismaErrorInterceptor) +export class UserController { + constructor(@Inject(UserService) private user: UserService) { + } + + @Post("find/unique") + @HttpCode(200) + async FindUnique(@Body() userFindUniqueArgs: Prisma.UserFindUniqueArgs): Promise | null> { + return await this.user.FindUnique(userFindUniqueArgs); + } + + @Post("find/first") + @HttpCode(200) + async FindFirst(@Body() userFindFirstArgs: Prisma.UserFindFirstArgs): Promise | null> { + return await this.user.FindFirst(userFindFirstArgs); + } + + @Post("find/many") + @HttpCode(200) + async FindMany(@Body() userFindManyArgs: Prisma.UserFindManyArgs): Promise[]> { + return await this.user.FindMany(userFindManyArgs); + } + + @Post("update") + @HttpCode(200) + async Update(@Body() userUpdateArgs: Prisma.UserUpdateArgs): Promise> { + return await this.user.Update(userUpdateArgs); + } + + @Post("count") + @HttpCode(200) + async Count(@Body() userCountArgs: Prisma.UserCountArgs): Promise { + return await this.user.Count(userCountArgs); + } + + @Post("create") + @HttpCode(200) + async Create(@Body() userCreateArgs: Prisma.UserCreateArgs): Promise> { + return await this.user.Create(userCreateArgs); + } + + @Post("delete") + @HttpCode(200) + async Delete(@Body() userDeleteArgs: Prisma.UserDeleteArgs): Promise> { + return await this.user.Delete(userDeleteArgs); + } +} diff --git a/apps/user-data/src/user/user.module.ts b/apps/user-data/src/user/user.module.ts new file mode 100644 index 0000000..250f120 --- /dev/null +++ b/apps/user-data/src/user/user.module.ts @@ -0,0 +1,12 @@ +import { Module } from "@nestjs/common"; +import { UserController } from "./user.controller"; +import { UserService } from "./service/user.service"; +import { PrismaModule } from "../prisma/prisma.module"; + +@Module({ + imports: [PrismaModule], + controllers: [UserController], + providers: [UserService] +}) +export class UserModule { +} diff --git a/apps/user-data/tsconfig.app.json b/apps/user-data/tsconfig.app.json new file mode 100644 index 0000000..a2ce765 --- /dev/null +++ b/apps/user-data/tsconfig.app.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["node"], + "emitDecoratorMetadata": true, + "target": "es2021" + }, + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/apps/user-data/tsconfig.json b/apps/user-data/tsconfig.json new file mode 100644 index 0000000..8fe9526 --- /dev/null +++ b/apps/user-data/tsconfig.json @@ -0,0 +1,31 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + }, + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "es2017", + "sourceMap": true, + "incremental": true, + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "noImplicitAny": true, + "strictBindCallApply": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true +} diff --git a/apps/user-data/tsconfig.spec.json b/apps/user-data/tsconfig.spec.json new file mode 100644 index 0000000..9b2a121 --- /dev/null +++ b/apps/user-data/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/user-data/webpack.config.js b/apps/user-data/webpack.config.js new file mode 100644 index 0000000..81db92b --- /dev/null +++ b/apps/user-data/webpack.config.js @@ -0,0 +1,8 @@ +const { composePlugins, withNx } = require('@nx/webpack'); + +// Nx plugins for webpack. +module.exports = composePlugins(withNx(), (config) => { + // Update the webpack config as needed here. + // e.g. `config.plugins.push(new MyPlugin())` + return config; +}); diff --git a/docker-compose.yml b/docker-compose.yml index e69de29..cc4fc41 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -0,0 +1,47 @@ +version: '3' +services: + zookeeper-log: + image: confluentinc/cp-zookeeper:latest + container_name: zookeeper + ports: + - "2181:2181" + environment: + - ZOOKEEPER_CLIENT_PORT=2181 + - ZOOKEEPER_TICK_TIME=2000 + networks: + - dev-panels + - kafka-log + + kafka-log: + image: confluentinc/cp-kafka:latest + container_name: kafka + ports: + - "9092:9092" + environment: + - KAFKA_BROKER_ID=1 + - KAFKA_LISTENERS=PLAINTEXT://:9092 + - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 + - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 + - KAFKA_ZOOKEEPER_CONNECT=zookeeper-log:2181 + depends_on: + - zookeeper-log + networks: + - kafka-log + + kafka-log-manager: + image: hlebalbau/kafka-manager:latest + container_name: kafka-manager + ports: + - "9000:9000" + environment: + - ZK_HOSTS=zookeeper:2181 + depends_on: + - zookeeper-log + networks: + - kafka-log + +networks: + dev-panels: + driver: bridge + kafka-log: + driver: bridge diff --git a/package-lock.json b/package-lock.json index fa8b283..e705bc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@nestjs/graphql": "^12.0.3", "@nestjs/platform-express": "^10.0.2", "@nestjs/typeorm": "^10.0.0", + "@prisma/client": "^4.16.1", "@swc/helpers": "~0.5.0", "axios": "^1.0.0", "graphql": "^16.7.1", @@ -66,6 +67,7 @@ "nx": "16.4.0", "nx-cloud": "latest", "prettier": "^2.6.2", + "prisma": "^4.16.1", "react-refresh": "^0.10.0", "ts-jest": "^29.1.0", "ts-node": "10.9.1", @@ -4469,6 +4471,38 @@ "node": ">= 8" } }, + "node_modules/@prisma/client": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.16.1.tgz", + "integrity": "sha512-CoDHu7Bt+NuDo40ijoeHP79EHtECsPBTy3yte5Yo3op8TqXt/kV0OT5OrsWewKvQGKFMHhYQ+ePed3zzjYdGAw==", + "hasInstallScript": true, + "dependencies": { + "@prisma/engines-version": "4.16.0-66.b20ead4d3ab9e78ac112966e242ded703f4a052c" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/engines": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.16.1.tgz", + "integrity": "sha512-gpZG0kGGxfemgvK/LghHdBIz+crHkZjzszja94xp4oytpsXrgt/Ice82MvPsWMleVIniKuARrowtsIsim0PFJQ==", + "devOptional": true, + "hasInstallScript": true + }, + "node_modules/@prisma/engines-version": { + "version": "4.16.0-66.b20ead4d3ab9e78ac112966e242ded703f4a052c", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.16.0-66.b20ead4d3ab9e78ac112966e242ded703f4a052c.tgz", + "integrity": "sha512-tMWAF/qF00fbUH1HB4Yjmz6bjh7fzkb7Y3NRoUfMlHu6V+O45MGvqwYxqwBjn1BIUXkl3r04W351D4qdJjrgvA==" + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -15387,6 +15421,23 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/prisma": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.16.1.tgz", + "integrity": "sha512-C2Xm7yxHxjFjjscBEW4tmoraPHH/Vyu/A0XABdbaFtoiOZARsxvOM7rwc2iZ0qVxbh0bGBGBWZUSXO/52/nHBQ==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/engines": "4.16.1" + }, + "bin": { + "prisma": "build/index.js", + "prisma2": "build/index.js" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", diff --git a/package.json b/package.json index 44ff2ca..176c8cb 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@nestjs/graphql": "^12.0.3", "@nestjs/platform-express": "^10.0.2", "@nestjs/typeorm": "^10.0.0", + "@prisma/client": "^4.16.1", "@swc/helpers": "~0.5.0", "axios": "^1.0.0", "graphql": "^16.7.1", @@ -62,6 +63,7 @@ "nx": "16.4.0", "nx-cloud": "latest", "prettier": "^2.6.2", + "prisma": "^4.16.1", "react-refresh": "^0.10.0", "ts-jest": "^29.1.0", "ts-node": "10.9.1",