A Alphazed opera mais de 7 aplicativos educacionais (Amal, Thurayya, Qais, KidElite, Alphazed School, Alphazed Montessori e outros) a partir de um único código backend e uma estrutura móvel Flutter compartilhada. Cada aplicativo possui suas próprias tabelas de banco de dados (com prefixo), configuração, notificações push, modelos de email e conteúdo — mas compartilham autenticação (AWS Cognito), infraestrutura de análise e algoritmos centrais de aprendizagem.
Backend: Seleção do App em Tempo de Execução
Como Funciona
No momento do deploy, uma variável de ambiente seleciona o app:
# Deploy Amal
export APP_NAME=amal
serverless deploy
Deploy Thurayya
export APP_NAME=thurayya
serverless deploy
Deploy Qais
export APP_NAME=qais
serverless deploy
Cada implantação cria funções Lambda independentes, rotas API Gateway e monitoramento — mas todas se conectam ao mesmo código backend.
Prioridade de Configuração em Três Camadas
# src/config.py
import os
app_name = os.getenv('APP_NAME', 'amal')
Camada 1: Configuração exata do app
config = load_json(f'config/{app_name}.json')
Camada 2: Configuração da família do app (se não existir configuração exata)
if not config:
family = app_name.split('_')[0] # 'amal_beta' → 'amal'
config = load_json(f'config/{family}.json')
Camada 3: Configuração padrão
if not config:
config = load_json('config/default.json')
Configuração por App (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": "Equipe Amal"
},
"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
}
}
Recursos Compartilhados vs Por App
| Recurso | Compartilhado | Por App | Razão |
|---|---|---|---|
| Código Lambda | ✓ Sim | ✗ Não | Código único, ramificação via APP_NAME |
| Instância RDS | ✓ Sim | ✗ Não (tabelas com prefixo) | Redução de custo, backup único |
| Conteúdo S3 | ✗ Não | ✓ Sim | Cada app tem seu próprio currículo |
| AWS Cognito | ✓ Sim | ✗ Não (via app_id) | Autenticação central, app_id diferencia |
| Lago de Analytics | ✓ Sim | ✗ Não (particionado por app) | Pipeline unificado, dados segregados |
| Mensagens Firebase | ✗ Não | ✓ Sim | APNs + FCM específicos do app |
Frontend: Arquitetura Multi-App Flutter
Core Compartilhado (packages/alphazed_common)
- Gerenciamento de estado (Riverpod)
- Manipulação de áudio
- Biblioteca de animações (integração Rive)
- Sistema de design (cores, tipografia, widgets)
- Fluxos de autenticação
- Cliente de analytics
Camadas Específicas de Apps (apps/amal, apps/thurayya, etc.)
apps/
├── amal/
│ ├── lib/
│ │ ├── main.dart (ponto de entrada do app)
│ │ ├── config/
│ │ │ ├── curriculum.json (estrutura das aulas do Amal)
│ │ │ ├── colors.dart (tema do Amal)
│ │ │ └── characters.json (customização de avatar)
│ │ └── screens/ (telas específicas do Amal)
│ └── pubspec.yaml (dependências do Amal)
│
├── thurayya/
│ ├── lib/
│ │ ├── main.dart (entrada diferente)
│ │ ├── config/
│ │ │ ├── curriculum.json (estrutura do Juz Amma)
│ │ │ ├── colors.dart (tema do Thurayya)
│ │ │ └── characters.json (customização de avatar)
│ │ └── screens/ (telas específicas do Thurayya)
│ └── pubspec.yaml (dependências do Thurayya)
│
└── packages/
└── alphazed_common/ (código compartilhado)
Configuração na Hora da 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
Na build, cada app recebe seus dados de currículo, cores e configuração incorporados. Um único repositório de código, múltiplos binários compilados.
Implantação: Stacks Independentes
Configuração do Serverless Framework
# serverless.yml
service: alphazed-backend
custom:
pythonRequirements:
dockerizePip: true
app_name: ${env:APP_NAME}
functions:
Funções implantadas para cada valor 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:
# Cada app tem seu próprio grupo de logs CloudWatch
${self:custom.app_name}LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /aws/lambda/alphazed-${self:custom.app_name}
RetentionInDays: 30
Ao implantar com APP_NAME=amal, o CloudFormation cria:
- Funções Lambda prefixadas
alphazed-amal-* - Rotas API Gateway em
/amal/* - Logs CloudWatch em
/aws/lambda/alphazed-amal - Escalabilidade e monitoramento independentes
Por Que Isso É Importante
Para Times de Produto
- Lançar novo app em semanas, não meses (infrastrutura compartilhada)
- Paridade de recursos: correções e melhorias aplicadas em todos os apps instantaneamente
- Teste A/B fácil em um app antes de liberar para os demais
Para Engenharia
- Código único: um conjunto de testes, uma pipeline CI/CD
- Algoritmos de aprendizagem compartilhados: repetição espaçada e mistura de conteúdo beneficiam todos os apps
- Eficiência operacional: um time para toda infraestrutura
Para Custo
- RDS compartilhado: fração do custo de 7 bancos de dados independentes
- Cognito compartilhado: um provedor de autenticação para todos apps
- Analytics unificado para os 7 apps
- Economia estimada: US$ 40.000-60.000 por ano comparado a backends separados
Desafios e Soluções
Desafio 1: Conflito no esquema do banco de dados
- Amal precisa da tabela amal_user_memory
- Thurayya precisa da tabela thurayya_user_memory (com campos diferentes para memorização do Alcorão)
- Solução: migrações conscientes do app. migrations/001_amal_user_memory.sql roda apenas se APP_NAME=amal
Desafio 2: Diferentes conjuntos de recursos
- Thurayya possui feedback de tajweed; Amal não
- Amal tem jogos de física; Thurayya não
- Solução: flags de recursos na configuração (enable_tajweed_feedback, enable_physics_games)
Desafio 3: Escalabilidade independente
- Amal tem pico de tráfego; Thurayya está calma
- Lambda compartilhado compete pelo limite de concorrência
- Solução: políticas de escalonamento CloudWatch por app. Se Lambdas amal-* atingem limite, escalam automaticamente
Perguntas Frequentes
P: Compartilhar um código só não cria dependência entre apps?
R: Não. O código de cada app fica em diretórios separados (apps/amal, apps/thurayya). O código compartilhado está em packages/alphazed_common, com versionamento explícito. Dependência excessiva seria um problema detectado nas revisões.
P: E se um app precisar de uma mudança pesada na API?
R: Versionamos APIs por app: /amal/v1/*, /thurayya/v1/*. Apps atualizam independentemente. Versões antigas rodam por 12 meses para dar tempo de adaptação.
P: Os apps podem compartilhar usuários?
R: Por padrão não. Cada app tem sua própria tabela de usuários (com prefixo). Se um responsável quiser assinar Amal e Thurayya, cria contas separadas (ou podemos adicionar um recurso de “família” para vincular depois).



