مینی بک آفیس برای پت شاپ

این یک ارسال برای چالش AWS Amplify Fullstack TypeScript است
چیزی که من ساختم
من در Angular یک برنامه کوچک توسعه دادم که به عنوان یک دفتر پشتیبان برای یک سایت فروش حیوانات خانگی خدمت می کند. ایده در اینجا ارائه اطلاعات ثبت شده در پلت فرم در مورد حیوان خانگی و فروشنده آن است که معمولاً صاحب نامیده می شود.
برای اینکه بتوانید از برنامه استفاده کنید، احراز هویت با رمز عبور/نام کاربری (ایمیل) ضروری است، کاربر در صورت نداشتن میتواند یکی را ایجاد کند. هنگامی که کاربر متصل می شود، اطلاعات صاحب حیوان را ثبت می کند، سپس با انتخاب یک صاحب از لیست ایجاد شده قبلی، حیوانات خانگی را یکی یکی ثبت می کند.
نسخه ی نمایشی و کد
کد منبع –> مخزن Github
نسخه ی نمایشی زنده –>
نسخه ی نمایشی (1/3)
ورود رمز عبور/ایمیل
نسخه ی نمایشی (2/3)
ثبت نام مالک
نسخه ی نمایشی (3/3)
ثبت نام حیوان خانگی
ادغام ها
خدمات AWS زیر یکپارچه شده است:
- S3
- AppSync
- لامبدا
- دیانمودب
- آموختن
1. DynamoDB و AppSync بدون سرور
تمام داده های وارد شده توسط کاربران در جدول Dynamodb ذخیره می شود. در اینجا طرح جدول و پیکربندی تقویت کننده آمده است:
export const petsSchema = {
PetOwner: a
.model({
OwnerID: a.id(),
Name: a.string().required(),
Email: a.email().required(),
Phone: a.string(),
Bio: a.string(),
Picture: a.string(),
})
.authorization((allow) => allow.publicApiKey()),
PetKind: a.enum(['FEMALE', 'MALE']),
PetCategorySchema: a.enum(
Object.keys(PetCategory).filter((v) => isNaN(v as any))
),
Pet: a
.model({
ID: a.id(),
NickelName: a.string().required(),
Price: a.float().required(),
Category: a.ref('PetCategorySchema').required(),
Breed: a.string(),
Rate: a.float().default(0.0),
Kind: a.ref('PetKind'),
BornDate: a.date().required(),
Weight: a.float().required(),
PetBio: a.string(),
OwnerID: a.id(),
//Owner: a.belongsTo('PetOwner', 'OwnerID'),
Images: a.string().array(),
DefaultImage: a.string(),
})
.authorization((allow) => allow.publicApiKey()),
};
2. S3
برای ذخیره تصاویر حیوانات خانگی و عکس صاحبان از سرویس ذخیره سازی S3 استفاده کردم. چگونه تصاویر را در S3 ذخیره کردم؟ هنگام ثبت نام حیوان خانگی صاحب خود، اولین رکورد را در جدول DynamoDB ایجاد می کنم تا _ID را دریافت کنم، سپس فایل(ها) را در سطل S3 آپلود می کنم و سپس اطلاعات را با فایل ObjectKey به روز می کنم.
پیکربندی amplify/s3
export const storage = defineStorage({
name: 'amplifyPetShop',
triggers: {...}),
},
access: (allow) => ({
'owner-pictures/*': [
allow.guest.to(['read']),
allow.authenticated.to(['read', 'delete', 'write']),
],
'pets-thumbs/*': [
allow.guest.to(['read']),
allow.resource(createImageThumbs).to(['read', 'write', 'delete']),
allow.entity('identity').to(['read', 'write', 'delete']),
],
'pets/*': [
allow.guest.to(['read']),
allow.resource(createImageThumbs).to(['read']),// Lambda resource
allow.entity('identity').to(['read', 'write', 'delete']),
],
}),
});
const files =...; // <-- list of File
const prefix = "pets";
const arr = [...files].map((file) =>
from(
uploadData({
data: file,
path: `${prefix}${uuid}_${file.name}`,
}).result.then((result) => ({ result, original: file.name }))
)
);
3. لامبدا بدون سرور
من به منظور خودکارسازی ایجاد تصاویر در نسخه های کوچک شده (تصاویر کوچک) با هزینه کمتر، لامبدا را انتخاب کردم که هر بار که یک فایل بارگذاری می شود فعال می شود. حیوانات خانگی پوشه، این لامبدا تابعی را اجرا می کند که یک تصویر کوچک تولید می کند و به نوبه خود آن را در سطل S3 بارگذاری می کند. در اینجا پیکربندی و کد تقویت کننده برای تابع مورد نظر آمده است.
تقویت پیکربندی
export const createImageThumbs = defineFunction({
name: 'gen-image-thumbs',
entry: './handler.ts',
runtime: 20,
memoryMB: 256,
});
و کد تابع لامبدا
export const handler: S3Handler = async (event: S3Event) => {
const objectKeysUploaded = event.Records.map(
(record: any) => record.s3.object.key
);
const srcBucket = process.env.AMPLIFY_PET_SHOP_BUCKET_NAME;
const srcKey = event.Records[0].s3.object.key;
if (srcKey.startsWith('pets/')) {
const dstKey = `pets-thumbnails/${srcKey.split('pets/')[1]}`;
const originalImage = await s3Client.send(
new GetObjectCommand({
Bucket: srcBucket,
Key: dstKey,
})
);
// @ts-ignore
const resizedImage = await sharp(originalImage).resize(128).toBuffer();
const command = new PutObjectCommand({
Bucket: srcBucket,
Key: `thumbnails/${objectKeysUploaded[0]}`,
Body: resizedImage,
});
await s3Client
.send(command)
.then((value) => {
console.log(`Thumbnail uploaded for objects ${srcKey}]`, value);
})
.catch((reason) => {
console.error(reason);
});
}
};
برای اینکه لامبدا توسط منبع S3 اجرا شود، باید حقوق لازم را به آن اختصاص دهیم، به طور مشابه تابع لامبدا نیز به حقوق خواندن و نوشتن در سطل S3 نیاز دارد. در اینجا پیکربندی تقویت کننده است:
'pets-thumbnails/*': [
...
allow.resource(createImageThumbs).to(['read', 'write', 'delete']),
],
'pets/*': [
...
allow.resource(createImageThumbs).to(['read']),
],
خط اول حقوق w/r را به لامبدا در سطل می دهد تا فایل ها را بارگیری کند و خط دوم برای بارگیری فایل اصلی.
و در نهایت اینجا پیکربندی ماشه است:
export const storage = defineStorage({
name: 'amplifyPetShop',
triggers: {
onUpload: defineFunction({
entry: '../functions/create-image-thumbs/handler.ts',
environment: {
TARGET_BUCKET_NAME: 'pets-thumbs',
},
}),
},
...
اجزای متصل و/یا ویژگی کامل
این پروژه با Angular توسعه داده شد و به همین مناسبت از افزونه اتصال @amplify/angular-ui برای مدیریت صفحات ثبت اتصال و استفاده استفاده کردم، بقیه پروژه با کامپوننت های o priming توسعه داده شد.