# Research — 099 Alerts v1 (Teams + Email) This document resolves the Phase 0 technical unknowns from the implementation plan. ## Decision: Delivery mechanism (Teams) - **Decision**: Use Laravel HTTP client (`Illuminate\Support\Facades\Http`) to POST JSON to a Teams incoming webhook URL. - **Rationale**: The repo already uses the Laravel HTTP client for remote calls (e.g., Microsoft Graph). It provides timeouts and structured error handling, and it keeps delivery logic self-contained. - **Alternatives considered**: - Guzzle direct client: unnecessary since Laravel HTTP client is already available. - Third-party Teams SDK: adds dependency surface; avoid without explicit need. ## Decision: Delivery mechanism (Email) - **Decision**: Use Laravel mail/notification delivery and queue it. - **Rationale**: Integrates with Laravel queue retries and provides a standard path for SMTP/mail providers. - **Alternatives considered**: - Direct SMTP calls: not aligned with framework patterns. ## Decision: Retry + backoff policy - **Decision**: Implement bounded retries using queued jobs with exponential backoff. - **Rationale**: Matches spec FR-017 and constitution guidance for transient failure handling. - **Alternatives considered**: - Retry loops inline: violates “start surfaces enqueue-only” and increases request latency. ## Decision: Secrets storage and redaction - **Decision**: Store destination configuration (webhook URL, recipient list) using Laravel encrypted casts (`encrypted` / `encrypted:array`), and ensure audit/log context is sanitized. - **Rationale**: The repo already uses encrypted casting for sensitive payloads (example: `ProviderCredential::$casts['payload' => 'encrypted:array']`). `WorkspaceAuditLogger` sanitizes metadata. - **Alternatives considered**: - Plaintext storage + hiding in UI: insufficient; secrets can leak to logs/DB dumps. ## Decision: Quiet-hours timezone fallback - **Decision**: 1) Use the rule’s `quiet_hours_timezone` when set. 2) Else use a workspace-level timezone setting. 3) If no workspace timezone exists yet, fallback to `config('app.timezone')`. - **Rationale**: Implements spec FR-009 while remaining robust if workspace timezone is not yet modeled as a first-class setting. - **Alternatives considered**: - Always `UTC`: contradicts the clarified requirement (workspace fallback). ## Notes / follow-ups - No existing mail delivery usage was found in `app/` at planning time; v1 will introduce the first alert-specific email delivery path. - No existing Teams webhook sender was found; v1 will implement a minimal sender using Laravel HTTP client.