Add PollutantType enum and update AQI-related entities and services to use it

This commit is contained in:
faris Aljohari
2025-06-11 00:28:00 -06:00
parent c86be27576
commit 2cb77504ca
5 changed files with 72 additions and 67 deletions

View File

@ -0,0 +1,8 @@
export enum PollutantType {
AQI = 'aqi',
PM25 = 'pm25',
PM10 = 'pm10',
VOC = 'voc',
CO2 = 'co2',
CH2O = 'ch2o',
}

View File

@ -9,173 +9,173 @@ export class AqiSpaceDailyPollutantStatsEntity extends AbstractEntity<AqiSpaceDa
@Column({ nullable: false }) @Column({ nullable: false })
public spaceUuid: string; public spaceUuid: string;
@ManyToOne(() => SpaceEntity, (space) => space.presenceSensorDaily) @ManyToOne(() => SpaceEntity, (space) => space.aqiSensorDaily)
space: SpaceEntity; space: SpaceEntity;
@Column({ type: 'date', nullable: false }) @Column({ type: 'date', nullable: false })
public eventDate: Date; public eventDate: Date;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public goodAqiPercentage: number; public goodAqiPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public moderateAqiPercentage: number; public moderateAqiPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthySensitiveAqiPercentage: number; public unhealthySensitiveAqiPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthyAqiPercentage: number; public unhealthyAqiPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public veryUnhealthyAqiPercentage: number; public veryUnhealthyAqiPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public hazardousAqiPercentage: number; public hazardousAqiPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyAvgAqi: number; public dailyAvgAqi?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMaxAqi: number; public dailyMaxAqi?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMinAqi: number; public dailyMinAqi?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public goodPm25Percentage: number; public goodPm25Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public moderatePm25Percentage: number; public moderatePm25Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthySensitivePm25Percentage: number; public unhealthySensitivePm25Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthyPm25Percentage: number; public unhealthyPm25Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public veryUnhealthyPm25Percentage: number; public veryUnhealthyPm25Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public hazardousPm25Percentage: number; public hazardousPm25Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyAvgPm25: number; public dailyAvgPm25?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMaxPm25: number; public dailyMaxPm25?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMinPm25: number; public dailyMinPm25?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public goodPm10Percentage: number; public goodPm10Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public moderatePm10Percentage: number; public moderatePm10Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthySensitivePm10Percentage: number; public unhealthySensitivePm10Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthyPm10Percentage: number; public unhealthyPm10Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public veryUnhealthyPm10Percentage: number; public veryUnhealthyPm10Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public hazardousPm10Percentage: number; public hazardousPm10Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyAvgPm10: number; public dailyAvgPm10?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMaxPm10: number; public dailyMaxPm10?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMinPm10: number; public dailyMinPm10?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public goodVocPercentage: number; public goodVocPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public moderateVocPercentage: number; public moderateVocPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthySensitiveVocPercentage: number; public unhealthySensitiveVocPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthyVocPercentage: number; public unhealthyVocPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public veryUnhealthyVocPercentage: number; public veryUnhealthyVocPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public hazardousVocPercentage: number; public hazardousVocPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyAvgVoc: number; public dailyAvgVoc?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMaxVoc: number; public dailyMaxVoc?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMinVoc: number; public dailyMinVoc?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public goodCo2Percentage: number; public goodCo2Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public moderateCo2Percentage: number; public moderateCo2Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthySensitiveCo2Percentage: number; public unhealthySensitiveCo2Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthyCo2Percentage: number; public unhealthyCo2Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public veryUnhealthyCo2Percentage: number; public veryUnhealthyCo2Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public hazardousCo2Percentage: number; public hazardousCo2Percentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyAvgCo2: number; public dailyAvgCo2?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMaxCo2: number; public dailyMaxCo2?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMinCo2: number; public dailyMinCo2?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public goodCh2oPercentage: number; public goodCh2oPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public moderateCh2oPercentage: number; public moderateCh2oPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthySensitiveCh2oPercentage: number; public unhealthySensitiveCh2oPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public unhealthyCh2oPercentage: number; public unhealthyCh2oPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public veryUnhealthyCh2oPercentage: number; public veryUnhealthyCh2oPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public hazardousCh2oPercentage: number; public hazardousCh2oPercentage?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyAvgCh2o: number; public dailyAvgCh2o?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMaxCh2o: number; public dailyMaxCh2o?: number;
@Column('float', { nullable: true }) @Column('float', { nullable: true })
public dailyMinCh2o: number; public dailyMinCh2o?: number;
constructor(partial: Partial<AqiSpaceDailyPollutantStatsEntity>) { constructor(partial: Partial<AqiSpaceDailyPollutantStatsEntity>) {
super(); super();

View File

@ -11,6 +11,7 @@ import { InviteUserSpaceEntity } from '../../Invite-user/entities';
import { SpaceProductAllocationEntity } from './space-product-allocation.entity'; import { SpaceProductAllocationEntity } from './space-product-allocation.entity';
import { SubspaceEntity } from './subspace/subspace.entity'; import { SubspaceEntity } from './subspace/subspace.entity';
import { PresenceSensorDailySpaceEntity } from '../../presence-sensor/entities'; import { PresenceSensorDailySpaceEntity } from '../../presence-sensor/entities';
import { AqiSpaceDailyPollutantStatsEntity } from '../../aqi/entities';
@Entity({ name: 'space' }) @Entity({ name: 'space' })
export class SpaceEntity extends AbstractEntity<SpaceDto> { export class SpaceEntity extends AbstractEntity<SpaceDto> {
@ -115,6 +116,9 @@ export class SpaceEntity extends AbstractEntity<SpaceDto> {
@OneToMany(() => PresenceSensorDailySpaceEntity, (sensor) => sensor.space) @OneToMany(() => PresenceSensorDailySpaceEntity, (sensor) => sensor.space)
presenceSensorDaily: PresenceSensorDailySpaceEntity[]; presenceSensorDaily: PresenceSensorDailySpaceEntity[];
@OneToMany(() => AqiSpaceDailyPollutantStatsEntity, (aqi) => aqi.space)
aqiSensorDaily: AqiSpaceDailyPollutantStatsEntity[];
constructor(partial: Partial<SpaceEntity>) { constructor(partial: Partial<SpaceEntity>) {
super(); super();
Object.assign(this, partial); Object.assign(this, partial);

View File

@ -1,3 +1,4 @@
import { PollutantType } from '@app/common/constants/pollutants.enum';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { Matches, IsNotEmpty, IsString } from 'class-validator'; import { Matches, IsNotEmpty, IsString } from 'class-validator';
@ -16,8 +17,8 @@ export class GetAqiDailyBySpaceDto {
export class GetAqiPollutantBySpaceDto { export class GetAqiPollutantBySpaceDto {
@ApiProperty({ @ApiProperty({
description: 'Pollutant Type', description: 'Pollutant Type',
enum: ['aqi', 'pm25', 'pm10', 'voc', 'co2', 'ch2o'], enum: PollutantType,
example: 'aqi', example: PollutantType.AQI,
required: true, required: true,
}) })
@IsString() @IsString()

View File

@ -10,6 +10,7 @@ import { DataSource } from 'typeorm';
import { SQL_PROCEDURES_PATH } from '@app/common/constants/sql-query-path'; import { SQL_PROCEDURES_PATH } from '@app/common/constants/sql-query-path';
import { BaseResponseDto } from '@app/common/dto/base.response.dto'; import { BaseResponseDto } from '@app/common/dto/base.response.dto';
import { convertKeysToCamelCase } from '@app/common/helper/camelCaseConverter'; import { convertKeysToCamelCase } from '@app/common/helper/camelCaseConverter';
import { PollutantType } from '@app/common/constants/pollutants.enum';
@Injectable() @Injectable()
export class AqiService { export class AqiService {
@ -24,15 +25,6 @@ export class AqiService {
const { monthDate, pollutantType } = query; const { monthDate, pollutantType } = query;
const { spaceUuid } = params; const { spaceUuid } = params;
// Validate pollutantType against the allowed values
const allowedPollutants = ['aqi', 'pm25', 'pm10', 'voc', 'co2', 'ch2o'];
if (!allowedPollutants.includes(pollutantType.toLowerCase())) {
throw new HttpException(
`Invalid pollutant type. Allowed values: ${allowedPollutants.join(', ')}`,
HttpStatus.BAD_REQUEST,
);
}
try { try {
const data = await this.executeProcedure( const data = await this.executeProcedure(
'fact_daily_space_aqi', 'fact_daily_space_aqi',
@ -95,7 +87,7 @@ export class AqiService {
); );
// Define pollutants dynamically // Define pollutants dynamically
const pollutants = ['aqi', 'pm25', 'pm10', 'voc', 'co2', 'ch2o']; const pollutants = Object.values(PollutantType);
const transformedData = data.map((item) => { const transformedData = data.map((item) => {
const date = new Date(item.event_date).toLocaleDateString('en-CA'); // YYYY-MM-DD const date = new Date(item.event_date).toLocaleDateString('en-CA'); // YYYY-MM-DD