From 4fa5362ade74e2d0de52cfa5566bf25cb123631f Mon Sep 17 00:00:00 2001 From: Uros Stankovic Date: Tue, 19 Nov 2024 23:21:40 +0100 Subject: [PATCH] Add photo print request handler --- .env | 2 + stampa_back/config.ts | 1 + stampa_back/db/db-access.ts | 6 +++ stampa_back/db/db_init.sql | 49 ++++++++++++++++++---- stampa_back/db/models/PrintRequests.ts | 22 ++++++++++ stampa_back/db/models/User.ts | 1 + stampa_back/db/printrequest-db.ts | 56 +++++++++++++++++++++++++ stampa_back/handlers/handler-factory.ts | 12 ++++-- stampa_back/handlers/print-requests.ts | 30 +++++++++++++ stampa_back/main.ts | 6 ++- 10 files changed, 172 insertions(+), 13 deletions(-) create mode 100644 .env create mode 100644 stampa_back/config.ts create mode 100644 stampa_back/db/models/PrintRequests.ts create mode 100644 stampa_back/db/printrequest-db.ts create mode 100644 stampa_back/handlers/print-requests.ts diff --git a/.env b/.env new file mode 100644 index 0000000..b9796f4 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +JWT_PRIVATE_KEY= +USER_PASSWORD_SALT= \ No newline at end of file diff --git a/stampa_back/config.ts b/stampa_back/config.ts new file mode 100644 index 0000000..97907d9 --- /dev/null +++ b/stampa_back/config.ts @@ -0,0 +1 @@ +export const MAX_PICTURE_UPLOAD_PER_REQUEST = 50 \ No newline at end of file diff --git a/stampa_back/db/db-access.ts b/stampa_back/db/db-access.ts index 9b3131c..5a46a27 100644 --- a/stampa_back/db/db-access.ts +++ b/stampa_back/db/db-access.ts @@ -1,3 +1,4 @@ +import { DBAccessPrintRequest, DBAccessPrintRequestImpl } from "./printrequest-db"; import { DBAccessUser, DBAccessUserImpl } from "./user-db"; export const knexAccess = require('knex')({ @@ -12,10 +13,15 @@ export const knexAccess = require('knex')({ export abstract class DBAccessFactory { abstract getUserAccess(): DBAccessUser + abstract getPrintRequestAccess(): DBAccessPrintRequest } export class DBAccessFactoryImpl extends DBAccessFactory { getUserAccess(): DBAccessUser { return new DBAccessUserImpl() } + + getPrintRequestAccess(): DBAccessPrintRequest { + return new DBAccessPrintRequestImpl() + } } diff --git a/stampa_back/db/db_init.sql b/stampa_back/db/db_init.sql index 41d1d36..93d5665 100644 --- a/stampa_back/db/db_init.sql +++ b/stampa_back/db/db_init.sql @@ -6,11 +6,44 @@ USE photostudio; CREATE TABLE user( username VARCHAR(255), - password: VARCHAR(255), - name: VARCHAR(255), - surname: VARCHAR(255), - street: VARCHAR(255), - streetnumber: VARCHAR(31), - city: VARCHAR(255), - zip: INTEGER, - phone: VARCHAR(31)); + password VARCHAR(255), + name VARCHAR(255), + surname VARCHAR(255), + street VARCHAR(255), + streetnumber VARCHAR(31), + city VARCHAR(255), + zip INTEGER, + phone VARCHAR(31), + PRIMARY KEY (username) +); + +CREATE TABLE print_request( + request_id INTEGER NOT NULL AUTO_INCREMENT, + status VARCHAR(15) NOT NULL, -- new, accepted, sent + request_type VARCHAR(31) NOT NULL, -- photo_batch + PRIMARY KEY (request_id) +); + +CREATE TABLE print_request_client_data( + name VARCHAR(255), + surname VARCHAR(255), + street VARCHAR(255), + streetnumber VARCHAR(31), + city VARCHAR(255), + zip INTEGER, + phone VARCHAR(31), + request_id INTEGER NOT NULL, + + FOREIGN KEY request_id + REFERENCES print_request(request_id) + ON UPDATE CASCADE ON DELETE CASCADE +); + +CREATE TABLE print_request_photo_batch( + request_id INTEGER NOT NULL, + photo VARCHAR(4095), -- Path to uploaded photo + + FOREIGN KEY request_id + REFERENCES print_request(request_id) + ON UPDATE CASCADE ON DELETE CASCADE +); diff --git a/stampa_back/db/models/PrintRequests.ts b/stampa_back/db/models/PrintRequests.ts new file mode 100644 index 0000000..8c12099 --- /dev/null +++ b/stampa_back/db/models/PrintRequests.ts @@ -0,0 +1,22 @@ +export interface PrintRequest { + requestId: number, + status: PrintRequestStatus, + clientData: PrintRequestClientData +} + +export interface PrintRequestPhotoBatch extends PrintRequest { + photos: string[] +} + +export type PrintRequestStatus = 'new' | 'accepted' | 'sent' + +export interface PrintRequestClientData { + name: string, + surname: string, + streetNumber: string, + street: string, + zipCode: string, + city: string, + phone: string, + email: string | null +} diff --git a/stampa_back/db/models/User.ts b/stampa_back/db/models/User.ts index 600a31f..3a2ce39 100644 --- a/stampa_back/db/models/User.ts +++ b/stampa_back/db/models/User.ts @@ -13,6 +13,7 @@ export interface UserWithCredentials extends User { export interface Address { street: string, streetNumber: string, + // TODO: Add apartment city: string, zip: string } diff --git a/stampa_back/db/printrequest-db.ts b/stampa_back/db/printrequest-db.ts new file mode 100644 index 0000000..56ab959 --- /dev/null +++ b/stampa_back/db/printrequest-db.ts @@ -0,0 +1,56 @@ +import { knexAccess } from './db-access'; +import * as dotenv from 'dotenv' +import { PrintRequestPhotoBatch } from './models/PrintRequests'; + +dotenv.config() + +export abstract class DBAccessPrintRequest { + // abstract getPrintRequests(status) + abstract addPhotoBatchPrintRequest(printRequest: PrintRequestPhotoBatch): Promise +} + +export class DBAccessPrintRequestImpl extends DBAccessPrintRequest { + printRequestTable = 'print_request' + printRequestClientDataTable = 'print_request_client_data' + printRequestPhotoBatchTable = 'print_request_photo_batch' + + async addPhotoBatchPrintRequest(printRequest: PrintRequestPhotoBatch): Promise { + const requestIds = await knexAccess + .table(this.printRequestClientDataTable) + .insert({ + request_id: printRequest.requestId, + status: printRequest.status, + }) + + if (requestIds[0] <= 0) { + throw new Error("Print request insertion unsuccessful") + } + + const requestId = requestIds[0] + const clientData = printRequest.clientData + + await knexAccess + .table(this.printRequestClientDataTable) + .insert({ + name: clientData.name, + surname: clientData.surname, + street: clientData.street, + streetnumber: clientData.streetNumber, + city: clientData.city, + zip: clientData.zipCode, + phone: clientData.phone, + request_id: requestId // Foreign key for request id + }) + + const insertPhotoPromises = printRequest.photos.map(photo => { + return knexAccess + .table(this.printRequestPhotoBatchTable) + .insert({ + request_id: requestId, + photo: photo + }); + }) + + await Promise.all(insertPhotoPromises) + } +} diff --git a/stampa_back/handlers/handler-factory.ts b/stampa_back/handlers/handler-factory.ts index c5747d3..fdebbc8 100644 --- a/stampa_back/handlers/handler-factory.ts +++ b/stampa_back/handlers/handler-factory.ts @@ -1,4 +1,5 @@ -import { userLoginHandler, userSignUpHandler } from "./user-managements"; +import * as printRequestHandlers from "./print-requests"; +import * as userManagementHandlers from "./user-managements"; import { Request, Response } from "express" export type ExpressHandler = (request: Request, response: Response) => void @@ -6,14 +7,19 @@ export type ExpressHandler = (request: Request, response: Response) => void export abstract class ExpressHandlerFactory { abstract getUserLoginHandler(): ExpressHandler abstract getUserSignUpHandler(): ExpressHandler + abstract getPhotoBatchPrintRequestHandler(): ExpressHandler } export class ExpressHandlerFactoryImpl extends ExpressHandlerFactory { getUserLoginHandler(): ExpressHandler { - return userLoginHandler + return userManagementHandlers.userLoginHandler } getUserSignUpHandler(): ExpressHandler { - return userSignUpHandler + return userManagementHandlers.userSignUpHandler + } + + getPhotoBatchPrintRequestHandler(): ExpressHandler { + return printRequestHandlers.postPhotoBatchPrintRequest } } diff --git a/stampa_back/handlers/print-requests.ts b/stampa_back/handlers/print-requests.ts new file mode 100644 index 0000000..5024443 --- /dev/null +++ b/stampa_back/handlers/print-requests.ts @@ -0,0 +1,30 @@ +import { randomUUID } from "crypto" +import { Request, Response } from "express" +import { getAppContext } from "../context" +import { PrintRequestClientData } from "../db/models/PrintRequests" + + +export async function postPhotoBatchPrintRequest(request: Request, response: Response) { + const { + photos, + clientData + } = request.body as PhotoBatchPrintRequestData + + // TODO: Add validation of data + + const printRequestAccess = getAppContext() + .getDBAccess() + .getPrintRequestAccess() + + await printRequestAccess.addPhotoBatchPrintRequest({ + requestId: 0, // Request id will be auto generated on database level + status: 'new', + clientData, + photos + }) +} + +interface PhotoBatchPrintRequestData { + photos: string[], + clientData: PrintRequestClientData +} diff --git a/stampa_back/main.ts b/stampa_back/main.ts index 2293cc9..c961ae5 100644 --- a/stampa_back/main.ts +++ b/stampa_back/main.ts @@ -6,6 +6,7 @@ import { multerMiddleware, multiplePictureUpload } from './picture_handlers' import { destroyDBAccess } from './db/user-db' import { getAppContext } from './context' import * as dotenv from 'dotenv' +import * as config from './config' dotenv.config() const app = express() @@ -24,8 +25,9 @@ app.get('/myorders', notImplementedHandler) // POST PHOTOS -app.post('/imageupload', multerMiddleware.array('pictures', 3), multiplePictureUpload) -app.post('/photorequest', notImplementedHandler) +app.post('/imageupload', multerMiddleware.array('pictures', config.MAX_PICTURE_UPLOAD_PER_REQUEST), multiplePictureUpload) + +app.post('/printrequest/photobatch', handlerFactory.getPhotoBatchPrintRequestHandler()) // ADMIN PANEL