Обновление PROD состояния кодовой базой dev контура #7
2
migrations/0002_current_value_nullable.sql
Normal file
2
migrations/0002_current_value_nullable.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE current
|
||||||
|
ALTER COLUMN value DROP NOT NULL;
|
||||||
11
src/common/is-nullable-number.decorator.ts
Normal file
11
src/common/is-nullable-number.decorator.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { applyDecorators } from '@nestjs/common';
|
||||||
|
import { Transform } from 'class-transformer';
|
||||||
|
import { IsNumber, ValidateIf, ValidationOptions } from 'class-validator';
|
||||||
|
|
||||||
|
export function IsNullableNumber(options?: ValidationOptions): PropertyDecorator {
|
||||||
|
return applyDecorators(
|
||||||
|
Transform(({ value }) => (value === null ? null : Number(value))),
|
||||||
|
ValidateIf((_, value) => value !== null),
|
||||||
|
IsNumber({}, options),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
export type CurrentRow = {
|
export type CurrentRow = {
|
||||||
edge: string;
|
edge: string;
|
||||||
tag: string;
|
tag: string;
|
||||||
value: number;
|
value: number | null;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
name: string | null;
|
name: string | null;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export type CurrentItemDto = {
|
export type CurrentItemDto = {
|
||||||
edge: string;
|
edge: string;
|
||||||
tag: string;
|
tag: string;
|
||||||
value: number;
|
value: number | null;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
time: Date;
|
time: Date;
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ export class IngestEdgeValuesDto {
|
|||||||
timestamp!: string;
|
timestamp!: string;
|
||||||
|
|
||||||
@IsObject()
|
@IsObject()
|
||||||
values!: Record<string, number>;
|
values!: Record<string, number | null>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Type } from 'class-transformer';
|
import { IsDateString, IsNotEmpty, IsString } from 'class-validator';
|
||||||
import { IsDateString, IsNotEmpty, IsNumber, IsString } from 'class-validator';
|
import { IsNullableNumber } from '../../common/is-nullable-number.decorator';
|
||||||
|
|
||||||
export class IngestPointDto {
|
export class IngestPointDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@@ -13,7 +13,6 @@ export class IngestPointDto {
|
|||||||
@IsDateString()
|
@IsDateString()
|
||||||
timestamp!: string;
|
timestamp!: string;
|
||||||
|
|
||||||
@Type(() => Number)
|
@IsNullableNumber()
|
||||||
@IsNumber()
|
value!: number | null;
|
||||||
value!: number;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export class IngestController {
|
|||||||
const points = Object.entries(body.values).map(([tag, value]) => ({
|
const points = Object.entries(body.values).map(([tag, value]) => ({
|
||||||
edge,
|
edge,
|
||||||
tag,
|
tag,
|
||||||
value: Number(value),
|
value: value === null ? null : Number(value),
|
||||||
timestamp: body.timestamp,
|
timestamp: body.timestamp,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ type IngestResult = {
|
|||||||
export class IngestService {
|
export class IngestService {
|
||||||
constructor(private readonly db: DbService) {}
|
constructor(private readonly db: DbService) {}
|
||||||
|
|
||||||
/** Пишет одну входящую точку в history и обновляет текущий снимок current для UI/SSE. */
|
/** Пишет числовую точку в history и всегда обновляет текущий снимок current для UI/SSE. */
|
||||||
async ingestPoint(point: IngestPointDto): Promise<IngestResult> {
|
async ingestPoint(point: IngestPointDto): Promise<IngestResult> {
|
||||||
|
if (point.value !== null) {
|
||||||
await this.db.query(
|
await this.db.query(
|
||||||
`
|
`
|
||||||
INSERT INTO history (timestamp, edge, tag, value)
|
INSERT INTO history (timestamp, edge, tag, value)
|
||||||
@@ -19,6 +20,7 @@ export class IngestService {
|
|||||||
`,
|
`,
|
||||||
[point.timestamp, point.edge, point.tag, point.value],
|
[point.timestamp, point.edge, point.tag, point.value],
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
await this.db.query(
|
await this.db.query(
|
||||||
`
|
`
|
||||||
|
|||||||
Reference in New Issue
Block a user