Pular para conteúdo

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

  1. implemente em functions/src/<contexto>.js;
  2. exporte por functions/index.js;
  3. fixe região coerente com o projeto quando aplicável;
  4. valide auth antes de ler dados protegidos;
  5. normalize erros para HttpsError;
  6. adicione unit test; use Emulator quando o comportamento depender de Rules/transactions reais;
  7. 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 analyze nas áreas Dart/Flutter afetadas;
  • melos run test ou testes focados;
  • npm test em Functions quando backend mudar;
  • npm run test:emulator para Rules/concorrência relevante;
  • mkdocs build --strict se esta documentação mudar;
  • nenhum secret, credencial ou dado pessoal adicionado ao diff;
  • nenhuma regra antiga reintroduzida por copiar documentação histórica.