Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ As versões do produto seguem as [regras de release](docs/releases.md). O histó

## [Unreleased]

### Changed

- Novos usuários passam a iniciar com resumos semanais e mensais desativados, preservando as preferências existentes.
- A confirmação do vínculo Telegram explica como consultar e ativar cada resumo com `/alertas`.

### Tests

- Adicionada cobertura para o padrão opt-in dos resumos, preservação das preferências na reconexão e orientação após o vínculo.

## [v1.10.1] — 2026-09-16

### Changed
Expand Down
8 changes: 7 additions & 1 deletion docs/alerts.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ No Telegram:
- `/alertas semanal ligar|desligar`: controlar somente o resumo semanal.
- `/alertas mensal ligar|desligar`: controlar somente o resumo mensal.

As preferências existentes começam ativadas. A geração respeita cada opção;
Novos usuários começam com os resumos semanal e mensal desativados e escolhem
explicitamente se desejam recebê-los. Alertas financeiros permanecem ativados
por padrão e podem ser controlados separadamente. A migration V16 altera apenas
o padrão de novas inserções; não modifica as preferências já persistidas. Ao
vincular o Telegram, o bot apresenta os comandos de consulta e ativação.

A geração respeita cada opção;
a reserva de entrega verifica novamente preferências, vínculo Telegram,
expiração e configuração global. Uma alteração não cancela uma chamada ao
Telegram que já começou. Desativação ou desvinculação antes da reserva cancela
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,16 @@ public String formatConnectInstructionsMessage() { return """
<code>/connect FIN-ABC123</code>
"""; }

public String formatConnectSuccessMessage(String message) { return escapeHtml(defaultText(message)); }
public String formatConnectSuccessMessage(String message) {
return """
%s

🔔 <b>Resumos automáticos são opcionais.</b>
Consulte suas preferências com <code>/alertas</code>.
Para ativar, use <code>/alertas semanal ligar</code> ou <code>/alertas mensal ligar</code>.
Você pode alterar essas opções quando quiser.
""".formatted(escapeHtml(defaultText(message))).strip();
}

public String formatDisconnectSuccessMessage() { return """
✅ <b>Sua conta do Telegram foi desconectada com sucesso.</b>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.mockito.junit.jupiter.MockitoExtension;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import com.financebot.telegrambot.dto.response.TelegramLinkConfirmResponse;

@ExtendWith(MockitoExtension.class)
class TelegramAlertPreferencesHandlerTest {
Expand Down Expand Up @@ -60,4 +61,16 @@ void backendFailureIsExplainedWithoutPretendingPreferencesChanged() {
assertThat(handler.handleAlerts("/alertas desligar", 123L)).contains("Não foi possível");
verify(client, never()).updateAlertPreferences(anyLong(), any());
}

@Test
void successfulConnectionExplainsHowToChooseAutomaticSummaries() {
when(client.confirmTelegramLink(any())).thenReturn(
new TelegramLinkConfirmResponse(true, "Conta conectada com sucesso ao Telegram."));
when(formatter.formatConnectSuccessMessage(anyString())).thenCallRealMethod();

String response = handler.handleConnect("/conectar FIN-ABC123", 123L, "bryan");

assertThat(response).contains("Resumos automáticos são opcionais", "/alertas",
"/alertas semanal ligar", "/alertas mensal ligar");
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/financebot/user/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ public class User implements UserDetails {
private boolean financialAlertsEnabled = true;

@Column(name = "weekly_summary_enabled", nullable = false)
private boolean weeklySummaryEnabled = true;
private boolean weeklySummaryEnabled = false;

@Column(name = "monthly_summary_enabled", nullable = false)
private boolean monthlySummaryEnabled = true;
private boolean monthlySummaryEnabled = false;

@Column(name = "telegram_link_code", length = 30)
private String telegramLinkCode;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE users ALTER COLUMN weekly_summary_enabled SET DEFAULT FALSE;
ALTER TABLE users ALTER COLUMN monthly_summary_enabled SET DEFAULT FALSE;
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ void setup() {
analysis, notifications, Clock.fixed(Instant.parse("2026-09-15T09:00:00Z"), ZoneOffset.UTC));
ReflectionTestUtils.setField(scheduler, "alertsEnabled", true);
user = new User(); user.setId(1L); user.setTelegramId(123L);
user.setFinancialAlertsEnabled(true);
user.setWeeklySummaryEnabled(true);
user.setMonthlySummaryEnabled(true);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,16 @@ void shouldConfirmTelegramLinkSuccessfully() {
assertThat(savedUser.getTelegramId()).isEqualTo(987654L);
assertThat(savedUser.getTelegramLinkCode()).isNull();
assertThat(savedUser.getTelegramLinkCodeExpiresAt()).isNull();
assertThat(savedUser.isWeeklySummaryEnabled()).isFalse();
assertThat(savedUser.isMonthlySummaryEnabled()).isFalse();
}

@Test
@DisplayName("deve retornar sucesso quando Telegram ja estava vinculado ao mesmo usuario")
void shouldReturnSuccessWhenTelegramWasAlreadyLinkedToSameUser() {
User user = buildUser();
user.setWeeklySummaryEnabled(true);
user.setMonthlySummaryEnabled(true);
user.setTelegramId(987654L);
user.setTelegramLinkCode("FIN-ABC123");
user.setTelegramLinkCodeExpiresAt(LocalDateTime.now().plusMinutes(5));
Expand All @@ -251,6 +255,8 @@ void shouldReturnSuccessWhenTelegramWasAlreadyLinkedToSameUser() {
assertThat(savedUser.getTelegramId()).isEqualTo(987654L);
assertThat(savedUser.getTelegramLinkCode()).isNull();
assertThat(savedUser.getTelegramLinkCodeExpiresAt()).isNull();
assertThat(savedUser.isWeeklySummaryEnabled()).isTrue();
assertThat(savedUser.isMonthlySummaryEnabled()).isTrue();

verify(userRepository, never()).existsByTelegramId(anyLong());
}
Expand Down Expand Up @@ -389,4 +395,4 @@ private User buildUser() {
user.setOnboardingCompleted(false);
return user;
}
}
}
Loading