Skip to content

Core 645 generic alert types#2192

Merged
NoyaArie merged 3 commits intomasterfrom
core-645-generic-alert-types
Apr 16, 2026
Merged

Core 645 generic alert types#2192
NoyaArie merged 3 commits intomasterfrom
core-645-generic-alert-types

Conversation

@NoyaArie
Copy link
Copy Markdown
Contributor

@NoyaArie NoyaArie commented Apr 15, 2026


Open with Devin

Summary by CodeRabbit

  • Refactor

    • Simplified and standardized alert display names across all alert types.
    • Improved internal alert type architecture and system consistency for better code maintainability.
    • Enhanced alert processing and integration handling for increased robustness and consistency.
  • Tests

    • Added comprehensive unit tests verifying alert model properties and behavior contracts.

NoyaArie and others added 3 commits April 15, 2026 17:40
Widens the hard-coded three-way Union[TestAlertModel, ModelAlertModel,
SourceFreshnessAlertModel] to the common AlertModel base across alert
group, message builder, and integration APIs, and widens
PendingAlertSchema.data to BaseAlertDataSchema. Enables downstream
packages to extend the alert hierarchy (e.g. pipeline alerts) without
needing type: ignore workarounds.

No behavioral changes — type-level only. mypy passes and unit tests
are unaffected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removed by mistake in the previous commit. It's a class-level setting
that still affects other Union/Optional fields on the schema, so
keeping it preserves the pre-existing parsing behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tract

- AlertModel.asset_type: new mandatory @Property (NotImplementedError on base)
- AlertModel.concise_name: now raises NotImplementedError on base (was "Alert")
- TestAlertModel.asset_type -> "test"
- ModelAlertModel.asset_type -> "snapshot" | "model" (based on materialization)
- ModelAlertModel.concise_name -> self.alias (was "dbt {type} alert - {alias}")
- SourceFreshnessAlertModel.asset_type -> "source"
- SourceFreshnessAlertModel.concise_name -> "{source_name}.{identifier}"
  (was "source freshness alert - {source_name}.{identifier}")
- AlertMessageBuilder._get_run_alert_subtitle_blocks now consumes
  alert.asset_type / alert.concise_name instead of an isinstance chain,
  so downstream subclasses (e.g. pipeline alerts) work without edits here.
- Widened _get_run_alert_subtitle_block's `type` param from Literal to str.
- Added unit tests for asset_type/concise_name on every concrete subclass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@linear
Copy link
Copy Markdown

linear bot commented Apr 15, 2026

@github-actions
Copy link
Copy Markdown
Contributor

👋 @NoyaArie
Thank you for raising your pull request.
Please make sure to add tests and document all user-facing changes.
You can do this by editing the docs files in this pull request.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 15, 2026

📝 Walkthrough

Walkthrough

The pull request generalizes alert handling by introducing abstract concise_name and asset_type properties to the base Alert class, implementing them in concrete alert models, and simplifying type unions across messaging and integration modules to use the common AlertModel base type instead of explicit alert model class unions.

Changes

Cohort / File(s) Summary
Alert Base Class & Abstractions
elementary/monitor/alerts/alert.py
Made concise_name and new asset_type properties abstract, raising NotImplementedError in the base class.
Alert Model Implementations
elementary/monitor/alerts/model_alert.py, elementary/monitor/alerts/source_freshness_alert.py, elementary/monitor/alerts/test_alert.py
Added asset_type property implementations returning "model"/"snapshot", "source", and "test" respectively. Simplified concise_name to return core identifiers without alert-type prefixes.
Message Builder Type Simplification
elementary/monitor/alerts/alert_messages/builder.py
Replaced unions of specific alert model classes with AlertModel type in method signatures; removed runtime isinstance branching for deriving type and name attributes, now sourcing them directly from AlertModel properties.
Alerts Group Type Generalization
elementary/monitor/alerts/alerts_groups/alerts_group.py, elementary/monitor/alerts/alerts_groups/base_alerts_group.py
Updated type annotations to accept Sequence[AlertModel] instead of unions of specific alert model types; maintained runtime sorting and categorization logic.
Integration Handler Type Updates
elementary/monitor/data_monitoring/alerts/integrations/base_integration.py, elementary/monitor/data_monitoring/alerts/integrations/slack/slack.py
Simplified method parameter types across _get_alert_template, _get_fallback_template, send_alert, and related methods from unions with explicit alert classes to Union[AlertModel, GroupedByTableAlerts, BaseAlertsGroup].
Alert Data Schema Expansion
elementary/monitor/fetchers/alerts/schema/alert_data.py
Added optional resource_type: Optional[ResourceType] = None field to BaseAlertDataSchema.
Schema Field Generalization
elementary/monitor/fetchers/alerts/schema/pending_alerts.py
Changed PendingAlertSchema.data from a union of concrete alert data schemas to BaseAlertDataSchema.
API Type Annotation
elementary/monitor/api/alerts/alert_filters.py
Updated type-ignore comment from union-attr to attr-defined for improved clarity.
Data Monitoring Alerts
elementary/monitor/data_monitoring/alerts/data_monitoring_alerts.py
Simplified sent_successfully_alerts type annotation from a union of alert model types to List[AlertModel].
Alert Model Behavior Tests
tests/unit/monitor/alerts/test_alert_models.py
Added comprehensive unit tests for abstract property enforcement and concrete property implementations across all alert model types.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Alert types hop in harmony,
From scattered unions, now one base we see—
Asset types bloom, concise names take flight,
Generic types make the code clean and bright!
A refactor's grace, when abstractions align. 🌟

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Core 645 generic alert types' refers to the PR number and feature branch but does not clearly describe the main technical changes in the changeset. Revise the title to specifically describe the main change, such as 'Refactor alert types to use common AlertModel base class' or 'Generalize alert type hierarchy with abstract properties'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch core-645-generic-alert-types

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
elementary/monitor/alerts/alert_messages/builder.py (2)

100-110: Rename parameter type to avoid shadowing Python builtin.

The parameter type shadows Python's built-in type() function, flagged by Ruff (A002). While this works, it's a minor code quality issue that can cause confusion or unexpected behavior if the builtin is needed within this method.

♻️ Suggested rename
     def _get_run_alert_subtitle_block(
         self,
-        type: str,
+        asset_type: str,
         name: str,
         status: Optional[str] = None,
         detected_at_str: Optional[str] = None,
         suppression_interval: Optional[int] = None,
         env: Optional[str] = None,
         links: list[ReportLinkData] = [],
         orchestrator_info: Optional[OrchestratorInfo] = None,
     ) -> LinesBlock:
         summary = []
-        summary.append((type.capitalize() + ":", name))
+        summary.append((asset_type.capitalize() + ":", name))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@elementary/monitor/alerts/alert_messages/builder.py` around lines 100 - 110,
The parameter name "type" in _get_run_alert_subtitle_block shadows Python's
built-in; rename it (e.g., to alert_type) in the function signature and update
every reference inside the function body and any callers (tests or other
modules) to use the new name to avoid the Ruff A002 warning and potential
confusion; ensure imports/annotations (if any) and docstrings are adjusted
accordingly and run the test/lint suite to confirm no remaining references to
"type" remain in this context.

501-507: Type annotation inconsistency for model_errors parameter.

The model_errors parameter is typed as Sequence[AlertModel], but it will only ever receive ModelAlertModel instances from callers (e.g., AlertsGroup.model_errors is List[ModelAlertModel]). While this works at runtime, keeping it as Sequence[ModelAlertModel] would be more precise and self-documenting.

♻️ Suggested type refinement
     def _get_sub_alert_groups_blocks(
         self,
         test_errors: Sequence[AlertModel],
         test_warnings: Sequence[AlertModel],
         test_failures: Sequence[AlertModel],
-        model_errors: Sequence[AlertModel],
+        model_errors: Sequence[ModelAlertModel],
     ) -> List[MessageBlock]:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@elementary/monitor/alerts/alert_messages/builder.py` around lines 501 - 507,
The _get_sub_alert_groups_blocks method currently types the model_errors
parameter as Sequence[AlertModel]; change its annotation to
Sequence[ModelAlertModel] to reflect the actual objects passed in and improve
static typing; update any imports/typing in the file to reference
ModelAlertModel and adjust downstream usages/signatures that depend on this
parameter (e.g., callers or other helper functions) to ensure consistency with
the new Sequence[ModelAlertModel] annotation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@elementary/monitor/alerts/alert_messages/builder.py`:
- Around line 100-110: The parameter name "type" in
_get_run_alert_subtitle_block shadows Python's built-in; rename it (e.g., to
alert_type) in the function signature and update every reference inside the
function body and any callers (tests or other modules) to use the new name to
avoid the Ruff A002 warning and potential confusion; ensure imports/annotations
(if any) and docstrings are adjusted accordingly and run the test/lint suite to
confirm no remaining references to "type" remain in this context.
- Around line 501-507: The _get_sub_alert_groups_blocks method currently types
the model_errors parameter as Sequence[AlertModel]; change its annotation to
Sequence[ModelAlertModel] to reflect the actual objects passed in and improve
static typing; update any imports/typing in the file to reference
ModelAlertModel and adjust downstream usages/signatures that depend on this
parameter (e.g., callers or other helper functions) to ensure consistency with
the new Sequence[ModelAlertModel] annotation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 967c0987-72cf-4722-9719-eab1a4bba951

📥 Commits

Reviewing files that changed from the base of the PR and between c642a36 and 5d5032d.

📒 Files selected for processing (15)
  • elementary/monitor/alerts/alert.py
  • elementary/monitor/alerts/alert_messages/builder.py
  • elementary/monitor/alerts/alerts_groups/alerts_group.py
  • elementary/monitor/alerts/alerts_groups/base_alerts_group.py
  • elementary/monitor/alerts/model_alert.py
  • elementary/monitor/alerts/source_freshness_alert.py
  • elementary/monitor/alerts/test_alert.py
  • elementary/monitor/api/alerts/alert_filters.py
  • elementary/monitor/data_monitoring/alerts/data_monitoring_alerts.py
  • elementary/monitor/data_monitoring/alerts/integrations/base_integration.py
  • elementary/monitor/data_monitoring/alerts/integrations/slack/slack.py
  • elementary/monitor/fetchers/alerts/schema/alert_data.py
  • elementary/monitor/fetchers/alerts/schema/pending_alerts.py
  • tests/unit/monitor/alerts/__init__.py
  • tests/unit/monitor/alerts/test_alert_models.py

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

else:
dbt_type = "model"
return f"dbt {dbt_type} alert - {self.alias}"
return self.alias
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it a change in behavior for existing alerts?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the existing concise_name is used only for test alert

@property
def concise_name(self) -> str:
return f"source freshness alert - {self.source_name}.{self.identifier}"
return f"{self.source_name}.{self.identifier}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it a change in behavior for existing alerts?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the existing concise_name is used only for test alert

@NoyaArie NoyaArie merged commit e5af7e7 into master Apr 16, 2026
25 checks passed
@NoyaArie NoyaArie deleted the core-645-generic-alert-types branch April 16, 2026 11:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants