commit
265da5aa19
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CsvFileAttributes">
|
||||
<option name="attributeMap">
|
||||
<map>
|
||||
<entry key="/weather_platform/apps/py-multy-agent-interpreter/examples/files/extracted_data.csv">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value="," />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DiscordProjectSettings">
|
||||
<option name="show" value="ASK" />
|
||||
<option name="description" value="" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="6cb4dca5-d93c-4b61-8425-4ba8b7c9b2ff" name="Changes" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/weather_platform/apps/py-tg-bot-weather-agent/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/weather_platform/apps/py-tg-bot-weather-agent/main.py" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="TypeScript File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="MarkdownSettingsMigration">
|
||||
<option name="stateVersion" value="1" />
|
||||
</component>
|
||||
<component name="ProjectId" id="2WQSJMtSztUrKlia6nQzkrUUqV2" />
|
||||
<component name="ProjectLevelVcsManager">
|
||||
<ConfirmationsSetting value="1" id="Add" />
|
||||
</component>
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"WebServerToolWindowFactoryState": "false",
|
||||
"last_opened_file_path": "/Users/darius/Desktop/ASC/CyberGarden/kempt-kinkajou/weather_platform/apps",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"ts.external.directory.path": "/Users/darius/Desktop/ASC/CyberGarden/kempt-kinkajou/weather_platform/node_modules/typescript/lib",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="$PROJECT_DIR$/weather_platform/apps" />
|
||||
<recent name="$PROJECT_DIR$/weather_platform/ui-modules/src/lib/navbar" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="6cb4dca5-d93c-4b61-8425-4ba8b7c9b2ff" name="Changes" comment="" />
|
||||
<created>1696663237589</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1696663237589</updated>
|
||||
<workItem from="1696663238626" duration="5030000" />
|
||||
<workItem from="1696670312018" duration="20846000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,13 @@
|
||||
# K-Lab Weather Platform
|
||||
|
||||
## Hardware
|
||||
|
||||
![Screenshot 2023-10-07 at 19.07.30.png](assets%2FScreenshot%202023-10-07%20at%2019.07.30.png)
|
||||
|
||||
## Software Platform
|
||||
|
||||
![Screenshot 2023-10-07 at 19.08.07.png](assets%2FScreenshot%202023-10-07%20at%2019.08.07.png)
|
||||
|
||||
## Telegram Bot with AI
|
||||
|
||||
![Screenshot 2023-10-07 at 19.08.53.png](assets%2FScreenshot%202023-10-07%20at%2019.08.53.png)
|
After Width: | Height: | Size: 314 KiB |
After Width: | Height: | Size: 354 KiB |
After Width: | Height: | Size: 809 KiB |
@ -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
|
@ -0,0 +1,8 @@
|
||||
AGW_PORT=8045
|
||||
SENSORS_SERVICE_PORT=8046
|
||||
AGREGATORS_SERVICE_PORT=8047
|
||||
MEASURES_SERVICE_PORT=8048
|
||||
PORT=8080
|
||||
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
|
@ -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
|
@ -0,0 +1 @@
|
||||
node_modules
|
@ -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": {}
|
||||
}
|
||||
]
|
||||
}
|
@ -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
|
@ -0,0 +1,3 @@
|
||||
# Add files here to ignore them from prettier formatting
|
||||
/dist
|
||||
/coverage
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"singleQuote": true
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'agregators-service-e2e',
|
||||
preset: '../../jest.preset.js',
|
||||
globalSetup: '<rootDir>/src/support/global-setup.ts',
|
||||
globalTeardown: '<rootDir>/src/support/global-teardown.ts',
|
||||
setupFiles: ['<rootDir>/src/support/test-setup.ts'],
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\.[tj]s$': [
|
||||
'ts-jest',
|
||||
{
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
},
|
||||
],
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'js', 'html'],
|
||||
coverageDirectory: '../../coverage/agregators-service-e2e',
|
||||
};
|
@ -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}"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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' });
|
||||
});
|
||||
});
|
@ -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';
|
||||
};
|
@ -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__);
|
||||
};
|
@ -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}`;
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["jest.config.ts", "src/**/*.ts"]
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'agregators-service',
|
||||
preset: '../../jest.preset.js',
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'js', 'html'],
|
||||
coverageDirectory: '../../coverage/apps/agregators-service',
|
||||
};
|
@ -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": []
|
||||
}
|
@ -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'})
|
||||
lat: string;
|
||||
@ApiProperty({description: 'The agregator longitude'})
|
||||
lng: string;
|
||||
@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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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>(AppController);
|
||||
expect(appController.getData()).toEqual({ message: 'Hello API' });
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,136 @@
|
||||
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;
|
||||
lat: string;
|
||||
lng: string;
|
||||
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<Agregator[]> {
|
||||
|
||||
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<Agregator> {
|
||||
|
||||
const { uuid } = uuidv4();
|
||||
|
||||
const updatedWhere: Prisma.AgregatorCreateInput = {
|
||||
...sectionData,
|
||||
uuid: uuid,
|
||||
};
|
||||
|
||||
console.log(updatedWhere);
|
||||
|
||||
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<Agregator> {
|
||||
const { data, where } = params;
|
||||
|
||||
const agregator: Agregator = await this.appService.update({
|
||||
where,
|
||||
data,
|
||||
});
|
||||
|
||||
return agregator;
|
||||
}
|
||||
}
|
@ -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 {}
|
@ -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>(AppService);
|
||||
});
|
||||
|
||||
describe('getData', () => {
|
||||
it('should return "Hello API"', () => {
|
||||
expect(service.getData()).toEqual({ message: 'Hello API' });
|
||||
});
|
||||
});
|
||||
});
|
@ -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<Agregator> {
|
||||
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<Agregator[]> {
|
||||
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<Agregator> {
|
||||
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<Agregator> {
|
||||
try {
|
||||
return this.prisma.agregator.update({
|
||||
where: {
|
||||
uuid: uuid,
|
||||
},
|
||||
data: {
|
||||
isDeleted: true,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e.code);
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
}
|
@ -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(
|
||||
`🚀 Agregators Service is running on: http://localhost:${port}/${globalPrefix}`
|
||||
);
|
||||
}
|
||||
|
||||
bootstrap();
|
@ -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"]
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
@ -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"
|
||||
]
|
||||
}
|
@ -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;
|
||||
});
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'agw-e2e',
|
||||
preset: '../../jest.preset.js',
|
||||
globalSetup: '<rootDir>/src/support/global-setup.ts',
|
||||
globalTeardown: '<rootDir>/src/support/global-teardown.ts',
|
||||
setupFiles: ['<rootDir>/src/support/test-setup.ts'],
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\.[tj]s$': [
|
||||
'ts-jest',
|
||||
{
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
},
|
||||
],
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'js', 'html'],
|
||||
coverageDirectory: '../../coverage/agw-e2e',
|
||||
};
|
@ -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}"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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' });
|
||||
});
|
||||
});
|
@ -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';
|
||||
};
|
@ -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__);
|
||||
};
|
@ -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}`;
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["jest.config.ts", "src/**/*.ts"]
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'agw',
|
||||
preset: '../../jest.preset.js',
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'js', 'html'],
|
||||
coverageDirectory: '../../coverage/apps/agw',
|
||||
};
|
@ -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": []
|
||||
}
|
@ -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>(AgregatorController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
@ -0,0 +1,89 @@
|
||||
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<Partial<Agregator[]> | null> {
|
||||
console.log(params);
|
||||
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<Partial<Agregator> | null> {
|
||||
console.log(sectionData);
|
||||
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<Partial<Agregator> | null> {
|
||||
return await this.agregatorService.update(params);
|
||||
}
|
||||
}
|
@ -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 {}
|
@ -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>(AgregatorService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
@ -0,0 +1,48 @@
|
||||
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/';
|
||||
|
||||
AGREGATOR_SERVICE_URL = 'http://localhost:8047/api/';
|
||||
|
||||
async get(data: Prisma.AgregatorFindManyArgs): Promise<Partial<Agregator[]> | 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<Partial<Agregator> | 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<Partial<Agregator> | 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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>(AppController);
|
||||
expect(appController.getData()).toEqual({ message: 'Hello API' });
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,36 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
|
||||
import { AppService } from './app.service';
|
||||
import {AgregatorService} from "../agregator/agregator.service";
|
||||
// eslint-disable-next-line @nx/enforce-module-boundaries
|
||||
import {AgregatorCreateDTOClass} from "../../../agregators-service/src/DTO/AgregatorCreateDTOClass.dto";
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
constructor(private readonly appService: AppService,
|
||||
private readonly agregatorService: AgregatorService,
|
||||
) {}
|
||||
|
||||
@Get('/seed/test/data')
|
||||
setSeedTestData() {
|
||||
const data: AgregatorCreateDTOClass = {
|
||||
sendedInDate: new Date().toISOString(),
|
||||
creatorUUID: "test",
|
||||
name: "agregator 1",
|
||||
lat: "45",
|
||||
lng: "76",
|
||||
height: 1,
|
||||
country: "russia",
|
||||
city: "taganrog",
|
||||
region: "rostov",
|
||||
street: "street",
|
||||
}
|
||||
this.agregatorService.create(data);
|
||||
return "success";
|
||||
}
|
||||
|
||||
@Get()
|
||||
getData() {
|
||||
return this.appService.getData();
|
||||
}
|
||||
}
|
@ -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 {}
|
@ -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>(AppService);
|
||||
});
|
||||
|
||||
describe('getData', () => {
|
||||
it('should return "Hello API"', () => {
|
||||
expect(service.getData()).toEqual({ message: 'Hello API' });
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class AppService {
|
||||
getData(): { message: string } {
|
||||
return { message: 'Hello API' };
|
||||
}
|
||||
}
|
@ -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(
|
||||
`🚀 AGW is running on: http://localhost:${port}/${globalPrefix}`
|
||||
);
|
||||
}
|
||||
|
||||
bootstrap();
|
@ -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;
|
||||
}
|
@ -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>(MeasuresController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
@ -0,0 +1,106 @@
|
||||
import {Body, Controller, Get, 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";
|
||||
// eslint-disable-next-line @nx/enforce-module-boundaries
|
||||
import {AgregatorGetDTO} from "../../../agregators-service/src/app/app.controller";
|
||||
import {Measures} from "@weather-platform/prisma-clients/Measures";
|
||||
// eslint-disable-next-line @nx/enforce-module-boundaries
|
||||
import {MeasureGetDTOClass} from "../../../measures-service/src/DTO/MeasureGetDTOClass.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<Partial<MeasuresCreateSuccessResponse> | 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);
|
||||
|
||||
console.log(res);
|
||||
|
||||
if (!res) {
|
||||
check = true;
|
||||
}
|
||||
});
|
||||
|
||||
return check ? { code: '200' } : { code: '500' };
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ApiOperation({
|
||||
summary: 'Get measures data with Prisma params', tags: ['Measures'], description: 'Get measures with Prisma params', operationId: 'getWithParams',
|
||||
})
|
||||
@ApiResponse({ status: 200, type: MeasureGetDTOClass, headers: { 'X-Request-Id': { schema: { type: 'string' } } }, description: 'The found measure', })
|
||||
@ApiResponse({ status: 500, type: Error, description: 'Internal server error', headers: { 'X-Request-Id': { schema: { type: 'string' } } }, })
|
||||
@ApiOkResponse({
|
||||
description: 'Retrieved measures successfully',
|
||||
type: MeasureGetDTOClass, status: 200, headers: { 'X-Request-Id': { schema: { type: 'string' } } },
|
||||
})
|
||||
@ApiNotFoundResponse({
|
||||
description: 'No measures 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: MeasureGetDTOClass,
|
||||
): Promise<Partial<Measures[]> | null> {
|
||||
return await this.measuresService.get(params);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Get('get-for-ai')
|
||||
async getAgregatorsForAI() {
|
||||
const res = await this.measuresService.get({});
|
||||
const newArray = res.map(item => ({
|
||||
sensor_uuid: item.sensor_uuid,
|
||||
agregator_uuid: item.agregator_uuid,
|
||||
type: item.type,
|
||||
value: item.value,
|
||||
time: item.time
|
||||
}));
|
||||
return newArray;
|
||||
}
|
||||
}
|
@ -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 {}
|
@ -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>(MeasuresService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
@ -0,0 +1,75 @@
|
||||
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 = "http://localhost:8048/api/"
|
||||
|
||||
async get(data: Prisma.MeasuresFindManyArgs): Promise<Partial<Measures[]> | 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<Partial<Measures> | null> {
|
||||
// eslint-disable-next-line no-useless-catch
|
||||
try {
|
||||
const updated_data: any = {
|
||||
...data,
|
||||
};
|
||||
console.log(updated_data);
|
||||
const response = await this.httpService.post(this.MEASURES_SERVICE_URL + 'create', updated_data).toPromise();
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async update(data: {
|
||||
where: Prisma.MeasuresWhereUniqueInput;
|
||||
data: Prisma.MeasuresUpdateInput;
|
||||
}): Promise<Partial<Measures> | 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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>(SensorsController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
@ -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<Partial<Sensor[]> | 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<Partial<Sensor> | null> {
|
||||
return await this.sensorsService.create(sectionData);
|
||||
}
|
||||
}
|
@ -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 {}
|
@ -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>(SensorsService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
@ -0,0 +1,43 @@
|
||||
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 = 'http://localhost:8046/api/';
|
||||
|
||||
async get(data: Prisma.SensorFindManyArgs): Promise<Partial<Sensor[]> | 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<Partial<Sensor> | 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<Partial<Sensor> | 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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"]
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
@ -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"
|
||||
]
|
||||
}
|
@ -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;
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset';
|
||||
|
||||
export default defineConfig({
|
||||
e2e: nxE2EPreset(__dirname, {
|
||||
bundler: 'vite',
|
||||
}),
|
||||
});
|
@ -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"]
|
||||
}
|
@ -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');
|
||||
});
|
||||
});
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io"
|
||||
}
|
@ -0,0 +1 @@
|
||||
export const getGreeting = () => cy.get('h1');
|
@ -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<Subject> {
|
||||
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) => { ... })
|
@ -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';
|
@ -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"]
|
||||
}
|
@ -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": {}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Crud</title>
|
||||
<base href="/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="/src/styles.scss" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
@ -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: {},
|
||||
},
|
||||
};
|
@ -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": []
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"/api": {
|
||||
"target": "http://localhost:8045",
|
||||
"secure": false
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1 @@
|
||||
/* Your styles goes here. */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue