# 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.
