Skip to content

Commit

Permalink
Merge pull request #42 from Code-4-Community/dl-POST-new-site-GI-40
Browse files Browse the repository at this point in the history
Dl post new site gi 40
  • Loading branch information
dli85 authored Oct 28, 2024
2 parents 98e1e0c + cbbc250 commit f13416f
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 3 deletions.
12 changes: 12 additions & 0 deletions apps/backend/src/dtos/newSiteDTO.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export type NewSiteInput = {
// siteID: number /// will be auto generated
siteName: string,
// siteStatus: string, will always be "AVAILABLE"
assetType: string,
symbolType: string,
siteLatitude: string,
siteLongitude: string,
// dateAdopted: Date, will be null
neighborhood: string,
address: string
};
44 changes: 42 additions & 2 deletions apps/backend/src/dynamodb.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DynamoDBClient, GetItemCommand, ScanCommand } from "@aws-sdk/client-dynamodb";
import { Injectable } from "@nestjs/common";
import { DynamoDBClient, GetItemCommand, PutItemCommand, ScanCommand } from "@aws-sdk/client-dynamodb";
import { Injectable, Put } from "@nestjs/common";

Check warning on line 2 in apps/backend/src/dynamodb.ts

View workflow job for this annotation

GitHub Actions / pre-deploy

'Put' is defined but never used
import { table } from "console";

Check warning on line 3 in apps/backend/src/dynamodb.ts

View workflow job for this annotation

GitHub Actions / pre-deploy

'table' is defined but never used

@Injectable()
export class DynamoDbService {
Expand Down Expand Up @@ -36,6 +37,30 @@ export class DynamoDbService {
}
}

public async getHighestSiteId(tableName: string): Promise<number | undefined> {
const params: any = {

Check warning on line 41 in apps/backend/src/dynamodb.ts

View workflow job for this annotation

GitHub Actions / pre-deploy

Unexpected any. Specify a different type
TableName: tableName,
ProjectionExpression: "siteId" // Project only the siteId attribute
};

try {
const data = await this.dynamoDbClient.send(new ScanCommand(params));
const siteIds = data.Items.map(item => parseInt(item.siteId.S, 10)); // Convert to numbers

// Handle potential parsing errors
const validSiteIds = siteIds.filter(id => !isNaN(id));

if (validSiteIds.length === 0) {
return undefined; // No valid site IDs found
}

const highestSiteId = validSiteIds.reduce((max, current) => Math.max(max, current));
return highestSiteId;
} catch (error) {
console.error('DynamoDB Scan Error:', error);
throw new Error(`Unable to scan table ${tableName}`);
}
}

public async getItem(tableName: string, key: { [key: string]: any }): Promise<any> {

Check warning on line 65 in apps/backend/src/dynamodb.ts

View workflow job for this annotation

GitHub Actions / pre-deploy

Unexpected any. Specify a different type

Check warning on line 65 in apps/backend/src/dynamodb.ts

View workflow job for this annotation

GitHub Actions / pre-deploy

Unexpected any. Specify a different type
const params = {
Expand All @@ -52,4 +77,19 @@ export class DynamoDbService {
}
}

public async postItem(tableName: string, item) {
const command = new PutItemCommand({
TableName: tableName,
Item: item,
});

console.log(command);
try {
const result = await this.dynamoDbClient.send(command);
return result;
} catch (error) {
console.log(`Error posting item to table ${tableName}`);
throw new Error(error);
}
}
}
8 changes: 8 additions & 0 deletions apps/backend/src/site/site.controller.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import {
Controller,
Get,
Post,
Body,
Param,
Query
} from "@nestjs/common";
import { SiteService } from "./site.service";
import { SiteModel } from "./site.model";
import { NewSiteInput } from "../dtos/newSiteDTO";
import { ApiQuery } from "@nestjs/swagger";

@Controller("sites")
Expand All @@ -19,6 +22,11 @@ export class SiteController {
return this.siteService.getSite(siteId);
}

@Post()
public async postSite(@Body() siteData: NewSiteInput) {
return this.siteService.postSite(siteData);
}

@Get()
@ApiQuery({ name: 'status', required: false }) // makes query parameter optional
@ApiQuery({ name: 'symbol-type', required: false })
Expand Down
12 changes: 12 additions & 0 deletions apps/backend/src/site/site.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ export type SiteModel = {
address: string
};

export type SiteInputModel = {
siteId: {S: string},
siteName: {S: string},
siteStatus: {S: string},
assetType: {S: string},
symbolType: {S: string},
siteLatitude: {S: string},
siteLongitude: {S: string},
neighborhood: {S: string},
address: {S: string},
};

export enum SiteStatus {
ADOPTED = "Adopted",
AVAILABLE = "Available",
Expand Down
30 changes: 29 additions & 1 deletion apps/backend/src/site/site.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Injectable } from "@nestjs/common";
import { SiteModel, SiteStatus } from "./site.model";
import { SiteInputModel, SiteModel, SiteStatus, SymbolType } from "./site.model";
import { DynamoDbService } from "../dynamodb";
import { NewSiteInput } from "../dtos/newSiteDTO";

@Injectable()
export class SiteService {
Expand All @@ -25,6 +26,19 @@ export class SiteService {
}
}

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 getFilteredSites(filters: { status?: string, symbolType?: string }): Promise<SiteModel[]> {
try {
const filterExpressionParts = [];
Expand Down Expand Up @@ -76,4 +90,18 @@ export class SiteService {
};
};

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},
};
}

}

0 comments on commit f13416f

Please sign in to comment.