# Data Model: Filter UX Standardization ## Overview This feature introduces no new persistent storage. It defines a conceptual model for how in-scope Filament resource lists are classified, standardized, and protected against drift. ## Entities ### FilterTier - Purpose: Classifies a resource list by rollout priority and required filter behavior. - Source: The feature spec’s Tier 1, Tier 2, and Tier 3 model. #### Fields | Field | Type | Required | Description | |-------|------|----------|-------------| | `tier_key` | enum(`tier_1`,`tier_2`,`tier_3`) | yes | Standard priority bucket for the list | | `criticality` | enum(`critical`,`important`,`standard`) | yes | Human-readable priority level | | `requires_persistence` | boolean | yes | Whether search, sort, and filter state must persist | | `requires_core_filters` | boolean | yes | Whether domain-appropriate filters are mandatory | | `requires_date_range_when_time_based` | boolean | yes | Whether time-series lists in the tier must expose date range | | `notes` | string nullable | no | Explanatory notes for exceptions or optional scope | #### Validation Rules - Tier 1 and Tier 2 must set `requires_persistence` to true. - Tier 3 must remain optional unless elevated by a later spec. ### ResourceFilterProfile - Purpose: Represents the agreed filter contract for one resource list. - Source: Existing Filament resource tables such as `FindingResource`, `PolicyVersionResource`, `AlertDeliveryResource`, and peers. #### Fields | Field | Type | Required | Description | |-------|------|----------|-------------| | `resource_class` | string | yes | Backing Filament resource class | | `route_scope` | enum(`tenant`,`workspace`,`canonical_view`) | yes | Scope model used by the resource list | | `data_ownership` | enum(`tenant_owned`,`workspace_owned`,`mixed`) | yes | Ownership context of listed records | | `tier` | reference `FilterTier` | yes | Required behavior level | | `has_filters` | boolean | yes | Whether the list exposes at least one filter | | `has_persistence_trio` | boolean | yes | Whether filters, search, and sort persist in session | | `supports_soft_delete` | boolean | yes | Whether the resource is soft deletable | | `uses_standard_archived_filter` | boolean | yes | Whether the standard archive filter is present | | `uses_central_status_source` | boolean | yes | Whether prioritized status/outcome filters derive from a central source | | `has_date_range_filter` | boolean | yes | Whether the list exposes a date-range filter | | `date_range_column` | string nullable | no | Primary time column used for the filter | | `default_filter_behavior` | string nullable | no | Optional smart default such as open-only or active-only | | `query_risk` | enum(`low`,`medium`,`high`) | yes | Risk level for added filter/query complexity | | `exception_reason` | string nullable | no | Required when the standard is intentionally not fully applied | #### Validation Rules - If `tier` is Tier 1 or Tier 2 and `has_filters` is true, `has_persistence_trio` must be true. - If `supports_soft_delete` is true, `uses_standard_archived_filter` must be true unless `exception_reason` is populated. - If the list is time-based and in Tier 1 or Tier 2, `has_date_range_filter` must be true unless `exception_reason` is populated. ### FilterDimension - Purpose: Describes one business-relevant filter dimension on a list. #### Fields | Field | Type | Required | Description | |-------|------|----------|-------------| | `dimension_key` | string | yes | Stable filter identifier such as `status`, `outcome`, `platform`, or `date_range` | | `filter_type` | enum(`select`,`trashed`,`ternary`,`custom`,`date_range`) | yes | Native Filament filter type | | `label` | string | yes | User-facing label | | `source_type` | enum(`enum`,`catalog`,`model_constant`,`query_distinct`,`custom_query`) | yes | Origin of the filter options or behavior | | `is_priority_dimension` | boolean | yes | Whether this is a core required filter for the list | | `has_indicator_support` | boolean | yes | Whether active filter indicators appear in the summary UI | | `query_cost` | enum(`low`,`medium`,`high`) | yes | Estimated cost of applying the filter | #### Validation Rules - `date_range` filters must set `has_indicator_support` to true. - `status` and `outcome` dimensions on prioritized resources should use `enum` or `catalog` source types where possible. ### CentralOptionSource - Purpose: Represents the shared vocabulary source used by a filter dimension. #### Fields | Field | Type | Required | Description | |-------|------|----------|-------------| | `source_key` | string | yes | Identifier such as `BaselineProfileStatus`, `BadgeDomain::FindingStatus`, or `TagBadgeDomain::Platform` | | `source_kind` | enum(`enum`,`badge_catalog`,`tag_badge_catalog`,`config_registry`,`static_helper`) | yes | Kind of central option source | | `provides_labels` | boolean | yes | Whether the source exposes user-facing labels | | `provides_ordering` | boolean | yes | Whether the source defines preferred option order | | `requires_adapter` | boolean | yes | Whether a thin helper is needed to convert the source into filter options | #### Notes - `BaselineProfileStatus` is already an enum-backed source. - `FindingStatus` and `AlertDeliveryStatus` currently have centralized badge semantics but may need a thin adapter to become filter option sources cleanly. - Policy type and platform labels may continue to come from existing config or tag-badge catalogs. ### FilterGuardRule - Purpose: Defines one regression rule enforced in tests. #### Fields | Field | Type | Required | Description | |-------|------|----------|-------------| | `rule_key` | string | yes | Stable guard identifier | | `rule_type` | enum(`persistence`,`archive_visibility`,`central_status_source`,`functional_behavior`,`scope_safety`) | yes | What the rule protects | | `coverage_level` | enum(`static_guard`,`livewire_behavior`,`feature_scope`) | yes | Test style used to enforce the rule | | `applies_to` | list | yes | Resource classes or test targets covered | | `failure_mode` | string | yes | What kind of regression this rule should catch | ## Relationships - One `FilterTier` applies to many `ResourceFilterProfile` records. - One `ResourceFilterProfile` contains many `FilterDimension` definitions. - One `FilterDimension` may depend on one `CentralOptionSource`. - One `FilterGuardRule` may protect many `ResourceFilterProfile` records. ## State Transitions - Audit: Record the current `ResourceFilterProfile` for each in-scope list. - Standardization: Add missing persistence, archive visibility, date-range filters, and essential dimensions. - Alignment: Swap prioritized local status arrays for central option sources or thin adapters. - Guarding: Extend `FilterGuardRule` coverage so the standardized state cannot drift silently. ## Notes - No migrations, new tables, or new Eloquent models are required. - This conceptual model exists to support planning, implementation sequencing, and regression protection.