شرکت Alphazed بیش از ۷ اپ آموزشی (Amal, Thurayya, Qais, KidElite, Alphazed School, Alphazed Montessori و غیره) را از طریق یک کدبیس بکاند یکپارچه و فریمورک موبایل مشترک Flutter مدیریت میکند. هر اپ دارای جداول بانک اطلاعاتی (با پیشوند مخصوص)، تنظیمات، اعلانهای پوش، قالبهای ایمیل و محتوای خاص خود است اما احراز هویت (AWS Cognito)، زیرساخت تحلیل دادهها و الگوریتمهای اصلی یادگیری بین همه مشترک است.
بکاند: انتخاب اپ در زمان اجرا
چگونه کار میکند
در زمان استقرار (deployment)، یک متغیر محیطی اپ مورد نظر را تعیین میکند:
# Deploy Amal
export APP_NAME=amal
serverless deploy
# Deploy Thurayya
export APP_NAME=thurayya
serverless deploy
# Deploy Qais
export APP_NAME=qais
serverless deploy
هر استقرار توابع Lambda مستقل، مسیرهای API Gateway و مانیتورینگ جداگانه ایجاد میکند ولی همه به یک کدبیس واحد متصلاند.
اولویتهای سهگانه تنظیمات
# src/config.py
import os
app_name = os.getenv('APP_NAME', 'amal')
# اول: تطابق دقیق با نام اپ
config = load_json(f'config/{app_name}.json')
# دوم: تطابق خانواده اپ (اگر تنظیمات دقیق نباشد)
if not config:
family = app_name.split('_')[0] # 'amal_beta' → 'amal'
config = load_json(f'config/{family}.json')
# سوم: تنظیمات پیشفرض
if not config:
config = load_json('config/default.json')
تنظیمات مخصوص هر اپ (مثال config/amal.json)
{
"app_name": "amal",
"app_id": "com.alphazed.amal",
"database": {
"table_prefix": "amal_"
},
"email": {
"template_dir": "templates/amal",
"from_address": "amal@alphazed.com",
"from_name": "Amal Team"
},
"push_notifications": {
"firebase_project": "alphazed-amal",
"apns_certificate": "certs/amal.pem"
},
"content": {
"s3_bucket": "amal-content-production",
"curriculum_id": "amal_v3_arabic"
},
"feature_flags": {
"enable_tajweed_feedback": false,
"enable_noorani_qaida": false,
"enable_juz_amma": false,
"enable_creature_building": true,
"enable_physics_games": true
},
"pricing": {
"monthly_usd": 6.99,
"yearly_usd": 67.99,
"trial_days": 14
}
}
منابع مشترک و اختصاصی هر اپ
| منبع | مشترک | مخصوص اپ | دلیل |
|---|---|---|---|
| کد Lambda | ✓ بله | ✗ خیر | یک کدبیس با شاخهبندی بر اساس APP_NAME |
| نمونه RDS | ✓ بله | ✗ خیر (جداول پیشونددار) | کاهش هزینه، بکاپ یکپارچه |
| محتوای S3 | ✗ خیر | ✓ بله | هر اپ برنامه آموزشی خود را دارد |
| AWS Cognito | ✓ بله | ✗ خیر (بر اساس app_id) | احراز هویت مرکزی و تمایز توسط app_id |
| تالاب تحلیل | ✓ بله | ✗ خیر (بخشبندی شده بر اساس اپ) | خط لوله داده یکپارچه اما جداسازی دادهها |
| ارسال پیام Firebase | ✗ خیر | ✓ بله | APNs و FCM مخصوص هر اپ |
فرانتاند: معماری چند اپ در Flutter
هسته مشترک (packages/alphazed_common)
- مدیریت وضعیت (Riverpod)
- پخش صدا
- کتابخانه انیمیشن (ادغام Rive)
- سیستم طراحی (رنگها، قلمها، ویجتها)
- روندهای احراز هویت
- کلاینت تحلیل
لایههای اختصاصی هر اپ (apps/amal, apps/thurayya و غیره)
apps/
├── amal/
│ ├── lib/
│ │ ├── main.dart (ورودی اپ)
│ │ ├── config/
│ │ │ ├── curriculum.json (ساختار درس Amal)
│ │ │ ├── colors.dart (تم Amal)
│ │ │ └── characters.json (شخصیتها)
│ │ └── screens/ (صفحههای مختص Amal)
│ └── pubspec.yaml (وابستگیهای Amal)
│
├── thurayya/
│ ├── lib/
│ │ ├── main.dart (ورودی متفاوت)
│ │ ├── config/
│ │ │ ├── curriculum.json (ساختار جزء عمّا)
│ │ │ ├── colors.dart (تم Thurayya)
│ │ │ └── characters.json (شخصیتها)
│ │ └── screens/ (صفحههای مختص Thurayya)
│ └── pubspec.yaml (وابستگیهای Thurayya)
│
└── packages/
└── alphazed_common/ (کد مشترک)
تنظیمات زمان ساخت
# ساخت Amal
flutter build apk --dart-define=APP_NAME=amal --dart-define=CURRICULUM=amal_v3
# ساخت Thurayya
flutter build apk --dart-define=APP_NAME=thurayya --dart-define=CURRICULUM=thurayya_juzamma
در زمان ساخت، هر اپ دادههای برنامه آموزشی، رنگها و تنظیمات مخصوص به خود را دریافت میکند. یک مخزن کد، چند باینری مختلف.
استقرار: استکهای مستقل
پیکربندی Serverless Framework
# serverless.yml
service: alphazed-backend
custom:
pythonRequirements:
dockerizePip: true
app_name: ${env:APP_NAME}
functions:
# این توابع برای هر مقدار APP_NAME منتشر میشوند
get_user:
handler: src/handlers/user.get_user
events:
- http:
path: app/{app_name}/user/{user_id}
method: get
content_duo:
handler: src/handlers/content.generate_content_duo
timeout: 20
events:
- http:
path: app/{app_name}/content_duo
method: post
resources:
Resources:
# هر اپ گروه لاگ جداگانه در CloudWatch دارد
${self:custom.app_name}LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /aws/lambda/alphazed-${self:custom.app_name}
RetentionInDays: 30
با استقرار برای APP_NAME=amal، CloudFormation موارد زیر را ایجاد میکند:
- توابع Lambda با پیشوند
alphazed-amal-* - مسیرهای API Gateway زیر
/amal/* - لاگهای CloudWatch در
/aws/lambda/alphazed-amal - مقیاسپذیری و مانیتورینگ مستقل
چرا این مهم است
برای تیم محصول
- زمان راهاندازی اپ جدید: هفتهها به جای ماهها به دلیل اشتراک زیرساخت
- تطابق امکانات: رفع اشکال و بهبود الگوریتمها بلافاصله در همه اپها اعمال میشود
- تست A/B آسان: آزمایش ویژگیها در یک اپ پیش از انتشار به بقیه
برای تیم مهندسی
- یک کدبیس واحد: یک مجموعه تست و یک خط تولید CI/CD
- الگوریتمهای یادگیری مشترک: تکرار فاصلهای و ترکیب محتوا برای همه اپها
- کارایی عملیاتی: مدیریت تمام زیرساخت توسط یک تیم
برای هزینهها
- رایگانتر بودن RDS مشترک نسبت به ۷ پایگاه جداگانه
- یک ارائهدهنده احراز هویت AWS Cognito برای همه اپها
- یک خط لوله تحلیل داده برای همه ۷ اپ
- صرفهجویی تخمینی ۴۰ تا ۶۰ هزار دلار در سال نسبت به بکاندهای جداگانه
چالشها و راهحلها
چالش ۱: تداخل در ساختار دیتابیس
- Amal به جدول
amal_user_memoryنیاز دارد - Thurayya به جدول
thurayya_user_memoryنیاز دارد با فیلدهای متفاوت برای حفظ قرآن - راهحل: مهاجرتها با آگاهی از اپ اجرا میشوند. اسکریپت
migrations/001_amal_user_memory.sqlتنها برایAPP_NAME=amalاجرا میشود
چالش ۲: مجموعه امکانات متفاوت
- Thurayya بازخورد تجوید دارد؛ Amal ندارد
- Amal بازیهای فیزیک دارد؛ Thurayya ندارد
- راهحل: استفاده از پرچمهای ویژگی در تنظیمات
enable_tajweed_feedbackوenable_physics_games
چالش ۳: مقیاسپذیری مستقل
- Amal افزایش ترافیک دارد؛ Thurayya کم است
- استخر Lambda مشترک باعث رقابت برای همزمانی میشود
- راهحل: سیاستهای مقیاسگذاری CloudWatch برای هر اپ. اگر توابع
amal-*به حد همزمانی برسند، به طور مستقل مقیاس میشوند
پرسشهای متداول
Q: آیا اشتراک یک کدبیس باعث وابستگی زیاد بین اپها نمیشود؟
A: خیر. کد هر اپ در دایرکتوریهای جداگانه (apps/amal, apps/thurayya) است. کد مشترک در packages/alphazed_common و نسخهبندی شده است. وابستگی شدید نشانه طراحی بد است و در بازبینی کد پیدا میشود.
Q: اگر یک اپ نیاز به تغییر شکسته در API داشته باشد چه؟
A: ما APIها را بر اساس اپ نسخهبندی میکنیم: /amal/v1/, /thurayya/v1/. اپها میتوانند مستقل بهروزرسانی شوند. نسخههای قدیمی تا ۱۲ ماه اجرا میشوند تا فرصت بروزرسانی باشد.
Q: آیا کاربران بین اپها مشترک اند؟
A: به طور پیشفرض خیر. هر اپ جدول کاربران جداگانه دارد (با پیشوند). اگر والدین بخواهند هر دو اپ Amal و Thurayya را داشته باشند، باید حسابهای مجزا بسازند (یا میتوان ویژگی لینک «خانواده» افزود).



