claude-os/docs/BLOCKS_DEPRECATION_STRATEGY.md
2025-10-27 17:41:44 -05:00

321 lines
8.4 KiB
Markdown

# Block System Deprecation Strategy
**Status**: Research & Planning Phase
**Date**: 2025-10-24
**Purpose**: Plan migration from custom Block templating engine to standard Rails views
---
## Current Block System Architecture
### What Are Blocks?
Blocks are PISTN's custom templating layer that allows CSRs to modify dealer-specific HTML/CSS/JS without code changes.
**Core Components**:
- **Block.rb** (1014 lines) - Hierarchical rendering engine
- **BlockSetting.rb** - Configuration & image handling
- **blocks.js** - Frontend behaviors
- **Admin UI** - Block editor interface
### How Blocks Work
#### 1. Hierarchical Structure (acts_as_tree)
```ruby
# Parent-child relationship with roles
parent_block
├── child_block (role: "header")
├── child_block (role: "content")
└── child_block (role: "footer")
```
#### 2. Template Substitution ({{...}} syntax)
```html
<!-- Variable substitution -->
<h1>{{account.name}}</h1>
<!-- Conditional logic -->
{{if account.has_appointments?}}
<div>{{yield.appointments}}</div>
{{/if}}
<!-- Ternary -->
{{account.is_active? ? 'Open' : 'Closed'}}
<!-- Loops -->
{{yield.services.each do |service|}}
<div>{{service.name}}</div>
{{/yield.services.each}}
```
#### 3. Whitelist Security
```ruby
# Only whitelisted methods can be called
WHITELIST = {
'account' => %w(name phone_number services ...),
'block' => %w(image_url ...),
'ANY' => %w(present? blank? to_s zero?)
}
```
#### 4. Account-Specific Content
- Universal blocks: `account_id = NULL`
- Account-specific: `account_id = specific_account`
- Group inheritance: Accounts inherit parent group's blocks
- Priority: Account-specific > Group > Universal
---
## Why Deprecate Blocks?
### Pain Points
#### Developer Experience
- ❌ 1000+ lines of state machine rendering logic
- ❌ Three languages in one file: HTML + Handlebars + Ruby
- ❌ No IDE support (syntax highlighting, autocomplete)
- ❌ Difficult to debug template logic
#### Maintenance & Testing
- ❌ Complex caching logic (cache invalidation bugs)
- ❌ Hard to unit test (requires full render context)
- ❌ N+1 query potential in template evaluation
- ❌ Security audits need constant whitelist review
#### Performance
- ❌ Interpretation layer (regex parsing, method lookup)
- ❌ Heavy context object passing
- ❌ Caching complexity adds overhead
#### User Experience (CSRs)
- ❌ Admin UI for block editing is clunky
- ❌ Learning curve (handlebars syntax)
- ❌ No real-time preview
- ❌ Error messages unhelpful
#### Architecture
- ⚠️ **Views Still Required**: Rails views exist anyway (blocks are a layer on top)
- ⚠️ **Duplication**: Both block template + Rails view exist
- ⚠️ **Migration Complexity**: Must maintain dual rendering for transition
---
## Migration Strategy
### Phase 1: Analysis & Mapping (Current)
**Tasks**:
1. ✅ Understand Block.rb rendering engine (done)
2. Identify all active blocks in production
3. Categorize blocks:
- Simple HTML passthrough
- Moderate complexity (some conditionals)
- Complex (loops, dynamic content)
4. Map each block to Rails view equivalent
5. Document {{}} syntax usage patterns
6. Identify which blocks use advanced features
**Block 112 Case Study** (Appointment Form):
```
TODO: Query production database
- Block structure
- {{}} syntax patterns
- Block settings used
- Conditional rendering logic
- Child blocks/context
```
### Phase 2: Create Replacement Views
**For Each Block Type**:
1. **Create Rails Partial/View**
```erb
<!-- app/views/account_specific/_appointment_form.html.erb -->
<%= form_for @appointment do |f| %>
<%= f.text_field :date %>
<%= f.text_field :time %>
<%= f.submit %>
<% end %>
```
2. **Move Whitelist Logic to Presenter**
```ruby
# app/presenters/account_presenter.rb
class AccountPresenter
def initialize(account)
@account = account
end
def appointment_link
# Only include if account has appointments enabled
link_to "Book Appointment", appointment_path if @account.appointments_enabled?
end
end
```
3. **Use Rails Helpers**
- Form helpers (form_for, form_with)
- Link helpers (link_to, button_to)
- Conditional helpers (if, unless)
- Loop helpers (each, collect)
### Phase 3: Gradual Migration
**Feature Flag Approach**:
```ruby
# config/initializers/feature_flags.rb
FEATURE_FLAGS = {
use_rails_views: false # Start as false, enable per account
}
# In views/controllers
if account.use_rails_views?
render :appointment_form_v2
else
render_block(112) # Old block system
end
```
**Per-Account Migration**:
- Add boolean `use_rails_views` to Account model
- Gradual rollout: test accounts → all dealers
- Monitor performance & error rates
- Easy rollback if issues
### Phase 4: Decommission
**Remove Block System**:
1. Delete Block rendering code
2. Remove block admin UI
3. Drop blocks/block_settings tables
4. Delete Block & BlockSetting models
5. Remove {{}} template syntax processor
6. Clean up views that use render_block()
---
## Implementation Steps
### Step 1: Research & Planning
- [ ] Query block 112 from production
- [ ] Document all {{}} patterns used
- [ ] Identify all active blocks
- [ ] Categorize by complexity
- [ ] Create mapping document
### Step 2: Build Replacement Views
- [ ] Create V2 views in app/views/account_specific/
- [ ] Create presenters in app/presenters/
- [ ] Move authorization logic to policies
- [ ] Create helpers for common patterns
### Step 3: Feature Flag & Testing
- [ ] Add `use_rails_views` to Account
- [ ] Implement feature flag logic
- [ ] Test with sample accounts
- [ ] Performance testing
- [ ] Error monitoring
### Step 4: Rollout
- [ ] Internal team testing
- [ ] Beta test with select dealers
- [ ] Gradual rollout to all accounts
- [ ] Monitor metrics
- [ ] Collect feedback
### Step 5: Cleanup
- [ ] Remove block system code
- [ ] Delete admin UI
- [ ] Drop database tables
- [ ] Update documentation
---
## Benefits After Migration
| Aspect | Before (Blocks) | After (Rails Views) |
|--------|-----------------|-------------------|
| **Code** | Custom 1000+ line engine | Standard Rails patterns |
| **Language** | HTML + Handlebars + Ruby | ERB only |
| **Testing** | Integration tests required | Standard view tests |
| **IDE** | No support | Full syntax highlighting |
| **Performance** | Interpretation layer | Direct rendering |
| **Security** | Massive whitelist | Rails authorization |
| **Debugging** | Context tracing | Standard stack traces |
| **CSR UX** | Block admin UI | Standard Rails admin (ActiveAdmin, etc) |
| **Onboarding** | Learn handlebars syntax | Standard Rails knowledge |
---
## Risk Mitigation
### Risks
**Performance**: Template rendering much slower?
- Mitigation: Rails view caching (fragment caching, etags)
- Testing: Benchmark before/after
**Breaking Changes**: Block customizations that can't translate?
- Mitigation: Identify edge cases in Phase 1
- Fallback: Keep Block system for complex accounts
**CSR Disruption**: CSRs dependent on block editor?
- Mitigation: Train on new Rails admin interface
- Timeline: Gradual rollout (6+ months)
**Database Migration**: Data loss from dropping tables?
- Mitigation: Archive block data before deletion
- Backup: Keep block definitions in version control
### Contingency Plans
1. If too many blocks use advanced features:
- Keep blocks for "legacy mode"
- Migrate new features to Rails views
- Hybrid approach long-term
2. If performance regression:
- Implement aggressive view caching
- Use Redis for cache
- Defer to background jobs
3. If CSR adoption slow:
- Extend timeline
- Provide better training
- Create CSR-facing abstraction layer
---
## Next Steps
1. **This Session**:
- Query block 112 structure
- Document current {{}} syntax patterns
- Identify block complexity categories
2. **Next Session**:
- Create first V2 view (appointment form)
- Build presenter/helper structure
- Implement feature flag logic
3. **Future**:
- Beta testing with select accounts
- Performance optimization
- Full rollout plan
---
## Resources
- Block.rb: 1014 lines, rendering logic in `render()` and `subbed_content()`
- BlockSetting.rb: Configuration and image handling
- BLOCKS_SYSTEM_GUIDE.md: Comprehensive architecture documentation
- Database: blocks, block_settings, accounts tables
---
**Status**: Ready for Phase 1 Analysis
**Owner**: Engineering Team
**Timeline**: 3-6 months estimated