Initial commit
This commit is contained in:
800
.claude/skills/automation-refactor/EXAMPLE.md
Normal file
800
.claude/skills/automation-refactor/EXAMPLE.md
Normal file
@@ -0,0 +1,800 @@
|
||||
# Automation Refactor - Complete Example
|
||||
|
||||
This document demonstrates a comprehensive workflow refactoring scenario using the automation-refactor skill.
|
||||
|
||||
## Scenario
|
||||
|
||||
**User Request**: "Optimize this Power Automate flow to reduce API calls and improve error handling"
|
||||
|
||||
**Platform**: Power Automate
|
||||
|
||||
**Original Flow Purpose**: Process new SharePoint list items by fetching user details and sending notification emails
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Original Flow (Before Refactoring)
|
||||
|
||||
### Original flow.json
|
||||
|
||||
```json
|
||||
{
|
||||
"definition": {
|
||||
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"triggers": {
|
||||
"When_a_new_item_is_created": {
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"host": {
|
||||
"connectionName": "shared_sharepointonline",
|
||||
"operationId": "GetOnNewItems",
|
||||
"apiId": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline"
|
||||
},
|
||||
"parameters": {
|
||||
"dataset": "https://contoso.sharepoint.com/sites/TeamSite",
|
||||
"table": "RequestsList"
|
||||
}
|
||||
},
|
||||
"recurrence": {
|
||||
"frequency": "Minute",
|
||||
"interval": 5
|
||||
}
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"Get_items": {
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"host": {
|
||||
"connectionName": "shared_sharepointonline",
|
||||
"operationId": "GetItems",
|
||||
"apiId": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline"
|
||||
},
|
||||
"parameters": {
|
||||
"dataset": "https://contoso.sharepoint.com/sites/TeamSite",
|
||||
"table": "RequestsList"
|
||||
}
|
||||
},
|
||||
"runAfter": {}
|
||||
},
|
||||
"Apply_to_each": {
|
||||
"type": "Foreach",
|
||||
"foreach": "@body('Get_items')?['value']",
|
||||
"actions": {
|
||||
"Get_user": {
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"host": {
|
||||
"connectionName": "shared_office365users",
|
||||
"operationId": "UserProfile_V2",
|
||||
"apiId": "/providers/Microsoft.PowerApps/apis/shared_office365users"
|
||||
},
|
||||
"parameters": {
|
||||
"id": "@items('Apply_to_each')?['CreatedBy']?['Email']"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Send_email": {
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"host": {
|
||||
"connectionName": "shared_office365",
|
||||
"operationId": "SendEmailV2",
|
||||
"apiId": "/providers/Microsoft.PowerApps/apis/shared_office365"
|
||||
},
|
||||
"parameters": {
|
||||
"emailMessage/To": "@body('Get_user')?['Mail']",
|
||||
"emailMessage/Subject": "Request Received",
|
||||
"emailMessage/Body": "Your request has been received."
|
||||
}
|
||||
},
|
||||
"runAfter": {
|
||||
"Get_user": ["Succeeded"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"runAfter": {
|
||||
"Get_items": ["Succeeded"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Problems Identified
|
||||
|
||||
1. **Performance Issues**:
|
||||
- Gets ALL items instead of just new ones
|
||||
- Makes individual API call for each user (N+1 query problem)
|
||||
- Sequential processing (no concurrency)
|
||||
- Total: 1 + N + N = 2N+1 API calls for N items
|
||||
|
||||
2. **Reliability Issues**:
|
||||
- No error handling
|
||||
- No retry logic
|
||||
- Single failure breaks entire flow
|
||||
- No logging
|
||||
|
||||
3. **Maintainability Issues**:
|
||||
- Generic action names ("Get_items", "Apply_to_each")
|
||||
- No comments or documentation
|
||||
- Hardcoded values
|
||||
- No variable initialization
|
||||
|
||||
4. **Security Issues**:
|
||||
- Site URL hardcoded in JSON
|
||||
- No input validation
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Analysis & Research
|
||||
|
||||
### Documentation Research Findings
|
||||
|
||||
From `Docs/PowerAutomateDocs/SharePoint/overview.md`:
|
||||
- API Limit: 600 calls per 60 seconds
|
||||
- Recommendation: Use $expand to fetch related data
|
||||
- Best practice: Filter items at source with $filter
|
||||
|
||||
From `Docs/PowerAutomateDocs/Excel/overview.md`:
|
||||
- Recommendation: Use $select to limit fields
|
||||
- Pagination: Default 256 rows, can increase to 5000
|
||||
|
||||
From `Docs/PowerAutomateDocs/BuiltIn/control.md`:
|
||||
- Error handling: Use Scope with Configure run after
|
||||
- Concurrency: Can be enabled for independent operations
|
||||
|
||||
### Optimization Strategy
|
||||
|
||||
1. **Reduce API Calls**:
|
||||
- Use $expand to get user data with items (1 call instead of N+1)
|
||||
- Add $filter to get only recent items
|
||||
- Add $select to fetch only needed fields
|
||||
|
||||
2. **Add Error Handling**:
|
||||
- Wrap operations in Scopes
|
||||
- Add Configure run after for error catching
|
||||
- Log errors for debugging
|
||||
|
||||
3. **Improve Maintainability**:
|
||||
- Rename actions descriptively
|
||||
- Initialize variables at start
|
||||
- Add comments via Compose actions
|
||||
|
||||
4. **Enhance Reliability**:
|
||||
- Add retry logic for transient failures
|
||||
- Validate data before processing
|
||||
- Add monitoring points
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Refactored Flow (After Optimization)
|
||||
|
||||
### Refactored flow.json
|
||||
|
||||
```json
|
||||
{
|
||||
"definition": {
|
||||
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"$connections": {
|
||||
"defaultValue": {},
|
||||
"type": "Object"
|
||||
},
|
||||
"SharePointSiteURL": {
|
||||
"defaultValue": "https://contoso.sharepoint.com/sites/TeamSite",
|
||||
"type": "String"
|
||||
},
|
||||
"ListName": {
|
||||
"defaultValue": "RequestsList",
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
"triggers": {
|
||||
"When_a_new_item_is_created": {
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"host": {
|
||||
"connectionName": "@parameters('$connections')['shared_sharepointonline']['connectionId']",
|
||||
"operationId": "GetOnNewItems",
|
||||
"apiId": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline"
|
||||
},
|
||||
"parameters": {
|
||||
"dataset": "@parameters('SharePointSiteURL')",
|
||||
"table": "@parameters('ListName')"
|
||||
}
|
||||
},
|
||||
"recurrence": {
|
||||
"frequency": "Minute",
|
||||
"interval": 5
|
||||
}
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"Initialize_ErrorLog": {
|
||||
"type": "InitializeVariable",
|
||||
"inputs": {
|
||||
"variables": [{
|
||||
"name": "ErrorLog",
|
||||
"type": "Array",
|
||||
"value": []
|
||||
}]
|
||||
},
|
||||
"runAfter": {},
|
||||
"description": "Stores any errors encountered during processing for debugging"
|
||||
},
|
||||
"Initialize_ProcessedCount": {
|
||||
"type": "InitializeVariable",
|
||||
"inputs": {
|
||||
"variables": [{
|
||||
"name": "ProcessedCount",
|
||||
"type": "Integer",
|
||||
"value": 0
|
||||
}]
|
||||
},
|
||||
"runAfter": {
|
||||
"Initialize_ErrorLog": ["Succeeded"]
|
||||
}
|
||||
},
|
||||
"Main_Processing_Scope": {
|
||||
"type": "Scope",
|
||||
"actions": {
|
||||
"Get_Recent_Items_With_User_Details": {
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"host": {
|
||||
"connectionName": "@parameters('$connections')['shared_sharepointonline']['connectionId']",
|
||||
"operationId": "GetItems",
|
||||
"apiId": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline"
|
||||
},
|
||||
"parameters": {
|
||||
"dataset": "@parameters('SharePointSiteURL')",
|
||||
"table": "@parameters('ListName')",
|
||||
"$filter": "Created ge '@{addDays(utcNow(), -1)}'",
|
||||
"$expand": "Author",
|
||||
"$select": "ID,Title,Author/DisplayName,Author/Email,Created",
|
||||
"$top": 5000
|
||||
}
|
||||
},
|
||||
"runAfter": {},
|
||||
"description": "Fetches items created in last 24h with user details in single API call using $expand",
|
||||
"runtimeConfiguration": {
|
||||
"contentTransfer": {
|
||||
"transferMode": "Chunked"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Check_Items_Exist": {
|
||||
"type": "If",
|
||||
"expression": {
|
||||
"and": [{
|
||||
"greater": [
|
||||
"@length(body('Get_Recent_Items_With_User_Details')?['value'])",
|
||||
0
|
||||
]
|
||||
}]
|
||||
},
|
||||
"actions": {
|
||||
"Process_Each_Request": {
|
||||
"type": "Foreach",
|
||||
"foreach": "@body('Get_Recent_Items_With_User_Details')?['value']",
|
||||
"actions": {
|
||||
"Validate_Email_Exists": {
|
||||
"type": "If",
|
||||
"expression": {
|
||||
"and": [{
|
||||
"not": {
|
||||
"equals": [
|
||||
"@empty(items('Process_Each_Request')?['Author']?['Email'])",
|
||||
true
|
||||
]
|
||||
}
|
||||
}]
|
||||
},
|
||||
"actions": {
|
||||
"Send_Notification_Email": {
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"host": {
|
||||
"connectionName": "@parameters('$connections')['shared_office365']['connectionId']",
|
||||
"operationId": "SendEmailV2",
|
||||
"apiId": "/providers/Microsoft.PowerApps/apis/shared_office365"
|
||||
},
|
||||
"parameters": {
|
||||
"emailMessage/To": "@items('Process_Each_Request')?['Author']?['Email']",
|
||||
"emailMessage/Subject": "Request Received - @{items('Process_Each_Request')?['Title']}",
|
||||
"emailMessage/Body": "<p>Hello @{items('Process_Each_Request')?['Author']?['DisplayName']},</p><p>Your request <strong>@{items('Process_Each_Request')?['Title']}</strong> has been received and is being processed.</p><p>Request ID: @{items('Process_Each_Request')?['ID']}<br>Submitted: @{formatDateTime(items('Process_Each_Request')?['Created'], 'yyyy-MM-dd HH:mm')}</p><p>Thank you!</p>",
|
||||
"emailMessage/Importance": "Normal"
|
||||
}
|
||||
},
|
||||
"runAfter": {},
|
||||
"runtimeConfiguration": {
|
||||
"policy": {
|
||||
"retry": {
|
||||
"type": "exponential",
|
||||
"count": 3,
|
||||
"interval": "PT10S",
|
||||
"minimumInterval": "PT10S",
|
||||
"maximumInterval": "PT1H"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Sends email with retry logic for transient failures"
|
||||
},
|
||||
"Increment_Processed_Count": {
|
||||
"type": "IncrementVariable",
|
||||
"inputs": {
|
||||
"name": "ProcessedCount",
|
||||
"value": 1
|
||||
},
|
||||
"runAfter": {
|
||||
"Send_Notification_Email": ["Succeeded"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"else": {
|
||||
"actions": {
|
||||
"Log_Missing_Email": {
|
||||
"type": "AppendToArrayVariable",
|
||||
"inputs": {
|
||||
"name": "ErrorLog",
|
||||
"value": {
|
||||
"ItemID": "@items('Process_Each_Request')?['ID']",
|
||||
"Error": "Missing author email",
|
||||
"Timestamp": "@utcNow()"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"runAfter": {}
|
||||
}
|
||||
},
|
||||
"runAfter": {},
|
||||
"runtimeConfiguration": {
|
||||
"concurrency": {
|
||||
"repetitions": 5
|
||||
}
|
||||
},
|
||||
"description": "Processes up to 5 items concurrently for faster execution"
|
||||
}
|
||||
},
|
||||
"else": {
|
||||
"actions": {
|
||||
"Log_No_Items": {
|
||||
"type": "Compose",
|
||||
"inputs": "No new items to process",
|
||||
"description": "No items found matching filter criteria"
|
||||
}
|
||||
}
|
||||
},
|
||||
"runAfter": {
|
||||
"Get_Recent_Items_With_User_Details": ["Succeeded"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"runAfter": {
|
||||
"Initialize_ProcessedCount": ["Succeeded"]
|
||||
}
|
||||
},
|
||||
"Error_Handling_Scope": {
|
||||
"type": "Scope",
|
||||
"actions": {
|
||||
"Log_Flow_Error": {
|
||||
"type": "Compose",
|
||||
"inputs": {
|
||||
"FlowRunID": "@workflow()?['run']?['name']",
|
||||
"ErrorDetails": "@result('Main_Processing_Scope')",
|
||||
"ErrorLog": "@variables('ErrorLog')",
|
||||
"ProcessedCount": "@variables('ProcessedCount')",
|
||||
"Timestamp": "@utcNow()"
|
||||
},
|
||||
"runAfter": {}
|
||||
},
|
||||
"Send_Error_Notification_To_Admin": {
|
||||
"type": "ApiConnection",
|
||||
"inputs": {
|
||||
"host": {
|
||||
"connectionName": "@parameters('$connections')['shared_office365']['connectionId']",
|
||||
"operationId": "SendEmailV2",
|
||||
"apiId": "/providers/Microsoft.PowerApps/apis/shared_office365"
|
||||
},
|
||||
"parameters": {
|
||||
"emailMessage/To": "admin@contoso.com",
|
||||
"emailMessage/Subject": "Flow Error - Request Notification System",
|
||||
"emailMessage/Body": "<p><strong>Flow Error Detected</strong></p><p>Flow Run ID: @{workflow()?['run']?['name']}</p><p>Items Processed: @{variables('ProcessedCount')}</p><p>Error Details: <pre>@{body('Log_Flow_Error')}</pre></p>",
|
||||
"emailMessage/Importance": "High"
|
||||
}
|
||||
},
|
||||
"runAfter": {
|
||||
"Log_Flow_Error": ["Succeeded"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"runAfter": {
|
||||
"Main_Processing_Scope": ["Failed", "TimedOut"]
|
||||
},
|
||||
"description": "Handles any errors from main processing and notifies admin"
|
||||
},
|
||||
"Success_Summary": {
|
||||
"type": "Compose",
|
||||
"inputs": {
|
||||
"Status": "Completed Successfully",
|
||||
"ItemsProcessed": "@variables('ProcessedCount')",
|
||||
"ErrorCount": "@length(variables('ErrorLog'))",
|
||||
"Errors": "@variables('ErrorLog')",
|
||||
"CompletionTime": "@utcNow()"
|
||||
},
|
||||
"runAfter": {
|
||||
"Main_Processing_Scope": ["Succeeded"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Refactoring Report
|
||||
|
||||
### Summary
|
||||
|
||||
- **Platform**: Power Automate
|
||||
- **Flow Name**: Request Notification System
|
||||
- **Refactoring Goals**: Reduce API calls, improve error handling, enhance maintainability
|
||||
- **Changes Applied**: 12 major improvements
|
||||
- **Functional Impact**: Maintained equivalence - same notifications sent, same logic
|
||||
- **Performance Improvement**: ~95% reduction in API calls (2N+1 → 1-2 calls)
|
||||
|
||||
---
|
||||
|
||||
### Changes Implemented
|
||||
|
||||
#### Performance Optimizations
|
||||
|
||||
1. **Eliminated N+1 Query Problem**
|
||||
- **Before**: 1 call to get items + N calls to get users = N+1 calls
|
||||
- **After**: 1 call with $expand to get items with user data = 1 call
|
||||
- **Impact**: For 100 items: 101 calls → 1 call (99% reduction)
|
||||
- **Documentation**: Docs/PowerAutomateDocs/SharePoint/overview.md - "Use $expand for related data"
|
||||
|
||||
2. **Added Data Filtering at Source**
|
||||
- **Before**: Fetched all items (potentially thousands)
|
||||
- **After**: $filter for items in last 24 hours only
|
||||
- **Impact**: Reduces data transfer and processing time
|
||||
- **Documentation**: Docs/PowerAutomateDocs/SharePoint/actions.md - "Filter at source with $filter"
|
||||
|
||||
3. **Optimized Field Selection**
|
||||
- **Before**: Retrieved all fields
|
||||
- **After**: $select for only needed fields (ID, Title, Author, Created)
|
||||
- **Impact**: 50-70% reduction in response size
|
||||
- **Documentation**: Docs/PowerAutomateDocs/SharePoint/overview.md - "Use $select to minimize data"
|
||||
|
||||
4. **Enabled Concurrency**
|
||||
- **Before**: Sequential processing (1 email at a time)
|
||||
- **After**: Process 5 items concurrently
|
||||
- **Impact**: 5x faster email sending (safe for independent operations)
|
||||
- **Documentation**: Docs/PowerAutomateDocs/BuiltIn/control.md - "Concurrency for independent actions"
|
||||
|
||||
#### Reliability Improvements
|
||||
|
||||
5. **Added Comprehensive Error Handling**
|
||||
- Wrapped main logic in Scope with error catching
|
||||
- Error Handling Scope runs on failure/timeout
|
||||
- Logs all errors for debugging
|
||||
- **Documentation**: Docs/PowerAutomateDocs/BuiltIn/control.md - "Scope-based error handling"
|
||||
|
||||
6. **Implemented Retry Logic**
|
||||
- Send email action has exponential backoff retry (3 attempts)
|
||||
- Handles transient Office 365 failures gracefully
|
||||
- **Documentation**: Docs/PowerAutomateDocs/Outlook/overview.md - "Retry policy for transient failures"
|
||||
|
||||
7. **Added Input Validation**
|
||||
- Checks if items array is not empty before processing
|
||||
- Validates email address exists before sending
|
||||
- Prevents null reference errors
|
||||
- **Documentation**: Docs/PowerAutomateDocs/BuiltIn/control.md - "Validate inputs"
|
||||
|
||||
8. **Implemented Error Logging**
|
||||
- ErrorLog variable tracks all issues
|
||||
- Captures missing emails, failed sends
|
||||
- Included in admin notification for review
|
||||
- **Custom best practice**
|
||||
|
||||
#### Maintainability Enhancements
|
||||
|
||||
9. **Renamed All Actions Descriptively**
|
||||
- "Get_items" → "Get_Recent_Items_With_User_Details"
|
||||
- "Apply_to_each" → "Process_Each_Request"
|
||||
- "Send_email" → "Send_Notification_Email"
|
||||
- Makes flow immediately understandable
|
||||
- **Documentation**: Docs/PowerAutomateDocs/ - "Use clear, descriptive names"
|
||||
|
||||
10. **Added Descriptive Comments**
|
||||
- Description field on 8 key actions
|
||||
- Explains WHY each action exists
|
||||
- Helps future maintainers understand logic
|
||||
- **Best practice**
|
||||
|
||||
11. **Parameterized Configuration**
|
||||
- SharePointSiteURL as parameter (not hardcoded)
|
||||
- ListName as parameter
|
||||
- Easy to duplicate for other sites/lists
|
||||
- **Documentation**: Docs/PowerAutomateDocs/ - "Use parameters for reusability"
|
||||
|
||||
12. **Organized into Logical Scopes**
|
||||
- Main_Processing_Scope: Core logic
|
||||
- Error_Handling_Scope: Error recovery
|
||||
- Clear separation of concerns
|
||||
- **Documentation**: Docs/PowerAutomateDocs/BuiltIn/control.md - "Organize with Scopes"
|
||||
|
||||
---
|
||||
|
||||
### Documentation References
|
||||
|
||||
All changes based on official Microsoft documentation:
|
||||
|
||||
- `Docs/PowerAutomateDocs/SharePoint/overview.md` - API limits, $expand usage, $filter best practices
|
||||
- `Docs/PowerAutomateDocs/SharePoint/actions.md` - GetItems parameters and optimization
|
||||
- `Docs/PowerAutomateDocs/Outlook/overview.md` - Email retry policy patterns
|
||||
- `Docs/PowerAutomateDocs/BuiltIn/control.md` - Scope-based error handling, concurrency
|
||||
- `Docs/PowerAutomateDocs/BuiltIn/variable.md` - Variable initialization and usage
|
||||
|
||||
---
|
||||
|
||||
### Additional Optimization Opportunities
|
||||
|
||||
#### High Priority (Recommended)
|
||||
|
||||
1. **Implement Caching for Frequently Sent Notifications**
|
||||
- Store sent notifications in SharePoint list
|
||||
- Check before sending to avoid duplicates
|
||||
- **Why not implemented**: Requires additional list/database (architectural change)
|
||||
- **Impact**: Prevents duplicate notifications
|
||||
- **Reference**: Custom pattern
|
||||
|
||||
2. **Add Adaptive Card Emails Instead of HTML**
|
||||
- Richer, interactive notifications
|
||||
- Better mobile experience
|
||||
- **Why not implemented**: Requires Teams integration and redesign
|
||||
- **Impact**: Improved user experience
|
||||
- **Reference**: Docs/PowerAutomateDocs/Teams/overview.md
|
||||
|
||||
3. **Implement Batch Email Sending**
|
||||
- Collect all notifications
|
||||
- Send in single digest email
|
||||
- **Why not implemented**: Changes notification model (behavioral change)
|
||||
- **Impact**: Reduces emails, fewer API calls
|
||||
- **Reference**: Docs/PowerAutomateDocs/Outlook/best-practices.md
|
||||
|
||||
#### Medium Priority
|
||||
|
||||
4. **Add Flow Analytics Dashboard**
|
||||
- Log metrics to Azure Application Insights
|
||||
- Track success rates, performance trends
|
||||
- **Impact**: Better monitoring and optimization insights
|
||||
|
||||
5. **Implement Rate Limit Awareness**
|
||||
- Track API calls per minute
|
||||
- Add dynamic delays if approaching limits
|
||||
- **Impact**: Prevents throttling errors
|
||||
|
||||
#### Low Priority
|
||||
|
||||
6. **Add Unit Testing for Expressions**
|
||||
- Test complex expressions in isolation
|
||||
- Validate before deployment
|
||||
- **Impact**: Reduces runtime errors
|
||||
|
||||
7. **Create Child Flows for Reusability**
|
||||
- Extract email sending to child flow
|
||||
- Reuse across multiple parent flows
|
||||
- **Impact**: Better code reuse, easier maintenance
|
||||
|
||||
---
|
||||
|
||||
### Testing Recommendations
|
||||
|
||||
#### Functional Testing
|
||||
|
||||
1. **Verify Same Emails Sent**
|
||||
- Create test item in SharePoint
|
||||
- Confirm email received by author
|
||||
- Verify email content matches original
|
||||
|
||||
2. **Test with Multiple Items**
|
||||
- Create 10 test items with different authors
|
||||
- Verify all 10 emails sent
|
||||
- Confirm no duplicates or missing emails
|
||||
|
||||
3. **Test Error Scenarios**
|
||||
- Create item with user that has no email
|
||||
- Verify error logged in ErrorLog variable
|
||||
- Confirm flow doesn't fail completely
|
||||
|
||||
4. **Test Empty Scenario**
|
||||
- Run flow with no recent items
|
||||
- Verify flow completes successfully
|
||||
- Check no errors logged
|
||||
|
||||
#### Performance Testing
|
||||
|
||||
1. **Measure API Call Reduction**
|
||||
- **Before**: Check flow run history - count API calls
|
||||
- **After**: Check flow run history - count API calls
|
||||
- **Expected**: ~95% reduction (101 → 1-5 calls for 100 items)
|
||||
|
||||
2. **Measure Execution Time**
|
||||
- **Before**: Note total run duration for 100 items
|
||||
- **After**: Note total run duration for 100 items
|
||||
- **Expected**: 80-90% faster due to concurrency
|
||||
|
||||
3. **Load Testing**
|
||||
- Create 100 test items
|
||||
- Verify all processed successfully
|
||||
- Check for throttling errors (should be none)
|
||||
|
||||
#### Error Testing
|
||||
|
||||
1. **Test Office 365 Outage**
|
||||
- Temporarily disable Office 365 connection
|
||||
- Verify Error_Handling_Scope runs
|
||||
- Verify admin notification sent
|
||||
- Verify ErrorLog captured issue
|
||||
|
||||
2. **Test SharePoint Throttling**
|
||||
- Intentionally trigger throttling (make many rapid calls)
|
||||
- Verify retry logic activates
|
||||
- Verify eventual success or logged failure
|
||||
|
||||
3. **Test Invalid Data**
|
||||
- Create item with null/invalid author
|
||||
- Verify validation catches it
|
||||
- Verify logged in ErrorLog
|
||||
|
||||
---
|
||||
|
||||
### Migration Guide
|
||||
|
||||
#### Deployment Steps
|
||||
|
||||
1. **Backup Original Flow**
|
||||
```
|
||||
- Export original flow as ZIP
|
||||
- Save to safe location with timestamp
|
||||
- Document current version number
|
||||
```
|
||||
|
||||
2. **Create Parameters**
|
||||
```
|
||||
- Add SharePointSiteURL parameter
|
||||
- Add ListName parameter
|
||||
- Set default values from original flow
|
||||
```
|
||||
|
||||
3. **Import Refactored JSON**
|
||||
```
|
||||
- Copy refactored JSON
|
||||
- Use "Paste code" in flow designer
|
||||
- Flow will be imported with new structure
|
||||
```
|
||||
|
||||
4. **Update Connections**
|
||||
```
|
||||
- Reconnect SharePoint connection
|
||||
- Reconnect Office 365 connection
|
||||
- Reconnect Office 365 Users connection (no longer needed - can remove)
|
||||
- Test connections
|
||||
```
|
||||
|
||||
5. **Configure Admin Email**
|
||||
```
|
||||
- Update "Send_Error_Notification_To_Admin" action
|
||||
- Set correct admin email address
|
||||
- Test by manually triggering error
|
||||
```
|
||||
|
||||
6. **Test in Development**
|
||||
```
|
||||
- Run flow manually
|
||||
- Create test SharePoint items
|
||||
- Verify emails received
|
||||
- Check Success_Summary output
|
||||
```
|
||||
|
||||
7. **Deploy to Production**
|
||||
```
|
||||
- Turn off original flow
|
||||
- Turn on refactored flow
|
||||
- Monitor closely for 1 hour
|
||||
- Check run history for errors
|
||||
```
|
||||
|
||||
#### Rollback Plan
|
||||
|
||||
If issues arise:
|
||||
|
||||
1. **Immediate Rollback**
|
||||
```
|
||||
- Turn off refactored flow
|
||||
- Turn on original flow backup
|
||||
- System restored to working state
|
||||
```
|
||||
|
||||
2. **Investigate Issues**
|
||||
```
|
||||
- Review flow run history
|
||||
- Check ErrorLog variable contents
|
||||
- Review admin error notifications
|
||||
- Identify root cause
|
||||
```
|
||||
|
||||
3. **Fix and Retry**
|
||||
```
|
||||
- Apply fix to refactored flow
|
||||
- Test in development again
|
||||
- Redeploy with closer monitoring
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Next Steps
|
||||
|
||||
1. **Review Changes** - Examine refactored JSON and report
|
||||
2. **Test in Development** - Follow testing recommendations above
|
||||
3. **Get Stakeholder Approval** - Share performance improvements
|
||||
4. **Deploy to Production** - Follow migration guide
|
||||
5. **Monitor for 48 Hours** - Watch for any issues
|
||||
6. **Measure Results** - Document actual performance gains
|
||||
7. **Consider Additional Optimizations** - Evaluate high-priority suggestions
|
||||
|
||||
---
|
||||
|
||||
## Results Summary
|
||||
|
||||
### Before Refactoring
|
||||
- **API Calls (100 items)**: 201 calls (1 + 100 + 100)
|
||||
- **Execution Time**: ~120 seconds (sequential)
|
||||
- **Error Handling**: None
|
||||
- **Maintainability**: Poor (cryptic names, no comments)
|
||||
- **Reliability**: Low (single failure breaks flow)
|
||||
- **Security**: Poor (hardcoded values)
|
||||
|
||||
### After Refactoring
|
||||
- **API Calls (100 items)**: 1-5 calls (1 + 0-4 for emails)
|
||||
- **Execution Time**: ~15 seconds (95% concurrency)
|
||||
- **Error Handling**: Comprehensive (Scope-based with admin alerts)
|
||||
- **Maintainability**: Excellent (clear names, comments, parameters)
|
||||
- **Reliability**: High (retry logic, validation, error logging)
|
||||
- **Security**: Good (parameterized, validated inputs)
|
||||
|
||||
### Impact
|
||||
- **95% fewer API calls** → Dramatically reduced throttling risk
|
||||
- **87% faster execution** → Near real-time notifications
|
||||
- **100% error visibility** → No silent failures
|
||||
- **∞% maintainability improvement** → Clear, documented, reusable
|
||||
|
||||
---
|
||||
|
||||
**Refactoring Completed**: 2025-10-31
|
||||
**Documentation Consulted**: 5 official docs
|
||||
**Confidence Level**: High (all changes based on official documentation)
|
||||
**Production Ready**: Yes (after testing)
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
This example demonstrates the power of the automation-refactor skill:
|
||||
|
||||
✅ **Dramatic performance improvement** (95% API reduction, 87% faster)
|
||||
✅ **Production-grade reliability** (comprehensive error handling)
|
||||
✅ **Future-proof maintainability** (clear, documented, parameterized)
|
||||
✅ **Documentation-driven** (no hallucinations, all references cited)
|
||||
✅ **Functional equivalence** (same notifications, same logic)
|
||||
✅ **Actionable guidance** (complete testing & deployment plan)
|
||||
|
||||
The refactored flow does exactly what the original did, just **better, faster, and more reliably**.
|
||||
Reference in New Issue
Block a user