From 628e2ed99a02997b1ce34a6b4d5b97d83e038ef9 Mon Sep 17 00:00:00 2001 From: Torkild Kjevik Date: Fri, 25 Jul 2025 10:31:34 +0200 Subject: [PATCH 1/5] Add AI assistant docs. --- docs/ai-changelog.md | 95 ++++ docs/ai-documentation-update-guide.md | 158 ++++++ docs/ai-implementation-guide.md | 580 +++++++++++++++++++ docs/ai-index.md | 147 +++++ docs/ai-quick-reference.md | 252 +++++++++ docs/ai-readme-update-guide.md | 656 +++++++++++++++++++++ docs/ai-troubleshooting.md | 783 ++++++++++++++++++++++++++ docs/ai-usage-rules-update-guide.md | 282 ++++++++++ docs/ai-validation-safety.md | 407 +++++++++++++ 9 files changed, 3360 insertions(+) create mode 100644 docs/ai-changelog.md create mode 100644 docs/ai-documentation-update-guide.md create mode 100644 docs/ai-implementation-guide.md create mode 100644 docs/ai-index.md create mode 100644 docs/ai-quick-reference.md create mode 100644 docs/ai-readme-update-guide.md create mode 100644 docs/ai-troubleshooting.md create mode 100644 docs/ai-usage-rules-update-guide.md create mode 100644 docs/ai-validation-safety.md diff --git a/docs/ai-changelog.md b/docs/ai-changelog.md new file mode 100644 index 0000000..c48f71a --- /dev/null +++ b/docs/ai-changelog.md @@ -0,0 +1,95 @@ +# AshEvents AI Assistant Changelog + +## Overview + +This changelog provides context for the current state of the project and tracks the evolution of implementation approaches. It helps AI assistants understand why certain patterns exist and the reasoning behind architectural decisions. + +## Entry Format + +Each entry includes: +- **Date**: When the change was made +- **Change**: What was modified/added/removed +- **Context**: Why the change was necessary +- **Files**: Which files were affected +- **Impact**: How this affects future development +- **Key Insights**: Lessons learned or patterns discovered + +--- + +## 2025-07-18 + +### AI Documentation Framework Scaffolding +**Change**: Created comprehensive AI documentation scaffolding system for AshEvents project +**Context**: Project had minimal CLAUDE.md referencing non-existent AGENTS.md; needed structured AI assistant documentation to improve development efficiency and reduce implementation errors +**Files**: +- Created `docs/ai-index.md` - Central documentation index with task-specific guidance +- Created `docs/ai-changelog.md` - Context tracking for architectural decisions +- Created `docs/` directory structure for organized AI documentation +**Impact**: AI assistants now have structured access to project-specific patterns, critical rules, and implementation workflows +**Key Insights**: Existing `usage-rules.md` (472 lines) already contains comprehensive usage patterns for AshEvents - this should be leveraged as primary reference for implementation guidance + +### Project Analysis and Pattern Identification +**Change**: Analyzed existing codebase to identify critical patterns and architectural decisions +**Context**: Needed to understand current state before creating AI documentation framework +**Files**: +- Analyzed `lib/event_log/` and `lib/events/` for core implementation patterns +- Reviewed `test/support/` for example implementations and testing patterns +- Examined `mix.exs` for project configuration and available commands +**Impact**: AI assistants now understand the project's structure, key abstractions, and testing patterns +**Key Insights**: +- AshEvents follows Ash Framework patterns with extensions for EventLog and Events +- Project has comprehensive test suite with example implementations +- Critical commands include `mix test.reset` for database management and `mix credo --strict` for code quality +- Actor attribution is mandatory for proper event tracking + +### Current State Documentation +**Change**: Documented current architectural state and critical rules +**Context**: Established baseline understanding of AshEvents implementation patterns +**Files**: All core library files, test files, and configuration +**Impact**: Future AI assistants will understand the current implementation without needing to discover patterns from scratch +**Key Insights**: +- **Event Log Resource**: Central resource using `AshEvents.EventLog` extension with required `clear_records_for_replay` implementation +- **Events Extension**: Added to resources needing event tracking via `AshEvents.Events` extension +- **Actor Attribution**: Critical for audit trails - always set actor when performing actions +- **Lifecycle Hooks**: Skipped during replay to prevent duplicate side effects +- **Version Management**: Handled via `current_action_versions` and `replay_overrides` for schema evolution +- **Side Effects**: Should be encapsulated in separate tracked actions rather than lifecycle hooks + +--- + +## Entry Guidelines + +### What to Include +- **Major architectural decisions** and their reasoning +- **Pattern changes** that affect how code should be written +- **Critical bug fixes** and their root causes +- **Performance improvements** and optimization strategies +- **Breaking changes** and migration strategies +- **Documentation restructuring** and new workflows +- **Tool or dependency changes** and their impact + +### What to Exclude +- **Routine maintenance** without architectural impact +- **Minor bug fixes** that don't reveal patterns +- **Cosmetic changes** without functional impact +- **Experimental changes** that were reverted +- **Personal preferences** without project-wide impact + +### Writing Style +- **Be concise** but provide enough context +- **Focus on reasoning** rather than just what changed +- **Include file references** for easy navigation +- **Highlight patterns** that apply to future work +- **Use present tense** for current state descriptions +- **Use past tense** for completed changes + +### Update Frequency +- **After significant changes** that affect how work is done +- **When new patterns emerge** from implementation work +- **After architectural decisions** that impact future development +- **When documentation structure changes** occur +- **After major bug fixes** that reveal important insights + +--- + +**Last Updated**: 2025-07-18 \ No newline at end of file diff --git a/docs/ai-documentation-update-guide.md b/docs/ai-documentation-update-guide.md new file mode 100644 index 0000000..d615938 --- /dev/null +++ b/docs/ai-documentation-update-guide.md @@ -0,0 +1,158 @@ +# AI Assistant Documentation Update Guide + +## Overview + +When updating AI assistant documentation, maintain established patterns and focus on creating a practical reference corpus. Documentation should provide AI assistants with the context and knowledge needed to complete tasks efficiently and correctly. + +## Pre-Update Analysis (MANDATORY) + +Before making any AI documentation changes, you MUST: + +1. **Read the AI Index First**: Start with `docs/ai-index.md` to understand current documentation structure and find related content +2. **Identify Documentation Type**: Determine if you're updating: + - AI implementation guides (setup, patterns, workflows) + - AI troubleshooting documentation (error patterns, debugging guides) + - AI quick reference materials (command references, critical reminders) + - AI-specific architectural documentation (context optimization, task mapping) +3. **Check Dependencies**: Identify other AI documentation files that reference the content you're updating +4. **Assess Impact**: Determine if changes will affect the AI index, task-to-documentation mappings, or established workflows + +## AI Documentation Update Workflow + +### 1. Planning Phase + +Use TodoWrite to create an update plan with these steps: +- Read `docs/ai-index.md` to understand current documentation structure +- Identify specific AI documentation files to update/create/remove +- Check cross-references and dependencies +- Plan updates to maintain workflow consistency +- Update AI index task mappings if needed +- Plan changelog entry for significant changes + +### 2. Content Standards + +**Focus Areas:** +- Current state of the system and correct usage patterns +- Code patterns that should be used +- Anti-patterns that should be avoided +- Workflows for different types of tasks +- Context needed for efficient task completion + +**Content Requirements:** +- Follow existing documentation patterns (structure, tone, formatting) +- Use consistent terminology and command examples +- Maintain technical detail appropriate for AI assistants +- Include practical, actionable information +- Remove any change tracking or historical references + +**Prohibited Content:** +- ❌ "This is a new feature" or similar announcement language +- ❌ Timestamp announcements ("Changed at...", "Updated on...") +- ❌ "NOW UPDATED" or similar change tracking language +- ❌ Historical change references or version comparisons +- ❌ Meta-commentary about features being new or old + +### 3. File Guidelines + +**For All Documentation Updates:** +- Document the current state only +- Focus on practical usage patterns +- Include command examples that work with current codebase +- Maintain consistent file structure and organization +- Ensure all internal links remain functional + +**For New Documentation:** +- Place in `docs/` directory following established categorization +- Use consistent naming conventions (kebab-case, descriptive) +- Include proper documentation headers and structure +- Immediately update `docs/ai-index.md` with new file reference + +**For Removing Documentation:** +- Mark as deprecated first with clear migration path +- Update all references to point to replacement documentation +- Remove from `docs/ai-index.md` and update task mappings +- Delete only after confirming no dependencies exist + +### 4. AI Index Maintenance (CRITICAL) + +Whenever you update AI documentation, update `docs/ai-index.md`: +- Add new documentation files to appropriate task categories +- Update file descriptions and context window size references +- Maintain task-to-documentation mapping +- Update context window optimization notes +- Keep "Quick Navigation" section current + +### 5. Changelog Maintenance (REQUIRED) + +For significant changes, update `docs/ai-changelog.md`: +- Add entry with current date +- Describe what was changed and why +- List affected files +- Explain impact on future development +- Include key insights or patterns discovered +- Follow the established entry format + +### 6. Quality Assurance + +**Content Quality:** +- Information accurate for current codebase +- Command examples tested and functional +- Technical depth appropriate for AI implementation +- Consistent tone and style +- TodoWrite examples functional + +**Structure Quality:** +- Follows established formatting patterns +- Headers and organization match similar documents +- Code blocks use consistent syntax highlighting +- All links and references functional + +**Integration Quality:** +- AI index updated with content changes +- Cross-references updated throughout documentation +- Task-to-documentation mappings accurate +- No broken internal links + +### 7. Specialized Documentation Types + +**Implementation Guides:** +- Include task-to-documentation mappings +- Reference file sizes for context window optimization +- Maintain mandatory documentation reading workflow +- Include TodoWrite examples and patterns +- Specify correct command usage (e.g., `mix test.reset`) + +**Troubleshooting Documentation:** +- Include error patterns and solutions +- Reference common workflow mistakes and corrections +- Maintain debugging patterns and approaches +- Include validation steps and quality checks + +**Quick Reference Materials:** +- Optimize for quick AI assistant lookup +- Include critical workflow reminders and patterns +- Maintain consistent command reference formats +- Include safety checks and validation steps + +## Validation Steps + +After completing documentation updates: +1. **Test Examples**: Ensure workflow examples and commands work with current codebase +2. **Check Links**: Verify all internal links are functional +3. **Review AI Index**: Confirm `docs/ai-index.md` accurately reflects changes +4. **Update Changelog**: Add entry to `docs/ai-changelog.md` for significant changes +5. **Cross-Reference Check**: Ensure other documentation referencing changes is accurate +6. **Pattern Consistency**: Verify changes follow established patterns +7. **Context Window Check**: Ensure documentation remains optimized for AI context usage + +## Error Prevention + +Common mistakes to avoid: +- ❌ Creating documentation without updating AI index +- ❌ Making significant changes without updating changelog +- ❌ Changing established workflow patterns without updating related files +- ❌ Removing documentation without checking dependencies +- ❌ Adding content without considering context window impact +- ❌ Updating technical details without testing workflow examples +- ❌ Breaking existing cross-references and links +- ❌ Including change tracking or historical references \ No newline at end of file diff --git a/docs/ai-implementation-guide.md b/docs/ai-implementation-guide.md new file mode 100644 index 0000000..f6a01af --- /dev/null +++ b/docs/ai-implementation-guide.md @@ -0,0 +1,580 @@ +# AshEvents AI Assistant Implementation Guide + +## Overview + +This guide provides comprehensive implementation workflows for AshEvents development tasks, designed specifically for AI assistant efficiency and accuracy. + +## Core Implementation Patterns + +### Event Log Resource Implementation + +#### Prerequisites +- [ ] Read [usage-rules.md](../usage-rules.md) sections 1-2 +- [ ] Understand AshEvents.EventLog extension +- [ ] Review [test/support/events/event_log.ex](../test/support/events/event_log.ex) + +#### Implementation Steps +1. **Create Event Log Resource**: + ```elixir + defmodule MyApp.Events.Event do + use Ash.Resource, + extensions: [AshEvents.EventLog] + + event_log do + clear_records_for_replay MyApp.Events.ClearAllRecords + primary_key_type Ash.Type.UUIDv7 + persist_actor_primary_key :user_id, MyApp.User + end + end + ``` + +2. **Create Clear Records Module**: + ```elixir + defmodule MyApp.Events.ClearAllRecords do + use AshEvents.ClearRecordsForReplay + + @impl true + def clear_records!(opts) do + # Clear all resources with event tracking + MyApp.User |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + MyApp.Org |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + :ok + end + end + ``` + +3. **Test Implementation**: `mix test test/support/events/` + +#### Validation +- [ ] Event log resource compiles without errors +- [ ] Clear records module implements required callback +- [ ] Actor attribution is properly configured +- [ ] Primary key type is set to UUIDv7 for performance + +#### Common Pitfalls +- ❌ **Missing Clear Records**: Not implementing clear_records_for_replay breaks replay +- ❌ **Wrong Primary Key Type**: Using default :id instead of Ash.Type.UUIDv7 +- ✅ **Correct Pattern**: Always implement clear_records_for_replay with comprehensive resource clearing + +### Events Extension Implementation + +#### Prerequisites +- [ ] Read [usage-rules.md](../usage-rules.md) section 3 +- [ ] Understand Events extension configuration +- [ ] Review [test/support/accounts/user.ex](../test/support/accounts/user.ex) + +#### Implementation Steps +1. **Add Events Extension**: + ```elixir + defmodule MyApp.User do + use Ash.Resource, + extensions: [AshEvents.Events] + + events do + event_log MyApp.Events.Event + current_action_versions create: 1, update: 1 + end + end + ``` + +2. **Configure Actor Attribution**: Always set actor when performing actions + ```elixir + user = User + |> Ash.Changeset.for_create(:create, %{name: "John"}) + |> Ash.create!(actor: current_user) + ``` + +3. **Test Event Creation**: Verify events are created with proper attribution + +#### Validation +- [ ] Resource compiles with Events extension +- [ ] Event log is properly referenced +- [ ] Actor attribution works correctly +- [ ] Events are created when actions are performed + +#### Common Pitfalls +- ❌ **Missing Event Log Reference**: Not configuring event_log in events block +- ❌ **No Actor Attribution**: Forgetting to set actor when performing actions +- ✅ **Correct Pattern**: Always reference event log and set actor attribution + +### Event Replay Implementation + +#### Prerequisites +- [ ] Read [usage-rules.md](../usage-rules.md) section 5 +- [ ] Understand replay mechanics and limitations +- [ ] Review [test/support/events/clear_records.ex](../test/support/events/clear_records.ex) + +#### Implementation Steps +1. **Implement Comprehensive Clear Records**: + ```elixir + defmodule MyApp.Events.ClearAllRecords do + use AshEvents.ClearRecordsForReplay + + @impl true + def clear_records!(opts) do + # Clear all resources with event tracking in dependency order + MyApp.UserRole |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + MyApp.User |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + MyApp.Org |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + :ok + end + end + ``` + +2. **Configure Replay Action**: Use built-in replay action + ```elixir + MyApp.Events.Event + |> Ash.ActionInput.for_action(:replay, %{}) + |> Ash.run_action!() + ``` + +3. **Test Replay Functionality**: Verify state restoration works correctly + +#### Validation +- [ ] Clear records implementation is comprehensive +- [ ] Replay action executes without errors +- [ ] State is properly restored after replay +- [ ] No duplicate data or side effects + +#### Common Pitfalls +- ❌ **Incomplete Clear Records**: Missing resources causes replay failures +- ❌ **Dependency Order**: Not clearing resources in correct dependency order +- ✅ **Correct Pattern**: Clear all tracked resources in proper dependency order + +### Version Management Implementation + +#### Prerequisites +- [ ] Read [usage-rules.md](../usage-rules.md) "Version Management and Replay Overrides" +- [ ] Understand schema evolution requirements +- [ ] Review version management examples + +#### Implementation Steps +1. **Update Action Versions**: + ```elixir + events do + event_log MyApp.Events.Event + current_action_versions create: 2, update: 1 # Increment version + end + ``` + +2. **Configure Replay Overrides**: + ```elixir + # In Event Log Resource + replay_overrides do + replay_override MyApp.User, :create do + versions [1] + route_to MyApp.User, :old_create_v1 + end + end + ``` + +3. **Create Legacy Actions**: + ```elixir + actions do + create :old_create_v1 do + # Implementation for version 1 events + accept [:name] # Old schema + end + end + + events do + event_log MyApp.Events.Event + ignore_actions [:old_create_v1] # Don't create new events + end + ``` + +4. **Test Version Routing**: Verify events route to correct actions + +#### Validation +- [ ] Action versions are properly incremented +- [ ] Replay overrides are configured correctly +- [ ] Legacy actions handle old event schemas +- [ ] Version routing works during replay + +#### Common Pitfalls +- ❌ **Missing Legacy Actions**: Not implementing old action versions +- ❌ **Incorrect Version Routing**: Events not routing to correct actions +- ✅ **Correct Pattern**: Implement legacy actions and configure proper routing + +### Actor Attribution Implementation + +#### Prerequisites +- [ ] Read [usage-rules.md](../usage-rules.md) "Actor Attribution" +- [ ] Understand actor configuration requirements +- [ ] Review actor attribution examples + +#### Implementation Steps +1. **Configure Actor Types in Event Log**: + ```elixir + event_log do + clear_records_for_replay MyApp.Events.ClearAllRecords + persist_actor_primary_key :user_id, MyApp.User + persist_actor_primary_key :system_actor, MyApp.SystemActor, attribute_type: :string + end + ``` + +2. **Set Actor in All Actions**: + ```elixir + # User actions + user = User + |> Ash.Changeset.for_create(:create, %{name: "John"}) + |> Ash.create!(actor: current_user) + + # System actions + user = User + |> Ash.Changeset.for_update(:system_update, %{status: "active"}) + |> Ash.update!(actor: %{id: "system", type: "automated"}) + ``` + +3. **Test Actor Attribution**: Verify events contain proper actor information + +#### Validation +- [ ] Actor types are configured in event log +- [ ] All actions set appropriate actor +- [ ] Events contain actor attribution +- [ ] Actor information is preserved during replay + +#### Common Pitfalls +- ❌ **Missing Actor Attribution**: Not setting actor on actions +- ❌ **Incorrect Actor Types**: Using wrong actor type for action +- ✅ **Correct Pattern**: Always set appropriate actor for all actions + +### Metadata Handling Implementation + +#### Prerequisites +- [ ] Read [usage-rules.md](../usage-rules.md) metadata examples +- [ ] Understand metadata structure and limitations +- [ ] Review metadata handling patterns + +#### Implementation Steps +1. **Add Metadata to Actions**: + ```elixir + User + |> Ash.Changeset.for_create(:create, %{name: "Jane"}, [ + actor: current_user, + context: %{ash_events_metadata: %{ + source: "api", + request_id: request_id, + ip_address: client_ip, + user_agent: user_agent + }} + ]) + |> Ash.create!() + ``` + +2. **Structure Metadata Consistently**: + ```elixir + # Standard metadata structure + metadata = %{ + source: "web_ui", # Where action originated + request_id: get_request_id(), + correlation_id: get_correlation_id(), + additional_context: %{ + feature_flag: "new_feature_enabled", + experiment_id: "exp_123" + } + } + ``` + +3. **Test Metadata Storage**: Verify metadata is properly stored and retrieved + +#### Validation +- [ ] Metadata is included in action context +- [ ] Metadata structure is consistent +- [ ] Metadata is stored in events +- [ ] Metadata is accessible during replay + +#### Common Pitfalls +- ❌ **Large Metadata**: Storing too much data in metadata +- ❌ **Inconsistent Structure**: Different metadata formats across actions +- ✅ **Correct Pattern**: Keep metadata concise and use consistent structure + +### Side Effects Implementation + +#### Prerequisites +- [ ] Read [usage-rules.md](../usage-rules.md) "Side Effects and Lifecycle Hooks" +- [ ] Understand lifecycle hook behavior during replay +- [ ] Review side effect handling examples + +#### Implementation Steps +1. **Create Side Effect Resources**: + ```elixir + defmodule MyApp.Notifications.Email do + use Ash.Resource, + extensions: [AshEvents.Events] + + events do + event_log MyApp.Events.Event + end + + actions do + create :send_welcome_email do + accept [:user_id, :email, :template] + + change after_action(fn changeset, record, context -> + # Actual email sending logic + result = MyApp.EmailService.send_email(record.email, record.template) + + # Update status (creates another event) + if result == :ok do + record + |> Ash.Changeset.for_update(:update_status, %{status: "sent"}) + |> Ash.update!(actor: context.actor) + end + + {:ok, record} + end) + end + end + end + ``` + +2. **Trigger Side Effects in Lifecycle Hooks**: + ```elixir + defmodule MyApp.User do + actions do + create :create do + accept [:name, :email] + + change after_action(fn changeset, user, context -> + # Trigger side effect as separate action + MyApp.Notifications.Email + |> Ash.Changeset.for_create(:send_welcome_email, %{ + user_id: user.id, + email: user.email, + template: "welcome" + }) + |> Ash.create!(actor: context.actor) + + {:ok, user} + end) + end + end + end + ``` + +3. **Test Side Effect Handling**: Verify side effects work correctly and don't duplicate during replay + +#### Validation +- [ ] Side effects are implemented as separate actions +- [ ] Side effect resources track events +- [ ] Side effects are triggered by lifecycle hooks +- [ ] Side effects don't duplicate during replay + +#### Common Pitfalls +- ❌ **Direct Side Effects**: Performing side effects directly in lifecycle hooks +- ❌ **Untracked Side Effects**: Side effects not implemented as tracked actions +- ✅ **Correct Pattern**: Implement side effects as separate tracked actions + +## Architecture Patterns + +### Event Log Resource Pattern + +**When to Use**: Always required for any AshEvents implementation +**Structure**: Central resource using AshEvents.EventLog extension +**Implementation**: + +```elixir +defmodule MyApp.Events.Event do + use Ash.Resource, + extensions: [AshEvents.EventLog] + + event_log do + clear_records_for_replay MyApp.Events.ClearAllRecords + primary_key_type Ash.Type.UUIDv7 + persist_actor_primary_key :user_id, MyApp.User + persist_actor_primary_key :system_actor, MyApp.SystemActor, attribute_type: :string + end +end +``` + +### Events Extension Pattern + +**When to Use**: For any resource that needs event tracking +**Structure**: Extension added to existing resources +**Implementation**: + +```elixir +defmodule MyApp.User do + use Ash.Resource, + extensions: [AshEvents.Events] + + events do + event_log MyApp.Events.Event + current_action_versions create: 1, update: 1 + end +end +``` + +### Clear Records Pattern + +**When to Use**: Required for event replay functionality +**Structure**: Module implementing AshEvents.ClearRecordsForReplay +**Implementation**: + +```elixir +defmodule MyApp.Events.ClearAllRecords do + use AshEvents.ClearRecordsForReplay + + @impl true + def clear_records!(opts) do + # Clear in dependency order + MyApp.UserRole |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + MyApp.User |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + MyApp.Org |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + :ok + end +end +``` + +## Testing Patterns + +### Event Creation Testing + +**Purpose**: Verify events are created when actions are performed +**Structure**: Test that creates resource and checks event creation +**Example**: + +```elixir +test "creates event when user is created" do + user = User + |> Ash.Changeset.for_create(:create, %{name: "Test"}) + |> Ash.create!(authorize?: false) + + events = MyApp.Events.Event |> Ash.read!(authorize?: false) + assert length(events) == 1 + + event = hd(events) + assert event.resource == MyApp.User + assert event.record_id == user.id + assert event.action == :create +end +``` + +### Event Replay Testing + +**Purpose**: Verify event replay restores state correctly +**Structure**: Create data, clear state, replay events, verify restoration +**Example**: + +```elixir +test "can replay events to rebuild state" do + # Create initial data + user = User + |> Ash.Changeset.for_create(:create, %{name: "Test"}) + |> Ash.create!(authorize?: false) + + # Store expected state + expected_name = user.name + + # Clear state + MyApp.Events.ClearAllRecords.clear_records!([]) + + # Replay events + MyApp.Events.Event + |> Ash.ActionInput.for_action(:replay, %{}) + |> Ash.run_action!(authorize?: false) + + # Verify state is restored + restored_user = User |> Ash.get!(user.id, authorize?: false) + assert restored_user.name == expected_name +end +``` + +### Actor Attribution Testing + +**Purpose**: Verify events contain proper actor information +**Structure**: Test that creates events with actor and checks attribution +**Example**: + +```elixir +test "events contain proper actor attribution" do + actor = %{id: 1, name: "Test Actor"} + + user = User + |> Ash.Changeset.for_create(:create, %{name: "Test"}) + |> Ash.create!(actor: actor, authorize?: false) + + events = MyApp.Events.Event |> Ash.read!(authorize?: false) + event = hd(events) + + assert event.user_id == actor.id +end +``` + +## Advanced Workflows + +### Schema Evolution Workflow + +1. **Plan Schema Changes**: Identify what needs to change in action schemas +2. **Increment Version Numbers**: Update current_action_versions +3. **Create Legacy Actions**: Implement old action versions for replay +4. **Configure Replay Overrides**: Route old events to legacy actions +5. **Test Version Routing**: Verify events route correctly during replay + +### Multi-Tenant Event Handling + +1. **Configure Tenant-Aware Resources**: Set up multitenancy on event-tracked resources +2. **Tenant-Specific Event Logs**: Consider separate event logs per tenant +3. **Tenant-Aware Clear Records**: Implement tenant-specific clearing +4. **Test Tenant Isolation**: Verify events don't leak between tenants + +### High-Volume Event Handling + +1. **Optimize Event Storage**: Use UUIDv7 primary keys for time-ordered events +2. **Implement Event Partitioning**: Consider database partitioning for large volumes +3. **Batch Event Processing**: Use bulk operations for efficiency +4. **Monitor Performance**: Track event creation and replay performance + +## File Location Reference + +### Core Implementation Files +- **Event Log Extension**: `lib/event_log/event_log.ex` - Core event log functionality +- **Events Extension**: `lib/events/events.ex` - Resource event tracking +- **Action Wrappers**: `lib/events/*_action_wrapper.ex` - Action interception +- **Replay Logic**: `lib/event_log/replay.ex` - Event replay implementation + +### Test Files +- **Event Log Test**: `test/support/events/event_log.ex` - Example event log resource +- **Clear Records Test**: `test/support/events/clear_records.ex` - Clear records implementation +- **User Resource Test**: `test/support/accounts/user.ex` - Example resource with events +- **Main Test**: `test/ash_events_test.exs` - Core functionality tests + +### Configuration Files +- **Mix Project**: `mix.exs` - Project configuration and dependencies +- **Test Config**: `config/test.exs` - Test environment configuration +- **App Config**: `config/config.exs` - Application configuration + +## Performance Considerations + +### Event Storage Optimization +- **Primary Key Type**: Use `Ash.Type.UUIDv7` for time-ordered events +- **Database Indexing**: Index frequently queried event fields +- **Event Retention**: Consider archiving old events to manage storage + +### Replay Performance +- **Batch Processing**: Process events in batches during replay +- **Dependency Ordering**: Clear resources in correct dependency order +- **Parallel Processing**: Consider parallel replay for independent resources + +### Metadata Management +- **Size Limits**: Keep metadata reasonably sized for JSON storage +- **Structured Data**: Use consistent metadata structure across events +- **Indexing**: Index metadata fields that are frequently queried + +## Security Considerations + +### Data Protection +- **Sensitive Data**: Never store sensitive data in metadata without encryption +- **Actor Validation**: Always validate actor permissions before creating events +- **Access Control**: Implement proper access controls on event log resources + +### Audit Trail Integrity +- **Event Immutability**: Ensure events cannot be modified after creation +- **Actor Attribution**: Always set actor attribution for accountability +- **Metadata Validation**: Validate metadata content for security + +### Compliance Requirements +- **Data Retention**: Implement data retention policies for compliance +- **Data Deletion**: Consider GDPR right-to-be-forgotten requirements +- **Audit Logging**: Ensure complete audit trail for compliance needs \ No newline at end of file diff --git a/docs/ai-index.md b/docs/ai-index.md new file mode 100644 index 0000000..0c66ed5 --- /dev/null +++ b/docs/ai-index.md @@ -0,0 +1,147 @@ +# AshEvents AI Assistant Documentation Index + +## Quick Access Guide + +This index helps AI assistants quickly find the most relevant documentation for specific tasks, optimizing context window usage. + +## Core Files (Always Start Here) + +| File | Purpose | When to Use | +|------|---------|-------------| +| [CLAUDE.md](../CLAUDE.md) | Main AI assistant guide | Start here for project overview, critical rules, and workflows | +| [ai-quick-reference.md](ai-quick-reference.md) | Quick commands and patterns | Need immediate help with common tasks | +| [ai-validation-safety.md](ai-validation-safety.md) | Testing and safety procedures | Before making any changes or troubleshooting | +| [ai-changelog.md](ai-changelog.md) | Context and evolution | Understanding why current patterns exist and architectural decisions | + +## Task-Specific Documentation + +### Implementation Tasks +| Task | Primary Documentation | Supporting Files | +|------|----------------------|------------------| +| **Event Log Resource Setup** | [ai-implementation-guide.md](ai-implementation-guide.md) | [test/support/events/](../test/support/events/) | +| **Adding Event Tracking** | [ai-quick-reference.md](ai-quick-reference.md) | [usage-rules.md](../usage-rules.md), [test/support/accounts/](../test/support/accounts/) | +| **Event Replay Implementation** | [ai-implementation-guide.md](ai-implementation-guide.md) | [test/support/events/clear_records.ex](../test/support/events/clear_records.ex) | +| **Version Management** | [ai-implementation-guide.md](ai-implementation-guide.md) | [ai-quick-reference.md](ai-quick-reference.md) | +| **Actor Attribution** | [ai-implementation-guide.md](ai-implementation-guide.md) | [test/support/accounts/user.ex](../test/support/accounts/user.ex) | +| **Metadata Handling** | [ai-implementation-guide.md](ai-implementation-guide.md) | [test/support/accounts/](../test/support/accounts/) | +| **Side Effects & Lifecycle** | [ai-implementation-guide.md](ai-implementation-guide.md) | [test/support/accounts/before_action_update_org_details.ex](../test/support/accounts/before_action_update_org_details.ex) | +| **Test Organization** | [ai-quick-reference.md](ai-quick-reference.md) | [test/ash_events_test.exs](../test/ash_events_test.exs), [test/support/](../test/support/) | + +### Troubleshooting +| Issue Type | Primary Documentation | Emergency Reference | +|------------|----------------------|-------------------| +| **Environment Issues** | [ai-troubleshooting.md](ai-troubleshooting.md) | [CLAUDE.md](../CLAUDE.md) (Critical Rules) | +| **Event Tracking Issues** | [ai-troubleshooting.md](ai-troubleshooting.md) | [ai-quick-reference.md](ai-quick-reference.md) | +| **Replay Issues** | [ai-troubleshooting.md](ai-troubleshooting.md) | [ai-implementation-guide.md](ai-implementation-guide.md) | +| **Database Issues** | [ai-troubleshooting.md](ai-troubleshooting.md) | [ai-validation-safety.md](ai-validation-safety.md) | + +### Deep Dives and Insights +| Topic | Primary Documentation | When to Read | +|-------|----------------------|--------------| +| **Architecture Decisions** | [ai-implementation-insights.md](ai-implementation-insights.md) | Understanding design choices | +| **Context and Evolution** | [ai-changelog.md](ai-changelog.md) | Understanding why current patterns exist | +| **Performance Patterns** | [ai-implementation-insights.md](ai-implementation-insights.md) | Optimizing implementations | + +## File Size Reference (Context Window Planning) + +### Small Files (< 500 lines) - Efficient for AI +- [ai-quick-reference.md](ai-quick-reference.md) (~300 lines) +- [ai-changelog.md](ai-changelog.md) (~150 lines) +- [ai-validation-safety.md](ai-validation-safety.md) (~250 lines) + +### Medium Files (500-800 lines) - Manageable +- [CLAUDE.md](../CLAUDE.md) (~600 lines) +- [usage-rules.md](../usage-rules.md) (~472 lines) + +### Large Files (> 1000 lines) - Use Sparingly +⚠️ **Context Window Warning**: These files consume significant context space +- [ai-implementation-guide.md](ai-implementation-guide.md) (~1200 lines) +- [ai-troubleshooting.md](ai-troubleshooting.md) (~800 lines) +- [ai-implementation-insights.md](ai-implementation-insights.md) (~900 lines) + +## Project-Specific File References + +### Core Implementation Files +- **Event Log Extension**: `lib/event_log/event_log.ex` - Core event log functionality +- **Events Extension**: `lib/events/events.ex` - Resource event tracking +- **Action Wrappers**: `lib/events/create_action_wrapper.ex`, `lib/events/update_action_wrapper.ex`, `lib/events/destroy_action_wrapper.ex` +- **Replay Logic**: `lib/event_log/replay.ex` - Event replay implementation + +### Test Support Files +- **Event Log Examples**: `test/support/events/event_log.ex` - Main event log resource +- **Clear Records**: `test/support/events/clear_records.ex` - Clear records implementation +- **User Resource**: `test/support/accounts/user.ex` - Example resource with events +- **Test Configuration**: `test/support/test_repo.ex` - Database configuration + +### Configuration Files +- **Mix Project**: `mix.exs` - Project configuration and dependencies +- **Database Config**: `config/test.exs` - Test database configuration +- **Environment Config**: `config/config.exs` - Application configuration + +## Legacy Documentation (Archived) + +The following files have been moved to `docs/legacy/` and should not be read: +- None currently - this is a new documentation structure + +## Recommended Reading Patterns + +### For Quick Tasks (1-2 steps) +1. [ai-quick-reference.md](ai-quick-reference.md) +2. [CLAUDE.md](../CLAUDE.md) (if needed) + +### For Implementation Tasks (3+ steps) +1. [CLAUDE.md](../CLAUDE.md) (Critical Rules) +2. [ai-implementation-guide.md](ai-implementation-guide.md) (Primary) +3. [ai-validation-safety.md](ai-validation-safety.md) (Testing) + +### For Troubleshooting +1. [CLAUDE.md](../CLAUDE.md) (Environment rules) +2. [ai-troubleshooting.md](ai-troubleshooting.md) (Issue-specific) +3. [ai-validation-safety.md](ai-validation-safety.md) (Validation) + +### For Understanding Context +1. [ai-changelog.md](ai-changelog.md) (Why current patterns exist) +2. [ai-implementation-insights.md](ai-implementation-insights.md) (Deep architectural insights) + +### For Deep Understanding +1. [ai-implementation-guide.md](ai-implementation-guide.md) +2. [ai-implementation-insights.md](ai-implementation-insights.md) + +## AshEvents-Specific Patterns + +### Event Log Resource Setup +- **Must Read**: [usage-rules.md](../usage-rules.md) sections 1-2 +- **Example**: [test/support/events/event_log.ex](../test/support/events/event_log.ex) +- **Key Requirement**: Always implement `clear_records_for_replay` module + +### Events Extension Usage +- **Must Read**: [usage-rules.md](../usage-rules.md) section 3 +- **Example**: [test/support/accounts/user.ex](../test/support/accounts/user.ex) +- **Key Requirement**: Reference event log resource in `events` block + +### Event Replay Implementation +- **Must Read**: [usage-rules.md](../usage-rules.md) section 5 +- **Example**: [test/support/events/clear_records.ex](../test/support/events/clear_records.ex) +- **Key Requirement**: Understand lifecycle hooks are skipped during replay + +### Version Management +- **Must Read**: [usage-rules.md](../usage-rules.md) "Version Management and Replay Overrides" +- **Key Requirement**: Use `current_action_versions` and `replay_overrides` for schema evolution + +### Actor Attribution +- **Must Read**: [usage-rules.md](../usage-rules.md) "Actor Attribution" +- **Key Requirement**: Always set actor when performing actions + +## Future Structure (Post-Restructuring) + +After Phase 2-4 implementation, this index will reference: +- `docs/implementation/` - Focused implementation guides (200-250 lines each) +- `docs/troubleshooting/` - Focused troubleshooting guides (200-250 lines each) +- `docs/insights/` - Focused insight documents (300-400 lines each) +- `docs/quick-guides/` - Task-specific guides (100-150 lines each) +- `docs/reference/` - Quick reference cards (50-150 lines each) + +--- + +**Last Updated**: 2025-07-18 +**Documentation Restructuring**: Phase 1 Complete \ No newline at end of file diff --git a/docs/ai-quick-reference.md b/docs/ai-quick-reference.md new file mode 100644 index 0000000..551c016 --- /dev/null +++ b/docs/ai-quick-reference.md @@ -0,0 +1,252 @@ +# AshEvents AI Assistant Quick Reference + +## Emergency Commands + +### 🚨 CRITICAL REMINDERS +- **ALWAYS set actor when performing actions** - Never omit actor attribution +- **ALWAYS read [usage-rules.md](../usage-rules.md) before implementing** - Contains comprehensive patterns +- **ALWAYS implement `clear_records_for_replay` module** - Required for event replay functionality + +### Core Commands + +```bash +# Database Management +mix test.reset # Drop, create, and migrate test database +mix test.create # Create test database +mix test.migrate # Run migrations +mix test.generate_migrations # Generate new migrations + +# Testing +mix test # Run all tests +mix test --trace # Run tests with detailed output +mix test test/specific_test.exs # Run specific test file + +# Code Quality +mix credo --strict # Run linting with strict rules +mix dialyzer # Run type checking +mix format # Format code + +# Documentation +mix docs # Generate documentation +mix ash.codegen # Run Ash codegen tasks +``` + +## Quick Task Patterns + +### Add Event Tracking to Resource +1. Add extension: `extensions: [AshEvents.Events]` +2. Configure event log: `event_log MyApp.Events.Event` +3. Set actor when performing actions: `actor: current_user` + +### Create Event Log Resource +1. Create resource with `AshEvents.EventLog` extension +2. Configure `clear_records_for_replay` module +3. Set `primary_key_type Ash.Type.UUIDv7` for performance +4. Add actor attribution: `persist_actor_primary_key :user_id, MyApp.User` + +### Event Replay Implementation +1. Implement `clear_records_for_replay` module +2. Use `AshEvents.ClearRecordsForReplay` behaviour +3. Call replay action: `Ash.ActionInput.for_action(:replay, %{})` + +## Common Error Patterns + +### Missing Actor Attribution +**Symptoms**: Events created without actor information +**Solution**: Always set actor when performing actions +**Command**: `Ash.create!(changeset, actor: current_user)` + +### Clear Records Not Implemented +**Symptoms**: Compilation error about missing clear_records_for_replay +**Solution**: Implement the clear records module +**Command**: `use AshEvents.ClearRecordsForReplay` + +### Event Replay Failures +**Symptoms**: Replay action fails with missing records +**Solution**: Ensure clear_records! implementation clears all tracked resources +**Command**: Check `clear_records!` implementation covers all event-tracked resources + +## Critical File Locations + +### Core Implementation Files +- **Event Log Extension**: `lib/event_log/event_log.ex` +- **Events Extension**: `lib/events/events.ex` +- **Action Wrappers**: `lib/events/*_action_wrapper.ex` +- **Replay Logic**: `lib/event_log/replay.ex` + +### Test Support Files +- **Event Log Example**: `test/support/events/event_log.ex` +- **Clear Records Example**: `test/support/events/clear_records.ex` +- **User Resource Example**: `test/support/accounts/user.ex` +- **Test Configuration**: `test/support/test_repo.ex` + +### Configuration Files +- **Project Config**: `mix.exs` +- **Test Config**: `config/test.exs` +- **App Config**: `config/config.exs` + +## Event Log Resource Pattern + +```elixir +defmodule MyApp.Events.Event do + use Ash.Resource, + extensions: [AshEvents.EventLog] + + event_log do + clear_records_for_replay MyApp.Events.ClearAllRecords + primary_key_type Ash.Type.UUIDv7 + persist_actor_primary_key :user_id, MyApp.User + end +end +``` + +## Events Extension Pattern + +```elixir +defmodule MyApp.Accounts.User do + use Ash.Resource, + extensions: [AshEvents.Events] + + events do + event_log MyApp.Events.Event + current_action_versions create: 1, update: 1 + end +end +``` + +## Clear Records Pattern + +```elixir +defmodule MyApp.Events.ClearAllRecords do + use AshEvents.ClearRecordsForReplay + + @impl true + def clear_records!(opts) do + # Clear all resources with event tracking + MyApp.User |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + :ok + end +end +``` + +## Actor Attribution Pattern + +```elixir +# CORRECT - Always set actor +user = User +|> Ash.Changeset.for_create(:create, %{name: "John"}) +|> Ash.create!(actor: current_user) + +# INCORRECT - No actor attribution +user = User +|> Ash.Changeset.for_create(:create, %{name: "John"}) +|> Ash.create!() +``` + +## Metadata Pattern + +```elixir +User +|> Ash.Changeset.for_create(:create, %{name: "Jane"}, [ + actor: current_user, + context: %{ash_events_metadata: %{ + source: "api", + request_id: request_id, + ip_address: client_ip + }} +]) +|> Ash.create!() +``` + +## Event Replay Pattern + +```elixir +# Replay all events +MyApp.Events.Event +|> Ash.ActionInput.for_action(:replay, %{}) +|> Ash.run_action!() + +# Replay up to specific event +MyApp.Events.Event +|> Ash.ActionInput.for_action(:replay, %{last_event_id: 1000}) +|> Ash.run_action!() +``` + +## Version Management Pattern + +```elixir +# In Event Log Resource +replay_overrides do + replay_override MyApp.User, :create do + versions [1] + route_to MyApp.User, :old_create_v1 + end +end + +# In Resource +events do + event_log MyApp.Events.Event + current_action_versions create: 2, update: 1 + ignore_actions [:old_create_v1] +end +``` + +## Side Effects Pattern + +```elixir +# CORRECT - Side effects as separate actions +actions do + create :create do + change after_action(fn changeset, user, context -> + MyApp.Notifications.Email + |> Ash.Changeset.for_create(:send_welcome, %{user_id: user.id}) + |> Ash.create!(actor: context.actor) + + {:ok, user} + end) + end +end + +# Email resource also tracks events +defmodule MyApp.Notifications.Email do + use Ash.Resource, extensions: [AshEvents.Events] + + events do + event_log MyApp.Events.Event + end +end +``` + +## Testing Pattern + +```elixir +test "creates user with event tracking" do + user = User + |> Ash.Changeset.for_create(:create, %{name: "Test"}) + |> Ash.create!(authorize?: false) + + events = MyApp.Events.Event |> Ash.read!(authorize?: false) + assert length(events) == 1 + assert hd(events).resource == MyApp.User +end +``` + +## Validation Checklist + +- [ ] Event log resource created with `AshEvents.EventLog` extension +- [ ] Clear records module implemented with `AshEvents.ClearRecordsForReplay` +- [ ] Resources have `AshEvents.Events` extension with event_log configured +- [ ] Actor attribution set on all actions +- [ ] Metadata includes relevant context information +- [ ] Side effects implemented as separate tracked actions +- [ ] Version management configured for schema evolution +- [ ] Tests verify event creation and replay functionality + +## Common Gotchas + +- **Lifecycle hooks skipped during replay** - Side effects won't re-execute +- **Actor attribution required** - Events without actors lose audit trail +- **Clear records must be comprehensive** - Must clear all event-tracked resources +- **Metadata size limits** - Keep metadata reasonable for JSON storage +- **Version management complexity** - Plan schema evolution carefully +- **Advisory locks** - Used automatically for concurrency control \ No newline at end of file diff --git a/docs/ai-readme-update-guide.md b/docs/ai-readme-update-guide.md new file mode 100644 index 0000000..45c2dc1 --- /dev/null +++ b/docs/ai-readme-update-guide.md @@ -0,0 +1,656 @@ +# AI README Update Guide + +## Overview + +This guide provides comprehensive instructions for creating and maintaining an excellent README.md file for your project. The README serves as the primary entry point for end-users and is crucial for project adoption and success. + +## 🚨 CRITICAL: END-USER FOCUS ONLY + +**MANDATORY RULE**: The README must ONLY contain information relevant to end-users who want to USE the project, not develop it. + +### ❌ AVOID These Internal Details: +- Development setup for contributing to the project +- Internal testing procedures for the project itself +- Migration guides (unless the project is specifically a replacement tool) +- Internal implementation details +- Contributor development workflows +- Project maintenance procedures + +### ✅ INCLUDE End-User Content: +- How to install and use the project +- How to test applications that use the project +- How to configure the project for different use cases +- Performance considerations for production use +- Troubleshooting user issues +- Contributing guidelines (brief, with links to detailed guides) + +## Purpose and Scope + +### What a Great README Should Achieve + +A top-notch README should: +- **Immediately communicate value**: Users should understand what the project does and why they need it within seconds +- **Provide quick wins**: Users should be able to get started successfully within minutes +- **Build confidence**: Clear examples and comprehensive documentation reduce friction +- **Support different user types**: From beginners to advanced users seeking specific features +- **Drive adoption**: Compelling presentation encourages usage and contribution + +### Target Audience + +The README targets several distinct user groups: +- **Elixir developers** looking for event sourcing solutions in the Ash ecosystem +- **Full-stack developers** building applications that need audit trails and event replay +- **Teams** evaluating event sourcing solutions for their specific needs +- **DevOps engineers** implementing event-driven architectures + +**NOT the target audience**: +- Contributors who want to work on the project itself (they should read CLAUDE.md and other dev docs) +- Maintainers looking for internal procedures (they should read internal documentation) + +## Content Structure and Guidelines + +### Essential README Structure + +All README files should follow this proven structure: + +```markdown +# Project Title + +Brief, compelling description (1-2 sentences) + +## Why [Project Name]? + +Value proposition and key benefits + +## Features + +Core capabilities and benefits + +## Quick Start + +Minimal working example (copy-paste ready) + +## Installation + +Quick installation instructions + +## Usage + +Comprehensive examples and patterns + +## Configuration + +Configuration options and customization + +## Advanced Features + +Complex usage patterns and edge cases + +## Event Log Structure (project-specific) + +What events look like + +## How It Works + +High-level explanation of the approach + +## Best Practices + +End-user best practices for production use + +## Troubleshooting + +Common user issues and solutions + +## Documentation + +Links to comprehensive documentation + +## Community + +Contributing guidelines and support channels + +## Reference + +API documentation links +``` + +### 🚨 SECTIONS TO AVOID + +**Never include these sections in end-user README:** +- **Migration Guide** (unless project is specifically designed as a replacement) +- **Development Setup** (for working on the project itself) +- **Internal Testing** (testing the project, not applications using it) +- **Maintenance Procedures** (internal project maintenance) +- **Architecture Decisions** (internal design choices) +- **Performance Internals** (internal implementation details) + +### Content Quality Standards + +**1. Clarity and Accessibility** +- Use clear, jargon-free language +- Provide context for technical terms +- Include visual examples where helpful +- Structure content for easy scanning + +**2. Practical Examples** +- Show real, working code examples +- Include complete, copy-paste ready snippets +- Demonstrate common use cases first +- Progress from simple to complex scenarios + +**3. Comprehensive Coverage** +- Cover all major features and capabilities +- Include edge cases and gotchas +- Provide troubleshooting guidance +- Link to additional resources + +**4. Professional Presentation** +- Use consistent formatting and style +- Include proper headings and organization +- Add visual elements (badges, diagrams) when helpful +- Maintain up-to-date information + +## Project-Specific Guidelines + +### Project Title and Description + +**Title**: Should be clear and memorable +```markdown +# AshEvents + +An extension for the Ash Framework that provides event capabilities for Ash resources, enabling complete audit trails and powerful event replay functionality. +``` + +**Description**: Expand on the value proposition +```markdown +AshEvents provides automatic event logging for Ash resources, ensuring complete audit trails and enabling powerful replay functionality. Track all changes, rebuild state from events, and handle schema evolution with version management. +``` + +### Installation Section + +**Must Include**: +- Hex package configuration +- Required Elixir and Ash versions +- Database setup requirements + +**Template**: +```markdown +## Installation + +Add `ash_events` to your dependencies in `mix.exs`: + +```elixir +def deps do + [ + {:ash_events, "~> 0.4.2"} + ] +end +``` + +**Requirements:** +- Elixir ~> 1.15 +- Ash ~> 3.5 +- PostgreSQL database +``` + +### Quick Start Section + +**Critical Requirements**: +- Complete, working example +- Copy-paste ready code +- Shows immediate value +- Takes under 5 minutes to implement + +**Template**: +```markdown +## Quick Start + +1. **Create an Event Log Resource:** + +```elixir +defmodule MyApp.Events.Event do + use Ash.Resource, + extensions: [AshEvents.EventLog] + + event_log do + clear_records_for_replay MyApp.Events.ClearAllRecords + primary_key_type Ash.Type.UUIDv7 + persist_actor_primary_key :user_id, MyApp.User + end +end +``` + +2. **Add Event Tracking to Resources:** + +```elixir +defmodule MyApp.User do + use Ash.Resource, + extensions: [AshEvents.Events] + + events do + event_log MyApp.Events.Event + end +end +``` + +3. **Use with Actor Attribution:** + +```elixir +user = User +|> Ash.Changeset.for_create(:create, %{name: "John"}) +|> Ash.create!(actor: current_user) +``` +``` + +### Features Section + +**Structure**: +- Lead with most compelling features +- Use bullet points for scannability +- Include brief explanations +- Highlight unique capabilities + +**Template**: +```markdown +## Features + +- **🔥 Automatic Event Logging** - Records all resource changes automatically +- **🛡️ Complete Audit Trails** - Track who did what and when +- **🚀 Event Replay** - Rebuild state by replaying events chronologically +- **📦 Version Management** - Handle schema evolution with replay overrides +- **🏢 Actor Attribution** - Support multiple actor types (users, systems, etc.) +- **⚡ High Performance** - Optimized for high-volume event logging +- **🔧 Flexible Configuration** - Customize event handling for your needs +``` + +### Usage Section + +**Must Include**: +- Event log resource setup +- Events extension configuration +- Actor attribution patterns +- Event replay examples +- Version management examples + +**Progressive Examples**: +```markdown +## Usage + +### Basic Event Tracking + +[Simple setup examples] + +### Event Replay + +[Replay functionality examples] + +### Advanced Configuration + +[Complex scenarios and patterns] + +### Error Handling + +[How to handle errors and edge cases] +``` + +### Configuration Section + +**Should Cover**: +- Event log resource configuration options +- Events extension configuration +- Actor attribution setup +- Performance optimization settings + +### Advanced Features Section + +**Include**: +- Version management and replay overrides +- Multiple actor type configuration +- Metadata handling and structure +- Performance optimization techniques +- Multi-tenant event handling + +### API Reference Section + +**Structure**: +- Link to generated HexDocs +- Key DSL configurations +- Important function signatures +- Configuration options + +### Examples Section + +**Include**: +- Real-world scenarios +- Complete project examples +- Integration patterns +- Common use cases + +### Testing Section (End-User Focus) + +**✅ INCLUDE - Testing Applications That Use the Project**: +- How to test resources with event tracking +- Testing event creation and replay in user applications +- Test setup patterns for applications using the project +- Testing best practices for end-users + +**❌ AVOID - Testing the Project Itself**: +- Running the project's test suite +- Contributing testing procedures +- Internal testing workflows +- Quality assurance procedures for the project + +### Performance Section (End-User Focus) + +**✅ INCLUDE - Production Usage Considerations**: +- Performance implications for end-users +- Configuration for high-volume scenarios +- Database optimization for event logs +- Monitoring and alerting recommendations + +**❌ AVOID - Internal Implementation Details**: +- Internal algorithm performance +- Development benchmarking procedures +- Internal optimization strategies +- Code profiling techniques + +### Migration Guide Rules + +**✅ INCLUDE Migration Guides When**: +- Project is specifically designed as a replacement for another tool +- Project provides migration utilities or scripts +- Common migration pattern exists that users request + +**❌ AVOID Migration Guides When**: +- Project is an addition to existing ecosystems (like AshEvents to Ash) +- No direct replacement relationship exists +- Migration would be project-specific and not generalizable + +**AshEvents Specific**: AshEvents is an addition to Ash projects, not a replacement for other tools. Users ADD AshEvents to their existing Ash resources, they don't migrate FROM other tools TO AshEvents. + +## Writing Process + +### 1. Planning Phase (Use TodoWrite) + +Create a comprehensive plan with these todos: +- Read current README.md structure and content +- Analyze user feedback and common questions +- Research competitor README files +- Identify missing content and improvement opportunities +- Plan new structure and content sections +- Draft core sections with examples +- Review and refine for clarity and completeness +- Validate all code examples and commands +- Test installation and quick start instructions + +### 2. Content Development + +**Start with Core Value Proposition**: +- What problem does AshEvents solve? +- Why should users choose it over alternatives? +- What makes it unique and valuable? + +**Build Progressive Examples**: +- Start with simplest possible example +- Add complexity gradually +- Show complete, working code +- Include expected outputs + +**Address Common Questions**: +- How does it work with existing Ash projects? +- What are the limitations? +- How does it compare to alternatives? +- What about performance and resource usage? + +### 3. Example Validation + +**Critical Requirements**: +- All code examples must work with current version +- All commands must execute successfully +- All configuration patterns must be tested +- All links must be functional + +**Testing Process**: +1. Create fresh project environment +2. Follow installation instructions exactly +3. Execute all code examples +4. Verify all generated outputs work correctly +5. Test all commands and options +6. Validate all configuration patterns + +### 4. Visual Enhancement + +**Include**: +- Badges for version, build status, documentation +- Code syntax highlighting +- Consistent formatting +- Clear section headings +- Visual separators where helpful + +## Quality Standards + +### Required Elements + +**Every README must include**: +- Clear value proposition +- Complete installation instructions +- Working quick start example +- Comprehensive usage examples +- Configuration documentation +- Link to full documentation +- Contributing guidelines +- License information + +### Content Requirements + +**Code Examples**: +- All examples must be tested and current +- Include complete imports and setup +- Show expected outputs where relevant +- Use realistic data and scenarios + +**Documentation Links**: +- Link to HexDocs +- Reference specific guides and tutorials +- Include troubleshooting resources +- Point to community resources + +### Technical Accuracy + +**Validation Checklist**: +- [ ] All dependencies are correct +- [ ] All version requirements are accurate +- [ ] All code examples execute successfully +- [ ] All configuration options are documented +- [ ] All links are functional +- [ ] All commands work as documented + +## Project-Specific Considerations + +### Unique Selling Points + +**Emphasize**: +- Automatic event logging vs manual alternatives +- End-to-end audit trails across workflows +- Integration with Ash Framework ecosystem +- Performance and optimization benefits +- Built-in version management capabilities + +### Common User Journeys + +**Address These Scenarios**: +- New Ash project adding event tracking +- Existing project migrating from other audit solutions +- Team adopting event sourcing approach +- Large application with complex requirements +- Special environment requirements + +### Integration Context + +**Show Integration With**: +- Ash Framework resources and actions +- AshPostgres for database operations +- Phoenix applications for web interfaces +- LiveView for real-time event monitoring +- CI/CD pipelines for testing + +## Maintenance Guidelines + +### When to Update + +Update README when: +- New major features are added +- Installation process changes +- API interface changes +- New configuration options are added +- User feedback indicates confusion +- Dependencies or requirements change + +### Update Process + +**Standard Workflow**: +1. **Identify Changes**: Review what has changed since last update +2. **Update Examples**: Ensure all code examples work with current version +3. **Validate Commands**: Test all commands and configuration options +4. **Check Links**: Verify all external links are functional +5. **Test Journey**: Follow installation and quick start as new user +6. **Review Feedback**: Address any outstanding user questions or confusion + +### Quality Checks + +**Before Publishing**: +- [ ] All code examples tested in clean environment +- [ ] All commands execute successfully +- [ ] All links are functional +- [ ] Installation instructions are complete +- [ ] Quick start example works end-to-end +- [ ] Configuration options are documented +- [ ] Advanced features are covered +- [ ] Troubleshooting guidance is current +- [ ] **END-USER FOCUS VERIFIED**: No internal project details included +- [ ] **TESTING CONTENT VERIFIED**: Only includes testing applications, not testing the project +- [ ] **PERFORMANCE CONTENT VERIFIED**: Only includes end-user considerations, not internals +- [ ] **NO MIGRATION GUIDES**: Unless project is specifically a replacement tool +- [ ] **COMMUNITY SECTION VERIFIED**: Contributing guidelines only, no development setup + +## Integration with Project Documentation + +### Relationship to Other Docs + +**README.md serves as**: +- Primary entry point for new users +- Quick reference for existing users +- Marketing material for project adoption +- Bridge to comprehensive documentation + +**Relationship to Other Files**: +- **CLAUDE.md**: Internal development guidance (NOT referenced in README) +- **CHANGELOG.md**: Version history and changes +- **docs/**: AI-specific guides and tutorials (NOT referenced in README) +- **HexDocs**: API documentation (LINK from README) +- **usage-rules.md**: Comprehensive usage patterns (LINK from README) + +### Cross-Reference Strategy + +**README should**: +- Link to comprehensive documentation +- Reference specific guides for advanced topics +- Point to examples and tutorials +- Include troubleshooting resources + +**Avoid**: +- Duplicating comprehensive documentation +- Including internal development details +- Overwhelming users with too much information +- Outdated or incorrect cross-references +- **Linking to internal development documentation (CLAUDE.md, docs/ai-*.md)** +- **Referencing contributor-specific resources in main content** + +### Community Section Guidelines + +**✅ INCLUDE in Community Section**: +- Contributing guidelines (brief overview) +- Links to detailed contributing docs +- Code of conduct reference +- Support channels and community resources +- How to get help + +**❌ AVOID in Community Section**: +- Development setup instructions for working on the project +- Internal development workflows +- Maintainer procedures +- Project architecture decisions +- Internal testing procedures + +**Template for Community Section**: +```markdown +## Community + +### Contributing + +We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. + +### Getting Help + +- 📚 **Documentation**: Check the [documentation](#documentation) first +- 💬 **Discord**: Join the [Ash Discord](https://discord.gg/ash-hq) for real-time help +- 🐛 **Issues**: Report bugs on [GitHub Issues](https://github.com/ash-project/ash_events/issues) +- 💡 **Discussions**: Share ideas on [GitHub Discussions](https://github.com/ash-project/ash_events/discussions) + +### Code of Conduct + +This project follows the [Ash Framework Code of Conduct](https://github.com/ash-project/ash/blob/main/CODE_OF_CONDUCT.md). +``` + +## Success Metrics + +### User Experience Goals + +**Users should be able to**: +- Understand value proposition in 30 seconds +- Complete installation in 5 minutes +- Generate their first event in 10 minutes +- Find answers to common questions quickly +- Discover advanced features when needed + +### Quality Indicators + +**Signs of Success**: +- Reduced support questions about basic setup +- Increased adoption and usage +- Positive community feedback +- Successful integration by new users +- Clear understanding of capabilities + +**Signs of Issues**: +- Frequent questions about installation +- Confusion about basic usage +- Abandonment during setup +- Misunderstanding of capabilities +- Negative feedback about documentation + +--- + +## Key Reminders for AshEvents + +### Project-Specific Rules + +1. **No Migration Guides**: AshEvents is an addition to Ash projects, not a replacement for other tools +2. **Testing Focus**: How to test applications that use AshEvents, not how to test AshEvents itself +3. **Performance Focus**: End-user production considerations, not internal implementation details +4. **Community Focus**: Contributing guidelines with links to detailed guides, not development setup + +### Content Validation Questions + +Before adding any section, ask: +- "Does this help end-users USE AshEvents in their applications?" +- "Is this about working ON the AshEvents project itself?" +- "Would a developer adding AshEvents to their Ash project need this information?" + +If the answer to the first question is "no" or the second question is "yes", don't include it. + +--- + +**Last Updated**: 2025-07-18 +**Next Review**: When AshEvents reaches next major version \ No newline at end of file diff --git a/docs/ai-troubleshooting.md b/docs/ai-troubleshooting.md new file mode 100644 index 0000000..9e58a8e --- /dev/null +++ b/docs/ai-troubleshooting.md @@ -0,0 +1,783 @@ +# AshEvents AI Assistant Troubleshooting Guide + +## Overview + +This guide provides systematic troubleshooting approaches for common AshEvents issues, optimized for AI assistant diagnosis and resolution. + +## Environment Issues + +### Mix Dependencies Resolution + +**Symptoms**: +- Compilation errors about missing AshEvents modules +- Version conflicts between Ash and AshEvents +- Missing dependencies during compilation + +**Diagnosis**: +```bash +mix deps.get +mix deps.compile +mix compile +``` + +**Resolution**: +1. Clean and reinstall dependencies: + ```bash + mix deps.clean --all + mix deps.get + mix deps.compile + ``` + +2. Check mix.exs for correct versions: + ```elixir + {:ash, "~> 3.5"}, + {:ash_events, "~> 0.4.2"} + ``` + +3. Verify compatibility matrix in README.md + +**Validation**: +```bash +mix compile --warnings-as-errors +``` + +### Database Connection Issues + +**Symptoms**: +- Database connection errors during tests +- Migration failures +- Repository not found errors + +**Diagnosis**: +```bash +mix test.create +mix test.migrate +``` + +**Resolution**: +1. Reset database completely: + ```bash + mix test.reset + ``` + +2. Check database configuration in `config/test.exs`: + ```elixir + config :ash_events, AshEvents.TestRepo, + username: "postgres", + password: "postgres", + hostname: "localhost", + database: "ash_events_test" + ``` + +3. Verify PostgreSQL is running and accessible + +**Validation**: +```bash +mix test.create && mix test.migrate +``` + +### Compilation Issues + +**Symptoms**: +- DSL compilation errors +- Extension not found errors +- Behaviour implementation errors + +**Diagnosis**: +```bash +mix compile --force +``` + +**Resolution**: +1. Check extension configuration: + ```elixir + use Ash.Resource, + extensions: [AshEvents.EventLog] # or [AshEvents.Events] + ``` + +2. Verify behaviour implementation: + ```elixir + defmodule MyApp.Events.ClearAllRecords do + use AshEvents.ClearRecordsForReplay + + @impl true + def clear_records!(opts) do + :ok + end + end + ``` + +3. Clean and recompile: + ```bash + mix clean + mix compile + ``` + +**Validation**: +```bash +mix compile --warnings-as-errors +``` + +## Event Tracking Issues + +### Events Not Being Created + +**Error Pattern**: +``` +No events found after performing action +``` + +**Common Causes**: +- Missing Events extension on resource +- Event log not configured +- Actor not set during action + +**Resolution Steps**: +1. Check resource has Events extension: + ```elixir + defmodule MyApp.User do + use Ash.Resource, + extensions: [AshEvents.Events] # Must be present + end + ``` + +2. Verify event log configuration: + ```elixir + events do + event_log MyApp.Events.Event # Must reference event log resource + end + ``` + +3. Ensure actor is set: + ```elixir + User + |> Ash.Changeset.for_create(:create, %{name: "Test"}) + |> Ash.create!(actor: current_user) # Actor must be set + ``` + +**Prevention**: +- Always use Events extension for tracked resources +- Always configure event_log reference +- Always set actor in actions + +### Event Log Configuration Errors + +**Error Pattern**: +``` +Event log resource not found or misconfigured +``` + +**Common Causes**: +- Event log resource missing EventLog extension +- Clear records module not implemented +- Actor configuration incorrect + +**Resolution Steps**: +1. Check event log resource configuration: + ```elixir + defmodule MyApp.Events.Event do + use Ash.Resource, + extensions: [AshEvents.EventLog] # Must be present + + event_log do + clear_records_for_replay MyApp.Events.ClearAllRecords + persist_actor_primary_key :user_id, MyApp.User + end + end + ``` + +2. Implement clear records module: + ```elixir + defmodule MyApp.Events.ClearAllRecords do + use AshEvents.ClearRecordsForReplay + + @impl true + def clear_records!(opts) do + # Clear all tracked resources + :ok + end + end + ``` + +3. Test event log functionality: + ```bash + mix test test/support/events/ + ``` + +**Prevention**: +- Always implement clear_records_for_replay +- Always configure actor attribution +- Test event log resource independently + +### Actor Attribution Problems + +**Error Pattern**: +``` +Events created without actor information +``` + +**Common Causes**: +- Actor not set during actions +- Actor configuration missing in event log +- Wrong actor type used + +**Resolution Steps**: +1. Configure actor types in event log: + ```elixir + event_log do + persist_actor_primary_key :user_id, MyApp.User + persist_actor_primary_key :system_actor, MyApp.SystemActor, attribute_type: :string + end + ``` + +2. Always set actor in actions: + ```elixir + User + |> Ash.Changeset.for_create(:create, %{name: "Test"}) + |> Ash.create!(actor: current_user) + ``` + +3. Test actor attribution: + ```elixir + test "events contain actor attribution" do + actor = %{id: 1, name: "Test"} + + user = User + |> Ash.Changeset.for_create(:create, %{name: "Test"}) + |> Ash.create!(actor: actor) + + events = MyApp.Events.Event |> Ash.read!() + event = hd(events) + assert event.user_id == actor.id + end + ``` + +**Prevention**: +- Configure all actor types in event log +- Always set actor in actions +- Test actor attribution in all scenarios + +## Event Replay Issues + +### Replay Failures + +**Error Pattern**: +``` +Event replay failed with errors +``` + +**Common Causes**: +- Incomplete clear_records implementation +- Missing resources during replay +- Version management issues + +**Resolution Steps**: +1. Check clear_records implementation: + ```elixir + defmodule MyApp.Events.ClearAllRecords do + use AshEvents.ClearRecordsForReplay + + @impl true + def clear_records!(opts) do + # Must clear ALL resources with event tracking + MyApp.UserRole |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + MyApp.User |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + MyApp.Org |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + :ok + end + end + ``` + +2. Test clear_records functionality: + ```elixir + test "clear_records clears all tracked resources" do + # Create test data + user = create_user() + org = create_org() + + # Clear records + MyApp.Events.ClearAllRecords.clear_records!([]) + + # Verify everything is cleared + assert User |> Ash.read!() == [] + assert Org |> Ash.read!() == [] + end + ``` + +3. Test replay functionality: + ```bash + mix test --grep "replay" + ``` + +**Prevention**: +- Include all event-tracked resources in clear_records +- Clear resources in correct dependency order +- Test replay functionality regularly + +### Version Management Issues + +**Error Pattern**: +``` +Events not routing to correct actions during replay +``` + +**Common Causes**: +- Action versions not configured +- Replay overrides missing +- Legacy actions not implemented + +**Resolution Steps**: +1. Configure action versions: + ```elixir + events do + event_log MyApp.Events.Event + current_action_versions create: 2, update: 1 + end + ``` + +2. Set up replay overrides: + ```elixir + replay_overrides do + replay_override MyApp.User, :create do + versions [1] + route_to MyApp.User, :old_create_v1 + end + end + ``` + +3. Implement legacy actions: + ```elixir + actions do + create :old_create_v1 do + # Handle version 1 events + end + end + + events do + ignore_actions [:old_create_v1] + end + ``` + +**Prevention**: +- Plan version management from the start +- Always implement legacy actions for old versions +- Test version routing during replay + +### Data Consistency Issues + +**Error Pattern**: +``` +Replayed state doesn't match expected state +``` + +**Common Causes**: +- Side effects duplicated during replay +- Incomplete event data +- Missing events in replay + +**Resolution Steps**: +1. Check side effect implementation: + ```elixir + # CORRECT - Side effects as separate actions + change after_action(fn changeset, record, context -> + MyApp.Notifications.Email + |> Ash.Changeset.for_create(:send_email, %{user_id: record.id}) + |> Ash.create!(actor: context.actor) + + {:ok, record} + end) + ``` + +2. Verify event completeness: + ```elixir + test "all events are captured" do + # Create, update, destroy operations + user = create_user() + user = update_user(user) + destroy_user(user) + + # Verify all events exist + events = MyApp.Events.Event |> Ash.read!() + assert length(events) == 3 + end + ``` + +3. Test state consistency: + ```elixir + test "replayed state matches original" do + # Create complex state + original_state = create_complex_state() + + # Clear and replay + clear_state() + replay_events() + + # Verify consistency + replayed_state = get_current_state() + assert replayed_state == original_state + end + ``` + +**Prevention**: +- Implement side effects as separate tracked actions +- Test event completeness for all operations +- Verify state consistency after replay + +## Database Issues + +### Migration Problems + +**Error Pattern**: +``` +Migration generation or execution failures +``` + +**Common Causes**: +- Database schema conflicts +- Migration dependency issues +- Resource configuration changes + +**Resolution Steps**: +1. Generate clean migrations: + ```bash + mix test.reset + mix test.generate_migrations + ``` + +2. Check for schema conflicts: + ```bash + mix test.generate_migrations --check + ``` + +3. Resolve migration issues: + ```bash + mix test.migrate + ``` + +**Validation**: +```bash +mix test.reset && mix test.migrate +``` + +### Database Performance Issues + +**Error Pattern**: +``` +Slow event queries or replay operations +``` + +**Common Causes**: +- Missing database indexes +- Inefficient primary key types +- Large event volumes + +**Resolution Steps**: +1. Use optimal primary key type: + ```elixir + event_log do + primary_key_type Ash.Type.UUIDv7 # Better for time-ordered events + end + ``` + +2. Add database indexes: + ```elixir + # In migration + create index(:events, [:resource]) + create index(:events, [:occurred_at]) + create index(:events, [:user_id]) + ``` + +3. Monitor query performance: + ```bash + mix test --trace + ``` + +**Prevention**: +- Use UUIDv7 for event primary keys +- Index frequently queried fields +- Monitor performance with realistic data volumes + +### Database Connection Pool Issues + +**Error Pattern**: +``` +Database connection timeout or pool exhaustion +``` + +**Common Causes**: +- Connection pool too small +- Long-running transactions +- Connection leaks + +**Resolution Steps**: +1. Increase connection pool size: + ```elixir + config :ash_events, AshEvents.TestRepo, + pool_size: 10 + ``` + +2. Check for connection leaks: + ```bash + mix test --trace + ``` + +3. Monitor connection usage: + ```elixir + # In test setup + :ok = Ecto.Adapters.SQL.Sandbox.checkout(AshEvents.TestRepo) + ``` + +**Prevention**: +- Configure adequate connection pool size +- Use database sandbox in tests +- Monitor connection pool usage + +## Performance Issues + +### Event Creation Performance + +**Error Pattern**: +``` +Slow event creation during actions +``` + +**Common Causes**: +- Inefficient event storage +- Large metadata payloads +- Database contention + +**Resolution Steps**: +1. Optimize event storage: + ```elixir + event_log do + primary_key_type Ash.Type.UUIDv7 + end + ``` + +2. Reduce metadata size: + ```elixir + context: %{ash_events_metadata: %{ + source: "api", + request_id: request_id # Keep minimal + }} + ``` + +3. Use advisory locks efficiently: + ```elixir + event_log do + advisory_lock_key_default 31337 + end + ``` + +**Prevention**: +- Use optimal primary key types +- Keep metadata concise +- Monitor event creation performance + +### Replay Performance + +**Error Pattern**: +``` +Slow event replay operations +``` + +**Common Causes**: +- Large event volumes +- Inefficient clear_records implementation +- Database performance issues + +**Resolution Steps**: +1. Optimize clear_records: + ```elixir + def clear_records!(opts) do + # Use bulk operations + MyApp.User |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + :ok + end + ``` + +2. Batch event processing: + ```elixir + # Process events in batches during replay + events = MyApp.Events.Event + |> Ash.Query.sort(occurred_at: :asc) + |> Ash.Query.limit(1000) + |> Ash.read!() + ``` + +3. Monitor replay performance: + ```bash + time mix test --grep "replay" + ``` + +**Prevention**: +- Use bulk operations for clearing +- Consider event archiving strategies +- Monitor replay performance + +## Emergency Recovery + +### Complete System Recovery + +**When to Use**: Complete database corruption or major replay failure + +**Recovery Steps**: +1. **Backup Current State**: + ```bash + pg_dump ash_events_test > backup.sql + ``` + +2. **Reset Database**: + ```bash + mix test.reset + ``` + +3. **Verify Migration**: + ```bash + mix test.generate_migrations --check + ``` + +4. **Restore Known Good State**: + ```bash + # Restore from backup or recreate test data + mix test.reset + ``` + +5. **Validate Functionality**: + ```bash + mix test + ``` + +### Partial Recovery + +**When to Use**: Specific event or resource issues + +**Recovery Steps**: +1. **Identify Problem**: + ```bash + mix test --grep "specific_issue" + ``` + +2. **Clear Affected Resources**: + ```elixir + MyApp.ProblemResource |> Ash.bulk_destroy!(:destroy, %{}, authorize?: false) + ``` + +3. **Replay Subset of Events**: + ```elixir + MyApp.Events.Event + |> Ash.ActionInput.for_action(:replay, %{last_event_id: specific_id}) + |> Ash.run_action!() + ``` + +4. **Verify State**: + ```bash + mix test --grep "state_verification" + ``` + +## Troubleshooting Workflows + +### Systematic Diagnosis + +1. **Environment Check**: + ```bash + mix deps.get && mix deps.compile + ``` + +2. **Database Validation**: + ```bash + mix test.reset + ``` + +3. **Compilation Check**: + ```bash + mix compile --warnings-as-errors + ``` + +4. **Test Execution**: + ```bash + mix test --trace + ``` + +5. **Quality Validation**: + ```bash + mix credo --strict + ``` + +### Quick Diagnostic + +For immediate issue resolution: + +```bash +# 1. Check basic functionality +mix test test/ash_events_test.exs + +# 2. Check event creation +mix test -t event_creation + +# 3. Check event replay +mix test -t event_replay + +# 4. Check database state +mix test.reset && mix test +``` + +## Prevention Strategies + +### Event Tracking Prevention +- Always use Events extension for tracked resources +- Always configure event_log reference +- Always set actor attribution +- Test event creation for all actions + +### Replay Prevention +- Implement comprehensive clear_records +- Test replay functionality regularly +- Configure version management proactively +- Handle side effects as separate actions + +### Performance Prevention +- Use optimal primary key types +- Keep metadata concise +- Monitor performance with realistic data +- Use bulk operations for efficiency + +## Logging and Monitoring + +### Event Creation Monitoring +```elixir +# Add logging to debug event creation +require Logger + +defmodule MyApp.Events.DebugWrapper do + def create_event(resource, action, data) do + Logger.info("Creating event for #{resource}.#{action}") + Logger.debug("Event data: #{inspect(data)}") + # Create event + end +end +``` + +### Replay Monitoring +```elixir +# Monitor replay progress +def debug_replay(opts \\ %{}) do + events = MyApp.Events.Event + |> Ash.Query.sort(occurred_at: :asc) + |> Ash.read!() + + Logger.info("Replaying #{length(events)} events") + + # Replay events + MyApp.Events.Event + |> Ash.ActionInput.for_action(:replay, opts) + |> Ash.run_action!() +end +``` + +## External Resources + +- [Ash Framework Documentation](https://hexdocs.pm/ash) +- [AshEvents Documentation](https://hexdocs.pm/ash_events) +- [PostgreSQL Documentation](https://www.postgresql.org/docs/) +- [Elixir Documentation](https://hexdocs.pm/elixir) \ No newline at end of file diff --git a/docs/ai-usage-rules-update-guide.md b/docs/ai-usage-rules-update-guide.md new file mode 100644 index 0000000..1199d23 --- /dev/null +++ b/docs/ai-usage-rules-update-guide.md @@ -0,0 +1,282 @@ +# AI Usage Rules Update Guide + +## Overview + +This guide provides instructions for creating and updating `usage-rules.md` files that help AI assistants work effectively with packages as dependencies. Unlike internal project documentation, usage rules focus exclusively on end-user patterns and best practices for AI assistants working on projects that use the package. + +**File Location**: The `usage-rules.md` file should be created in the project's root folder (same level as README.md and package configuration files). + +## Purpose and Scope + +### What usage-rules.md Is For + +Usage rules are consumed by AI assistants working on projects where this package is a dependency. The file should provide: +- Essential knowledge for correct package usage +- Common patterns and best practices +- Critical gotchas and constraints +- Quick reference information +- Troubleshooting guidance + +### What usage-rules.md Is NOT For + +Usage rules should **not** include: +- Internal package architecture details +- Development workflows for the package itself +- Comprehensive API documentation (link to external docs instead) +- Package maintenance or contribution guidelines +- Implementation details of package internals + +## Content Structure and Guidelines + +### Standard Structure + +All usage-rules.md files should follow this structure: + +```markdown +# PackageName Usage Rules + +## Quick Reference +- Most critical information first +- Key configuration requirements +- Most common usage pattern + +## Core Patterns +- Most common usage patterns (80% of use cases) +- Code examples with explanations +- Required configuration patterns + +## Common Gotchas +- Frequent mistakes and how to avoid them +- Environment-specific issues +- Configuration pitfalls + +## Advanced Features +- Optional but important capabilities +- Complex usage patterns +- Integration considerations + +## Troubleshooting +- Common error patterns and solutions +- Debugging approaches +- When to consult external documentation + +## External Resources +- Links to official documentation +- Important external guides +- Version compatibility information +``` + +### Content Guidelines + +**Be Compact but Comprehensive:** +- Target 300-1100 lines total, depending on package complexity +- Use bullet points and scannable formatting +- Include practical examples +- Focus on actionable information + +**Focus on End-User Patterns:** +- How to configure the package in a consuming project +- Common usage patterns and workflows +- Integration with other tools/frameworks +- Configuration options that matter to end users + +**Highlight Critical Information:** +- Use **bold** for critical constraints +- Use ⚠️ for important warnings +- Use ✅ for recommended patterns +- Use ❌ for anti-patterns + +**Include Practical Examples:** +- Show actual code, not pseudo-code +- Include file paths and directory structure when relevant +- Demonstrate common workflows +- Show both minimal and complete examples + +## Project-Specific Considerations + +When creating usage rules for AshEvents, focus on: + +### Quick Reference Section +- Key requirement: Always set actor attribution +- Primary command: `mix test.reset` for database management +- Generated output: Event log entries with actor attribution + +### Setup Section +- Event log resource creation with AshEvents.EventLog +- Clear records implementation for replay functionality +- Basic actor attribution configuration + +### Core Patterns Section +- Event log resource configuration patterns +- Events extension usage on resources +- Actor attribution in all actions +- Clear records implementation +- Event replay workflow + +### Common Gotchas Section +- **Critical**: Always set actor attribution - never omit actor +- Must implement clear_records_for_replay for replay functionality +- Use mix test.reset instead of mix ecto.reset +- Side effects must be implemented as separate tracked actions +- Version management required for schema evolution + +### Advanced Features Section +- Version management and replay overrides +- Multiple actor type configuration +- Metadata handling and structure +- Performance optimization with UUIDv7 +- Multi-tenant event handling + +### Troubleshooting Section +- "Events not created" errors (missing Events extension or actor) +- "Replay failed" errors (incomplete clear_records implementation) +- Version management configuration issues +- Database migration and performance issues + +## Writing Process + +### 1. Planning Phase (Use TodoWrite) + +Create a comprehensive plan with these todos: +- Research AshEvents documentation and current usage-rules.md +- Analyze event tracking patterns and common usage workflows +- Identify critical constraints and gotchas specific to AshEvents +- Plan content structure and examples +- Write draft content +- Review and refine for clarity and completeness +- Validate examples and commands + +### 2. Research Phase + +**Read Package Documentation:** +- README.md for installation and basic usage +- Current usage-rules.md for existing patterns +- Common workflow patterns in test files + +**Analyze AshEvents Patterns:** +- Check event log resource configuration +- Examine Events extension usage patterns +- Identify actor attribution requirements + +**Identify Key Constraints:** +- Actor attribution mandatory for all actions +- Clear records implementation required for replay +- Version management critical for schema evolution +- Database management using mix test.reset + +### 3. Content Creation + +**Start with Quick Reference:** +- 3-5 bullet points covering 80% of usage +- Key configuration step (Event log resource) +- Primary usage pattern (Events extension + actor attribution) + +**Expand Each Section:** +- Include practical, tested examples +- Focus on patterns that work +- Highlight what commonly goes wrong +- Provide clear, actionable guidance + +**Validate Examples:** +- Ensure all code examples are current and correct +- Test commands and configuration patterns +- Verify links to external documentation +- Check that examples match current package version + +### 4. Review and Refinement + +**Content Review:** +- Is the information accurate for current AshEvents version? +- Are examples practical and tested? +- Is the content focused on end-user patterns? +- Are common gotchas clearly highlighted? + +**Structure Review:** +- Is the file scannable and well-organized? +- Are the most important patterns covered first? +- Is the content appropriately concise? +- Are advanced features clearly separated from basics? + +**AI Assistant Perspective:** +- Would this provide sufficient context for an AI assistant? +- Are common failure modes and solutions covered? +- Is the information actionable and specific? +- Are external documentation links provided where needed? + +## Quality Standards + +### Required Elements + +**Every usage-rules.md file must include:** +- Basic configuration requirements +- At least one complete usage example +- Common gotchas section +- Links to official documentation + +**Content Requirements:** +- All examples must be tested and current +- All configuration patterns must be validated +- All commands must work with current package version +- All links must be functional + +### Validation Process + +**Before Publishing:** +1. Test all code examples in a real project +2. Verify all commands work as documented +3. Check that all links are functional +4. Ensure examples match current package version +5. Validate that gotchas are still relevant + +**Quality Checks:** +- File length appropriate (300-1100 lines) +- Content focused on end-user patterns +- Examples are practical and complete +- Gotchas are clearly highlighted +- Structure follows established pattern + +## Maintenance Guidelines + +### When to Update + +Update usage-rules.md when: +- AshEvents version changes significantly +- Configuration patterns change +- New common gotchas are discovered +- Core usage patterns evolve +- External documentation links change + +### Update Process + +1. **Review Current Content**: Check accuracy against current AshEvents version +2. **Update Examples**: Ensure all code examples work with current version +3. **Validate Commands**: Test all commands and configuration patterns +4. **Check Links**: Verify external documentation links are current +5. **Update Gotchas**: Add new common issues, remove obsolete ones + +### Maintenance Schedule + +- **Major Version Updates**: Full review and update required +- **Minor Version Updates**: Review examples and gotchas +- **Patch Updates**: Verify that current content is still accurate +- **Quarterly**: Review external links and validate examples + +## Integration with Project Documentation + +### Relationship to CLAUDE.md + +Usage rules complement but don't replace project-specific documentation: +- **CLAUDE.md**: Internal project patterns, workflows, and constraints +- **usage-rules.md**: Package-specific usage patterns for AI assistants +- **AI documentation**: Project-specific AI assistant guidance + +### Cross-Reference Strategy + +- Usage rules should link to official AshEvents documentation +- Internal documentation should reference usage rules for AshEvents patterns +- Keep usage rules focused on the package, not project-specific integration + +--- + +**Last Updated**: 2025-07-18 +**Next Review**: When AshEvents reaches next major version \ No newline at end of file diff --git a/docs/ai-validation-safety.md b/docs/ai-validation-safety.md new file mode 100644 index 0000000..17f3fdc --- /dev/null +++ b/docs/ai-validation-safety.md @@ -0,0 +1,407 @@ +# AshEvents AI Assistant Validation & Safety + +## Pre-Change Validation + +### Mandatory Checks Before Any Changes + +1. **Environment Validation** + ```bash + mix deps.get && mix deps.compile + ``` + +2. **Database State Check** + ```bash + mix test.reset + ``` + +3. **Test Status** + ```bash + mix test --trace + ``` + +4. **Code Quality Check** + ```bash + mix credo --strict + ``` + +## Post-Change Validation + +### Required Validation Steps + +1. **Event Tracking Validation** + ```bash + mix test test/ash_events_test.exs --trace + ``` + +2. **Database Migration Validation** + ```bash + mix test.generate_migrations --check + ``` + +3. **Type Checking** + ```bash + mix dialyzer + ``` + +4. **Documentation Generation** + ```bash + mix docs + ``` + +5. **Code Formatting** + ```bash + mix format --check-formatted + ``` + +### Critical Safety Checks + +- [ ] **Actor Attribution**: All actions have proper actor attribution +- [ ] **Clear Records Implementation**: `clear_records_for_replay` module exists and is comprehensive +- [ ] **Event Log Configuration**: Resources properly reference event log resource +- [ ] **Version Management**: Action versions are properly configured for schema evolution +- [ ] **Side Effects**: Side effects are implemented as separate tracked actions +- [ ] **Test Coverage**: New functionality has corresponding tests + +## Testing Workflows + +### Complete Testing Workflow + +1. **Database Reset**: `mix test.reset` +2. **Unit Tests**: `mix test --trace` +3. **Integration Tests**: `mix test test/ash_events_test.exs` +4. **Code Quality**: `mix credo --strict` +5. **Type Checking**: `mix dialyzer` + +### Event Tracking Testing + +```bash +# Test event creation +mix test -t event_creation + +# Test event replay +mix test -t event_replay + +# Test version management +mix test -t version_management + +# Test actor attribution +mix test -t actor_attribution +``` + +### Database Testing + +```bash +# Reset database for clean state +mix test.reset + +# Test migrations +mix test.generate_migrations --check + +# Test tenant migrations (if applicable) +mix test.migrate_tenants + +# Test rollback capability +mix test.rollback +``` + +## Event-Specific Validation + +### Event Log Resource Validation + +```elixir +# Test event log resource compilation +defmodule TestEventLogValidation do + def validate_event_log_resource(module) do + # Check extension is present + assert AshEvents.EventLog in module.spark_dsl_config().extensions + + # Check clear_records_for_replay is configured + event_log_config = module.spark_dsl_config().event_log + assert event_log_config.clear_records_for_replay != nil + + # Check primary key type + assert event_log_config.primary_key_type != nil + end +end +``` + +### Events Extension Validation + +```elixir +# Test events extension compilation +defmodule TestEventsValidation do + def validate_events_extension(module) do + # Check extension is present + assert AshEvents.Events in module.spark_dsl_config().extensions + + # Check event log is configured + events_config = module.spark_dsl_config().events + assert events_config.event_log != nil + + # Check action versions if specified + if events_config.current_action_versions do + assert is_map(events_config.current_action_versions) + end + end +end +``` + +### Actor Attribution Validation + +```elixir +# Test actor attribution in actions +test "actions properly attribute actors" do + user = User + |> Ash.Changeset.for_create(:create, %{name: "Test"}) + |> Ash.create!(actor: %{id: 1, name: "Test Actor"}) + + events = MyApp.Events.Event |> Ash.read!(authorize?: false) + event = Enum.find(events, &(&1.record_id == user.id)) + + assert event.user_id == 1 +end +``` + +### Event Replay Validation + +```elixir +# Test event replay functionality +test "can replay events to rebuild state" do + # Create initial data + user = create_test_user() + update_test_user(user) + + # Store expected final state + expected_state = get_user_state(user.id) + + # Clear state + clear_all_records() + + # Replay events + MyApp.Events.Event + |> Ash.ActionInput.for_action(:replay, %{}) + |> Ash.run_action!(authorize?: false) + + # Verify state is restored + restored_state = get_user_state(user.id) + assert restored_state == expected_state +end +``` + +## Error Recovery + +### Common Recovery Patterns + +#### Database Corruption +1. **Reset Database**: `mix test.reset` +2. **Regenerate Migrations**: `mix test.generate_migrations` +3. **Verify Migration**: `mix test.migrate` + +#### Event Replay Failures +1. **Check Clear Records**: Verify `clear_records!` implementation +2. **Check Version Management**: Verify replay overrides +3. **Check Actor Configuration**: Verify actor attribution setup + +#### Compilation Errors +1. **Clean Dependencies**: `mix deps.clean --all && mix deps.get` +2. **Clean Build**: `mix clean && mix compile` +3. **Reset Database**: `mix test.reset` + +## Quality Assurance + +### Code Quality Checks + +```bash +# Comprehensive code quality validation +mix credo --strict # Linting with strict rules +mix dialyzer # Type checking +mix format --check-formatted # Code formatting +mix compile --warnings-as-errors # Strict compilation +``` + +### Performance Validation + +```bash +# Performance testing for large datasets +mix test test/performance/ --trace # Performance-specific tests +mix test --only slow # Slow test suite +``` + +### Security Validation + +```bash +# Security scanning +mix sobelow --skip -i Config.HTTPS # Security analysis +mix audit # Dependency audit +``` + +## Event-Specific Safety Procedures + +### Before Adding Event Tracking + +1. **Plan Version Management**: Determine initial action versions +2. **Design Clear Records**: Plan what resources need clearing +3. **Configure Actor Types**: Plan actor attribution strategy +4. **Test Side Effects**: Identify and plan side effect handling + +### Before Modifying Event Schema + +1. **Plan Migration Strategy**: How to handle existing events +2. **Configure Replay Overrides**: How to route old event versions +3. **Test Backward Compatibility**: Ensure existing events still work +4. **Document Changes**: Update version numbers and documentation + +### Before Event Replay + +1. **Backup Current State**: Save current data before replay +2. **Verify Clear Records**: Ensure all tracked resources are cleared +3. **Test Replay Logic**: Test with subset of events first +4. **Monitor Performance**: Large replays can be time-consuming + +## Testing Patterns + +### Unit Testing Pattern + +```elixir +defmodule MyApp.EventsTest do + use ExUnit.Case + + setup do + # Reset database for each test + :ok = MyApp.Events.ClearAllRecords.clear_records!([]) + :ok + end + + test "creates event when resource action is performed" do + user = User + |> Ash.Changeset.for_create(:create, %{name: "Test"}) + |> Ash.create!(authorize?: false) + + events = MyApp.Events.Event |> Ash.read!(authorize?: false) + assert length(events) == 1 + + event = hd(events) + assert event.resource == MyApp.User + assert event.record_id == user.id + assert event.action == :create + end +end +``` + +### Integration Testing Pattern + +```elixir +defmodule MyApp.EventReplayTest do + use ExUnit.Case + + test "full event replay scenario" do + # Create test data with events + user = create_user_with_events() + org = create_org_with_events() + associate_user_with_org(user, org) + + # Store expected final state + expected_users = User |> Ash.read!(authorize?: false) + expected_orgs = Org |> Ash.read!(authorize?: false) + + # Clear all data + MyApp.Events.ClearAllRecords.clear_records!([]) + + # Verify data is cleared + assert User |> Ash.read!(authorize?: false) == [] + assert Org |> Ash.read!(authorize?: false) == [] + + # Replay events + MyApp.Events.Event + |> Ash.ActionInput.for_action(:replay, %{}) + |> Ash.run_action!(authorize?: false) + + # Verify state is restored + restored_users = User |> Ash.read!(authorize?: false) + restored_orgs = Org |> Ash.read!(authorize?: false) + + assert length(restored_users) == length(expected_users) + assert length(restored_orgs) == length(expected_orgs) + end +end +``` + +## Debugging Procedures + +### Event Tracking Debug + +```elixir +# Debug event creation +def debug_event_creation(resource, action, params) do + IO.puts("Creating #{resource} with action #{action}") + IO.inspect(params, label: "Parameters") + + result = resource + |> Ash.Changeset.for_create(action, params) + |> Ash.create!(authorize?: false) + + events = MyApp.Events.Event |> Ash.read!(authorize?: false) + IO.inspect(events, label: "Events after creation") + + result +end +``` + +### Event Replay Debug + +```elixir +# Debug event replay +def debug_event_replay(opts \\ %{}) do + events = MyApp.Events.Event + |> Ash.Query.sort(occurred_at: :asc) + |> Ash.read!(authorize?: false) + + IO.puts("Replaying #{length(events)} events") + + Enum.each(events, fn event -> + IO.puts("Replaying event #{event.id}: #{event.resource} #{event.action}") + end) + + MyApp.Events.Event + |> Ash.ActionInput.for_action(:replay, opts) + |> Ash.run_action!(authorize?: false) +end +``` + +## Emergency Procedures + +### Complete System Recovery + +**When to Use**: Complete database corruption or major event replay failure + +**Recovery Steps**: +1. **Backup Current State**: `pg_dump` if using PostgreSQL +2. **Reset Database**: `mix test.reset` +3. **Regenerate Migrations**: `mix test.generate_migrations` +4. **Restore Known Good Data**: From backup or re-create test data +5. **Verify Event Tracking**: Create test events and verify functionality + +### Partial Recovery + +**When to Use**: Specific event replay issues or data inconsistencies + +**Recovery Steps**: +1. **Identify Issue**: Check event log for problematic events +2. **Clear Affected Resources**: Use targeted clearing +3. **Replay Subset**: Replay only affected events +4. **Verify Consistency**: Check data integrity + +## Validation Checklist + +Before any deployment or major change: + +- [ ] All tests pass: `mix test` +- [ ] Code quality passes: `mix credo --strict` +- [ ] Type checking passes: `mix dialyzer` +- [ ] Documentation builds: `mix docs` +- [ ] Migrations are clean: `mix test.generate_migrations --check` +- [ ] Event tracking works: Create test events and verify +- [ ] Event replay works: Test replay with sample data +- [ ] Actor attribution works: Verify events have proper actors +- [ ] Side effects are properly handled: Verify no duplicate effects during replay +- [ ] Performance is acceptable: Test with realistic data volumes \ No newline at end of file From e92f7af670ed358c7f4a1834df3837a8dc776fd6 Mon Sep 17 00:00:00 2001 From: Torkild Kjevik Date: Fri, 25 Jul 2025 10:32:58 +0200 Subject: [PATCH 2/5] fix: silence compile warning for Ecto.Adapters.SQL --- lib/events/action_wrapper_helpers.ex | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/events/action_wrapper_helpers.ex b/lib/events/action_wrapper_helpers.ex index 18c9c3a..abfd07e 100644 --- a/lib/events/action_wrapper_helpers.ex +++ b/lib/events/action_wrapper_helpers.ex @@ -40,11 +40,17 @@ defmodule AshEvents.Events.ActionWrapperHelpers do module_opts[:advisory_lock_key_default] ) - if is_list(lock_key) do - [key1, key2] = lock_key - Ecto.Adapters.SQL.query(pg_repo, "SELECT pg_advisory_xact_lock($1, $2)", [key1, key2]) - else - Ecto.Adapters.SQL.query(pg_repo, "SELECT pg_advisory_xact_lock($1)", [lock_key]) + case Code.ensure_loaded(Ecto.Adapters.SQL) do + {:module, _} -> + if is_list(lock_key) do + [key1, key2] = lock_key + Ecto.Adapters.SQL.query(pg_repo, "SELECT pg_advisory_xact_lock($1, $2)", [key1, key2]) + else + Ecto.Adapters.SQL.query(pg_repo, "SELECT pg_advisory_xact_lock($1)", [lock_key]) + end + + {:error, _} -> + raise "Ecto.Adapters.SQL not available when trying to set advisory lock" end end From 6850872bfe45f5271a69a1e2255b0e02bfed5231 Mon Sep 17 00:00:00 2001 From: Torkild Kjevik Date: Fri, 25 Jul 2025 10:34:07 +0200 Subject: [PATCH 3/5] fix: set ash_postgres as a dependency in any env. --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 41826f9..e86a38f 100644 --- a/mix.exs +++ b/mix.exs @@ -125,7 +125,7 @@ defmodule AshEvents.MixProject do {:ash, ash_version("~> 3.5")}, {:git_ops, "~> 2.0", only: [:dev], runtime: false}, {:sourceror, "~> 1.7", only: [:dev, :test]}, - {:ash_postgres, "~> 2.0", only: [:dev, :test]}, + {:ash_postgres, "~> 2.0"}, {:faker, "~> 0.18", only: :test}, {:ex_check, "~> 0.12", only: [:dev, :test]}, {:credo, ">= 0.0.0", only: [:dev, :test], runtime: false}, From 1adae4dc85d42713ac648b19296903de2e6a728b Mon Sep 17 00:00:00 2001 From: Torkild Kjevik Date: Fri, 25 Jul 2025 10:34:23 +0200 Subject: [PATCH 4/5] fix: Update README.md --- .gitignore | 4 +- README.md | 241 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 242 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 9e0b074..9407891 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # The directory Mix will write compiled artifacts to. /_build/ +/.claude/*.local.json # If you run "mix test --cover", coverage assets end up here. /cover/ @@ -24,6 +25,3 @@ ash_events-*.tar # Temporary files, for example, from tests. /tmp/ - -/test/test.db -reset-db \ No newline at end of file diff --git a/README.md b/README.md index 85a18af..966fac9 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,51 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Hex version badge](https://img.shields.io/hexpm/v/ash_events.svg)](https://hex.pm/packages/ash_events) [![Hexdocs badge](https://img.shields.io/badge/docs-hexdocs-purple)](https://hexdocs.pm/ash_events) + # AshEvents AshEvents is an extension for the [Ash Framework](https://ash-hq.org/) that provides event capabilities for Ash resources. It allows you to track and persist events when actions (create, update, destroy) are performed on your resources, providing a complete audit trail and enabling powerful replay functionality. +## Table of Contents + +- [Why AshEvents?](#why-ashevents) +- [Features](#features) +- [Quick Start](#quick-start) +- [Installation](#installation) +- [Usage](#usage) + - [1. Create an Event Log Resource](#1-create-an-event-log-resource) + - [2. Define a Clear Records Implementation](#2-define-a-clear-records-implementation) + - [3. Enable Event Logging on Resources](#3-enable-event-logging-on-resources) + - [4. Track Metadata with Actions](#4-track-metadata-with-actions) + - [5. Replay Events](#5-replay-events) +- [Event Log Structure](#event-log-structure) +- [Using AshEvents for Audit Logging Only](#using-ashevents-for-audit-logging-only) +- [Differences from ash_paper_trail](#differences-from-ash_paper_trail-with-regards-to-audit-logging) +- [How It Works](#how-it-works) +- [Lifecycle Hooks During Replay](#lifecycle-hooks-during-replay) +- [Best Practices for Side Effects](#best-practices-for-side-effects) +- [Advanced Configuration](#advanced-configuration) +- [Testing](#testing) +- [Performance Considerations](#performance-considerations) +- [Migration Guide](#migration-guide) +- [Troubleshooting](#troubleshooting) +- [Documentation](#documentation) +- [Community](#community) +- [Reference](#reference) + +## Why AshEvents? + +AshEvents solves critical challenges in modern applications: + +- **🔍 Complete Audit Trail**: Know exactly what happened, when, and who did it +- **🔄 Time Travel**: Rebuild your application state at any point in time +- **🔧 Schema Evolution**: Handle changes to your data structure over time +- **📊 Business Intelligence**: Rich event data for analytics and reporting +- **🚀 Event-Driven Architecture**: Build reactive systems with event sourcing +- **🛡️ Compliance**: Meet regulatory requirements with immutable audit logs + +Unlike traditional audit logging, AshEvents provides both audit trails AND the ability to replay events to rebuild state, making it ideal for event sourcing patterns. + ## Features - **Automatic Event Logging**: Records create, update, and destroy actions as events @@ -16,6 +57,50 @@ AshEvents is an extension for the [Ash Framework](https://ash-hq.org/) that prov - **Event Replay**: Rebuild resource state by replaying events - **Version-specific Replay Routing**: Route events to different actions based on their version - **Customizable Metadata**: Attach arbitrary metadata to events +- **Multi-tenant Support**: Works seamlessly with Ash's multitenancy features +- **Type Safety**: Full Elixir type system integration +- **Performance Optimized**: Advisory locks and efficient replay algorithms + +## Quick Start + +Get up and running with AshEvents in 5 minutes: + +1. **Add to your project**: + ```elixir + # In mix.exs + {:ash_events, "~> 0.4.2"} + ``` + +2. **Create an event log resource**: + ```elixir + defmodule MyApp.Events.Event do + use Ash.Resource, extensions: [AshEvents.EventLog] + + event_log do + clear_records_for_replay MyApp.Events.ClearAllRecords + end + end + ``` + +3. **Add events to your resource**: + ```elixir + defmodule MyApp.User do + use Ash.Resource, extensions: [AshEvents.Events] + + events do + event_log MyApp.Events.Event + end + end + ``` + +4. **Always use actor attribution**: + ```elixir + User + |> Ash.Changeset.for_create(:create, %{name: "Jane"}) + |> Ash.create!(actor: current_user) + ``` + +**That's it!** Your actions now create events automatically. See the [full usage guide](#usage) for complete setup. ## Installation @@ -29,6 +114,16 @@ def deps do ] end ``` + +**Version Requirements**: +- Elixir ~> 1.15 +- Ash ~> 3.5 +- PostgreSQL (for AshPostgres users) + +**Installation Notes**: +- Run `mix deps.get` after adding the dependency +- No additional configuration required for basic usage +- See [Advanced Configuration](#advanced-configuration) for customization options > ### Note: Using with AshAuthentication > > When you use **AshEvents** with **AshAuthentication**, you must let AshEvents @@ -478,7 +573,153 @@ event_log do end ``` +## Testing + +When testing applications with AshEvents: + +```elixir +# In your test setup +setup do + # Always use actor attribution in tests + user = create_test_user() + {:ok, user: user} +end + +test "user creation creates event", %{user: actor} do + user = + User + |> Ash.Changeset.for_create(:create, %{name: "Test User"}) + |> Ash.create!(actor: actor) + + # Verify event was created + events = EventLog |> Ash.read!() + assert length(events) == 1 + assert hd(events).action == :create +end +``` + +**Testing Best Practices**: +- Always set actor attribution in tests +- Test both event creation and replay functionality +- Use factories for consistent test data +- Test version migration scenarios + +## Performance Considerations + +**Advisory Locks**: AshEvents uses PostgreSQL advisory locks to prevent race conditions during event creation. This ensures data consistency but may impact high-concurrency scenarios. + +**Event Volume**: Consider event log size for high-volume applications: +- Implement event log archiving strategies +- Use appropriate database indices +- Monitor event log growth + +**Replay Performance**: Event replay processes all events chronologically: +- Optimize clear_records implementation +- Consider parallel processing for large datasets +- Use point-in-time replay for specific scenarios + +**Best Practices**: +- Use UUIDv7 for event log primary keys in multi-tenant setups +- Implement proper database indexing strategies +- Monitor event log size and implement archiving +- Consider read replicas for event analytics + +## Troubleshooting + +### Common Issues + +**Q: Events not being created** +- ✅ Verify actor attribution is set: `actor: current_user` +- ✅ Check that resource has `AshEvents.Events` extension +- ✅ Ensure event log resource is properly configured + +**Q: Replay fails** +- ✅ Implement `clear_records_for_replay` module +- ✅ Verify all event-tracked resources are cleared +- ✅ Check for missing version management configuration + +**Q: Missing actor information** +- ✅ Configure `persist_actor_primary_key` in event log +- ✅ Ensure actor is set for all actions +- ✅ Check actor resource exists and is accessible + +**Q: Performance issues** +- ✅ Review advisory lock configuration +- ✅ Implement database indexing strategies +- ✅ Consider event log archiving + +### Getting Help + +If you encounter issues: +1. Check the [documentation](#documentation) +2. Search existing [GitHub issues](https://github.com/ash-project/ash_events/issues) +3. Join the [Ash Discord](https://discord.gg/ash-hq) for community support +4. Create a [new issue](https://github.com/ash-project/ash_events/issues/new) with reproduction steps + +## Documentation + +AshEvents provides comprehensive documentation: + +### API Documentation +- **[API Reference](https://hexdocs.pm/ash_events)** - Complete API documentation +- **[DSL Reference](documentation/dsls/)** - Event Log and Events DSL guides + +### Usage Documentation +- **[Usage Rules](usage-rules.md)** - Complete patterns and best practices +- **[AI Assistant Guide](CLAUDE.md)** - Development workflows and commands + +### Community Resources +- **[Ash Framework](https://ash-hq.org/)** - Main framework documentation +- **[Discord Community](https://discord.gg/ash-hq)** - Community support and discussions +- **[GitHub Discussions](https://github.com/ash-project/ash_events/discussions)** - Q&A and feature discussions + +## Community + +### Contributing + +We welcome contributions! Please: + +1. **Fork the repository** +2. **Create a feature branch**: `git checkout -b feature/my-feature` +3. **Make your changes** with tests +4. **Run the test suite**: `mix test` +5. **Submit a pull request** + +### Development Setup + +```bash +# Clone the repository +git clone https://github.com/ash-project/ash_events.git +cd ash_events + +# Install dependencies +mix deps.get + +# Set up test database +mix test.reset + +# Run tests +mix test + +# Run quality checks +mix credo --strict +mix dialyzer +``` + +### Code of Conduct + +This project follows the [Ash Framework Code of Conduct](https://github.com/ash-project/ash/blob/main/CODE_OF_CONDUCT.md). + +### Getting Help + +- 📚 **Documentation**: Check the [documentation](#documentation) first +- 💬 **Discord**: Join the [Ash Discord](https://discord.gg/ash-hq) for real-time help +- 🐛 **Issues**: Report bugs on [GitHub Issues](https://github.com/ash-project/ash_events/issues) +- 💡 **Discussions**: Share ideas on [GitHub Discussions](https://github.com/ash-project/ash_events/discussions) + ## Reference - [AshEvents.Events DSL](documentation/dsls/DSL-AshEvents.Events.md) - [AshEvents.EventLog DSL](documentation/dsls/DSL-AshEvents.EventLog.md) +- [Changelog](CHANGELOG.md) +- [Usage Rules](usage-rules.md) From 96f4fbf0ef4a6b66231802804a44506bbc86181a Mon Sep 17 00:00:00 2001 From: Torkild Kjevik Date: Fri, 25 Jul 2025 10:34:34 +0200 Subject: [PATCH 5/5] fix: Update usage-rules.md --- usage-rules.md | 188 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 145 insertions(+), 43 deletions(-) diff --git a/usage-rules.md b/usage-rules.md index b756fd1..fb63916 100644 --- a/usage-rules.md +++ b/usage-rules.md @@ -1,8 +1,61 @@ -# Rules for working with AshEvents +# AshEvents Usage Rules and Patterns + +## 🚨 CRITICAL RULES - READ FIRST + +### **RULE 1: ALWAYS SET ACTOR ATTRIBUTION** + +**MANDATORY**: You MUST set actor attribution for ALL actions that create events. + +```elixir +# ✅ CORRECT - Always set actor +Ash.create!(changeset, actor: current_user) +Ash.update!(changeset, actor: current_user) +Ash.destroy!(record, actor: current_user) + +# ❌ WRONG - Missing actor attribution +Ash.create!(changeset) # Will lose audit trail information +``` + +### **RULE 2: IMPLEMENT CLEAR_RECORDS_FOR_REPLAY** + +**MANDATORY**: You MUST implement the `clear_records_for_replay` module for event replay. + +```elixir +defmodule MyApp.Events.ClearAllRecords do + use AshEvents.ClearRecordsForReplay + + @impl true + def clear_records!(opts) do + # Must clear ALL resources with event tracking + :ok + end +end +``` + +--- + +## Table of Contents + +1. [Understanding AshEvents](#understanding-ashevents) +2. [Core Concepts](#core-concepts) +3. [Quick Start Setup](#quick-start-setup) +4. [Event Tracking Patterns](#event-tracking-patterns) +5. [Event Replay](#event-replay) +6. [Version Management](#version-management) +7. [Side Effects and Lifecycle](#side-effects-and-lifecycle) +8. [Advanced Configuration](#advanced-configuration) +9. [Testing Best Practices](#testing-best-practices) +10. [Common Patterns](#common-patterns) +11. [Error Handling](#error-handling) +12. [Performance & Security](#performance--security) + +--- ## Understanding AshEvents -AshEvents is an extension for the Ash Framework that provides event capabilities for Ash resources. It allows you to track and persist events when actions (create, update, destroy) are performed on your resources, providing a complete audit trail and enabling powerful replay functionality. **Read the documentation thoroughly before implementing** - AshEvents has specific patterns and conventions that must be followed correctly. +AshEvents is an extension for the Ash Framework that provides event capabilities for Ash resources. It allows you to track and persist events when actions (create, update, destroy) are performed on your resources, providing a complete audit trail and enabling powerful replay functionality. + +**🔗 For implementation guidance, see [docs/ai-index.md](docs/ai-index.md)** ## Core Concepts @@ -12,9 +65,9 @@ AshEvents is an extension for the Ash Framework that provides event capabilities - **Actor Attribution**: Stores who performed each action (users, system processes, etc) - **Metadata Tracking**: Attaches arbitrary metadata to events for audit purposes -## Project Structure & Setup +## Quick Start Setup -### 1. Event Log Resource (Required) +### Step 1: Create Event Log Resource (Required) **Always start by creating a centralized event log resource** using the `AshEvents.EventLog` extension: @@ -37,9 +90,9 @@ defmodule MyApp.Events.Event do end ``` -### 2. Clear Records Implementation (Required for Replay) +### Step 2: Clear Records Implementation (Required for Replay) -**Always implement the clear records module** if you plan to use event replay: +**🚨 CRITICAL**: Always implement the clear records module for event replay functionality: ```elixir defmodule MyApp.Events.ClearAllRecords do @@ -54,7 +107,7 @@ defmodule MyApp.Events.ClearAllRecords do end ``` -### 3. Enable Event Tracking on Resources +### Step 3: Enable Event Tracking on Resources **Add the `AshEvents.Events` extension to resources you want to track**: @@ -85,10 +138,10 @@ end **Events are created automatically** when you perform actions on resources with events enabled: ```elixir -# This automatically creates an event in your event log +# ✅ This automatically creates an event in your event log user = User |> Ash.Changeset.for_create(:create, %{name: "John", email: "john@example.com"}) -|> Ash.create!(actor: current_user) +|> Ash.create!(actor: current_user) # 🚨 CRITICAL: Always set actor! ``` ### Adding Metadata to Events @@ -110,18 +163,24 @@ User ### Actor Attribution -**Always set the actor** when performing actions to ensure proper attribution: +**🚨 CRITICAL**: Always set the actor when performing actions to ensure proper attribution: ```elixir -# GOOD - Actor is properly attributed +# ✅ CORRECT - Actor is properly attributed User -|> Ash.Query.for_read(:read, %{}, actor: current_user) -|> Ash.read!() +|> Ash.Changeset.for_create(:create, %{name: "John"}) +|> Ash.create!(actor: current_user) -# BAD - No actor attribution User -|> Ash.Query.for_read(:read, %{}) -|> Ash.read!() +|> Ash.Changeset.for_update(:update, %{name: "Jane"}) +|> Ash.update!(actor: current_user) + +Ash.destroy!(user, actor: current_user) + +# ❌ WRONG - No actor attribution (loses audit trail) +User +|> Ash.Changeset.for_create(:create, %{name: "John"}) +|> Ash.create!() # Missing actor! ``` ## Event Replay @@ -198,15 +257,17 @@ end ## Side Effects and Lifecycle Hooks -### Important: Lifecycle Hooks During Replay +### 🚨 CRITICAL: Lifecycle Hooks During Replay **Understand that ALL lifecycle hooks are skipped during replay**: - `before_action`, `after_action`, `around_action` - `before_transaction`, `after_transaction`, `around_transaction` -This prevents side effects like emails, notifications, or API calls from being triggered during replay. +**Why this matters**: This prevents side effects like emails, notifications, or API calls from being triggered during replay. -### Best Practice: Encapsulate Side Effects +**Key insight**: If you put side effects in lifecycle hooks, they won't execute during replay - this is intentional to prevent duplicate effects. + +### ✅ Best Practice: Encapsulate Side Effects **Create separate Ash actions for side effects** instead of putting them directly in lifecycle hooks: @@ -252,7 +313,7 @@ end ### External Service Integration -**Wrap external API calls in tracked actions**: +**✅ Best Practice**: Wrap external API calls in tracked actions: ```elixir defmodule MyApp.External.APICall do @@ -304,11 +365,11 @@ event_log do end ``` -**Note**: All actor primary key fields must have `allow_nil?: true` (this is the default). +**📝 Note**: All actor primary key fields must have `allow_nil?: true` (this is the default). ### Encryption Support -**Use encryption for sensitive event data**: +**🔐 Use encryption for sensitive event data**: ```elixir event_log do @@ -318,7 +379,7 @@ end ### Advisory Locks -**Configure advisory locks** for high-concurrency scenarios: +**⚡ Configure advisory locks** for high-concurrency scenarios: ```elixir event_log do @@ -329,7 +390,7 @@ end ### Timestamp Tracking -**Configure timestamp tracking** if your resources have custom timestamp fields: +**⏰ Configure timestamp tracking** if your resources have custom timestamp fields: ```elixir events do @@ -343,7 +404,7 @@ end ### Testing with Events -**Use `authorize?: false` in tests** where authorization is not the focus: +**🧪 Use `authorize?: false` in tests** where authorization is not the focus: ```elixir test "creates user with event" do @@ -357,7 +418,7 @@ test "creates user with event" do end ``` -**Test event replay functionality**: +**🧪 Test event replay functionality**: ```elixir test "can replay events to rebuild state" do @@ -383,11 +444,11 @@ end ### Event Creation Failures -**Events are created in the same transaction** as the original action, so event creation failures will rollback the entire operation. +**⚠️ Events are created in the same transaction** as the original action, so event creation failures will rollback the entire operation. ### Replay Failures -**Handle replay failures gracefully**: +**🛠️ Handle replay failures gracefully**: ```elixir case MyApp.Events.Event |> Ash.ActionInput.for_action(:replay, %{}) |> Ash.run_action() do @@ -401,13 +462,13 @@ end ## Audit Logging Only -**You can use AshEvents solely for audit logging** without implementing replay: +**💡 You can use AshEvents solely for audit logging** without implementing replay: 1. **Skip implementing `clear_records_for_replay`** - only needed for replay -2. **Skip defining `current_action_versions`** - only needed for schema evolution during replay +2. **Skip defining `current_action_versions`** - only needed for schema evolution during replay 3. **Skip implementing replay overrides** - only needed for replay functionality -This gives you automatic audit trails without the complexity of event sourcing. +**Benefit**: This gives you automatic audit trails without the complexity of event sourcing. ## Common Patterns @@ -455,18 +516,59 @@ defmodule MyApp.Blog.Post do end ``` -## Performance Considerations +## Performance & Security + +### Performance Considerations + +- **⚡ Event insertion uses advisory locks** to prevent race conditions +- **⏳ Replay operations are sequential** and can be time-consuming for large datasets +- **🗄️ Consider event retention policies** for long-running applications +- **🚀 Use `primary_key_type Ash.Type.UUIDv7`** for better performance with time-ordered events +- **📊 Metadata should be kept reasonable in size** as it's stored as JSON + +### Security Considerations + +- **🔐 Never store sensitive data in metadata** unless using encryption +- **🛡️ Always validate actor permissions** before performing actions +- **🔒 Use encryption** when storing PII or sensitive information in events +- **🚧 Implement proper access controls** on your event log resource +- **📋 Consider data retention requirements** for compliance (GDPR, etc.) + +--- + +## Quick Reference + +### Essential Commands +```bash +# Database management +mix test.reset # Reset test database (preferred) +mix test.create # Create test database +mix test.migrate # Run migrations + +# Testing +mix test # Run all tests +mix test --trace # Run with detailed output + +# Quality +mix credo --strict # Linting +mix dialyzer # Type checking +mix format # Code formatting +``` + +### Must-Have Checklist +- [ ] Event log resource with `AshEvents.EventLog` extension +- [ ] Clear records module with `AshEvents.ClearRecordsForReplay` +- [ ] Resources with `AshEvents.Events` extension +- [ ] Actor attribution on ALL actions +- [ ] Side effects as separate tracked actions +- [ ] Event replay testing -- **Event insertion uses advisory locks** to prevent race conditions -- **Replay operations are sequential** and can be time-consuming for large datasets -- **Consider event retention policies** for long-running applications -- **Use `primary_key_type Ash.Type.UUIDv7`** for better performance with time-ordered events -- **Metadata should be kept reasonable in size** as it's stored as JSON +### Emergency Debugging +1. **Events not created?** → Check actor attribution +2. **Replay fails?** → Check clear records implementation +3. **Compilation errors?** → Check clear_records_for_replay configuration +4. **Performance issues?** → Check advisory locks and metadata size -## Security Considerations +--- -- **Never store sensitive data in metadata** unless using encryption -- **Always validate actor permissions** before performing actions -- **Use encryption** when storing PII or sensitive information in events -- **Implement proper access controls** on your event log resource -- **Consider data retention requirements** for compliance (GDPR, etc.) \ No newline at end of file +**🔗 For more guidance, see [docs/ai-index.md](docs/ai-index.md)** \ No newline at end of file