diff --git a/packages/doorman-api/src/functions/api/door/info.ts b/packages/doorman-api/src/functions/api/door/info.ts index 7905786..4922ccc 100644 --- a/packages/doorman-api/src/functions/api/door/info.ts +++ b/packages/doorman-api/src/functions/api/door/info.ts @@ -4,9 +4,10 @@ import { ServerlessEventObject, ServerlessFunctionSignature } from "@twilio-labs/serverless-runtime-types/types"; import { TwilioContext } from "../../../types/TwilioContext"; -import { createDDBClient, ddbItemToJSON, getDoorAliasCommand, getDoorConfigCommand, getLockStatusCommand, isLockOpen } from "../../../utils/ddb"; +import { createDDBClient, createDynaBridgeClient, ddbItemToJSON, getDoorAliasCommand, getDoorConfigCommand, getLockStatusCommand, isLockOpen } from "../../../utils/ddb"; import { DoorStatus } from "../../../types/DoorStatus"; import { DoorConfig } from "../../../types/DoorConfig"; +import { DOOR_CONFIG_SK, getDoorConfigID } from "../../../schema/DoorConfig"; export interface InfoRequest extends ServerlessEventObject { door?: string; @@ -38,6 +39,7 @@ export const handler: ServerlessFunctionSignature = } const client = createDDBClient(context); + const db = createDynaBridgeClient(context); if (buzzer) { door = await client.send(getDoorAliasCommand(buzzer)) @@ -54,9 +56,9 @@ export const handler: ServerlessFunctionSignature = } if (door) { - const config = await client.send(getDoorConfigCommand(door)); + const config = await db.entities.doorConfig.findById(getDoorConfigID(door)); - if (!config.Item) { + if (!config) { response .setStatusCode(404) .appendHeader('Content-Type', 'application/json') @@ -70,13 +72,14 @@ export const handler: ServerlessFunctionSignature = .setBody({ buzzer, door, - fallbackNumbers: config.Item.fallbackNumbers.SS, - pressKey: config.Item.pressKey.S, - discordUsers: config.Item?.discordUsers?.SS || [], + fallbackNumbers: config.fallbackNumbers, + pressKey: config.pressKey, + discordUsers: config.discordUsers || [], }); } else { await client.send(getLockStatusCommand(door)) .then(async (lock) => { + const config = await client.send(getDoorConfigCommand(door)); const status = isLockOpen(lock) ? DoorStatus.OPEN: DoorStatus.CLOSED; const doorConfig: DoorConfig = ddbItemToJSON(config); diff --git a/packages/doorman-api/src/schema/DoorConfig.ts b/packages/doorman-api/src/schema/DoorConfig.ts new file mode 100644 index 0000000..895976e --- /dev/null +++ b/packages/doorman-api/src/schema/DoorConfig.ts @@ -0,0 +1,47 @@ +import { z } from "zod"; +import { DynaBridge, DynaBridgeEntity } from 'dynabridge'; + +export const DOOR_CONFIG_SK = "config"; +export const EDIT_DOOR_CONFIG_SK = "config-update"; + +export const DoorConfigSchema = z.object({ + // keys + PK: z.string().startsWith("door-", "Invalid door key"), + SK: z.literal(DOOR_CONFIG_SK).default(DOOR_CONFIG_SK), + + buzzer: z.string(), + buzzerCode: z.string(), + discordUsers: z.array(z.string()), + fallbackNumbers: z.array(z.string()), + pin: z.string(), + pressKey: z.string(), + greeting: z.string(), + timeout: z.number(), +}); + +export const getDoorConfigID = (doorName: string): string[] => { + return ['door-' + doorName, DOOR_CONFIG_SK]; +} + +export const EditDoorConfigSchema = DoorConfigSchema.extend({ + SK: z.literal(EDIT_DOOR_CONFIG_SK).default(EDIT_DOOR_CONFIG_SK), + + approvalId: z.string(), +}); + +export const getEditDoorConfigID = (doorName: string): string[] => { + return getDoorConfigID(doorName).with(1, EDIT_DOOR_CONFIG_SK); +} + +export type DoorConfig = z.infer; +export type EditDoorConfig = z.infer; + +export const DoorConfigEntity: DynaBridgeEntity = { + tableName: "doorman", + id: ["PK", "SK"], +}; + +export const EditDoorConfigEntity: DynaBridgeEntity = { + tableName: "doorman", + id: ["PK", "SK"], +}; diff --git a/packages/doorman-api/src/utils/ddb.ts b/packages/doorman-api/src/utils/ddb.ts index 3637c72..6d92d14 100644 --- a/packages/doorman-api/src/utils/ddb.ts +++ b/packages/doorman-api/src/utils/ddb.ts @@ -2,6 +2,8 @@ import { randomUUID } from "crypto"; import { DynamoDBClient, GetItemCommand, DeleteItemCommand, PutItemCommand, UpdateItemCommand, GetItemOutput } from "@aws-sdk/client-dynamodb"; import { TwilioContext } from "../types/TwilioContext"; import { DoorConfig } from "../types/DoorConfig"; +import { DynaBridge } from "dynabridge"; +import { DoorConfigEntity, EditDoorConfigEntity } from "../schema/DoorConfig"; export const createDDBClient = (context: TwilioContext) => { return new DynamoDBClient({ @@ -13,6 +15,20 @@ export const createDDBClient = (context: TwilioContext) => { }); }; +export const createDynaBridgeClient = (context: TwilioContext) => { + // register all entities here + return new DynaBridge({ + doorConfig: DoorConfigEntity, + editDoorConfig: EditDoorConfigEntity, + }, undefined, { + region: "us-east-1" , + credentials: { + accessKeyId: context.AWS_ACCESS_KEY, + secretAccessKey: context.AWS_SECRET_ACCESS_KEY, + }, + }); +}; + export const getLockStatusCommand = (door: string) => { return new GetItemCommand({ TableName: "doorman",