76 lines
3.5 KiB
Ruby
76 lines
3.5 KiB
Ruby
# Eventos de notificação + assinatura por grupo.
|
|
#
|
|
# O ADM cadastra quantos eventos quiser, mas o GATILHO sai de uma lista fixa:
|
|
# gatilho é código. `manual` cobre o aviso pontual (botão "disparar agora") e
|
|
# `agendado` cobre o resumo periódico; os demais são pontos que o sistema já
|
|
# conhece (consolidação finalizada, pagamento efetuado, valor alterado, dados da
|
|
# operação mudaram).
|
|
#
|
|
# `sistema: true` marca os eventos que nascem com o app: podem ser editados e
|
|
# desligados, mas não apagados — apagar deixaria o código disparando no vazio.
|
|
class CreateNotificacaoEventos < ActiveRecord::Migration[7.1]
|
|
GATILHOS = %w[manual consolidacao_finalizada pagamento_efetuado
|
|
valor_alterado operacao_alterada agendado].freeze
|
|
|
|
def up
|
|
create_table :eventos_notificacao do |t|
|
|
t.string :nome, null: false
|
|
t.string :chave, null: false # slug estável usado pelo código
|
|
t.string :gatilho, null: false
|
|
t.string :descricao
|
|
t.boolean :ativo, null: false, default: true
|
|
t.boolean :sistema, null: false, default: false
|
|
|
|
# Avisar também a pessoa diretamente envolvida no fato (o motorista do
|
|
# pagamento), além dos grupos assinantes. É o comportamento de hoje.
|
|
t.boolean :notificar_envolvido, null: false, default: true
|
|
|
|
# Só para gatilho `agendado`.
|
|
t.string :frequencia # diaria | semanal
|
|
t.integer :hora, default: 8 # 0..23
|
|
t.integer :dia_semana # 0..6 (domingo=0), só na semanal
|
|
t.datetime :ultimo_disparo_em
|
|
|
|
t.timestamps
|
|
end
|
|
add_index :eventos_notificacao, :chave, unique: true
|
|
|
|
create_table :grupo_evento_assinaturas do |t|
|
|
# ⚠️ `to_table:` é OBRIGATÓRIO aqui. Com `foreign_key: true` o Rails
|
|
# PLURALIZA o nome da referência para achar a tabela alvo, e o Inflector
|
|
# não fala português: `grupo_contato` → "grupo_contatos" e
|
|
# `evento_notificacao` → "evento_notificacaos". As tabelas reais são
|
|
# `grupos_contato` e `eventos_notificacao` (plural no primeiro termo).
|
|
t.references :grupo_contato, null: false, foreign_key: { to_table: :grupos_contato }
|
|
t.references :evento_notificacao, null: false, foreign_key: { to_table: :eventos_notificacao }
|
|
t.string :canal, null: false, default: 'ambos' # ambos | whatsapp | email
|
|
t.boolean :ativo, null: false, default: true
|
|
t.timestamps
|
|
end
|
|
add_index :grupo_evento_assinaturas, %i[grupo_contato_id evento_notificacao_id],
|
|
unique: true, name: 'index_assinatura_grupo_evento_unico'
|
|
|
|
# Os dois eventos que o código JÁ dispara hoje, para nada parar de funcionar
|
|
# no deploy. SQL cru de propósito: migration não deve depender de model.
|
|
agora = 'NOW()'
|
|
[
|
|
['Pagamento fechado', 'consolidacao_finalizada', 'consolidacao_finalizada',
|
|
'Disparado quando uma consolidação é finalizada.'],
|
|
['Pagamento efetuado', 'pagamento_efetuado', 'pagamento_efetuado',
|
|
'Disparado quando o pagamento de um motorista é marcado como pago.']
|
|
].each do |nome, chave, gatilho, descricao|
|
|
execute(<<~SQL.squish)
|
|
INSERT INTO eventos_notificacao
|
|
(nome, chave, gatilho, descricao, ativo, sistema, notificar_envolvido, hora, created_at, updated_at)
|
|
VALUES (#{quote(nome)}, #{quote(chave)}, #{quote(gatilho)}, #{quote(descricao)},
|
|
true, true, true, 8, #{agora}, #{agora})
|
|
SQL
|
|
end
|
|
end
|
|
|
|
def down
|
|
drop_table :grupo_evento_assinaturas
|
|
drop_table :eventos_notificacao
|
|
end
|
|
end
|