Skip to content
This repository was archived by the owner on Jan 12, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
306 changes: 165 additions & 141 deletions apps/backend/src/site/site.service.ts
Original file line number Diff line number Diff line change
@@ -1,158 +1,182 @@
import { Injectable } from "@nestjs/common";
import { SiteInputModel, SiteModel, SiteStatus, SymbolType } from "./site.model";
import { DynamoDbService } from "../dynamodb";
import { NewSiteInput } from "../dtos/newSiteDTO";
import { Injectable } from '@nestjs/common';
import {
SiteInputModel,
SiteModel,
SiteStatus,
SymbolType,
} from './site.model';
import { DynamoDbService } from '../dynamodb';
import { NewSiteInput } from '../dtos/newSiteDTO';

@Injectable()
export class SiteService {

private readonly tableName = 'greenInfraBostonSites';

constructor(private readonly dynamoDbService: DynamoDbService) {}

/**
* Gets a site information based on that site's id.
* @param siteId
* @returns
*/
public async getSite(siteId: number): Promise<SiteModel> {
try{
const key = { 'siteId': { S: siteId.toString() } };
const data = await this.dynamoDbService.getItem(this.tableName, key);
return(this.mapDynamoDBItemToSite(siteId, data));
}
catch(e) {
throw new Error("Unable to get site data: "+ e)
}
private readonly tableName = 'greenInfraBostonSites';

constructor(private readonly dynamoDbService: DynamoDbService) {}

/**
* Gets a site information based on that site's id.
* @param siteId
* @returns
*/
public async getSite(siteId: number): Promise<SiteModel | null> {
try {
const key = { siteId: { S: siteId.toString() } };
const data = await this.dynamoDbService.getItem(this.tableName, key);

if (!data) {
console.warn(`No site found with id: ${siteId}`);
return null;
}

return this.mapDynamoDBItemToSite(siteId, data);
} catch (e) {
throw new Error('Unable to get site data: ' + e);
}

/**
* Scans the entire sites table and returns all rows.
* @returns the full list of sites
*/
public async getAllSites(): Promise<SiteModel[]> {
}

/**
* Scans the entire sites table and returns all rows.
* @returns the full list of sites
*/
public async getAllSites(): Promise<SiteModel[]> {
try {
const data = await this.dynamoDbService.scanTable(this.tableName);
const sites: SiteModel[] = [];
for (let i = 0; i < data.length; i++) {
try {
const data = await this.dynamoDbService.scanTable(this.tableName);
const sites: SiteModel[] = [];
for (let i = 0; i < data.length; i++) {
try {
sites.push(this.mapDynamoDBItemToSite(parseInt(data[i]["siteId"].S), data[i]));
} catch (error) {
console.error('Error mapping site:', error, data[i]);
}

}
return sites;
}
catch(e) {
throw new Error("Unable to get all site data: "+ e)
sites.push(
this.mapDynamoDBItemToSite(parseInt(data[i]['siteId'].S), data[i]),
);
} catch (error) {
console.error('Error mapping site:', error, data[i]);
}
}
return sites;
} catch (e) {
throw new Error('Unable to get all site data: ' + e);
}

public async postSite(siteData: NewSiteInput) {
const siteModel = this.PostInputToSiteModel(siteData);
const newId = await this.dynamoDbService.getHighestSiteId(this.tableName) + 1;
siteModel.siteId.S = newId.toString();
console.log("Using new ID:" + siteModel.siteId.S)
try {
const result = await this.dynamoDbService.postItem(this.tableName, siteModel);
return {...result, newSiteId: newId.toString()};
} catch (e) {
throw new Error("Unable to post new site: " + e);
}
}

public async postSite(siteData: NewSiteInput) {
const siteModel = this.PostInputToSiteModel(siteData);
const newId =
(await this.dynamoDbService.getHighestSiteId(this.tableName)) + 1;
siteModel.siteId.S = newId.toString();
console.log('Using new ID:' + siteModel.siteId.S);
try {
const result = await this.dynamoDbService.postItem(
this.tableName,
siteModel,
);
return { ...result, newSiteId: newId.toString() };
} catch (e) {
throw new Error('Unable to post new site: ' + e);
}



public async getSitesByStatus(status: string): Promise<SiteModel[]> {
}

public async getSitesByStatus(status: string): Promise<SiteModel[]> {
try {
const data = await this.dynamoDbService.scanTable(
this.tableName,
'siteStatus = :status',
{ ':status': { S: status } },
);
const sites: SiteModel[] = [];
for (let i = 0; i < data.length; i++) {
try {
const data = await this.dynamoDbService.scanTable(this.tableName, "siteStatus = :status", { ":status": { S: status } } );
const sites: SiteModel[] = [];
for (let i = 0; i < data.length; i++) {
try {
sites.push(this.mapDynamoDBItemToSite(parseInt(data[i]["siteId"].S), data[i]));
} catch (error) {
console.error('Error mapping site:', error, data[i]);
}

}
console.log("Found " + sites.length + " \"" + status + "' sites");
return sites;
}
catch(e) {
throw new Error("Unable to get site by status: "+ e)
sites.push(
this.mapDynamoDBItemToSite(parseInt(data[i]['siteId'].S), data[i]),
);
} catch (error) {
console.error('Error mapping site:', error, data[i]);
}

}
console.log('Found ' + sites.length + ' "' + status + "' sites");
return sites;
} catch (e) {
throw new Error('Unable to get site by status: ' + e);
}

public async getSitesBySymbolType(symbolType: string): Promise<SiteModel[]> {
}

public async getSitesBySymbolType(symbolType: string): Promise<SiteModel[]> {
try {
const data = await this.dynamoDbService.scanTable(
this.tableName,
'symbolType = :symbolType',
{ ':symbolType': { S: symbolType } },
);
const sites: SiteModel[] = [];
for (let i = 0; i < data.length; i++) {
try {
const data = await this.dynamoDbService.scanTable(this.tableName, "symbolType = :symbolType", { ":symbolType": { S: symbolType } } );
const sites: SiteModel[] = [];
for (let i = 0; i < data.length; i++) {
try {
sites.push(this.mapDynamoDBItemToSite(parseInt(data[i]["siteId"].S), data[i]));
} catch (error) {
console.error('Error mapping site:', error, data[i]);
}

}
console.log("Found " + sites.length + " \"" + symbolType + "' sites");
return sites;
sites.push(
this.mapDynamoDBItemToSite(parseInt(data[i]['siteId'].S), data[i]),
);
} catch (error) {
console.error('Error mapping site:', error, data[i]);
}
catch(e) {
throw new Error("Unable to get site by symbol: "+ e)
}

}
console.log('Found ' + sites.length + ' "' + symbolType + "' sites");
return sites;
} catch (e) {
throw new Error('Unable to get site by symbol: ' + e);
}

public async deleteSite(siteId: number): Promise<void> {
try {
const key = { 'siteId': { S: siteId.toString() } };
await this.dynamoDbService.deleteItem(this.tableName, key);
console.log(`Deleted site with id ${siteId}`);
} catch (e) {
throw new Error("Unable to delete site data: " + e);
}
}

public async deleteSite(siteId: number): Promise<void> {
try {
const key = { siteId: { S: siteId.toString() } };
await this.dynamoDbService.deleteItem(this.tableName, key);
console.log(`Deleted site with id ${siteId}`);
} catch (e) {
throw new Error('Unable to delete site data: ' + e);
}

public async adoptSite(siteId: number): Promise<void> {
try {
const key = { 'siteId': { S: siteId.toString() } };
const result = await this.dynamoDbService.updateField(this.tableName, key, "siteStatus", "Adopted")
} catch (e) {
throw new Error("Unable to set site status to Adopted:" + e);
}
}

public async adoptSite(siteId: number): Promise<void> {
try {
const key = { siteId: { S: siteId.toString() } };
const result = await this.dynamoDbService.updateField(
this.tableName,
key,
'siteStatus',
'Adopted',
);
} catch (e) {
throw new Error('Unable to set site status to Adopted:' + e);
}

private mapDynamoDBItemToSite = (objectId: number, item: { [key: string]: any }): SiteModel => {
return {
siteID: objectId,
siteName: item["siteName"].S,
siteStatus: item["siteStatus"].S,
assetType: item["assetType"].S,
symbolType: item["symbolType"].S,
siteLatitude: item["siteLatitude"].S,
siteLongitude: item["siteLongitude"].S,
dateAdopted: new Date(), //placeholder until table is updated
maintenanceReports: [], //placeholder until table is updated
neighborhood: item["neighborhood"].S,
address: item["address"].S
};
}

private mapDynamoDBItemToSite = (
objectId: number,
item: { [key: string]: any },
): SiteModel => {
return {
siteID: objectId,
siteName: item['siteName'].S,
siteStatus: item['siteStatus'].S,
assetType: item['assetType'].S,
symbolType: item['symbolType'].S,
siteLatitude: item['siteLatitude'].S,
siteLongitude: item['siteLongitude'].S,
dateAdopted: new Date(), //placeholder until table is updated
maintenanceReports: [], //placeholder until table is updated
neighborhood: item['neighborhood'].S,
address: item['address'].S,
};

private PostInputToSiteModel = (input: NewSiteInput): SiteInputModel => {
return {
siteId: {S: ""},
siteName: {S: input.siteName},
siteStatus: {S: SiteStatus.AVAILABLE},
assetType: {S: input.assetType},
symbolType: {S: input.symbolType as SymbolType},
siteLatitude: {S: input.siteLatitude},
siteLongitude: {S: input.siteLongitude},
neighborhood: {S: input.neighborhood},
address: {S: input.address},
};
}

}
};

private PostInputToSiteModel = (input: NewSiteInput): SiteInputModel => {
return {
siteId: { S: '' },
siteName: { S: input.siteName },
siteStatus: { S: SiteStatus.AVAILABLE },
assetType: { S: input.assetType },
symbolType: { S: input.symbolType as SymbolType },
siteLatitude: { S: input.siteLatitude },
siteLongitude: { S: input.siteLongitude },
neighborhood: { S: input.neighborhood },
address: { S: input.address },
};
};
}
Loading
Loading