diff --git a/.DS_Store b/.DS_Store index 3e85d8c..b53964f 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index b58b603..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/discord.xml b/.idea/discord.xml deleted file mode 100644 index 30bab2a..0000000 --- a/.idea/discord.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/kempt-kinkajou.iml b/.idea/kempt-kinkajou.iml deleted file mode 100644 index 0c8867d..0000000 --- a/.idea/kempt-kinkajou.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 7ec6a29..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 83a2956..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/weather-platform b/weather-platform deleted file mode 160000 index 4f8ed19..0000000 --- a/weather-platform +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4f8ed19d5fd78029f3513a15381dbb8ab047f732 diff --git a/weather_platform/.editorconfig b/weather_platform/.editorconfig new file mode 100644 index 0000000..6e87a00 --- /dev/null +++ b/weather_platform/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/weather_platform/.env b/weather_platform/.env new file mode 100644 index 0000000..57c7868 --- /dev/null +++ b/weather_platform/.env @@ -0,0 +1,7 @@ +AGW_PORT=8045 +SENSORS_SERVICE_PORT=8046 +AGREGATORS_SERVICE_PORT=8047 +MEASURES_SERVICE_PORT=8048 +AGREGATORS_SOURCE_URL=postgresql://user2235:atlantium@localhost:5441/agregators +SENSORS_SOURCE_URL=postgresql://user2235:atlantium@localhost:5440/sensors +MEASURES_SOURCE_URL=postgresql://user2235:atlantium@localhost:5442/measures diff --git a/weather_platform/.env.example b/weather_platform/.env.example new file mode 100644 index 0000000..57c7868 --- /dev/null +++ b/weather_platform/.env.example @@ -0,0 +1,7 @@ +AGW_PORT=8045 +SENSORS_SERVICE_PORT=8046 +AGREGATORS_SERVICE_PORT=8047 +MEASURES_SERVICE_PORT=8048 +AGREGATORS_SOURCE_URL=postgresql://user2235:atlantium@localhost:5441/agregators +SENSORS_SOURCE_URL=postgresql://user2235:atlantium@localhost:5440/sensors +MEASURES_SOURCE_URL=postgresql://user2235:atlantium@localhost:5442/measures diff --git a/weather_platform/.eslintignore b/weather_platform/.eslintignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/weather_platform/.eslintignore @@ -0,0 +1 @@ +node_modules diff --git a/weather_platform/.eslintrc.json b/weather_platform/.eslintrc.json new file mode 100644 index 0000000..fd85475 --- /dev/null +++ b/weather_platform/.eslintrc.json @@ -0,0 +1,40 @@ +{ + "root": true, + "ignorePatterns": ["**/*"], + "plugins": ["@nx"], + "overrides": [ + { + "files": "*.json", + "parser": "jsonc-eslint-parser", + "rules": {} + }, + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": { + "@nx/enforce-module-boundaries": [ + "error", + { + "enforceBuildableLibDependency": true, + "allow": [], + "depConstraints": [ + { + "sourceTag": "*", + "onlyDependOnLibsWithTags": ["*"] + } + ] + } + ] + } + }, + { + "files": ["*.ts", "*.tsx"], + "extends": ["plugin:@nx/typescript"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "extends": ["plugin:@nx/javascript"], + "rules": {} + } + ] +} diff --git a/weather_platform/.gitignore b/weather_platform/.gitignore new file mode 100644 index 0000000..0016c21 --- /dev/null +++ b/weather_platform/.gitignore @@ -0,0 +1,43 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +dist +tmp +/out-tsc + +# dependencies +node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db + +data_db_agregators +data_db_measures +data_db_sensors diff --git a/weather_platform/.prettierignore b/weather_platform/.prettierignore new file mode 100644 index 0000000..9481e77 --- /dev/null +++ b/weather_platform/.prettierignore @@ -0,0 +1,3 @@ +# Add files here to ignore them from prettier formatting +/dist +/coverage \ No newline at end of file diff --git a/weather_platform/.prettierrc b/weather_platform/.prettierrc new file mode 100644 index 0000000..544138b --- /dev/null +++ b/weather_platform/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/weather_platform/README.md b/weather_platform/README.md new file mode 100644 index 0000000..ba10ef4 --- /dev/null +++ b/weather_platform/README.md @@ -0,0 +1,167 @@ +
+ +

K-Lab | Cyber Garden Weather

+
+ + + +
+ + + Processing Platform monorepo + +
+ + +## Описание +https://www.notion.so/sorrythisdomainisnotavailable/CyberGarden-k-Lab-docs-01392e46510e4d5c80c0a198c037d768?pvs=4 + + + +## Сервисы +- [frontend (ReactJS)](/apps/crud) +- [frontend e2e](/apps/crud-e2e) + +## Dev +### Backend +#### Prisma Types +```bash +nx g prisma-generator +``` + +### Frontend +#### Create a new Layout +```bash +nx g @nx/react:component NAME --project site-layouts +``` +#### Create a new Page +```bash +nx g @nx/react:component NAME --project site-pages +``` +#### Create a new Component +Like navbar, footer, login card, delete modal alert and et. +```bash +nx g @nx/react:component NAME --project ui-modules +``` +#### Create a new UI Component +Like nav_link, cta_button, username_input and et. +```bash +nx g @nx/react:component NAME --project ui +``` + + +## Развертывание + +To start the development server run `nx serve frontend`. Open your browser and navigate to http://localhost:4200/. Happy coding! +```bash +npm i -g prisma nx +``` + +```bash +yarn install +``` + +```bash +copy .env.example .env +``` + +```bash +cd apps/matrix-events-registry/docker && docker-compose up -d +``` +```bash +cd apps/matrix-registry/docker && docker-compose up -d +``` +```bash +cd apps/labs/docker && docker-compose up -d +``` +```bash +cd apps/labs/docker && docker-compose up -d +``` + +[Matrix Registry Service](/apps/matrix-registry) +```bash +prisma db push --schema="./libs/prisma-clients/matrix-device-registry/prisma/schema.prisma" +``` + +```bash +prisma generate --schema="./libs/prisma-clients/matrix-device-registry/prisma/schema.prisma" +``` + +[Matrix Events Registry Service](/apps/matrix-events-registry) +```bash +prisma db push --schema="./libs/prisma-clients/matrix-events/prisma/schema.prisma" +``` + +```bash +prisma generate --schema="./libs/prisma-clients/matrix-events/prisma/schema.prisma" +``` + +```bash +prisma db push --schema="./libs/prisma-clients/labs/prisma/schema.prisma" +``` + +```bash +prisma generate --schema="./libs/prisma-clients/labs/prisma/schema.prisma" +``` + +```bash +nx run py-multy-agent-interpreter:serve +``` + +Run all services: +```bash +nx run-many --parallel --target=serve --projects=frontend,agw,matrix-registry,matrix-events-registry,labs +``` + + +## Структура репозитория +Репозиторий содержит следующие основные каталоги и файлы: +- `apps` - приложения +- `libs` - библиотеки и генераторы +- `tools` - Nx workspaces tools +- `docs` - документация + + +## Коммиты +Используемые префиксы: +- **feat:** (от "feature") - новая функциональность или добавление нового компонента. +- **fix:** - исправление ошибок или дефектов. +- **docs:** - изменения, связанные с документацией, например, обновление README или документации в коде. +- **style:** - изменения внешнего вида кода, форматирование, пробелы, отступы и т.д., которые не влияют на его поведение. +- **refactor:** - рефакторинг кода без исправления ошибок или добавления новых функций. +- **test:** - добавление или исправление тестов. +- **chore:** - изменения в сборочных скриптах, настройках инструментов, обновление зависимостей и т.д. +- **perf:** - изменения, связанные с оптимизацией производительности. +- **revert:** - отмена предыдущего коммита. +- **merge:** - коммит, созданный при слиянии веток. +- **release:** - коммит, связанный с выпуском новой версии. +- **require:** - коммит, связанный с установкой новой библиотеки +--- +# Any NX comands log +- npx create-nx-workspace@latest --preset=react +- npm install -D @nrwl/nest +- nx g @nrwl/nest:app agw --frontendProject crud +- nx g @nx/react:setup-tailwind --project=crud +- nx g @nx/react:lib ui +- nx g @nx/react:component navbar --project ui +- nx run-many --parallel --target=serve --projects=agw,auth,crud +### Creating Prisma generator tool +- nx g plugin +- prisma-generator +- nx generate @nx/plugin:generator prisma-generator --project=prisma-generator +#### Run +- nx generate prisma-generator +#### Migrations +- prisma db push --schema="./libs/prisma-clients/Agregators/prisma/schema.prisma" +- prisma generate --schema="./libs/prisma-clients/Agregators/prisma/schema.prisma" +- prisma db push --schema="./libs/prisma-clients/Measures/prisma/schema.prisma" +- prisma generate --schema="./libs/prisma-clients/Measures/prisma/schema.prisma" +- prisma db push --schema="./libs/prisma-clients/Sensors/prisma/schema.prisma" +- prisma generate --schema="./libs/prisma-clients/Sensors/prisma/schema.prisma" +### Crud Pages +- nx generate @nrwl/react:lib site-pages --template=typescript +- nx g @nx/react:component NAME --project site-pages +- nx build site-pages +### Crud Layout +- nx generate @nrwl/react:lib site-layouts --template=typescript +- nx g @nx/react:component NAME --project site-layouts diff --git a/weather_platform/apps/agregators-service-e2e/.eslintrc.json b/weather_platform/apps/agregators-service-e2e/.eslintrc.json new file mode 100644 index 0000000..9d9c0db --- /dev/null +++ b/weather_platform/apps/agregators-service-e2e/.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/weather_platform/apps/agregators-service-e2e/jest.config.ts b/weather_platform/apps/agregators-service-e2e/jest.config.ts new file mode 100644 index 0000000..638f3b3 --- /dev/null +++ b/weather_platform/apps/agregators-service-e2e/jest.config.ts @@ -0,0 +1,19 @@ +/* eslint-disable */ +export default { + displayName: 'agregators-service-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/agregators-service-e2e', +}; diff --git a/weather_platform/apps/agregators-service-e2e/project.json b/weather_platform/apps/agregators-service-e2e/project.json new file mode 100644 index 0000000..b321fd6 --- /dev/null +++ b/weather_platform/apps/agregators-service-e2e/project.json @@ -0,0 +1,23 @@ +{ + "name": "agregators-service-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "implicitDependencies": ["agregators-service"], + "projectType": "application", + "targets": { + "e2e": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{e2eProjectRoot}"], + "options": { + "jestConfig": "apps/agregators-service-e2e/jest.config.ts", + "passWithNoTests": true + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/agregators-service-e2e/**/*.{js,ts}"] + } + } + } +} diff --git a/weather_platform/apps/agregators-service-e2e/src/agregators-service/agregators-service.spec.ts b/weather_platform/apps/agregators-service-e2e/src/agregators-service/agregators-service.spec.ts new file mode 100644 index 0000000..e8ac2a6 --- /dev/null +++ b/weather_platform/apps/agregators-service-e2e/src/agregators-service/agregators-service.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/weather_platform/apps/agregators-service-e2e/src/support/global-setup.ts b/weather_platform/apps/agregators-service-e2e/src/support/global-setup.ts new file mode 100644 index 0000000..c1f5144 --- /dev/null +++ b/weather_platform/apps/agregators-service-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/weather_platform/apps/agregators-service-e2e/src/support/global-teardown.ts b/weather_platform/apps/agregators-service-e2e/src/support/global-teardown.ts new file mode 100644 index 0000000..32ea345 --- /dev/null +++ b/weather_platform/apps/agregators-service-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/weather_platform/apps/agregators-service-e2e/src/support/test-setup.ts b/weather_platform/apps/agregators-service-e2e/src/support/test-setup.ts new file mode 100644 index 0000000..07f2870 --- /dev/null +++ b/weather_platform/apps/agregators-service-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/weather_platform/apps/agregators-service-e2e/tsconfig.json b/weather_platform/apps/agregators-service-e2e/tsconfig.json new file mode 100644 index 0000000..ed633e1 --- /dev/null +++ b/weather_platform/apps/agregators-service-e2e/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/weather_platform/apps/agregators-service-e2e/tsconfig.spec.json b/weather_platform/apps/agregators-service-e2e/tsconfig.spec.json new file mode 100644 index 0000000..d7f9cf2 --- /dev/null +++ b/weather_platform/apps/agregators-service-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/weather_platform/apps/agregators-service/.eslintrc.json b/weather_platform/apps/agregators-service/.eslintrc.json new file mode 100644 index 0000000..9d9c0db --- /dev/null +++ b/weather_platform/apps/agregators-service/.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/weather_platform/apps/agregators-service/jest.config.ts b/weather_platform/apps/agregators-service/jest.config.ts new file mode 100644 index 0000000..1f404a9 --- /dev/null +++ b/weather_platform/apps/agregators-service/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'agregators-service', + preset: '../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/apps/agregators-service', +}; diff --git a/weather_platform/apps/agregators-service/project.json b/weather_platform/apps/agregators-service/project.json new file mode 100644 index 0000000..ca72973 --- /dev/null +++ b/weather_platform/apps/agregators-service/project.json @@ -0,0 +1,64 @@ +{ + "name": "agregators-service", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/agregators-service/src", + "projectType": "application", + "targets": { + "build": { + "executor": "@nx/webpack:webpack", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "production", + "options": { + "target": "node", + "compiler": "tsc", + "outputPath": "dist/apps/agregators-service", + "main": "apps/agregators-service/src/main.ts", + "tsConfig": "apps/agregators-service/tsconfig.app.json", + "assets": ["apps/agregators-service/src/assets"], + "isolatedConfig": true, + "webpackConfig": "apps/agregators-service/webpack.config.js" + }, + "configurations": { + "development": {}, + "production": {} + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "agregators-service:build" + }, + "configurations": { + "development": { + "buildTarget": "agregators-service:build:development" + }, + "production": { + "buildTarget": "agregators-service:build:production" + } + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/agregators-service/**/*.ts"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "apps/agregators-service/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + } + }, + "tags": [] +} diff --git a/weather_platform/apps/agregators-service/src/DTO/AgregatorCreateDTOClass.dto.ts b/weather_platform/apps/agregators-service/src/DTO/AgregatorCreateDTOClass.dto.ts new file mode 100644 index 0000000..7450f10 --- /dev/null +++ b/weather_platform/apps/agregators-service/src/DTO/AgregatorCreateDTOClass.dto.ts @@ -0,0 +1,24 @@ +import { ApiProperty } from "@nestjs/swagger"; + +export class AgregatorCreateDTOClass { + @ApiProperty({description: 'The date when the was sent'}) + sendedInDate: string; + @ApiProperty({description: 'The UUID of the creator'}) + creatorUUID: string; + @ApiProperty({description: 'The agregator name'}) + name: string; + @ApiProperty({description: 'The agregator latitude'}) + let: number; + @ApiProperty({description: 'The agregator longitude'}) + lng: number; + @ApiProperty({description: 'The agregator height from the ground'}) + height: number; + @ApiProperty({description: 'The agregator country'}) + country: string; + @ApiProperty({description: 'The agregator city'}) + city: string; + @ApiProperty({description: 'The agregator region'}) + region: string; + @ApiProperty({description: 'The agregator street'}) + street: string; +} diff --git a/weather_platform/apps/agregators-service/src/DTO/AgregatorGetDTOClass.dto.ts b/weather_platform/apps/agregators-service/src/DTO/AgregatorGetDTOClass.dto.ts new file mode 100644 index 0000000..ce20027 --- /dev/null +++ b/weather_platform/apps/agregators-service/src/DTO/AgregatorGetDTOClass.dto.ts @@ -0,0 +1,15 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { Prisma } from "@weather-platform/prisma-clients/Agregators"; + +export class AgregatorGetDTOClass { + @ApiProperty({description: 'The number of items to skip'}) + skip?: number; + @ApiProperty({description: 'The number of items to take'}) + take?: number; + @ApiProperty({description: 'The cursor'}) + cursor?: Prisma.AgregatorWhereUniqueInput; + @ApiProperty({description: 'The where'}) + where?: Prisma.AgregatorWhereInput; + @ApiProperty({description: 'The orderBy'}) + orderBy?: Prisma.AgregatorOrderByWithRelationInput; +} diff --git a/weather_platform/apps/agregators-service/src/DTO/AgregatorUpdateDTOClass.dto.ts b/weather_platform/apps/agregators-service/src/DTO/AgregatorUpdateDTOClass.dto.ts new file mode 100644 index 0000000..d3d6788 --- /dev/null +++ b/weather_platform/apps/agregators-service/src/DTO/AgregatorUpdateDTOClass.dto.ts @@ -0,0 +1,13 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { Prisma } from "@weather-platform/prisma-clients/Agregators"; + +type AgregatorUpdateDTO = { + where: Prisma.AgregatorWhereUniqueInput; + data: Prisma.AgregatorUpdateInput; +}; +export class AgregatorUpdateDTOClass implements AgregatorUpdateDTO { + @ApiProperty({description: 'The where'}) + where: Prisma.AgregatorWhereUniqueInput; + @ApiProperty({description: 'The data'}) + data: Prisma.AgregatorUpdateInput; +} diff --git a/weather_platform/apps/agregators-service/src/app/app.controller.spec.ts b/weather_platform/apps/agregators-service/src/app/app.controller.spec.ts new file mode 100644 index 0000000..de8007e --- /dev/null +++ b/weather_platform/apps/agregators-service/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/weather_platform/apps/agregators-service/src/app/app.controller.ts b/weather_platform/apps/agregators-service/src/app/app.controller.ts new file mode 100644 index 0000000..e9cc03c --- /dev/null +++ b/weather_platform/apps/agregators-service/src/app/app.controller.ts @@ -0,0 +1,134 @@ +import { Body, Controller, Get, Post } from "@nestjs/common"; +import { AgregatorsClient } from '@weather-platform/prisma-clients'; +import { AppService } from './app.service'; +import { Agregator, Prisma } from '@weather-platform/prisma-clients/Agregators'; +import { v4 as uuidv4 } from 'uuid'; +import { + ApiInternalServerErrorResponse, + ApiNotFoundResponse, + ApiOkResponse, + ApiOperation, ApiProperty, + ApiResponse, + ApiTags, +} from '@nestjs/swagger'; +import { AgregatorCreateDTOClass } from "../DTO/AgregatorCreateDTOClass.dto"; +import { AgregatorGetDTOClass } from "../DTO/AgregatorGetDTOClass.dto"; +import { AgregatorUpdateDTOClass } from "../DTO/AgregatorUpdateDTOClass.dto"; + +export type AgregatorGetDTO = { + skip?: number; + take?: number; + cursor?: Prisma.AgregatorWhereUniqueInput; + where?: Prisma.AgregatorWhereInput; + orderBy?: Prisma.AgregatorOrderByWithRelationInput; +}; + +export type AgregatorCreateDTO = { + sendedInDate: string; + creatorUUID: string; + name: string; + let: number; + lng: number; + height: number; + country: string; + city: string; + region: string; + street: string; +}; + +@ApiTags('Agregators') +@Controller() +export class AppController { + constructor(private readonly appService: AppService) {} + + @ApiOperation({ + summary: 'Get agregator with Prisma params', + }) + @ApiResponse({ status: 200, type: AgregatorGetDTOClass }) + @ApiResponse({ status: 500, type: Error }) + @ApiOkResponse({ + description: 'Retrieved agregator successfully', + type: AgregatorGetDTOClass, + }) + @ApiNotFoundResponse({ + description: 'No agregator found for this request', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error', + }) + @Post('get-with-params') + async getAgregators( + @Body() params: AgregatorGetDTO, + ): Promise { + + const { skip, take, cursor, where, orderBy } = params; + + const updatedWhere: Prisma.AgregatorWhereInput = { + ...where, + isDeleted: false, + }; + + const res = this.appService.get({ + skip, + take, + cursor, + where: updatedWhere, + orderBy, + }); + return res; + } + + @ApiOperation({ summary: 'Create Agregator' }) + @ApiResponse({ status: 200, type: AgregatorCreateDTOClass }) + @ApiOkResponse({ + description: 'Retrieved to create a new agregator successfully', + type: AgregatorCreateDTOClass, + }) + @ApiNotFoundResponse({ + description: 'The agregator is not created successfully', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error', + }) + @Post('create') + async createAgregator( + @Body() sectionData: AgregatorCreateDTO, + ): Promise { + + const { uuid } = uuidv4(); + + const updatedWhere: Prisma.AgregatorCreateInput = { + ...sectionData, + uuid: uuid, + }; + + const agregator = await this.appService.create(updatedWhere); + return agregator; + } + + @ApiOperation({ summary: 'Update Agregator' }) + @ApiResponse({ status: 200, type: AgregatorUpdateDTOClass }) + @ApiOkResponse({ + description: 'Retrieved agregator successfully', + type: AgregatorUpdateDTOClass, + }) + @ApiNotFoundResponse({ + description: 'No Sensor found for this request', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error', + }) + @Post('update') + async updateAgregator( + @Body() params: AgregatorUpdateDTOClass, + ): Promise { + const { data, where } = params; + + const agregator: Agregator = await this.appService.update({ + where, + data, + }); + + return agregator; + } +} diff --git a/weather_platform/apps/agregators-service/src/app/app.module.ts b/weather_platform/apps/agregators-service/src/app/app.module.ts new file mode 100644 index 0000000..6a9bc16 --- /dev/null +++ b/weather_platform/apps/agregators-service/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/weather_platform/apps/agregators-service/src/app/app.service.spec.ts b/weather_platform/apps/agregators-service/src/app/app.service.spec.ts new file mode 100644 index 0000000..42cf0a2 --- /dev/null +++ b/weather_platform/apps/agregators-service/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/weather_platform/apps/agregators-service/src/app/app.service.ts b/weather_platform/apps/agregators-service/src/app/app.service.ts new file mode 100644 index 0000000..5d28009 --- /dev/null +++ b/weather_platform/apps/agregators-service/src/app/app.service.ts @@ -0,0 +1,79 @@ +import { Injectable } from '@nestjs/common'; +import { AgregatorsClient } from '@weather-platform/prisma-clients'; +import { Agregator, Prisma } from "@weather-platform/prisma-clients/Agregators"; + +@Injectable() +export class AppService { + private prisma: AgregatorsClient; + constructor() { + this.prisma = new AgregatorsClient() + } + + async create(data: Prisma.AgregatorCreateInput): Promise { + try { + this.prisma.$connect(); + const Agregator = await this.prisma.agregator.create({ + data, + }); + this.prisma.$disconnect(); + return Agregator; + } catch (e: any) { + console.log(e.code); + console.log(e.message); + } + } + + async get(params: { + skip?: number; + take?: number; + cursor?: Prisma.AgregatorWhereUniqueInput; + where?: Prisma.AgregatorWhereInput; + orderBy?: Prisma.AgregatorOrderByWithRelationInput; + }): Promise { + try { + const { skip, take, cursor, where, orderBy } = params; + return this.prisma.agregator.findMany({ + skip, + take, + cursor, + where, + orderBy, + }); + } catch (e) { + console.log(e.code); + console.log(e.message); + } + } + + async update(params: { + where: Prisma.AgregatorWhereUniqueInput; + data: Prisma.AgregatorUpdateInput; + }): Promise { + try { + const { where, data } = params; + return this.prisma.agregator.update({ + data, + where, + }); + } catch (e) { + console.log(e.code); + console.log(e.message); + } + } + + async delete(uuid: string): Promise { + try { + return this.prisma.agregator.update({ + where: { + uuid: uuid, + }, + data: { + isDeleted: true, + }, + }); + } catch (e) { + console.log(e.code); + console.log(e.message); + } + } +} diff --git a/weather_platform/apps/agregators-service/src/assets/.gitkeep b/weather_platform/apps/agregators-service/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/weather_platform/apps/agregators-service/src/main.ts b/weather_platform/apps/agregators-service/src/main.ts new file mode 100644 index 0000000..7b45f27 --- /dev/null +++ b/weather_platform/apps/agregators-service/src/main.ts @@ -0,0 +1,34 @@ +/** + * 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'; +import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger"; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + const globalPrefix = 'api'; + app.setGlobalPrefix(globalPrefix); + const port = process.env.AGREGATORS_SERVICE_PORT || 3000; + + const config = new DocumentBuilder() + .setTitle('CyberGarden Weather Agregators Service') + .setDescription('This api need for store agregators data') + .setVersion('1.0') + .addTag('Agregators Service') + .build(); + const document = SwaggerModule.createDocument(app, config); + SwaggerModule.setup('api', app, document); + + app.enableCors(); + await app.listen(port); + Logger.log( + `🚀 Application is running on: http://localhost:${port}/${globalPrefix}` + ); +} + +bootstrap(); diff --git a/weather_platform/apps/agregators-service/tsconfig.app.json b/weather_platform/apps/agregators-service/tsconfig.app.json new file mode 100644 index 0000000..a2ce765 --- /dev/null +++ b/weather_platform/apps/agregators-service/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/weather_platform/apps/agregators-service/tsconfig.json b/weather_platform/apps/agregators-service/tsconfig.json new file mode 100644 index 0000000..c1e2dd4 --- /dev/null +++ b/weather_platform/apps/agregators-service/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/weather_platform/apps/agregators-service/tsconfig.spec.json b/weather_platform/apps/agregators-service/tsconfig.spec.json new file mode 100644 index 0000000..9b2a121 --- /dev/null +++ b/weather_platform/apps/agregators-service/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/weather_platform/apps/agregators-service/webpack.config.js b/weather_platform/apps/agregators-service/webpack.config.js new file mode 100644 index 0000000..81db92b --- /dev/null +++ b/weather_platform/apps/agregators-service/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/weather_platform/apps/agw-e2e/.eslintrc.json b/weather_platform/apps/agw-e2e/.eslintrc.json new file mode 100644 index 0000000..9d9c0db --- /dev/null +++ b/weather_platform/apps/agw-e2e/.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/weather_platform/apps/agw-e2e/jest.config.ts b/weather_platform/apps/agw-e2e/jest.config.ts new file mode 100644 index 0000000..89d5d3a --- /dev/null +++ b/weather_platform/apps/agw-e2e/jest.config.ts @@ -0,0 +1,19 @@ +/* eslint-disable */ +export default { + displayName: 'agw-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/agw-e2e', +}; diff --git a/weather_platform/apps/agw-e2e/project.json b/weather_platform/apps/agw-e2e/project.json new file mode 100644 index 0000000..dde9b33 --- /dev/null +++ b/weather_platform/apps/agw-e2e/project.json @@ -0,0 +1,23 @@ +{ + "name": "agw-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "implicitDependencies": ["agw"], + "projectType": "application", + "targets": { + "e2e": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{e2eProjectRoot}"], + "options": { + "jestConfig": "apps/agw-e2e/jest.config.ts", + "passWithNoTests": true + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/agw-e2e/**/*.{js,ts}"] + } + } + } +} diff --git a/weather_platform/apps/agw-e2e/src/agw/agw.spec.ts b/weather_platform/apps/agw-e2e/src/agw/agw.spec.ts new file mode 100644 index 0000000..e8ac2a6 --- /dev/null +++ b/weather_platform/apps/agw-e2e/src/agw/agw.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/weather_platform/apps/agw-e2e/src/support/global-setup.ts b/weather_platform/apps/agw-e2e/src/support/global-setup.ts new file mode 100644 index 0000000..c1f5144 --- /dev/null +++ b/weather_platform/apps/agw-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/weather_platform/apps/agw-e2e/src/support/global-teardown.ts b/weather_platform/apps/agw-e2e/src/support/global-teardown.ts new file mode 100644 index 0000000..32ea345 --- /dev/null +++ b/weather_platform/apps/agw-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/weather_platform/apps/agw-e2e/src/support/test-setup.ts b/weather_platform/apps/agw-e2e/src/support/test-setup.ts new file mode 100644 index 0000000..07f2870 --- /dev/null +++ b/weather_platform/apps/agw-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/weather_platform/apps/agw-e2e/tsconfig.json b/weather_platform/apps/agw-e2e/tsconfig.json new file mode 100644 index 0000000..ed633e1 --- /dev/null +++ b/weather_platform/apps/agw-e2e/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/weather_platform/apps/agw-e2e/tsconfig.spec.json b/weather_platform/apps/agw-e2e/tsconfig.spec.json new file mode 100644 index 0000000..d7f9cf2 --- /dev/null +++ b/weather_platform/apps/agw-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/weather_platform/apps/agw/.eslintrc.json b/weather_platform/apps/agw/.eslintrc.json new file mode 100644 index 0000000..9d9c0db --- /dev/null +++ b/weather_platform/apps/agw/.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/weather_platform/apps/agw/jest.config.ts b/weather_platform/apps/agw/jest.config.ts new file mode 100644 index 0000000..84e001c --- /dev/null +++ b/weather_platform/apps/agw/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'agw', + preset: '../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/apps/agw', +}; diff --git a/weather_platform/apps/agw/project.json b/weather_platform/apps/agw/project.json new file mode 100644 index 0000000..7036fcc --- /dev/null +++ b/weather_platform/apps/agw/project.json @@ -0,0 +1,64 @@ +{ + "name": "agw", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/agw/src", + "projectType": "application", + "targets": { + "build": { + "executor": "@nx/webpack:webpack", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "production", + "options": { + "target": "node", + "compiler": "tsc", + "outputPath": "dist/apps/agw", + "main": "apps/agw/src/main.ts", + "tsConfig": "apps/agw/tsconfig.app.json", + "assets": ["apps/agw/src/assets"], + "isolatedConfig": true, + "webpackConfig": "apps/agw/webpack.config.js" + }, + "configurations": { + "development": {}, + "production": {} + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "agw:build" + }, + "configurations": { + "development": { + "buildTarget": "agw:build:development" + }, + "production": { + "buildTarget": "agw:build:production" + } + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/agw/**/*.ts"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "apps/agw/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + } + }, + "tags": [] +} diff --git a/weather_platform/apps/agw/src/agregator/agregator.controller.spec.ts b/weather_platform/apps/agw/src/agregator/agregator.controller.spec.ts new file mode 100644 index 0000000..0631ce4 --- /dev/null +++ b/weather_platform/apps/agw/src/agregator/agregator.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AgregatorController } from './agregator.controller'; + +describe('AgregatorController', () => { + let controller: AgregatorController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [AgregatorController], + }).compile(); + + controller = module.get(AgregatorController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/weather_platform/apps/agw/src/agregator/agregator.controller.ts b/weather_platform/apps/agw/src/agregator/agregator.controller.ts new file mode 100644 index 0000000..918e6d4 --- /dev/null +++ b/weather_platform/apps/agw/src/agregator/agregator.controller.ts @@ -0,0 +1,87 @@ +import { Body, Controller, Post } from "@nestjs/common"; +import { AgregatorService } from "./agregator.service"; +import { + ApiInternalServerErrorResponse, + ApiNotFoundResponse, + ApiOkResponse, + ApiOperation, + ApiResponse, ApiTags +} from "@nestjs/swagger"; +import { Agregator, Prisma } from "@weather-platform/prisma-clients/Agregators"; +// eslint-disable-next-line @nx/enforce-module-boundaries +import { AgregatorCreateDTO, AgregatorGetDTO } from "../../../agregators-service/src/app/app.controller"; +// eslint-disable-next-line @nx/enforce-module-boundaries +import { AgregatorCreateDTOClass } from "../../../agregators-service/src/DTO/AgregatorCreateDTOClass.dto"; +// eslint-disable-next-line @nx/enforce-module-boundaries +import { AgregatorGetDTOClass } from "../../../agregators-service/src/DTO/AgregatorGetDTOClass.dto"; +// eslint-disable-next-line @nx/enforce-module-boundaries +import { AgregatorUpdateDTOClass } from "../../../agregators-service/src/DTO/AgregatorUpdateDTOClass.dto"; +import { Sensor } from "@weather-platform/prisma-clients/Sensors"; + +@ApiTags('Agregators') +@Controller('agregator') +export class AgregatorController { + constructor( + private readonly agregatorService: AgregatorService, + ) {} + + @ApiOperation({ + summary: 'Get agregator with Prisma params', tags: ['Agregators'], description: 'Get agregator with Prisma params', operationId: 'getWithParams', + }) + @ApiResponse({ status: 200, type: AgregatorGetDTOClass, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, description: 'The found agregator', content: { 'application/json': { schema: { '$ref': '#/components/schemas/AgregatorGetDTOClass' } } }, }) + @ApiResponse({ status: 500, type: Error, description: 'Internal server error', headers: { 'X-Request-Id': { schema: { type: 'string' } } }, }) + @ApiOkResponse({ + description: 'Retrieved agregator successfully', + type: AgregatorGetDTOClass, status: 200, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, + }) + @ApiNotFoundResponse({ + description: 'No agreagator found for this request', type: Error, status: 404, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error', status: 500, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, type: Error, + }) + @Post('get-with-params') + async getAgregators( + @Body() params: AgregatorGetDTO, + ): Promise | null> { + return await this.agregatorService.get(params); + } + + @ApiOperation({ summary: 'Create Agregator', description: 'Create Agregator', operationId: 'create', tags: ['Agregators'], }) + @ApiResponse({ status: 200, type: AgregatorCreateDTOClass, description: 'The found agregator', content: { 'application/json': { schema: { '$ref': '#/components/schemas/AgregatorCreateDTOClass' } } }, }) + @ApiOkResponse({ + description: 'Retrieved to create a new agregator successfully', + type: AgregatorCreateDTOClass, status: 200, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, + }) + @ApiNotFoundResponse({ + description: 'The agregator is not created successfully', type: Error, status: 404, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error', status: 500, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, type: Error, + }) + @Post('create') + async createAgregator( + @Body() sectionData: AgregatorCreateDTO, + ): Promise | null> { + return await this.agregatorService.create(sectionData); + } + + @ApiOperation({ summary: 'Update Agregator', description: 'Update Agregator', operationId: 'update', tags: ['Agregators'], }) + @ApiResponse({ status: 200, type: AgregatorUpdateDTOClass }) + @ApiOkResponse({ + description: 'Retrieved agregator successfully', + type: AgregatorUpdateDTOClass, status: 200, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, + }) + @ApiNotFoundResponse({ + description: 'No Sensor found for this request', status: 404, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error', status: 500, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, type: Error, + }) + @Post('update') + async updateAgregator( + @Body() params: AgregatorUpdateDTOClass, + ): Promise | null> { + return await this.agregatorService.update(params); + } +} diff --git a/weather_platform/apps/agw/src/agregator/agregator.module.ts b/weather_platform/apps/agw/src/agregator/agregator.module.ts new file mode 100644 index 0000000..f084520 --- /dev/null +++ b/weather_platform/apps/agw/src/agregator/agregator.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { AgregatorService } from './agregator.service'; +import { AgregatorController } from './agregator.controller'; +import { HttpModule } from "@nestjs/axios"; + +@Module({ + imports: [HttpModule], + providers: [AgregatorService], + controllers: [AgregatorController], + exports: [AgregatorService], +}) +export class AgregatorModule {} diff --git a/weather_platform/apps/agw/src/agregator/agregator.service.spec.ts b/weather_platform/apps/agw/src/agregator/agregator.service.spec.ts new file mode 100644 index 0000000..bcb5ed2 --- /dev/null +++ b/weather_platform/apps/agw/src/agregator/agregator.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AgregatorService } from './agregator.service'; + +describe('AgregatorService', () => { + let service: AgregatorService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AgregatorService], + }).compile(); + + service = module.get(AgregatorService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/weather_platform/apps/agw/src/agregator/agregator.service.ts b/weather_platform/apps/agw/src/agregator/agregator.service.ts new file mode 100644 index 0000000..b22cf0f --- /dev/null +++ b/weather_platform/apps/agw/src/agregator/agregator.service.ts @@ -0,0 +1,46 @@ +import { Injectable } from '@nestjs/common'; +import { HttpService } from "@nestjs/axios"; +import { Agregator, Prisma } from "@weather-platform/prisma-clients/Agregators"; + +@Injectable() +export class AgregatorService { + constructor(private readonly httpService: HttpService) {} + + AGREGATOR_SERVICE_URL = (process.env.AGREGATOR_SERVICE_PROTOCOL || 'http://') + + (process.env.AGREGATOR_SERVICE_HOST || 'localhost') + ':' + + (process.env.AGREGATOR_SERVICE_PORT || 3000) + + '/api/'; + + async get(data: Prisma.AgregatorFindManyArgs): Promise | null> { + try { + const response = await this.httpService.post(this.AGREGATOR_SERVICE_URL + 'get-with-params', data).toPromise(); + return response.data; + } catch (error) { + console.log(error); + throw error; + } + } + + async create(data: Prisma.AgregatorCreateInput): Promise | null> { + // eslint-disable-next-line no-useless-catch + try { + const response = await this.httpService.post(this.AGREGATOR_SERVICE_URL + 'create', data).toPromise(); + return response.data; + } catch (error) { + throw error; + } + } + + async update(data: { + where: Prisma.AgregatorWhereUniqueInput; + data: Prisma.AgregatorUpdateInput; + }): Promise | null> { + // eslint-disable-next-line no-useless-catch + try { + const response = await this.httpService.post(this.AGREGATOR_SERVICE_URL + 'update', data).toPromise(); + return response.data; + } catch (error) { + throw error; + } + } +} diff --git a/weather_platform/apps/agw/src/app/app.controller.spec.ts b/weather_platform/apps/agw/src/app/app.controller.spec.ts new file mode 100644 index 0000000..de8007e --- /dev/null +++ b/weather_platform/apps/agw/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/weather_platform/apps/agw/src/app/app.controller.ts b/weather_platform/apps/agw/src/app/app.controller.ts new file mode 100644 index 0000000..dff210a --- /dev/null +++ b/weather_platform/apps/agw/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/weather_platform/apps/agw/src/app/app.module.ts b/weather_platform/apps/agw/src/app/app.module.ts new file mode 100644 index 0000000..6761bbc --- /dev/null +++ b/weather_platform/apps/agw/src/app/app.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; + +import { AppController } from './app.controller'; +import { AppService } from './app.service'; +import { MeasuresModule } from "../measures/measures.module"; +import { SensorsModule } from "../sensors/sensors.module"; +import { AgregatorModule } from "../agregator/agregator.module"; +import { HttpModule } from "@nestjs/axios"; + +@Module({ + imports: [HttpModule, MeasuresModule, AgregatorModule, SensorsModule], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} diff --git a/weather_platform/apps/agw/src/app/app.service.spec.ts b/weather_platform/apps/agw/src/app/app.service.spec.ts new file mode 100644 index 0000000..42cf0a2 --- /dev/null +++ b/weather_platform/apps/agw/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/weather_platform/apps/agw/src/app/app.service.ts b/weather_platform/apps/agw/src/app/app.service.ts new file mode 100644 index 0000000..cd8cede --- /dev/null +++ b/weather_platform/apps/agw/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/weather_platform/apps/agw/src/assets/.gitkeep b/weather_platform/apps/agw/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/weather_platform/apps/agw/src/main.ts b/weather_platform/apps/agw/src/main.ts new file mode 100644 index 0000000..8eedc80 --- /dev/null +++ b/weather_platform/apps/agw/src/main.ts @@ -0,0 +1,34 @@ +/** + * 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 {DocumentBuilder, SwaggerModule} from "@nestjs/swagger"; + +import { AppModule } from './app/app.module'; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + const globalPrefix = 'api/v1'; + app.setGlobalPrefix(globalPrefix); + + const config = new DocumentBuilder() + .setTitle('CyberGarden Weather AGW') + .setDescription('This api need for control weather processing store platform') + .setVersion('1.0') + .addTag('AGW Agregators Sensors') + .build(); + const document = SwaggerModule.createDocument(app, config); + SwaggerModule.setup('api', app, document); + + const port = process.env.AGW_PORT || 3000; + app.enableCors(); + await app.listen(port); + Logger.log( + `🚀 Application is running on: http://localhost:${port}/${globalPrefix}` + ); +} + +bootstrap(); diff --git a/weather_platform/apps/agw/src/measures/DTO/CreateMeasuresClass.dto.ts b/weather_platform/apps/agw/src/measures/DTO/CreateMeasuresClass.dto.ts new file mode 100644 index 0000000..54b06cc --- /dev/null +++ b/weather_platform/apps/agw/src/measures/DTO/CreateMeasuresClass.dto.ts @@ -0,0 +1,45 @@ +import { ApiProperty } from "@nestjs/swagger"; + +type MeasuresData = { + uuid: string; + agregator_uuid: string; + sensor_uuid: string; + msg_type: string; + msg_value: string; + sendedInDate: string; + math_time: string; +} + +type MeasuresCreateDTO = { + sendedInDate: string; + measuresDataList: [MeasuresData]; +} + +export class MeasuresDataClass implements MeasuresData { + @ApiProperty({description: 'The uuid of the measure'}) + uuid: string; + @ApiProperty({description: 'The agregator uuid'}) + agregator_uuid: string; + @ApiProperty({description: 'The sensor uuid'}) + sensor_uuid: string; + @ApiProperty({description: 'The type of the measure'}) + msg_type: string; + @ApiProperty({description: 'The value of the measure'}) + msg_value: string; + @ApiProperty({description: 'The date when the was sent'}) + sendedInDate: string; + @ApiProperty({description: 'The time that sensor was sent the measure'}) + math_time: string; +} + +export class MeasuresCreateDTOClass implements MeasuresCreateDTO { + @ApiProperty({description: 'The date when the was sent'}) + sendedInDate: string; + @ApiProperty({description: 'The measures data list'}) + measuresDataList: [MeasuresDataClass]; +} + +export class MeasuresCreateSuccessResponse { + @ApiProperty({description: 'The measures registred successfully'}) + code: string; +} diff --git a/weather_platform/apps/agw/src/measures/measures.controller.spec.ts b/weather_platform/apps/agw/src/measures/measures.controller.spec.ts new file mode 100644 index 0000000..4e3a8fb --- /dev/null +++ b/weather_platform/apps/agw/src/measures/measures.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { MeasuresController } from './measures.controller'; + +describe('MeasuresController', () => { + let controller: MeasuresController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [MeasuresController], + }).compile(); + + controller = module.get(MeasuresController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/weather_platform/apps/agw/src/measures/measures.controller.ts b/weather_platform/apps/agw/src/measures/measures.controller.ts new file mode 100644 index 0000000..4ddf445 --- /dev/null +++ b/weather_platform/apps/agw/src/measures/measures.controller.ts @@ -0,0 +1,60 @@ +import { Body, Controller, Post } from "@nestjs/common"; +import { MeasureCreateDTOLocalClass, MeasuresService } from "./measures.service"; +import { + ApiInternalServerErrorResponse, + ApiNotFoundResponse, + ApiOkResponse, + ApiOperation, + ApiResponse +} from "@nestjs/swagger"; +import { + MeasuresCreateDTOClass, + MeasuresCreateSuccessResponse, + MeasuresDataClass +} from "./DTO/CreateMeasuresClass.dto"; + +@Controller('measures') +export class MeasuresController { + constructor( + private readonly measuresService: MeasuresService, + ) {} + + @ApiOperation({ summary: 'Register Measure', description: 'Create Measure using ASC_WEATHER_RGM', operationId: 'create', tags: ['Measures StorePackages'], }) + @ApiResponse({ status: 200, type: MeasuresCreateSuccessResponse, description: 'The found measures', }) + @ApiOkResponse({ + description: 'Retrieved to register a new measures successfully', + type: MeasuresCreateDTOClass, status: 200, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, + }) + @ApiNotFoundResponse({ + description: 'The measures is not registered successfully', type: Error, status: 404, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error', status: 500, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, type: Error, + }) + @Post('register') + async createMeasuresPack( + @Body() packages: MeasuresCreateDTOClass, + ): Promise | null> { + + let check = true; + + packages.measuresDataList.map(async (measure: MeasuresDataClass) => { + const measure_create_data: MeasureCreateDTOLocalClass = { + sendedInDate: measure.sendedInDate, + sensor_uuid: measure.sensor_uuid, + agregator_uuid: measure.agregator_uuid, + time: measure.math_time, + type: measure.msg_type, + value: measure.msg_value, + }; + + const res = await this.measuresService.create(measure_create_data); + + if (!res) { + check = true; + } + }); + + return check ? { code: '200' } : { code: '500' }; + } +} diff --git a/weather_platform/apps/agw/src/measures/measures.module.ts b/weather_platform/apps/agw/src/measures/measures.module.ts new file mode 100644 index 0000000..cb47a51 --- /dev/null +++ b/weather_platform/apps/agw/src/measures/measures.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { MeasuresController } from './measures.controller'; +import { MeasuresService } from './measures.service'; +import { HttpModule } from "@nestjs/axios"; + +@Module({ + imports: [HttpModule], + controllers: [MeasuresController], + providers: [MeasuresService], + exports: [MeasuresService], +}) +export class MeasuresModule {} diff --git a/weather_platform/apps/agw/src/measures/measures.service.spec.ts b/weather_platform/apps/agw/src/measures/measures.service.spec.ts new file mode 100644 index 0000000..da78a7a --- /dev/null +++ b/weather_platform/apps/agw/src/measures/measures.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { MeasuresService } from './measures.service'; + +describe('MeasuresService', () => { + let service: MeasuresService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [MeasuresService], + }).compile(); + + service = module.get(MeasuresService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/weather_platform/apps/agw/src/measures/measures.service.ts b/weather_platform/apps/agw/src/measures/measures.service.ts new file mode 100644 index 0000000..af24b11 --- /dev/null +++ b/weather_platform/apps/agw/src/measures/measures.service.ts @@ -0,0 +1,78 @@ +import { Injectable } from '@nestjs/common'; +import { HttpService } from "@nestjs/axios"; +import { Measures, Prisma } from "@weather-platform/prisma-clients/Measures"; +import { ApiProperty } from "@nestjs/swagger"; +// eslint-disable-next-line @nx/enforce-module-boundaries +import { MeasureCreateDTOClass } from "../../../measures-service/src/DTO/MeasureCreateDTOClass.dto"; + +type MeasureCreateLocalDTO = { + sendedInDate: string; + sensor_uuid: string; + agregator_uuid: string; + time: string; + type: string; + value: string; +}; + +export class MeasureCreateDTOLocalClass implements MeasureCreateLocalDTO { + @ApiProperty({description: 'The date when the was sent'}) + sendedInDate: string; + @ApiProperty({description: 'The UUID of the creator'}) + sensor_uuid: string; + @ApiProperty({description: 'The agregator uuid'}) + agregator_uuid: string; + @ApiProperty({description: 'The time that sensor was sent the measure'}) + time: string; + @ApiProperty({description: 'The type of the measure'}) + type: string; + @ApiProperty({description: 'The value of the measure'}) + value: string; +} + + +@Injectable() +export class MeasuresService { + constructor(private readonly httpService: HttpService) {} + + MEASURES_SERVICE_URL = (process.env.MEASURES_SERVICE_PROTOCOL || 'http://') + + (process.env.MEASURES_SERVICE_HOST || 'localhost') + ':' + + (process.env.MEASURES_SERVICE_PORT || 3000) + + '/api/'; + + async get(data: Prisma.MeasuresFindManyArgs): Promise | null> { + try { + const response = await this.httpService.post(this.MEASURES_SERVICE_URL + 'get-with-params', data).toPromise(); + return response.data; + } catch (error) { + console.log(error); + throw error; + } + } + + async create(data: MeasureCreateDTOLocalClass): Promise | null> { + // eslint-disable-next-line no-useless-catch + try { + const updated_data: MeasureCreateDTOClass = { + ...data, + creatorUUID: '1', + } + const response = await this.httpService.post(this.MEASURES_SERVICE_URL + 'create', data).toPromise(); + return response.data; + } catch (error) { + throw error; + } + } + + async update(data: { + where: Prisma.MeasuresWhereUniqueInput; + data: Prisma.MeasuresUpdateInput; + }): Promise | null> { + // eslint-disable-next-line no-useless-catch + try { + const response = await this.httpService.post(this.MEASURES_SERVICE_URL + 'update', data).toPromise(); + return response.data; + } catch (error) { + throw error; + } + } +} diff --git a/weather_platform/apps/agw/src/sensors/sensors.controller.spec.ts b/weather_platform/apps/agw/src/sensors/sensors.controller.spec.ts new file mode 100644 index 0000000..02a9874 --- /dev/null +++ b/weather_platform/apps/agw/src/sensors/sensors.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { SensorsController } from './sensors.controller'; + +describe('SensorsController', () => { + let controller: SensorsController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [SensorsController], + }).compile(); + + controller = module.get(SensorsController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/weather_platform/apps/agw/src/sensors/sensors.controller.ts b/weather_platform/apps/agw/src/sensors/sensors.controller.ts new file mode 100644 index 0000000..e64c272 --- /dev/null +++ b/weather_platform/apps/agw/src/sensors/sensors.controller.ts @@ -0,0 +1,75 @@ +import { Body, Controller, Post } from "@nestjs/common"; +import { + ApiInternalServerErrorResponse, + ApiNotFoundResponse, + ApiOkResponse, + ApiOperation, + ApiResponse, + ApiTags +} from "@nestjs/swagger"; +import { SensorsService } from "./sensors.service"; +// eslint-disable-next-line @nx/enforce-module-boundaries +import { SensorGetDTOClass } from "../../../sensors-service/src/DTO/SensorGetDTOClass.dto"; +import { Prisma, Sensor } from "@weather-platform/prisma-clients/Sensors"; +// eslint-disable-next-line @nx/enforce-module-boundaries +import { SensorCreateDTOClass } from "../../../sensors-service/src/DTO/SensorCreateDTOClass.dto"; + +@ApiTags('Sensors') +@Controller('sensors') +export class SensorsController { + constructor( + private readonly sensorsService: SensorsService, + ) {} + + @ApiOperation({ summary: 'Get sensor with Prisma params', + description: 'Get sensor with Prisma params', + operationId: 'getWithParams', + tags: ['Sensors'] }) + @ApiResponse( + { status: 200, + type: SensorGetDTOClass, + description: 'The found sensor', + content: { 'application/json': { schema: { '$ref': '#/components/schemas/SensorGetDTOClass' } } }, + headers: { 'X-Request-Id': { schema: { type: 'string' } } } + }) + @ApiResponse({ status: 500, type: Error }) + @ApiOkResponse({ + description: 'Retrieved sensor successfully', + type: SensorGetDTOClass, + headers: { 'X-Request-Id': { schema: { type: 'string' } } }, + status: 200 + }) + @ApiNotFoundResponse({ + description: 'No sensor found for this request', status: 404, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, type: Error, + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error', status: 500, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, type: Error, + }) + @Post('get-with-params') + async getSensors( + @Body() params: SensorGetDTOClass, + ): Promise | null> { + return await this.sensorsService.get(params); + } + + + + @ApiOperation({ summary: 'Create Sensor' }) + @ApiResponse({ status: 200, type: SensorCreateDTOClass }) + @ApiOkResponse({ + description: 'Retrieved to create a new sensor successfully', + type: SensorCreateDTOClass, + }) + @ApiNotFoundResponse({ + description: 'The sensor is not created successfully', + }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error', + }) + @Post('create') + async createMatrix( + @Body() sectionData: SensorCreateDTOClass, + ): Promise | null> { + return await this.sensorsService.create(sectionData); + } +} diff --git a/weather_platform/apps/agw/src/sensors/sensors.module.ts b/weather_platform/apps/agw/src/sensors/sensors.module.ts new file mode 100644 index 0000000..3572baf --- /dev/null +++ b/weather_platform/apps/agw/src/sensors/sensors.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { SensorsService } from './sensors.service'; +import { SensorsController } from './sensors.controller'; +import { HttpModule } from "@nestjs/axios"; + +@Module({ + imports: [HttpModule], + providers: [SensorsService], + controllers: [SensorsController], + exports: [SensorsService], +}) +export class SensorsModule {} diff --git a/weather_platform/apps/agw/src/sensors/sensors.service.spec.ts b/weather_platform/apps/agw/src/sensors/sensors.service.spec.ts new file mode 100644 index 0000000..6e1fd15 --- /dev/null +++ b/weather_platform/apps/agw/src/sensors/sensors.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { SensorsService } from './sensors.service'; + +describe('SensorsService', () => { + let service: SensorsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [SensorsService], + }).compile(); + + service = module.get(SensorsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/weather_platform/apps/agw/src/sensors/sensors.service.ts b/weather_platform/apps/agw/src/sensors/sensors.service.ts new file mode 100644 index 0000000..7ccc093 --- /dev/null +++ b/weather_platform/apps/agw/src/sensors/sensors.service.ts @@ -0,0 +1,46 @@ +import { Injectable } from '@nestjs/common'; +import { HttpService } from "@nestjs/axios"; +import { Sensor, Prisma } from "@weather-platform/prisma-clients/Sensors"; + +@Injectable() +export class SensorsService { + constructor(private readonly httpService: HttpService) {} + + SENSORS_SERVICE_URL = (process.env.SENSORS_SERVICE_PROTOCOL || 'http://') + + (process.env.SENSORS_SERVICE_HOST || 'localhost') + ':' + + (process.env.SENSORS_SERVICE_PORT || 3000) + + '/api/'; + + async get(data: Prisma.SensorFindManyArgs): Promise | null> { + try { + const response = await this.httpService.post(this.SENSORS_SERVICE_URL + 'get-with-params', data).toPromise(); + return response.data; + } catch (error) { + console.log(error); + throw error; + } + } + + async create(data: Prisma.SensorCreateInput): Promise | null> { + // eslint-disable-next-line no-useless-catch + try { + const response = await this.httpService.post(this.SENSORS_SERVICE_URL + 'create', data).toPromise(); + return response.data; + } catch (error) { + throw error; + } + } + + async update(data: { + where: Prisma.SensorWhereUniqueInput; + data: Prisma.SensorUpdateInput; + }): Promise | null> { + // eslint-disable-next-line no-useless-catch + try { + const response = await this.httpService.post(this.SENSORS_SERVICE_URL + 'update', data).toPromise(); + return response.data; + } catch (error) { + throw error; + } + } +} diff --git a/weather_platform/apps/agw/tsconfig.app.json b/weather_platform/apps/agw/tsconfig.app.json new file mode 100644 index 0000000..a2ce765 --- /dev/null +++ b/weather_platform/apps/agw/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/weather_platform/apps/agw/tsconfig.json b/weather_platform/apps/agw/tsconfig.json new file mode 100644 index 0000000..c1e2dd4 --- /dev/null +++ b/weather_platform/apps/agw/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/weather_platform/apps/agw/tsconfig.spec.json b/weather_platform/apps/agw/tsconfig.spec.json new file mode 100644 index 0000000..9b2a121 --- /dev/null +++ b/weather_platform/apps/agw/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/weather_platform/apps/agw/webpack.config.js b/weather_platform/apps/agw/webpack.config.js new file mode 100644 index 0000000..81db92b --- /dev/null +++ b/weather_platform/apps/agw/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/weather_platform/apps/crud-e2e/.eslintrc.json b/weather_platform/apps/crud-e2e/.eslintrc.json new file mode 100644 index 0000000..696cb8b --- /dev/null +++ b/weather_platform/apps/crud-e2e/.eslintrc.json @@ -0,0 +1,10 @@ +{ + "extends": ["plugin:cypress/recommended", "../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/weather_platform/apps/crud-e2e/cypress.config.ts b/weather_platform/apps/crud-e2e/cypress.config.ts new file mode 100644 index 0000000..a45b4fd --- /dev/null +++ b/weather_platform/apps/crud-e2e/cypress.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'cypress'; +import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset'; + +export default defineConfig({ + e2e: nxE2EPreset(__dirname, { + bundler: 'vite', + }), +}); diff --git a/weather_platform/apps/crud-e2e/project.json b/weather_platform/apps/crud-e2e/project.json new file mode 100644 index 0000000..0d0c310 --- /dev/null +++ b/weather_platform/apps/crud-e2e/project.json @@ -0,0 +1,33 @@ +{ + "name": "crud-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/crud-e2e/src", + "projectType": "application", + "targets": { + "e2e": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/crud-e2e/cypress.config.ts", + "devServerTarget": "crud:serve:development", + "testingType": "e2e" + }, + "configurations": { + "production": { + "devServerTarget": "crud:serve:production" + }, + "ci": { + "devServerTarget": "crud:serve-static" + } + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/crud-e2e/**/*.{js,ts}"] + } + } + }, + "tags": [], + "implicitDependencies": ["crud"] +} diff --git a/weather_platform/apps/crud-e2e/src/e2e/app.cy.ts b/weather_platform/apps/crud-e2e/src/e2e/app.cy.ts new file mode 100644 index 0000000..70d7f37 --- /dev/null +++ b/weather_platform/apps/crud-e2e/src/e2e/app.cy.ts @@ -0,0 +1,13 @@ +import { getGreeting } from '../support/app.po'; + +describe('crud', () => { + beforeEach(() => cy.visit('/')); + + it('should display welcome message', () => { + // Custom command example, see `../support/commands.ts` file + cy.login('my-email@something.com', 'myPassword'); + + // Function helper example, see `../support/app.po.ts` file + getGreeting().contains('Welcome crud'); + }); +}); diff --git a/weather_platform/apps/crud-e2e/src/fixtures/example.json b/weather_platform/apps/crud-e2e/src/fixtures/example.json new file mode 100644 index 0000000..294cbed --- /dev/null +++ b/weather_platform/apps/crud-e2e/src/fixtures/example.json @@ -0,0 +1,4 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io" +} diff --git a/weather_platform/apps/crud-e2e/src/support/app.po.ts b/weather_platform/apps/crud-e2e/src/support/app.po.ts new file mode 100644 index 0000000..3293424 --- /dev/null +++ b/weather_platform/apps/crud-e2e/src/support/app.po.ts @@ -0,0 +1 @@ +export const getGreeting = () => cy.get('h1'); diff --git a/weather_platform/apps/crud-e2e/src/support/commands.ts b/weather_platform/apps/crud-e2e/src/support/commands.ts new file mode 100644 index 0000000..310f1fa --- /dev/null +++ b/weather_platform/apps/crud-e2e/src/support/commands.ts @@ -0,0 +1,33 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** + +// eslint-disable-next-line @typescript-eslint/no-namespace +declare namespace Cypress { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface Chainable { + login(email: string, password: string): void; + } +} +// +// -- This is a parent command -- +Cypress.Commands.add('login', (email, password) => { + console.log('Custom command example: Login', email, password); +}); +// +// -- This is a child command -- +// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/weather_platform/apps/crud-e2e/src/support/e2e.ts b/weather_platform/apps/crud-e2e/src/support/e2e.ts new file mode 100644 index 0000000..3d469a6 --- /dev/null +++ b/weather_platform/apps/crud-e2e/src/support/e2e.ts @@ -0,0 +1,17 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands'; diff --git a/weather_platform/apps/crud-e2e/tsconfig.json b/weather_platform/apps/crud-e2e/tsconfig.json new file mode 100644 index 0000000..cc509a7 --- /dev/null +++ b/weather_platform/apps/crud-e2e/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "sourceMap": false, + "outDir": "../../dist/out-tsc", + "allowJs": true, + "types": ["cypress", "node"] + }, + "include": ["src/**/*.ts", "src/**/*.js", "cypress.config.ts"] +} diff --git a/weather_platform/apps/crud/.eslintrc.json b/weather_platform/apps/crud/.eslintrc.json new file mode 100644 index 0000000..a39ac5d --- /dev/null +++ b/weather_platform/apps/crud/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nx/react", "../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/weather_platform/apps/crud/index.html b/weather_platform/apps/crud/index.html new file mode 100644 index 0000000..f4a96ee --- /dev/null +++ b/weather_platform/apps/crud/index.html @@ -0,0 +1,16 @@ + + + + + Crud + + + + + + + +
+ + + diff --git a/weather_platform/apps/crud/postcss.config.js b/weather_platform/apps/crud/postcss.config.js new file mode 100644 index 0000000..c72626d --- /dev/null +++ b/weather_platform/apps/crud/postcss.config.js @@ -0,0 +1,15 @@ +const { join } = require('path'); + +// Note: If you use library-specific PostCSS/Tailwind configuration then you should remove the `postcssConfig` build +// option from your application's configuration (i.e. project.json). +// +// See: https://nx.dev/guides/using-tailwind-css-in-react#step-4:-applying-configuration-to-libraries + +module.exports = { + plugins: { + tailwindcss: { + config: join(__dirname, 'tailwind.config.js'), + }, + autoprefixer: {}, + }, +}; diff --git a/weather_platform/apps/crud/project.json b/weather_platform/apps/crud/project.json new file mode 100644 index 0000000..f9813d2 --- /dev/null +++ b/weather_platform/apps/crud/project.json @@ -0,0 +1,79 @@ +{ + "name": "crud", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/crud/src", + "projectType": "application", + "targets": { + "build": { + "executor": "@nx/vite:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "production", + "options": { + "outputPath": "dist/apps/crud" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "serve": { + "executor": "@nx/vite:dev-server", + "defaultConfiguration": "development", + "options": { + "buildTarget": "crud:build", + "proxyConfig": "apps/crud/proxy.conf.json" + }, + "configurations": { + "development": { + "buildTarget": "crud:build:development", + "hmr": true + }, + "production": { + "buildTarget": "crud:build:production", + "hmr": false + } + } + }, + "preview": { + "executor": "@nx/vite:preview-server", + "defaultConfiguration": "development", + "options": { + "buildTarget": "crud:build" + }, + "configurations": { + "development": { + "buildTarget": "crud:build:development" + }, + "production": { + "buildTarget": "crud:build:production" + } + } + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "passWithNoTests": true, + "reportsDirectory": "../../coverage/apps/crud" + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/crud/**/*.{ts,tsx,js,jsx}"] + } + }, + "serve-static": { + "executor": "@nx/web:file-server", + "options": { + "buildTarget": "crud:build" + } + } + }, + "tags": [] +} diff --git a/weather_platform/apps/crud/proxy.conf.json b/weather_platform/apps/crud/proxy.conf.json new file mode 100644 index 0000000..63dd627 --- /dev/null +++ b/weather_platform/apps/crud/proxy.conf.json @@ -0,0 +1,6 @@ +{ + "/api": { + "target": "http://localhost:3000", + "secure": false + } +} diff --git a/weather_platform/apps/crud/public/favicon.ico b/weather_platform/apps/crud/public/favicon.ico new file mode 100644 index 0000000..317ebcb Binary files /dev/null and b/weather_platform/apps/crud/public/favicon.ico differ diff --git a/weather_platform/apps/crud/src/app/app.module.scss b/weather_platform/apps/crud/src/app/app.module.scss new file mode 100644 index 0000000..7b88fba --- /dev/null +++ b/weather_platform/apps/crud/src/app/app.module.scss @@ -0,0 +1 @@ +/* Your styles goes here. */ diff --git a/weather_platform/apps/crud/src/app/app.spec.tsx b/weather_platform/apps/crud/src/app/app.spec.tsx new file mode 100644 index 0000000..8bb4e39 --- /dev/null +++ b/weather_platform/apps/crud/src/app/app.spec.tsx @@ -0,0 +1,15 @@ +import { render } from '@testing-library/react'; + +import App from './app'; + +describe('App', () => { + it('should render successfully', () => { + const { baseElement } = render(); + expect(baseElement).toBeTruthy(); + }); + + it('should have a greeting as the title', () => { + const { getByText } = render(); + expect(getByText(/Welcome crud/gi)).toBeTruthy(); + }); +}); diff --git a/weather_platform/apps/crud/src/app/app.tsx b/weather_platform/apps/crud/src/app/app.tsx new file mode 100644 index 0000000..0645eb4 --- /dev/null +++ b/weather_platform/apps/crud/src/app/app.tsx @@ -0,0 +1,14 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import styles from './app.module.scss'; + +import NxWelcome from './nx-welcome'; + +export function App() { + return ( +
+ +
+ ); +} + +export default App; diff --git a/weather_platform/apps/crud/src/app/nx-welcome.tsx b/weather_platform/apps/crud/src/app/nx-welcome.tsx new file mode 100644 index 0000000..f0cd657 --- /dev/null +++ b/weather_platform/apps/crud/src/app/nx-welcome.tsx @@ -0,0 +1,845 @@ +/* + * * * * * * * * * * * * * * * * * * * * * * * * * * * * + This is a starter component and can be deleted. + * * * * * * * * * * * * * * * * * * * * * * * * * * * * + Delete this file and get started with your project! + * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ +export function NxWelcome({ title }: { title: string }) { + return ( + <> +