Bagaimana Kami Membangun Platform Multi-Aplikasi dari Satu Codebase
Alphazed mengoperasikan lebih dari 7 aplikasi edukasi (Amal, Thurayya, Qais, KidElite, Alphazed School, Alphazed Montessori, dan lainnya) dari satu backend codebase dan framework mobile Flutter yang sama. Setiap aplikasi memiliki tabel database tersendiri (dengan prefix), konfigurasi, notifikasi push, template email, dan konten — namun berbagi autentikasi (AWS Cognito), infrastruktur analitik, dan algoritma pembelajaran inti.
Backend: Pemilihan Aplikasi Saat Runtime
Cara Kerjanya
Saat deployment, sebuah environment variable menentukan aplikasi yang akan dijalankan:
# Deploy Amal
export APP_NAME=amal
serverless deploy
# Deploy Thurayya
export APP_NAME=thurayya
serverless deploy
# Deploy Qais
export APP_NAME=qais
serverless deploy
Setiap deployment membuat fungsi Lambda, rute API Gateway, dan monitoring yang terpisah—namun semuanya terkoneksi ke backend codebase yang sama.
Prioritas Konfigurasi Tiga Tingkat
# src/config.py
import os
app_name = os.getenv('APP_NAME', 'amal')
# Tingkat 1: Cocokkan nama app secara tepat
config = load_json(f'config/{app_name}.json')
# Tingkat 2: Cocokkan keluarga app (jika konfigurasi tepat tidak ada)
if not config:
family = app_name.split('_')[0] # 'amal_beta' → 'amal'
config = load_json(f'config/{family}.json')
# Tingkat 3: Default
if not config:
config = load_json('config/default.json')
Konfigurasi Per-Aplikasi (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
}
}
Resource Bersama vs Per-Aplikasi
| Resource | Bersama | Per-Aplikasi | Alasan |
|---|---|---|---|
| Kode Lambda | ✓ Ya | ✗ Tidak | Satu codebase dengan cabang berdasarkan APP_NAME |
| Instance RDS | ✓ Ya | ✗ Tidak (tabel diberi prefix) | Pengurangan biaya, backup tunggal |
| Konten S3 | ✗ Tidak | ✓ Ya | Setiap aplikasi memiliki kurikulum sendiri |
| AWS Cognito | ✓ Ya | ✗ Tidak (melalui app_id) | Autentikasi terpusat, pembeda dengan app_id |
| Analytics Lake | ✓ Ya | ✗ Tidak (dipartisi berdasarkan aplikasi) | Pipa data terpadu, data terpisah |
| Firebase Messaging | ✗ Tidak | ✓ Ya | APNs + FCM spesifik aplikasi |
Frontend: Arsitektur Multi-Aplikasi Flutter
Core Bersama (packages/alphazed_common)
- Manajemen state (Riverpod)
- Pengelolaan audio
- Perpustakaan animasi (integrasi Rive)
- Sistem desain (warna, tipografi, widget)
- Alur autentikasi
- Client analitik
Lapisan Spesifik Aplikasi (apps/amal, apps/thurayya, dll)
apps/
├── amal/
│ ├── lib/
│ │ ├── main.dart (titik masuk aplikasi)
│ │ ├── config/
│ │ │ ├── curriculum.json (struktur pelajaran Amal)
│ │ │ ├── colors.dart (tema Amal)
│ │ │ └── characters.json (kostumisasi avatar)
│ │ └── screens/ (layar khusus Amal)
│ └── pubspec.yaml (dependensi Amal)
│
├── thurayya/
│ ├── lib/
│ │ ├── main.dart (titik masuk berbeda)
│ │ ├── config/
│ │ │ ├── curriculum.json (struktur Juz Amma)
│ │ │ ├── colors.dart (tema Thurayya)
│ │ │ └── characters.json (kostumisasi avatar)
│ │ └── screens/ (layar khusus Thurayya)
│ └── pubspec.yaml (dependensi Thurayya)
│
└── packages/
└── alphazed_common/ (kode bersama)
Konfigurasi Saat Build
# Build Amal
flutter build apk --dart-define=APP_NAME=amal --dart-define=CURRICULUM=amal_v3
# Build Thurayya
flutter build apk --dart-define=APP_NAME=thurayya --dart-define=CURRICULUM=thurayya_juzamma
Pada saat build, setiap aplikasi mendapatkan data kurikulum, warna, dan konfigurasi yang tersimpan di dalamnya. Satu repositori kode, beberapa file biner hasil kompilasi.
Deployment: Stack Mandiri
Konfigurasi Serverless Framework
# serverless.yml
service: alphazed-backend
custom:
pythonRequirements:
dockerizePip: true
app_name: ${env:APP_NAME}
functions:
# Fungsi yang dideploy untuk setiap nilai 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:
# Setiap aplikasi memiliki grup log CloudWatch sendiri
${self:custom.app_name}LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /aws/lambda/alphazed-${self:custom.app_name}
RetentionInDays: 30
Saat melakukan deployment dengan APP_NAME=amal, CloudFormation membuat:
- Fungsi Lambda dengan prefix
alphazed-amal-* - Rute API Gateway di bawah
/amal/* - Log CloudWatch di
/aws/lambda/alphazed-amal - Skala dan monitoring mandiri
Mengapa Ini Penting
Untuk Tim Produk
- Peluncuran aplikasi baru: hitungan minggu bukan bulan (berbagi infrastruktur)
- Kesamaan fitur: perbaikan bug dan peningkatan algoritma langsung diterapkan ke semua aplikasi
- A/B testing: uji fitur di satu aplikasi sebelum meluas ke aplikasi lain
Untuk Tim Teknik
- Satu codebase: satu set tes dan pipeline CI/CD
- Algoritma pembelajaran terpusat: pengulangan bertahap dan pencampuran konten menguntungkan semua aplikasi
- Efisiensi operasional: satu tim mengelola semua infrastruktur
Untuk Biaya
- RDS bersama: sebagian kecil biaya dibandingkan 7 database terpisah
- Cognito bersama: satu penyedia autentikasi untuk semua aplikasi
- Analitik bersama: satu pipeline untuk 7 aplikasi
- Estimasi penghematan biaya: 40.000–60.000 USD per tahun dibandingkan backend terpisah
Tantangan dan Solusi
Tantangan 1: Konflik skema database
- Amal butuh tabel
amal_user_memory - Thurayya butuh
thurayya_user_memory(field berbeda untuk hafalan Quran) - Solusi: Migrasi aware aplikasi.
migrations/001_amal_user_memory.sqlhanya dijalankan saatAPP_NAME=amal
Tantangan 2: Set fitur berbeda
- Thurayya memiliki feedback tajweed, Amal tidak
- Amal ada game fisika, Thurayya tidak
- Solusi: Feature flag dalam konfigurasi (
enable_tajweed_feedback,enable_physics_games)
Tantangan 3: Skalabilitas mandiri
- Amal mengalami lonjakan traffic; Thurayya relatif sepi
- Pool Lambda bersama berarti mereka bersaing untuk concurrency
- Solusi: Kebijakan scaling CloudWatch per aplikasi. Jika Lambda
amal-*mencapai batas concurrency, auto-scale terpisah
FAQ
T: Apakah berbagi satu codebase menyebabkan coupling antar aplikasi?
J: Tidak. Kode tiap aplikasi terpisah di direktori berbeda (apps/amal, apps/thurayya). Kode bersama di packages/alphazed_common dan diperiksa versinya. Coupling ketat adalah bau desain yang kami tangani melalui review kode.
T: Bagaimana jika satu aplikasi butuh perubahan API breaking?
J: Kami versi API per aplikasi: /amal/v1/*, /thurayya/v1/*. Aplikasi dapat upgrade mandiri. Versi lama berjalan 12 bulan untuk memberi waktu update.
T: Apakah aplikasi bisa berbagi pengguna?
J: Tidak secara default. Masing-masing aplikasi punya tabel pengguna sendiri (diberi prefix). Jika orang tua ingin berlangganan Amal dan Thurayya, mereka harus buat akun terpisah (atau kami bisa tambahkan fitur pengaitan "keluarga" nanti).



