-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#56 integrated SMCloudStore with Azure provider; cleaned Item form in frontend #58
Changes from 1 commit
89c998a
6b2cf78
aa3bd84
6405d42
9e1103e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
-- AlterTable | ||
ALTER TABLE "DonatedItemStatus" ADD COLUMN "imageUrls" TEXT[]; |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. starting with Azure makes sense based on what we discussed. do you have an issue created to add an option for all the supported platforms? it seems like it would be a straightforward update to this file, the donated item service, and package.json. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. writing a new connection for other cloud storage is easy but I have to create accounts for other cloud providers to get the connection keys, storage account etc which is time consuming. I will create an issue for that. What is the purpose of the multiple cloud providers? Is it for fail safe or to be able to switch to other providers in future? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to switch to other providers in the future, especially if the solution is deployed by other users. solving for BWorks is our first use case, but in talking w/ Patrick my understanding is that his vision has always been something that anyone who does similar things could re-use the tool. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It makes sense. I will work on that. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
require('dotenv').config(); | ||
const SMCloudStore = require('smcloudstore') | ||
|
||
// connection options for Azure Blob Storage | ||
const connection = { | ||
storageAccount: process.env.AZURE_STORAGE_ACCOUNT_NAME, | ||
storageAccessKey: process.env.AZURE_STORAGE_ACCESS_KEY | ||
} | ||
|
||
// Return an instance of the AzureStorageProvider class | ||
export const storage = SMCloudStore.Create('azure-storage', connection) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,28 @@ | ||
import { Router, Request, Response } from 'express'; | ||
import multer from 'multer'; | ||
import prisma from '../prismaClient'; // Import Prisma client | ||
import { donatedItemValidator } from '../validators/donatedItemValidator'; // Import the validator | ||
import { validateDonor } from '../services/donorService'; | ||
import { validateProgram } from '../services/programService'; | ||
import { date } from 'joi'; | ||
import { uploadToAzure } from '../services/donatedItemService'; | ||
|
||
const router = Router(); | ||
const upload = multer({ storage: multer.memoryStorage() }); | ||
|
||
// POST /donatedItem - Create a new DonatedItem | ||
router.post('/', donatedItemValidator, async (req: Request, res: Response) => { | ||
router.post('/', [upload.array('imageFiles'), donatedItemValidator], async (req: Request, res: Response) => { | ||
try { | ||
|
||
const imageFiles = req.files as Express.Multer.File[]; | ||
const donorId = parseInt(req.body.donorId); | ||
const programId = parseInt(req.body.programId); | ||
const { dateDonated, ...rest } = req.body; | ||
|
||
try { | ||
await validateDonor(req.body.donorId); | ||
await validateProgram(req.body.programId); | ||
await validateDonor(donorId); | ||
await validateProgram(programId); | ||
} catch (error) { | ||
if (error instanceof Error) { | ||
console.log('error', error) | ||
return res.status(400).json({ error: error.message }); | ||
} | ||
} | ||
|
@@ -27,16 +32,24 @@ router.post('/', donatedItemValidator, async (req: Request, res: Response) => { | |
const newItem = await prisma.donatedItem.create({ | ||
data: { | ||
...rest, //spread the rest of the fields | ||
donorId, | ||
programId, | ||
dateDonated: dateDonatedDateTime, | ||
// dateDonated: new Date(dateDonated), | ||
// dateDonated: new Date(dateDonated).setUTCHours(0,0,0,0), // Set time to 00:00:00 UTC | ||
}, | ||
}); | ||
|
||
// upload images to Azure and get their filenames | ||
const imageUrls = await Promise.all(imageFiles.map((file, index) => { | ||
const formattedDate = new Date().toISOString(); | ||
return uploadToAzure(file, `item-${formattedDate}-${newItem.id}.jpg`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. assuming .jpg is fine for now, but long-term it might bite you. maybe you want a function to handle detecting file types and generating your uploaded image file name. you could create an issue to do that. it might make a good-first-issue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah it makes sense. I blindly used .jpg but it could be .png image also. I will try to fix it or create a good first issue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed this one by creating a function to find the file extension based on incoming file MIME type. |
||
})); | ||
|
||
const newStatus = await prisma.donatedItemStatus.create({ | ||
data: { | ||
statusType: 'Received', | ||
dateModified: dateDonatedDateTime, // Use the same date as dateDonated | ||
donatedItemId: newItem.id, | ||
imageUrls: imageUrls | ||
}, | ||
}); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import multer from 'multer'; | ||
import { storage } from "../configs/SMCloudStoreConfig"; | ||
|
||
export async function uploadToAzure(file: Express.Multer.File, filename: string): Promise<string> { | ||
const containerName = 'mdma-dev'; | ||
await storage.putObject(containerName, filename, file.buffer, { | ||
'Content-Type': file.mimetype | ||
}); | ||
return `${containerName}/${filename}`; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't see any validation that you're only accepting images, indication what sort of images types might be accepted, or limits on file size. these aren't urgent concerns, but you'll probably want them at least in the client, and probably in the server, at some point. maybe just drop a new issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes sense, Copied!!