From 78ea94d3686a94c01870f0d6e2874d4707cc056f Mon Sep 17 00:00:00 2001 From: Jonathan Memoli Date: Thu, 21 Mar 2024 22:12:51 -0400 Subject: [PATCH 1/4] Modified update endpoint to change the playground_frequency Also updated the zod typechecking and DELETE endpoint to work with new schema --- app/api/v1/antenna/[id]/route.ts | 58 ++++++++++++++++++++++++++++++-- app/api/v1/antenna/validate.ts | 32 +++++++++++------- 2 files changed, 76 insertions(+), 14 deletions(-) diff --git a/app/api/v1/antenna/[id]/route.ts b/app/api/v1/antenna/[id]/route.ts index 5b03d14..4a34707 100644 --- a/app/api/v1/antenna/[id]/route.ts +++ b/app/api/v1/antenna/[id]/route.ts @@ -4,9 +4,9 @@ import { isAntenna } from '@/app/api/v1/antenna/validate'; import { pool } from '@/app/api/v1/connection'; import StatusError from '@/app/api/(utils)/StatusError'; -export async function DELETE(_: Request, context: { params: { id: string } }) { +export async function DELETE(_: Request, context: { params: { id: number } }) { try { - if (context.params.id.trim().length == 0) + if (!context.params.id) throw new StatusError( 500, 'Internal Error: Id is missing from parameter' @@ -42,3 +42,57 @@ export async function DELETE(_: Request, context: { params: { id: string } }) { return NextResponse.json({ message }, { status }); } } +export async function PUT( + request: Request, + context: { params: { id: number } } +) { + try { + if (!context.params.id) { + throw { + status: 500, + message: 'Internal Error: Id is missing from parameter', + }; + } + + const id = context.params.id; + + const { frequency } = (await request.json()) as { frequency: number }; + + const client = await pool.connect(); + + const query = ` + UPDATE Antennas + SET playground_frequency = $1 + WHERE id = $2 + RETURNING *; + `; + const result = await client.query(query, [frequency, id]); + + if (result.rowCount === 0) { + throw new StatusError(404, `Antenna with ${id} does not exist.`); + } + if (!isAntenna(result.rows[0])) { + throw new StatusError( + 500, + 'Antenna must be updated with correct data types / values.' + ); + } + + const updatedAntenna = result.rows[0]; + + client.release(); + + return NextResponse.json(updatedAntenna, { status: 200 }); + } catch (error) { + let message = 'Internal Server Error'; + let status = 500; + if (typeof error === 'object') { + if (error && 'message' in error && typeof error.message === 'string') + message = error.message; + if (error && 'status' in error && typeof error.status === 'number') + status = error.status; + } + + return NextResponse.json({ message }, { status }); + } +} diff --git a/app/api/v1/antenna/validate.ts b/app/api/v1/antenna/validate.ts index 48c812b..b767aad 100644 --- a/app/api/v1/antenna/validate.ts +++ b/app/api/v1/antenna/validate.ts @@ -1,32 +1,40 @@ import { z } from 'zod'; export type Antenna = { - id: string; + id: number; name: string; hostname: string; model: string; modelname: string; frequency: number; - location: string; - initialheading: number; - heading: number; - radius: number; - sectorlobe: string; + playground_frequency: number; + latitude: string; + longitude: string; + azimuth: number; + typeantenna: number; + antenna_status: string; + cpu: number; + ram: number; }; export function isAntenna(antenna: unknown): antenna is Antenna { + console.log('validate'); + console.log(antenna); const antennaSchema = z.object({ - id: z.string(), + id: z.number(), name: z.string(), hostname: z.string(), model: z.string(), modelname: z.string(), frequency: z.number().int().gte(0), - location: z.string(), - initialheading: z.number().int().gte(0).lt(360), - heading: z.number().int().gte(0).lt(360), - radius: z.number().int().gte(0), - sectorlobe: z.string(), + playground_frequency: z.number().int().gte(0), + latitude: z.string(), + longitude: z.string(), + azimuth: z.number().int().gte(0).lt(360), + typeantenna: z.number().gte(0).lte(2), + antenna_status: z.string(), + cpu: z.number(), + ram: z.number(), }); const res = antennaSchema.safeParse(antenna); From 6604e56ab2b90bc328d4f398f5d46d10bfdb7c52 Mon Sep 17 00:00:00 2001 From: Jonathan Memoli Date: Thu, 21 Mar 2024 22:55:58 -0400 Subject: [PATCH 2/4] feat: Add endpoint to update multiple antenna playground_frequencies given a list of ids --- app/api/v1/antenna/route.ts | 52 ++++++++++++++++++++++++++++++++++ app/api/v1/antenna/validate.ts | 2 -- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/app/api/v1/antenna/route.ts b/app/api/v1/antenna/route.ts index eb2f983..5cbc4f7 100644 --- a/app/api/v1/antenna/route.ts +++ b/app/api/v1/antenna/route.ts @@ -1,5 +1,7 @@ import { NextResponse } from 'next/server'; import { pool } from '../connection'; +import { isAntenna, Antenna } from '@/app/api/v1/antenna/validate'; +import StatusError from '@/app/api/(utils)/StatusError'; export async function GET() { try { @@ -14,3 +16,53 @@ export async function GET() { return NextResponse.json({ message }, { status: 500 }); } } + +export async function PUT(request: Request) { + const updatedAntennas: Antenna[] = []; + try { + const { ids, newFrequencies } = (await request.json()) as { + ids: number[]; + newFrequencies: number[]; + }; + + const client = await pool.connect(); + + for (let i = 0; i < ids.length; i++) { + const id = ids[i]; + const frequency = newFrequencies[i]; + + const query = ` + UPDATE Antennas + SET playground_frequency = $1 + WHERE id = $2 + RETURNING * + `; + const result = await client.query(query, [frequency, id]); + if (result.rowCount === 0) { + throw new StatusError(404, `Antenna with ${id} does not exist.`); + } + if (!isAntenna(result.rows[0])) { + throw new StatusError( + 500, + 'Antenna must be updated with correct data types / values.' + ); + } + const updatedAntenna = result.rows[0]; + updatedAntennas.push(updatedAntenna); + } + client.release(); + + return NextResponse.json(updatedAntennas, { status: 200 }); + } catch (error) { + let message = 'Internal Server Error'; + let status = 500; + if (typeof error === 'object') { + if (error && 'message' in error && typeof error.message === 'string') + message = error.message; + if (error && 'status' in error && typeof error.status === 'number') + status = error.status; + } + + return NextResponse.json({ message }, { status }); + } +} diff --git a/app/api/v1/antenna/validate.ts b/app/api/v1/antenna/validate.ts index b767aad..f606b6c 100644 --- a/app/api/v1/antenna/validate.ts +++ b/app/api/v1/antenna/validate.ts @@ -18,8 +18,6 @@ export type Antenna = { }; export function isAntenna(antenna: unknown): antenna is Antenna { - console.log('validate'); - console.log(antenna); const antennaSchema = z.object({ id: z.number(), name: z.string(), From 9ea09de4038219962fc188991e893b683acb263f Mon Sep 17 00:00:00 2001 From: Jonathan Memoli Date: Sun, 14 Apr 2024 18:00:59 -0400 Subject: [PATCH 3/4] Added new labeledFrequencies type and changed request body sctucture accordingly --- app/api/v1/antenna/route.ts | 29 +++++++++++++++-------------- app/types.ts | 5 +++++ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/app/api/v1/antenna/route.ts b/app/api/v1/antenna/route.ts index 5cbc4f7..71b05dd 100644 --- a/app/api/v1/antenna/route.ts +++ b/app/api/v1/antenna/route.ts @@ -2,6 +2,7 @@ import { NextResponse } from 'next/server'; import { pool } from '../connection'; import { isAntenna, Antenna } from '@/app/api/v1/antenna/validate'; import StatusError from '@/app/api/(utils)/StatusError'; +import { labeledFrequencies } from '@/app/types'; export async function GET() { try { @@ -17,25 +18,25 @@ export async function GET() { } } +// request body should be: +// { +// "dataArray": [ +// {labeledFrequencies} +// ] +// } export async function PUT(request: Request) { const updatedAntennas: Antenna[] = []; try { - const { ids, newFrequencies } = (await request.json()) as { - ids: number[]; - newFrequencies: number[]; - }; - + const { dataArray }: { dataArray: labeledFrequencies[] } = + (await request.json()) as { dataArray: labeledFrequencies[] }; const client = await pool.connect(); - for (let i = 0; i < ids.length; i++) { - const id = ids[i]; - const frequency = newFrequencies[i]; - + for (const { id, frequency } of dataArray) { const query = ` - UPDATE Antennas - SET playground_frequency = $1 - WHERE id = $2 - RETURNING * + UPDATE Antennas + SET playground_frequency = $1 + WHERE id = $2 + RETURNING * `; const result = await client.query(query, [frequency, id]); if (result.rowCount === 0) { @@ -44,7 +45,7 @@ export async function PUT(request: Request) { if (!isAntenna(result.rows[0])) { throw new StatusError( 500, - 'Antenna must be updated with correct data types / values.' + 'Antenna must be updated with correct data types/values' ); } const updatedAntenna = result.rows[0]; diff --git a/app/types.ts b/app/types.ts index e601a17..e23d41b 100644 --- a/app/types.ts +++ b/app/types.ts @@ -20,6 +20,11 @@ export interface ReducedPoints { [key: string]: ReducedContent; } +export interface labeledFrequencies { + id: number; + frequency: number; +} + // Props export interface InfoProps { From 2fdfb529d557b2fda338f624c8cc65d5a13c1cd2 Mon Sep 17 00:00:00 2001 From: Jonathan Memoli Date: Fri, 19 Apr 2024 15:58:53 -0400 Subject: [PATCH 4/4] Fixed merge error --- app/types.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/types.ts b/app/types.ts index 1237615..e61b98e 100644 --- a/app/types.ts +++ b/app/types.ts @@ -47,7 +47,8 @@ export interface SectorlobeData { id: string; center: LatLngTuple; sectorVertices: LatLngExpression[]; -} + frequency: number; +} // Props export interface InfoProps {