Desenvolvimento e extensão¶
Adicionar uma feature de domínio¶
Use o fluxo abaixo como padrão quando a feature atravessa UI, regra e persistência:
flowchart LR
E[Entity / Value Object] --> C[Repository contract]
C --> U[Use case]
C --> RI[Repository impl]
RI --> DB[Firestore / Function]
U --> B[Cubit / Bloc]
B --> UI[Screen / Widget]
1. Domain¶
Crie/estenda entidade e contrato em packages/aivaleu_domain. Evite imports de Flutter/Firebase.
2. Data¶
Mapeie dados persistidos em aivaleu_data. Se a operação precisa de segredo, claim confiável, atomicidade entre documentos ou autoridade global, use uma Cloud Function em vez de write direto.
3. DI¶
Registre repository/use case no container do app consumidor. Não assuma que os três apps compartilham o mesmo GetIt: cada aplicação possui composição própria.
4. Presentation¶
Cubit/Bloc converte o resultado do domínio em estado de UI. Widgets não devem calcular cooldown, role, curadoria ou quota como fonte final de verdade.
5. Segurança e índices¶
Toda nova mutação Firestore deve responder:
- quem pode executá-la?
- o cliente precisa escrever direto?
- quais campos são imutáveis?
- existe concorrência que exige transaction?
- a query precisa de índice composto?
Atualize firestore.rules, storage.rules e firestore.indexes.json quando aplicável.
Adicionar uma Cloud Function¶
- implemente em
functions/src/<contexto>.js; - exporte por
functions/index.js; - fixe região coerente com o projeto quando aplicável;
- valide auth antes de ler dados protegidos;
- normalize erros para
HttpsError; - adicione unit test; use Emulator quando o comportamento depender de Rules/transactions reais;
- documente payload/efeitos se a Function for consumida por outro módulo.
Evite confiar em partnerId, role ou autoria enviados pelo cliente sem resolver a identidade real no backend.
Alterar o feed¶
O contrato mais estável para o app é a lista ordenada de offerIds. Uma estratégia nova pode mudar score internamente, mas deve preservar:
- autenticação;
- elegibilidade segura;
algorithmVersion;- ordem explícita;
- quota de oferta;
- fallback tolerável no repository.
Alterar quota de cupons¶
Não use apenas FieldValue.increment() fora de transaction. Reaproveite os helpers de coupon_usage_limit.js para garantir que a última vaga não seja consumida duas vezes.
Alterar autorização¶
Mudanças de UX e guard não bastam. Atualize/teste Rules ou a Function responsável. Para Super Admin, a fonte de verdade é a custom claim; para partner, a propriedade é derivada de owner_uid e partner_id.
Documentação sincronizada¶
Se a implementação alterar regra de negócio, entidade, fluxo, tela, permissão, Cloud Function, schema ou Remote Config, atualize a documentação técnica e o context/ ativo que descreve aquela decisão. Não deixe um documento histórico contraditório parecer vigente.
Checklist antes do PR¶
melos run analyzenas áreas Dart/Flutter afetadas;melos run testou testes focados;npm testem Functions quando backend mudar;npm run test:emulatorpara Rules/concorrência relevante;mkdocs build --strictse esta documentação mudar;- nenhum secret, credencial ou dado pessoal adicionado ao diff;
- nenhuma regra antiga reintroduzida por copiar documentação histórica.