Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions specs/planning/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Ash UI Architecture Execution Plan Index

This directory contains a phased implementation plan for executing the Ash UI architecture baseline aligned with the unified-ui ecosystem.

The plan aligns to:
- `rfcs/RFC-0002-ash-ui-unified-integration.md`
- `specs/topology.md`
- `specs/contracts/*`
- `specs/conformance/*`

## Phase Files
1. [Phase 1 - Core Ash Resource Integration](./phase-01-core-ash-resource-integration.md): implement Ash Resources for storing unified-ui DSL definitions with Ash actions and policies.
2. [Phase 2 - IUR Adapter and Canonical Conversion](./phase-02-iur-adapter-and-canonical-conversion.md): implement Ash IUR to canonical unified_iur conversion.
3. [Phase 3 - Data Binding and Signal Mapping](./phase-03-data-binding-and-signal-mapping.md): implement Ash resource data binding to unified-ui signals.
4. [Phase 4 - Runtime and LiveView Integration](./phase-04-runtime-and-liveview-integration.md): implement LiveView mount/unmount and screen lifecycle.
5. [Phase 5 - Authorization and Policy Enforcement](./phase-05-authorization-and-policy-enforcement.md): implement Ash policy integration for UI access control.
6. [Phase 6 - Compiler and DSL Integration](./phase-06-compiler-and-dsl-integration.md): integrate unified-ui compiler with Ash Resource loading.
7. [Phase 7 - Renderer Package Integration](./phase-07-renderer-package-integration.md): implement live_ui/web_ui/desktop_ui package integration.
8. [Phase 8 - Governance Gates and Release Readiness](./phase-08-governance-gates-and-release-readiness.md): finalize CI gates, conformance tests, and rollout readiness.

## Shared Conventions
- Numbering:
- Phases: `N`
- Sections: `N.M`
- Tasks: `N.M.K`
- Subtasks: `N.M.K.L`
- Tracking:
- Every phase, section, task, and subtask uses Markdown checkboxes (`[ ]`).
- Description requirement:
- Every phase, section, and task starts with a short description paragraph.
- Integration-test requirement:
- Each phase ends with a final integration-testing section.

## Shared Assumptions and Defaults
- Ash UI remains an Ash Framework integration layer for unified-ui
- UI definitions are stored as Ash Resources in the database
- unified-ui packages provide widgets, layouts, compilation, and rendering
- Ash policies control access to UI resources
- Data flows from Ash resources → Ash IUR → canonical IUR → renderer output
172 changes: 172 additions & 0 deletions specs/planning/phase-01-core-ash-resource-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# Phase 1 - Core Ash Resource Integration

Back to index: [README](./README.md)

## Relevant Shared APIs / Interfaces
- `AshUI.Resource`
- `AshUI.Resource.DSL`
- `Ash.Resource`
- `Ash.Domain`
- `Ash.DataLayer`
- `Ash.Query`

## Relevant Assumptions / Defaults
- UI definitions are stored as Ash Resources with PostgreSQL data layer
- unified-ui DSL is stored as a map attribute on Ash Resources
- Ash actions provide CRUD operations on UI definitions
- Ash policies authorize UI access and modification

[ ] 1 Phase 1 - Core Ash Resource Integration
Implement Ash Resources for storing unified-ui DSL definitions with database persistence, Ash actions, and policy-based authorization.

[ ] 1.1 Section - UI Screen Resource
Implement the UI.Screen Ash Resource for storing unified-ui screen definitions.

[ ] 1.1.1 Task - Define UI.Screen resource schema
Create the Ash Resource for screen definitions with unified-ui DSL storage.

[ ] 1.1.1.1 Subtask - Implement `AshUI.Screen` resource with `use Ash.Resource`
[ ] 1.1.1.2 Subtask - Add `id` (UUID primary key), `name` (string), `unified_dsl` (map) attributes
[ ] 1.1.1.3 Subtask - Add `layout` (atom), `route` (string), `metadata` (map) attributes
[ ] 1.1.1.4 Subtask - Add `version` (integer) for optimistic locking and timestamps
[ ] 1.1.1.5 Subtask - Configure `AshPostgres.DataLayer` with `table: "ui_screens"`

[ ] 1.1.2 Task - Define UI.Screen actions
Implement standard Ash actions for screen CRUD operations.

[ ] 1.1.2.1 Subtask - Add default actions: `:read`, `:create`, `:update`, `:destroy`
[ ] 1.1.2.2 Subtask - Implement `:mount` action with `user_id` and `params` arguments
[ ] 1.1.2.3 Subtask - Implement `:unmount` action for cleanup
[ ] 1.1.2.4 Subtask - Add action return types and error handling

[ ] 1.1.3 Task - Define UI.Screen relationships
Establish relationships to elements and bindings.

[ ] 1.1.3.1 Subtask - Add `has_many :elements` relationship to `AshUI.Element`
[ ] 1.1.3.2 Subtask - Add `has_many :bindings` relationship to `AshUI.Binding`
[ ] 1.1.3.3 Subtask - Configure cascade delete for child elements and bindings

[ ] 1.1.4 Task - Add UI.Screen DSL extension
Create the `ui_screen` DSL block for screen-specific configuration.

[ ] 1.1.4.1 Subtask - Implement `AshUI.Resource.DSL.Screen` extension
[ ] 1.1.4.2 Subtask - Add `layout/1`, `route/1`, `metadata/1` DSL functions
[ ] 1.1.4.3 Subtask - Validate DSL options at compile time
[ ] 1.1.4.4 Subtask - Store DSL options in resource attributes

[ ] 1.2 Section - UI Element Resource
Implement the UI.Element Ash Resource for storing unified-ui element definitions.

[ ] 1.2.1 Task - Define UI.Element resource schema
Create the Ash Resource for element definitions with unified-ui widget storage.

[ ] 1.2.1.1 Subtask - Implement `AshUI.Element` resource with `use Ash.Resource`
[ ] 1.2.1.2 Subtask - Add `id` (UUID), `type` (atom), `props` (map) attributes
[ ] 1.2.1.3 Subtask - Add `variants` (list of atoms), `position` (integer) attributes
[ ] 1.2.1.4 Subtask - Add `metadata` (map) and timestamps
[ ] 1.2.1.5 Subtask - Configure `AshPostgres.DataLayer` with `table: "ui_elements"`

[ ] 1.2.2 Task - Define UI.Element relationships
Establish relationships to screen and bindings.

[ ] 1.2.2.1 Subtask - Add `belongs_to :screen` relationship to `AshUI.Screen`
[ ] 1.2.2.2 Subtask - Add `has_many :bindings` relationship to `AshUI.Binding`
[ ] 1.2.2.3 Subtask - Add foreign key `screen_id` attribute

[ ] 1.2.3 Task - Add UI.Element DSL extension
Create the `ui_element` DSL block for element-specific configuration.

[ ] 1.2.3.1 Subtask - Implement `AshUI.Resource.DSL.Element` extension
[ ] 1.2.3.2 Subtask - Add `type/1`, `props/1`, `variants/1` DSL functions
[ ] 1.2.3.3 Subtask - Validate `type` against known unified-ui widget types
[ ] 1.2.3.4 Subtask - Store element definition in resource attributes

[ ] 1.3 Section - UI Binding Resource
Implement the UI.Binding Ash Resource for data binding definitions.

[ ] 1.3.1 Task - Define UI.Binding resource schema
Create the Ash Resource for binding Ash data to UI elements.

[ ] 1.3.1.1 Subtask - Implement `AshUI.Binding` resource with `use Ash.Resource`
[ ] 1.3.1.2 Subtask - Add `id` (UUID), `source` (string), `target` (string) attributes
[ ] 1.3.1.3 Subtask - Add `binding_type` (atom), `transform` (map) attributes
[ ] 1.3.1.4 Subtask - Add `metadata` (map) and timestamps
[ ] 1.3.1.5 Subtask - Configure `AshPostgres.DataLayer` with `table: "ui_bindings"`

[ ] 1.3.2 Task - Define UI.Binding relationships
Establish relationships to element and screen.

[ ] 1.3.2.1 Subtask - Add `belongs_to :element` relationship to `AshUI.Element`
[ ] 1.3.2.2 Subtask - Add `belongs_to :screen` relationship to `AshUI.Screen`
[ ] 1.3.2.3 Subtask - Add foreign keys `element_id` and `screen_id`

[ ] 1.3.3 Task - Add UI.Binding DSL extension
Create the `ui_binding` DSL block for binding configuration.

[ ] 1.3.3.1 Subtask - Implement `AshUI.Resource.DSL.Binding` extension
[ ] 1.3.3.2 Subtask - Add `source/1`, `target/1`, `binding_type/1` DSL functions
[ ] 1.3.3.3 Subtask - Add `transform/1` DSL function for transformations
[ ] 1.3.3.4 Subtask - Validate binding type is one of `:value`, `:list`, `:action`

[ ] 1.4 Section - Ash Domain Configuration
Implement the AshUI domain with all resources and authorization.

[ ] 1.4.1 Task - Create AshUI.Domain
Define the domain containing all Ash UI resources.

[ ] 1.4.1.1 Subtask - Implement `AshUI.Domain` with `use Ash.Domain`
[ ] 1.4.1.2 Subtask - Register `AshUI.Screen`, `AshUI.Element`, `AshUI.Binding` resources
[ ] 1.4.1.3 Subtask - Configure domain-level authorization with `Ash.Policy.Authorizer`

[ ] 1.4.2 Task - Configure resource validations
Add validations for UI resource attributes.

[ ] 1.4.2.1 Subtask - Validate `unified_dsl` is a valid map structure
[ ] 1.4.2.2 Subtask - Validate `binding_type` is in allowed list
[ ] 1.4.2.3 Subtask - Validate `source` format matches Ash resource paths
[ ] 1.4.2.4 Subtask - Add custom validations with `validate/1`

[ ] 1.5 Section - Database Migrations
Create Ecto migrations for UI resource tables.

[ ] 1.5.1 Task - Generate migration files
Create Ecto migrations for all UI resource tables.

[ ] 1.5.1.1 Subtask - Generate migration for `ui_screens` table
[ ] 1.5.1.2 Subtask - Generate migration for `ui_elements` table
[ ] 1.5.1.3 Subtask - Generate migration for `ui_bindings` table
[ ] 1.5.1.4 Subtask - Add foreign key constraints and indexes

[ ] 1.5.2 Task - Add unique constraints and indexes
Optimize queries with proper indexes.

[ ] 1.5.2.1 Subtask - Add unique index on `ui_screens.name`
[ ] 1.5.2.2 Subtask - Add index on `ui_elements.screen_id`
[ ] 1.5.2.3 Subtask - Add composite index on `ui_bindings.element_id` and `screen_id`

[ ] 1.6 Section - Phase 1 Integration Tests
Validate Ash Resource CRUD, relationships, and DSL behavior end-to-end.

[ ] 1.6.1 Task - Resource CRUD integration scenarios
Verify create, read, update, and destroy operations work correctly.

[ ] 1.6.1.1 Subtask - Verify screen creation with unified_dsl storage
[ ] 1.6.1.2 Subtask - Verify element creation with screen association
[ ] 1.6.1.3 Subtask - Verify binding creation with element and screen associations
[ ] 1.6.1.4 Subtask - Verify cascade delete from screen to elements and bindings

[ ] 1.6.2 Task - DSL and validation integration scenarios
Verify DSL extensions and validations work correctly.

[ ] 1.6.2.1 Subtask - Verify `ui_screen` DSL creates valid resource attributes
[ ] 1.6.2.2 Subtask - Verify `ui_element` DSL validates widget types
[ ] 1.6.2.3 Subtask - Verify `ui_binding` DSL validates binding types
[ ] 1.6.2.4 Subtask - Verify invalid DSL options produce validation errors

[ ] 1.6.3 Task - Relationship and query integration scenarios
Verify relationships and queries work correctly.

[ ] 1.6.3.1 Subtask - Verify loading screen with preloaded elements
[ ] 1.6.3.2 Subtask - Verify loading element with preloaded bindings
[ ] 1.6.3.3 Subtask - Verify querying elements by screen association
[ ] 1.6.3.4 Subtask - Verify querying bindings by element or screen associations
155 changes: 155 additions & 0 deletions specs/planning/phase-02-iur-adapter-and-canonical-conversion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Phase 2 - IUR Adapter and Canonical Conversion

Back to index: [README](./README.md)

## Relevant Shared APIs / Interfaces
- `AshUI.Compilation.IUR`
- `AshUI.Rendering.IURAdapter`
- `UnifiedIUR` (unified_iur package)
- `UnifiedIUR.Screen`
- `UnifiedIUR.Element`
- `UnifiedIUR.Signal`

## Relevant Assumptions / Defaults
- Ash UI compiles Ash Resources to Ash-internal IUR format
- IUR Adapter converts Ash IUR to canonical unified_iur format
- unified_iur package provides canonical data structures
- Renderer packages consume canonical IUR, not Ash-specific formats

[ ] 2 Phase 2 - IUR Adapter and Canonical Conversion
Implement the conversion layer from Ash Resources through Ash IUR to canonical unified_iur format for renderer consumption.

[ ] 2.1 Section - Ash IUR Compilation
Implement compilation from Ash Resources to Ash-internal IUR format.

[ ] 2.1.1 Task - Define Ash IUR data structures
Create the internal IUR representation used during compilation.

[ ] 2.1.1.1 Subtask - Implement `AshUI.Compilation.IUR` struct with `id`, `type`, `name` fields
[ ] 2.1.1.2 Subtask - Add `attributes` (map), `children` (list), `bindings` (list) fields
[ ] 2.1.1.3 Subtask - Add `metadata` (map) and `version` (string) fields
[ ] 2.1.1.4 Subtask - Implement `@enforce_keys` for required fields

[ ] 2.1.2 Task - Implement Resource to IUR compiler
Create the compiler that converts Ash Resources to IUR structures.

[ ] 2.1.2.1 Subtask - Implement `AshUI.Compiler.compile/2` for screen resources
[ ] 2.1.2.2 Subtask - Convert screen attributes to IUR root element
[ ] 2.1.2.3 Subtask - Load and convert associated elements as IUR children
[ ] 2.1.2.4 Subtask - Load and convert associated bindings as IUR bindings

[ ] 2.1.3 Task - Implement IUR validation
Ensure compiled IUR structures are valid before conversion.

[ ] 2.1.3.1 Subtask - Validate IUR has required fields and correct types
[ ] 2.1.3.2 Subtask - Validate children references exist
[ ] 2.1.3.3 Subtask - Validate binding references are resolvable
[ ] 2.1.3.4 Subtask - Return structured errors for invalid IUR

[ ] 2.2 Section - Canonical IUR Adapter
Implement conversion from Ash IUR to canonical unified_iur format.

[ ] 2.2.1 Task - Define adapter interface
Create the adapter contract for IUR conversion.

[ ] 2.2.1.1 Subtask - Implement `AshUI.Rendering.IURAdapter.to_canonical/1` function
[ ] 2.2.1.2 Subtask - Return `{:ok, UnifiedIUR.Screen.t()}` or `{:error, term()}`
[ ] 2.2.1.3 Subtask - Implement `compatible?/2` to check renderer compatibility
[ ] 2.2.1.4 Subtask - Add telemetry events for conversion success/failure

[ ] 2.2.2 Task - Implement element type mapping
Map Ash UI element types to unified-ui widget types.

[ ] 2.2.2.1 Subtask - Create type mapping table (button, input, text, image, etc.)
[ ] 2.2.2.2 Subtask - Convert Ash element `type` to unified widget `type`
[ ] 2.2.2.3 Subtask - Handle unknown element types with error or fallback
[ ] 2.2.2.4 Subtask - Document supported element types

[ ] 2.2.3 Task - Implement props mapping
Map Ash element props to unified-ui widget attributes.

[ ] 2.2.3.1 Subtask - Convert Ash `props` map to unified widget attributes
[ ] 2.2.3.2 Subtask - Handle prop name conversions (e.g., `onClick` → `on_click`)
[ ] 2.2.3.3 Subtask - Filter out Ash-specific props from canonical IUR
[ ] 2.2.3.4 Subtask - Apply prop transformations for type compatibility

[ ] 2.2.4 Task - Implement layout mapping
Convert Ash screen layout to unified-ui layout constructs.

[ ] 2.2.4.1 Subtask - Map Ash `layout` attribute to unified layout type
[ ] 2.2.4.2 Subtask - Convert children to unified container structure
[ ] 2.2.4.3 Subtask - Handle nested layouts and layering constructs
[ ] 2.2.4.4 Subtask - Preserve layout metadata in canonical IUR

[ ] 2.3 Section - Signal Conversion
Convert Ash UI bindings to unified-ui signal format.

[ ] 2.3.1 Task - Define signal mapping
Create the mapping from Ash bindings to unified signals.

[ ] 2.3.1.1 Subtask - Implement `AshUI.Signal.to_canonical/1` function
[ ] 2.3.1.2 Subtask - Convert binding source to unified signal source format
[ ] 2.3.1.3 Subtask - Convert binding target to unified signal target format
[ ] 2.3.1.4 Subtask - Map binding type to unified signal type

[ ] 2.3.2 Task - Implement binding type conversion
Map Ash binding types to unified signal types.

[ ] 2.3.2.1 Subtask - Convert `:value` binding to bidirectional signal
[ ] 2.3.2.2 Subtask - Convert `:list` binding to collection signal
[ ] 2.3.2.3 Subtask - Convert `:action` binding to event signal
[ ] 2.3.2.4 Subtask - Handle transformation rules in signal definition

[ ] 2.3.3 Task - Implement signal source resolution
Resolve Ash resource paths in binding sources.

[ ] 2.3.3.1 Subtask - Parse binding source path (Domain.Resource.Attribute)
[ ] 2.3.3.2 Subtask - Validate source exists in Ash resource definitions
[ ] 2.3.3.3 Subtask - Convert source path to unified signal reference
[ ] 2.3.3.4 Subtask - Handle nested paths and relationship traversal

[ ] 2.4 Section - Error Handling and Validation
Implement error handling for IUR conversion failures.

[ ] 2.4.1 Task - Define error types
Create structured error types for conversion failures.

[ ] 2.4.1.1 Subtask - Implement `AshUI.Rendering.ConversionError` exception
[ ] 2.4.1.2 Subtask - Add error fields: `phase`, `element_id`, `reason`
[ ] 2.4.1.3 Subtask - Implement error formatting for user display
[ ] 2.4.1.4 Subtask - Add error telemetry with correlation IDs

[ ] 2.4.2 Task - Implement validation checks
Add validation at each conversion stage.

[ ] 2.4.2.1 Subtask - Validate Ash IUR before canonical conversion
[ ] 2.4.2.2 Subtask - Validate canonical IUR structure after conversion
[ ] 2.4.2.3 Subtask - Collect all validation errors before returning
[ ] 2.4.2.4 Subtask - Provide detailed error location information

[ ] 2.5 Section - Phase 2 Integration Tests
Validate IUR compilation and canonical conversion end-to-end.

[ ] 2.5.1 Task - Compilation integration scenarios
Verify Ash Resource to IUR compilation works correctly.

[ ] 2.5.1.1 Subtask - Verify screen resource compiles to valid IUR structure
[ ] 2.5.1.2 Subtask - Verify elements are compiled as IUR children
[ ] 2.5.1.3 Subtask - Verify bindings are compiled as IUR bindings
[ ] 2.5.1.4 Subtask - Verify invalid resources produce compilation errors

[ ] 2.5.2 Task - Canonical conversion integration scenarios
Verify Ash IUR to canonical IUR conversion works correctly.

[ ] 2.5.2.1 Subtask - Verify simple element converts to canonical widget
[ ] 2.5.2.2 Subtask - Verify layout converts to canonical layout structure
[ ] 2.5.2.3 Subtask - Verify binding converts to canonical signal
[ ] 2.5.2.4 Subtask - Verify complex nested screen converts fully

[ ] 2.5.3 Task - Error handling integration scenarios
Verify errors are handled gracefully.

[ ] 2.5.3.1 Subtask - Verify invalid IUR produces structured error
[ ] 2.5.3.2 Subtask - Verify unknown element type produces clear error
[ ] 2.5.3.3 Subtask - Verify invalid binding source produces resolution error
[ ] 2.5.3.4 Subtask - Verify partial failures don't crash adapter
Loading
Loading