From 17bdca77522db8b856848709f791475887ed0374 Mon Sep 17 00:00:00 2001 From: david Date: Sat, 22 Jul 2023 17:20:43 -0400 Subject: [PATCH 1/6] dynamodb test --- src/aws/auth.controller.ts | 24 ++++++++++++++++++++++-- src/dynamodb.ts | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/aws/auth.controller.ts b/src/aws/auth.controller.ts index a168349..a5617c6 100644 --- a/src/aws/auth.controller.ts +++ b/src/aws/auth.controller.ts @@ -4,19 +4,20 @@ import { Post, Headers, Body, + Query, UseGuards, } from "@nestjs/common"; import { AuthService } from "./auth.service"; -import { WriteEntryToTable, UserTimesheets } from "../dynamodb"; +import { WriteEntryToTable, UserTimesheets, getTimesheetsForUsersInGivenTimeFrame } from "../dynamodb"; import TokenClient from './cognito/cognito.keyparser' import { TimeSheetSchema } from 'src/db/schemas/Timesheet'; import * as frontendTimesheetSchemas from 'src/db/schemas/Timesheet' +import { Roles } from "src/utils/decorators/roles.decorators"; // idk if this is correct import { RolesGuard } from 'src/utils/guards/roles.guard'; import { UploadTimesheet } from 'src/db/timesheets/UploadTimesheet'; import { TimesheetUpdateRequest } from 'src/db/schemas/UpdateTimesheet'; import { Formatter } from 'src/db/timesheets/Formatter'; - @Controller("auth") @UseGuards(RolesGuard) export class AuthController { @@ -51,4 +52,23 @@ export class AuthController { } return []; } + + @Get("getTimesheet") + @Roles("breaktime-admin", "breaktime-supervisor") + // supervisor/admin get the same data, just check that supervisor has access to data admin is free for all + public async get_timesheets( + @Headers() header: any, + @Query("userIds") userIds: string[] + ): Promise { + // if supervisors dont have access to a uuid throw an error + // if supervisor or admin request non existent uuid throw an error + const res = await getTimesheetsForUsersInGivenTimeFrame + console.log(res); + return []; + } } + +export type uuidToTimesheetMapping = { + uuid: string, + timesheet: TimeSheetSchema +}; \ No newline at end of file diff --git a/src/dynamodb.ts b/src/dynamodb.ts index 6a2954b..1e71fe3 100644 --- a/src/dynamodb.ts +++ b/src/dynamodb.ts @@ -160,3 +160,25 @@ export async function WriteEntryToTable(table:TimeSheetSchema): Promise }); return true; } + +export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], timeframe=7) { + // timeframe - startdate - end date + // UserID - string PageName: { S: "Home" }, + + const userKeys = uuids.map((uuid) => + {return {UserID: {S : uuid}}} + ) + + const command = new BatchGetItemCommand({ + RequestItems: { + BreaktimeTimesheets: { + Keys: userKeys + } + } + }); + + // get the items from DynamoDB with our query + const dynamoRawResult = await client.send(command); + + return dynamoRawResult; +} From 3a98887644dec0f094ed52e589e7e2c00d2736f1 Mon Sep 17 00:00:00 2001 From: david Date: Thu, 27 Jul 2023 21:40:21 -0400 Subject: [PATCH 2/6] added basic startdate/enddate filtering --- src/aws/auth.controller.ts | 8 ++-- src/dynamodb.ts | 90 +++++++++++++++++++++++++++++++------- 2 files changed, 77 insertions(+), 21 deletions(-) diff --git a/src/aws/auth.controller.ts b/src/aws/auth.controller.ts index a5617c6..0526247 100644 --- a/src/aws/auth.controller.ts +++ b/src/aws/auth.controller.ts @@ -54,16 +54,16 @@ export class AuthController { } @Get("getTimesheet") - @Roles("breaktime-admin", "breaktime-supervisor") + //@Roles('breaktime-management-role') + //@Roles("breaktime-admin", "breaktime-supervisor") // supervisor/admin get the same data, just check that supervisor has access to data admin is free for all public async get_timesheets( @Headers() header: any, @Query("userIds") userIds: string[] - ): Promise { + ): Promise { // if supervisors dont have access to a uuid throw an error // if supervisor or admin request non existent uuid throw an error - const res = await getTimesheetsForUsersInGivenTimeFrame - console.log(res); + await getTimesheetsForUsersInGivenTimeFrame(['77566d69-3b61-452a-afe8-73dcda96f876']); return []; } } diff --git a/src/dynamodb.ts b/src/dynamodb.ts index 1e71fe3..419191c 100644 --- a/src/dynamodb.ts +++ b/src/dynamodb.ts @@ -161,24 +161,80 @@ export async function WriteEntryToTable(table:TimeSheetSchema): Promise return true; } -export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], timeframe=7) { - // timeframe - startdate - end date - // UserID - string PageName: { S: "Home" }, - - const userKeys = uuids.map((uuid) => - {return {UserID: {S : uuid}}} - ) - - const command = new BatchGetItemCommand({ - RequestItems: { - BreaktimeTimesheets: { - Keys: userKeys - } +export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], StartDate:number = 1, EndDate:number = StartDate + 100000000000000000000) { + + if (StartDate > EndDate) { + throw new Error("Invalid EndDate") + } + + let result = [] + + for (let x in uuids) { + const command = new QueryCommand({ + TableName: "BreaktimeTimesheets", + KeyConditionExpression: "UserID = :s", + ExpressionAttributeValues: { + ":s": { S: `${uuids[x]}` }, + }, + ExpressionAttributeNames: { + "#S": "Status" + }, + ProjectionExpression: "UserID, TimesheetID, CompanyID, ScheduleData, StartDate, #S, WeekNotes" + }); + + // get the items from DynamoDB with our query + const dynamoRawResult = await client.send(command); + + if (dynamoRawResult == null || dynamoRawResult.Items == null) { + throw new Error("Invalid response from DynamoDB, got undefined/null"); } + + // Convert Dynamo items to JS objects + const unmarshalledItems = dynamoRawResult.Items.map((i) => unmarshall(i)); + + // Parse the items into our expected Company schema. + const timesheetData = unmarshalledItems.map((i) => TimeSheetSchema.parse(i)); + + const uuidSet = new Set(uuids) + + const modifiedTimesheetData = timesheetData.filter((sheet) => {return uuidSet.has(sheet.UserID) && sheet.StartDate >= StartDate && sheet.StartDate < EndDate}) + + const uuidToTimesheet = {"uuid": uuids[x], timesheet: modifiedTimesheetData} + + result.push(uuidToTimesheet); + }; + return result +} + +export async function filterUUIDsInCompanies(uuids: string[], companies: string[]) { + // check if given uuids exist in given companies and return valid uuids +} + + + /*const command = new QueryCommand({ + TableName: "BreaktimeTimesheets", + IndexName: "StartDate-index", + KeyConditionExpression: "StartDate = :unix", + ExpressionAttributeValues: { + ":unix": { N: StartDate.toString() }, + }, }); - // get the items from DynamoDB with our query const dynamoRawResult = await client.send(command); - - return dynamoRawResult; -} + + if (dynamoRawResult == null || dynamoRawResult.Items == null) { + throw new Error("Invalid response from DynamoDB, got undefined/null"); + } + + // Convert Dynamo items to JS objects + const unmarshalledItems = dynamoRawResult.Items.map((i) => unmarshall(i)); + + const timesheetData = unmarshalledItems.map((i) => TimeSheetSchema.parse(i)); + + const uuidSet = new Set(uuids) + + const modifiedTimesheetData = timesheetData.filter((item) => {return uuidSet.has(item.UserID) && item.StartDate < EndDate}); + // probably possible to do with dynamo but no difference in efficiency + const uuidToTimesheet = uuids.map((uuid, index) => {return {"uuid": uuid, "timesheet": modifiedTimesheetData[index]}}); + console.log(timesheetData) + return uuidToTimesheet*/ \ No newline at end of file From bf5e8c45bfd15dae5fd4dd078a585aa82e606b12 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 1 Aug 2023 13:43:09 -0400 Subject: [PATCH 3/6] wip --- src/aws/auth.controller.ts | 6 ++++ src/dynamodb.ts | 69 +++++++++++++++++++------------------- src/utils.ts | 21 ++++++++++++ 3 files changed, 61 insertions(+), 35 deletions(-) create mode 100644 src/utils.ts diff --git a/src/aws/auth.controller.ts b/src/aws/auth.controller.ts index 0526247..115adbf 100644 --- a/src/aws/auth.controller.ts +++ b/src/aws/auth.controller.ts @@ -63,7 +63,13 @@ export class AuthController { ): Promise { // if supervisors dont have access to a uuid throw an error // if supervisor or admin request non existent uuid throw an error + + // TODO: filter uuids before getting + // if associate only return their timesheet + // if supervisor ensure all uuids are in company + // if admin just make sure theyre all valid await getTimesheetsForUsersInGivenTimeFrame(['77566d69-3b61-452a-afe8-73dcda96f876']); + return []; } } diff --git a/src/dynamodb.ts b/src/dynamodb.ts index 419191c..b17c794 100644 --- a/src/dynamodb.ts +++ b/src/dynamodb.ts @@ -7,7 +7,9 @@ import { } from "@aws-sdk/client-dynamodb"; import { unmarshall, marshall } from "@aws-sdk/util-dynamodb"; import * as dotenv from "dotenv"; +import moment from "moment"; +import { timesheetToUpload } from "./utils"; import {TimeSheetSchema} from './db/schemas/Timesheet' import { CompanySchema, UserCompaniesSchema } from './db/schemas/CompanyUsers'; @@ -160,21 +162,24 @@ export async function WriteEntryToTable(table:TimeSheetSchema): Promise }); return true; } - +// EndDate should be start date plus one week export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], StartDate:number = 1, EndDate:number = StartDate + 100000000000000000000) { + // TODO: fix dates with moment + // TODO: create empty timesheets if timesheets dont exist for a week + if (StartDate > EndDate) { throw new Error("Invalid EndDate") } let result = [] - for (let x in uuids) { + for (let uuid of uuids) { const command = new QueryCommand({ TableName: "BreaktimeTimesheets", KeyConditionExpression: "UserID = :s", ExpressionAttributeValues: { - ":s": { S: `${uuids[x]}` }, + ":s": { S: `${uuid}` }, }, ExpressionAttributeNames: { "#S": "Status" @@ -188,7 +193,7 @@ export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], Sta if (dynamoRawResult == null || dynamoRawResult.Items == null) { throw new Error("Invalid response from DynamoDB, got undefined/null"); } - + // Convert Dynamo items to JS objects const unmarshalledItems = dynamoRawResult.Items.map((i) => unmarshall(i)); @@ -197,9 +202,32 @@ export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], Sta const uuidSet = new Set(uuids) - const modifiedTimesheetData = timesheetData.filter((sheet) => {return uuidSet.has(sheet.UserID) && sheet.StartDate >= StartDate && sheet.StartDate < EndDate}) - const uuidToTimesheet = {"uuid": uuids[x], timesheet: modifiedTimesheetData} + // TODO: have to check here the timesheets for all weeks exist then and create empty if not + let modifiedTimesheetData = timesheetData.filter((sheet) => {return uuidSet.has(sheet.UserID) && sheet.StartDate >= StartDate && sheet.StartDate < EndDate}) + + let existingWeeks = new Set() + + for (const sheet of modifiedTimesheetData) { + existingWeeks.add(sheet.StartDate) // make it sunday 00:00:00 + } + + for (const m = moment(StartDate); m.isBefore(EndDate); m.add(1, 'week')) { + if (!(m.unix() in existingWeeks)) { + const newSheet = timesheetToUpload(uuid, "Company 55"); + WriteEntryToTable(newSheet); + // add to modifiedTimesheetData + modifiedTimesheetData.push(newSheet); + } + + } + // go through modified timesheets + // make a dict of what weeks it has + // go through start to end and check that it has all weeks + + // modifiedTimesheetData not sorted by date but can be sorted + + const uuidToTimesheet = {"uuid": uuid, timesheet: modifiedTimesheetData} result.push(uuidToTimesheet); }; @@ -209,32 +237,3 @@ export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], Sta export async function filterUUIDsInCompanies(uuids: string[], companies: string[]) { // check if given uuids exist in given companies and return valid uuids } - - - /*const command = new QueryCommand({ - TableName: "BreaktimeTimesheets", - IndexName: "StartDate-index", - KeyConditionExpression: "StartDate = :unix", - ExpressionAttributeValues: { - ":unix": { N: StartDate.toString() }, - }, - }); - - const dynamoRawResult = await client.send(command); - - if (dynamoRawResult == null || dynamoRawResult.Items == null) { - throw new Error("Invalid response from DynamoDB, got undefined/null"); - } - - // Convert Dynamo items to JS objects - const unmarshalledItems = dynamoRawResult.Items.map((i) => unmarshall(i)); - - const timesheetData = unmarshalledItems.map((i) => TimeSheetSchema.parse(i)); - - const uuidSet = new Set(uuids) - - const modifiedTimesheetData = timesheetData.filter((item) => {return uuidSet.has(item.UserID) && item.StartDate < EndDate}); - // probably possible to do with dynamo but no difference in efficiency - const uuidToTimesheet = uuids.map((uuid, index) => {return {"uuid": uuid, "timesheet": modifiedTimesheetData[index]}}); - console.log(timesheetData) - return uuidToTimesheet*/ \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..396e03f --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,21 @@ +import { TimeSheetSchema } from "./db/Timesheet" +import { TimesheetStatus } from "./db/schemas/Timesheet"; +const moment = require('moment-timezone'); + + +export const timesheetToUpload = (UUID: string, CompanyID: string) => +TimeSheetSchema.parse({ + TimesheetID: Math.round(Math.random() * 1000000000), + UserID: UUID, + StartDate: moment().startOf('week').day(0).unix(), + Status: TimesheetStatus.parse({ + HoursSubmitted: undefined, + HoursReviewed: undefined, + ScheduleSubmitted: undefined, + Finalized: undefined + }), + CompanyID: CompanyID, + HoursData: [], + ScheduleData: [], + WeekNotes: [] +}) \ No newline at end of file From ee3323458460e66f95ef9a8879075c6aed75cf49 Mon Sep 17 00:00:00 2001 From: david Date: Wed, 9 Aug 2023 15:45:34 -0400 Subject: [PATCH 4/6] added logic for endpoint --- src/aws/auth.controller.ts | 55 +++++++++++++++++++++++++++++++------- src/dynamodb.ts | 30 +++++++++++++-------- src/utils.ts | 36 ++++++++++++------------- 3 files changed, 82 insertions(+), 39 deletions(-) diff --git a/src/aws/auth.controller.ts b/src/aws/auth.controller.ts index 115adbf..55fd852 100644 --- a/src/aws/auth.controller.ts +++ b/src/aws/auth.controller.ts @@ -8,7 +8,7 @@ import { UseGuards, } from "@nestjs/common"; import { AuthService } from "./auth.service"; -import { WriteEntryToTable, UserTimesheets, getTimesheetsForUsersInGivenTimeFrame } from "../dynamodb"; +import { getTimesheetsForUsersInGivenTimeFrame, doUUIDSExistInCompanies, GetCompaniesForUser, areUUIDsValid } from "../dynamodb"; import TokenClient from './cognito/cognito.keyparser' import { TimeSheetSchema } from 'src/db/schemas/Timesheet'; import * as frontendTimesheetSchemas from 'src/db/schemas/Timesheet' @@ -56,21 +56,56 @@ export class AuthController { @Get("getTimesheet") //@Roles('breaktime-management-role') //@Roles("breaktime-admin", "breaktime-supervisor") - // supervisor/admin get the same data, just check that supervisor has access to data admin is free for all public async get_timesheets( - @Headers() header: any, - @Query("userIds") userIds: string[] + @Headers() headers: any, + @Query("userIds") userIDs?: string[] ): Promise { // if supervisors dont have access to a uuid throw an error // if supervisor or admin request non existent uuid throw an error - - // TODO: filter uuids before getting - // if associate only return their timesheet + // if supervisor ensure all uuids are in company // if admin just make sure theyre all valid - await getTimesheetsForUsersInGivenTimeFrame(['77566d69-3b61-452a-afe8-73dcda96f876']); - - return []; + + // if associate only return their timesheet + + const userID = await TokenClient.grabUserID(headers); + let areAllUUIDsValid; + + if (!userIDs) { + if (1 == 1) { // associate + userIDs = [userID] + } else if (2 === 2) { // supervisor + userIDs = [] // get all users in their companies + } else if (3 === 3) { // admin + userIDs = [] // get all users they own + } else { + // no role no access + // throw error + } + } + + if (1 === 1) { // associate + areAllUUIDsValid = (userIDs.length === 1 && userID === userIDs[0]) + + } else if (2 === 2) { // supervisor + const supervisorCompanies = (await GetCompaniesForUser(userID)).SupervisorCompanyIDs + areAllUUIDsValid = await doUUIDSExistInCompanies(userIDs, supervisorCompanies) + + } else if (3 === 3) { //admin + areAllUUIDsValid = await areUUIDsValid(userIDs); + + } else { + // no role no access + // throw error + } + + if (areAllUUIDsValid) { + return await getTimesheetsForUsersInGivenTimeFrame(userIDs); + } else{ + // throw error + } + + //await getTimesheetsForUsersInGivenTimeFrame(['77566d69-3b61-452a-afe8-73dcda96f876']); } } diff --git a/src/dynamodb.ts b/src/dynamodb.ts index b17c794..8809602 100644 --- a/src/dynamodb.ts +++ b/src/dynamodb.ts @@ -7,7 +7,7 @@ import { } from "@aws-sdk/client-dynamodb"; import { unmarshall, marshall } from "@aws-sdk/util-dynamodb"; import * as dotenv from "dotenv"; -import moment from "moment"; +import moment = require("moment"); import { timesheetToUpload } from "./utils"; import {TimeSheetSchema} from './db/schemas/Timesheet' @@ -163,10 +163,7 @@ export async function WriteEntryToTable(table:TimeSheetSchema): Promise return true; } // EndDate should be start date plus one week -export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], StartDate:number = 1, EndDate:number = StartDate + 100000000000000000000) { - - // TODO: fix dates with moment - // TODO: create empty timesheets if timesheets dont exist for a week +export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], StartDate:number = moment().startOf('week').subtract(1, 'week').unix() , EndDate:number = moment().endOf('week').unix()): Promise { if (StartDate > EndDate) { throw new Error("Invalid EndDate") @@ -209,20 +206,24 @@ export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], Sta let existingWeeks = new Set() for (const sheet of modifiedTimesheetData) { - existingWeeks.add(sheet.StartDate) // make it sunday 00:00:00 + // maybe move to utils and can in theory have locale based issues so configure moment project wide + const beginningOfWeekDate = moment.unix(sheet.StartDate).set('second', 0).set('minute', 0).set('hour', 0).set('millisecond', 0).startOf('week').unix() + existingWeeks.add(beginningOfWeekDate) // make it sunday 00:00:00 } - for (const m = moment(StartDate); m.isBefore(EndDate); m.add(1, 'week')) { + console.log(existingWeeks, StartDate) + for (const m = moment.unix(StartDate); m.isBefore(moment.unix(EndDate)); m.add(1, 'week')) { if (!(m.unix() in existingWeeks)) { - const newSheet = timesheetToUpload(uuid, "Company 55"); + const newSheet = timesheetToUpload(uuid, "Company 55"); // TODO: should loop through companies user was active in and do it like that WriteEntryToTable(newSheet); // add to modifiedTimesheetData modifiedTimesheetData.push(newSheet); } } + // go through modified timesheets - // make a dict of what weeks it has + // make a set of what weeks it has // go through start to end and check that it has all weeks // modifiedTimesheetData not sorted by date but can be sorted @@ -231,9 +232,16 @@ export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], Sta result.push(uuidToTimesheet); }; + return result } -export async function filterUUIDsInCompanies(uuids: string[], companies: string[]) { - // check if given uuids exist in given companies and return valid uuids +export async function doUUIDSExistInCompanies(uuids: string[], companies: string[]): Promise { + // check if given uuids exist in given companies + return true +} + +export async function areUUIDsValid(uuids: string[]): Promise { + // check if uuids are valid + return true } diff --git a/src/utils.ts b/src/utils.ts index 396e03f..e99c0df 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,21 +1,21 @@ -import { TimeSheetSchema } from "./db/Timesheet" -import { TimesheetStatus } from "./db/schemas/Timesheet"; +import { TimeSheetSchema, TimesheetStatus } from "../src/db/schemas/Timesheet" const moment = require('moment-timezone'); - export const timesheetToUpload = (UUID: string, CompanyID: string) => -TimeSheetSchema.parse({ - TimesheetID: Math.round(Math.random() * 1000000000), - UserID: UUID, - StartDate: moment().startOf('week').day(0).unix(), - Status: TimesheetStatus.parse({ - HoursSubmitted: undefined, - HoursReviewed: undefined, - ScheduleSubmitted: undefined, - Finalized: undefined - }), - CompanyID: CompanyID, - HoursData: [], - ScheduleData: [], - WeekNotes: [] -}) \ No newline at end of file +{ + return TimeSheetSchema.parse({ + TimesheetID: Math.round(Math.random() * 1000000000), + UserID: UUID, + StartDate: moment().startOf('week').day(0).unix(), + Status: TimesheetStatus.parse({ + HoursSubmitted: undefined, + HoursReviewed: undefined, + ScheduleSubmitted: undefined, + Finalized: undefined + }), + CompanyID: CompanyID, + HoursData: [], + ScheduleData: [], + WeekNotes: [] + }) +} \ No newline at end of file From 2330ff8e79bf9da66932aa0da96cec81144dacca Mon Sep 17 00:00:00 2001 From: david Date: Fri, 11 Aug 2023 12:52:20 -0400 Subject: [PATCH 5/6] added dynamodb method to check uuids are in a company --- src/dynamodb.ts | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/dynamodb.ts b/src/dynamodb.ts index 8809602..f87d735 100644 --- a/src/dynamodb.ts +++ b/src/dynamodb.ts @@ -237,8 +237,28 @@ export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], Sta } export async function doUUIDSExistInCompanies(uuids: string[], companies: string[]): Promise { - // check if given uuids exist in given companies - return true + + const dynamoCompanyKey = companies.map((company) => {return {CompanyID: { S: company}}}) + + const command = new BatchGetItemCommand({ + RequestItems: { + BreaktimeCompanyToUsers : { + Keys : dynamoCompanyKey, + ProjectionExpression : "AssociateIDs" + } + } + }); + + const dynamoRawResult = await client.send(command); + + if (dynamoRawResult == null || dynamoRawResult.Responses == null) { + throw new Error("Invalid response from DynamoDB, got undefined/null"); + } + + const results = dynamoRawResult.Responses.BreaktimeCompanyToUsers.map((i) => unmarshall(i))[0].AssociateIDs; + + // so check results are same as uuids + return results.sort().toString() === uuids.sort().toString(); } export async function areUUIDsValid(uuids: string[]): Promise { From 0a23d2bbaa11e0c13ba2b20728d81782cd99f463 Mon Sep 17 00:00:00 2001 From: david Date: Fri, 11 Aug 2023 13:39:26 -0400 Subject: [PATCH 6/6] added do uuids exist in dynamo --- src/dynamodb.ts | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/dynamodb.ts b/src/dynamodb.ts index f87d735..4175acd 100644 --- a/src/dynamodb.ts +++ b/src/dynamodb.ts @@ -238,12 +238,12 @@ export async function getTimesheetsForUsersInGivenTimeFrame(uuids: string[], Sta export async function doUUIDSExistInCompanies(uuids: string[], companies: string[]): Promise { - const dynamoCompanyKey = companies.map((company) => {return {CompanyID: { S: company}}}) + const dynamoKeys = companies.map((company) => {return {CompanyID: { S: company}}}) const command = new BatchGetItemCommand({ RequestItems: { BreaktimeCompanyToUsers : { - Keys : dynamoCompanyKey, + Keys : dynamoKeys, ProjectionExpression : "AssociateIDs" } } @@ -262,6 +262,25 @@ export async function doUUIDSExistInCompanies(uuids: string[], companies: string } export async function areUUIDsValid(uuids: string[]): Promise { - // check if uuids are valid - return true + + const dynamoKeys = uuids.map((uuid) => {return {UserID: { S: uuid}}}) + + const command = new BatchGetItemCommand({ + RequestItems: { + BreaktimeUserToCompanies : { + Keys : dynamoKeys, + ProjectionExpression : "UserID" + } + } + }); + + const dynamoRawResult = await client.send(command); + + if (dynamoRawResult == null || dynamoRawResult.Responses == null) { + throw new Error("Invalid response from DynamoDB, got undefined/null"); + } + + const results = dynamoRawResult.Responses.BreaktimeUserToCompanies; + + return results.length === uuids.length; }