From d749a916e773dc5f036d38690da77281f4114426 Mon Sep 17 00:00:00 2001 From: Krista Strucke Date: Tue, 23 Apr 2024 19:10:03 -0700 Subject: [PATCH] fixed typescript bugs and refactored code to dry it out --- .../app/controllers/suggestion-controller.ts | 3 +- server/app/services/suggestion-service.ts | 6 +- .../validation-schema/suggestion-schema.ts | 129 +++++++++--------- server/types/suggestion-types.ts | 8 +- 4 files changed, 71 insertions(+), 75 deletions(-) diff --git a/server/app/controllers/suggestion-controller.ts b/server/app/controllers/suggestion-controller.ts index d7afe6d72..7568a0881 100644 --- a/server/app/controllers/suggestion-controller.ts +++ b/server/app/controllers/suggestion-controller.ts @@ -1,6 +1,7 @@ import suggestionService from "../services/suggestion-service"; import { RequestHandler, Response } from "express"; import { Suggestion } from "../../types/suggestion-types"; +import { SuggestionPostFields } from "../validation-schema/suggestion-schema"; const getAll: RequestHandler< // route params @@ -42,7 +43,7 @@ const getById: RequestHandler<{ id: string }, Suggestion, never> = async ( const post: RequestHandler< never, { id: number } | { error: string }, - Suggestion + SuggestionPostFields > = async (req, res) => { try { const resp = await suggestionService.insert(req.body); diff --git a/server/app/services/suggestion-service.ts b/server/app/services/suggestion-service.ts index bbb592809..88a793aa9 100644 --- a/server/app/services/suggestion-service.ts +++ b/server/app/services/suggestion-service.ts @@ -1,6 +1,7 @@ import db from "./db"; import camelcaseKeys from "camelcase-keys"; import { Suggestion } from "../../types/suggestion-types"; +import { SuggestionPostFields } from "../validation-schema/suggestion-schema"; const selectAll = async (params: { statusIds: string[]; @@ -43,8 +44,7 @@ const selectById = async (suggestionId: string): Promise => { return camelcaseKeys(row); }; -const insert = async (model: Suggestion): Promise<{ id: number }> => { - model.suggestionStatusId = 1; +const insert = async (model: SuggestionPostFields): Promise<{ id: number }> => { const sql = `insert into suggestion ( name, address_1, address_2, city, state, zip, @@ -59,7 +59,7 @@ const insert = async (model: Suggestion): Promise<{ id: number }> => { $, $, $, $ ) returning id`; - const result = await db.one(sql, model); + const result = await db.one(sql, { ...model, suggestionStatusId: 1 }); return { id: result.id }; }; diff --git a/server/app/validation-schema/suggestion-schema.ts b/server/app/validation-schema/suggestion-schema.ts index 82657059d..d431ff1cb 100644 --- a/server/app/validation-schema/suggestion-schema.ts +++ b/server/app/validation-schema/suggestion-schema.ts @@ -1,73 +1,68 @@ import { JSONSchemaType } from "ajv"; import { Suggestion } from "../../types/suggestion-types"; -export const suggestionPostRequestSchema: JSONSchemaType< - Omit -> = { - type: "object", - required: ["name", "tenantId"], - properties: { - stakeholderId: { - type: "integer", - nullable: true, - anyOf: [{ minimum: 1 }, { type: ["integer", "null"] }], - }, - adminNotes: { - type: "string", - }, - suggestionStatusId: { type: ["integer", "null"], nullable: true }, - name: { - type: ["string", "null"], - minLength: 1, - }, - address1: { - type: "string", - }, - address2: { - type: "string", - }, - city: { - type: "string", - }, - state: { - type: "string", - }, - zip: { - type: "string", - }, - phone: { - type: "string", - }, - email: { - // once we have set a value to format/pattern property, that property becomes required - // since email is optional, we can make UnionType to accept empty strings - // setting minLength to 0 or setting nullable: true won't help to leave email empty - type: "string", - anyOf: [ - { format: "email" }, - { maxLength: 0 }, // for an empty string - ], - }, - notes: { type: "string" }, // also called "other information" - tipsterName: { - type: "string", - }, - tipsterPhone: { - type: "string", - }, - tipsterEmail: { - type: "string", - anyOf: [{ format: "email" }, { maxLength: 0 }], - }, - hours: { type: "string" }, - category: { type: "string" }, - tenantId: { - type: "integer", - minimum: 1, - }, - }, - additionalProperties: true, -}; +export type SuggestionPostFields = Omit< + Suggestion, + "id" | "suggestionStatusId" | "stakeholderId" | "adminNotes" +>; + +export const suggestionPostRequestSchema: JSONSchemaType = + { + type: "object", + required: ["name", "tenantId"], + properties: { + name: { + type: "string", + minLength: 1, + }, + address1: { + type: "string", + }, + address2: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + zip: { + type: "string", + }, + phone: { + type: "string", + }, + email: { + // once we have set a value to format/pattern property, that property becomes required + // since email is optional, we can make UnionType to accept empty strings + // setting minLength to 0 or setting nullable: true won't help to leave email empty + type: "string", + anyOf: [ + { format: "email" }, + { maxLength: 0 }, // for an empty string + ], + }, + notes: { type: "string" }, // also called "other information" + tipsterName: { + type: "string", + }, + tipsterPhone: { + type: "string", + }, + tipsterEmail: { + type: "string", + anyOf: [{ format: "email" }, { maxLength: 0 }], + }, + hours: { type: "string" }, + category: { type: "string" }, + tenantId: { + type: "integer", + minimum: 1, + }, + }, + additionalProperties: true, + }; export const suggestionPutRequestSchema: JSONSchemaType = { type: "object", diff --git a/server/types/suggestion-types.ts b/server/types/suggestion-types.ts index 01d419af3..e9dfe40d8 100644 --- a/server/types/suggestion-types.ts +++ b/server/types/suggestion-types.ts @@ -1,6 +1,6 @@ export interface Suggestion { - id: number | null; - name: string | null; + id: number; + name: string; address1: string; address2: string; city: string; @@ -15,7 +15,7 @@ export interface Suggestion { hours: string; category: string; suggestionStatusId: number; - adminNotes?: string; - stakeholderId: number | null; + adminNotes: string; + stakeholderId: number; tenantId: number; }