Update architecture and project conventions docs
This commit is contained in:
@@ -127,8 +127,9 @@ Last.fm schemas (separate, not Ecto-persisted to main DB):
|
||||
| `RecordChat` | Chat implementation for records (OpenAI streaming, web search enabled) |
|
||||
| `ArtistChat` | Chat implementation for artists (OpenAI streaming, uses Wikipedia/artist context) |
|
||||
| `Country` | Country code (alpha-2, alpha-3, subdivision, IETF) to flag emoji conversion |
|
||||
| `ErrorTracker.ErrorNotifier` | GenServer: attaches to ErrorTracker telemetry, throttles repeated errors, dispatches email notifications |
|
||||
| `ErrorTracker.ErrorNotifier` | GenServer: attaches to ErrorTracker telemetry, skips muted errors, throttles repeated errors, dispatches email notifications |
|
||||
| `ErrorTracker.ErrorNotifier.Email` | Builds and sends Swoosh error notification emails with stack trace formatting |
|
||||
| `ErrorIgnorer` | ErrorTracker.Ignorer implementation: filters non-actionable errors (e.g., NoRouteError from bot scanners) |
|
||||
| `RecordsOnThisDayEmail` | Builds and sends daily "records on this day" email with cover images, anniversary styling |
|
||||
| `MusicLibrary.Mailer` | Swoosh mailer (Mailgun in prod, local adapter in dev) |
|
||||
| `FormatNumber` | Number formatting utility |
|
||||
@@ -281,7 +282,7 @@ All authenticated routes live inside a single `live_session` with three `on_moun
|
||||
| Module | Purpose |
|
||||
|--------|---------|
|
||||
| `ErrorMessages` | Maps internal error terms (atoms, structs) to user-friendly gettext strings via `friendly_message/1` |
|
||||
| `Markdown` | Markdown-to-HTML conversion with `[[double bracket]]` link syntax |
|
||||
| `Markdown` | Markdown-to-HTML conversion (MDEx with ammonia sanitization) with `[[double bracket]]` link syntax |
|
||||
| `Duration` | Milliseconds to human-readable duration formatting |
|
||||
| `Auth` | Authentication plugs: login password check, API token validation, session enforcement |
|
||||
| `LiveHelpers.Params` | Pagination param parsing from URL query params |
|
||||
|
||||
@@ -56,6 +56,8 @@ Rules extracted from commit history that are specific to this project and not al
|
||||
- **User-facing error reasons use `ErrorMessages.friendly_message/1`** — never `inspect(reason)`. Call sites keep their contextual prefix (e.g. `gettext("Error refreshing cover")`) and append `": " <> ErrorMessages.friendly_message(reason)` for the reason part. `Logger.error` calls keep `inspect` for debugging.
|
||||
- **`handle_async` always handles three cases:** `{:ok, {:ok, result}}`, `{:ok, {:error, reason}}`, and `{:exit, reason}`.
|
||||
- **Data cascade on upstream changes:** When artist metadata changes, regenerate dependent record embeddings.
|
||||
- **Non-actionable errors use `ErrorTracker.Ignorer`** behaviour to filter (e.g., NoRouteError from bot scanners) rather than blocking paths in the endpoint.
|
||||
- **Muted errors skip notifications.** `ErrorTracker.ErrorNotifier` checks the `muted` flag before sending email notifications.
|
||||
|
||||
## Testing
|
||||
|
||||
@@ -71,6 +73,8 @@ Rules extracted from commit history that are specific to this project and not al
|
||||
- **Never leak sensitive data in prod.** `show_sensitive_data_on_connection_error: false`.
|
||||
- **Commits are small and single-purpose.** One logical change per commit.
|
||||
- **Unused aliases are removed** when their module is no longer referenced. Aliases stay alphabetically sorted.
|
||||
- **Markdown sanitization via MDEx (ammonia).** Use `Markdown.to_html/1` for user content. Annotate raw output with `# sobelow_skip ["XSS.Raw"]` and a comment explaining the sanitization.
|
||||
- **Sobelow runs on CI** in skip mode for security analysis.
|
||||
|
||||
## JavaScript
|
||||
|
||||
|
||||
Reference in New Issue
Block a user