After considering everyone’s input and discussing with our team, here’s my analysis of the PX versus SDK decision for complex approval routing, focusing on the three key areas: PX maintainability, SDK flexibility, and upgrade compatibility.
PX Maintainability Assessment
PX offers excellent maintainability for straightforward scenarios but faces challenges with complex logic:
Advantages:
- Integrated deployment model - changes deploy with Agile patches
- Built-in transaction management and rollback support
- Direct access to Agile’s internal APIs and workflow context
- No separate infrastructure to manage
- Real-time execution tied to user actions
Disadvantages:
- Difficult to test - requires full Agile environment
- No local debugging - must deploy to server and attach remote debugger
- Complex logic becomes hard to read within PX constraints
- Limited error handling options - exceptions can halt workflow
- Difficult to version control effectively (stored in database)
For your multi-level conditional routing with parallel branches, PX maintainability deteriorates rapidly. Each conditional branch becomes nested if-else logic that’s hard to visualize and modify. The parallel approval branch requirement is particularly problematic - PX doesn’t provide native parallel execution constructs, so you’d be manually managing state across multiple approval objects.
Maintainability Verdict: PX works well for simple rules (“if cost > $10K, add VP approval”) but becomes unmaintainable for complex orchestration. Your requirements suggest SDK would be more maintainable long-term.
SDK Flexibility Analysis
SDK scripting provides superior flexibility for complex approval logic:
Technical Flexibility:
- Full Java language features - use design patterns, inheritance, composition
- Integration with external libraries (workflow engines, rules engines)
- Comprehensive error handling with custom retry logic
- Async processing for long-running operations
- Easy to implement state machines for complex routing
Development Flexibility:
- Standard IDE development with full debugging support
- Unit testing with mocked Agile API
- Version control with Git/SVN
- CI/CD pipeline integration
- Separate development/testing/production promotion
Operational Flexibility:
- Independent scaling - run approval routing on dedicated servers
- Monitoring and alerting through standard tools
- Granular control over execution timing and parallelism
- Easy to add logging, metrics, and performance tracking
For your specific requirements:
// Pseudocode - SDK approval routing structure:
1. Define ApprovalRule interface with evaluate() method
2. Implement specific rules: CostImpactRule, RegulatoryRule, AffectedItemsRule
3. Create ApprovalOrchestrator that chains rules and builds approval graph
4. Implement ParallelApprovalBranch for concurrent approver assignment
5. Add EscalationTimer component that monitors approval age
6. Use ExecutorService for parallel branch execution
7. Persist routing state to custom database tables for resume capability
// Result: Testable, maintainable, extensible architecture
This level of architectural sophistication is nearly impossible with PX.
Flexibility Verdict: SDK provides dramatically better flexibility for complex approval routing. The ability to use proper software engineering practices (design patterns, unit testing, modular architecture) is invaluable for maintainability.
Upgrade Compatibility Comparison
This is where the trade-offs become nuanced:
PX Upgrade Risks:
- Event framework changes can break PX implementations (happened in 9.3.5 → 9.3.6)
- Class loading changes may require PX recompilation
- Internal API deprecations affect PX more severely (no abstraction layer)
- Database schema changes can impact PX data access
- Agile patches may silently change PX behavior
SDK Upgrade Risks:
- Public API deprecations require code updates
- Authentication mechanism changes need adaptation
- Session management changes affect connection logic
- Less frequent but more predictable than PX issues
Historical Data (from our upgrade experiences):
Agile 9.3.3 → 9.3.6 upgrade:
- PX implementations: 40% required modifications (event handling changes)
- SDK scripts: 15% required modifications (mostly API deprecations)
Agile 9.3.6 → 9.3.9 upgrade:
- PX implementations: 25% required modifications (class loading changes)
- SDK scripts: 10% required modifications (authentication updates)
Upgrade Compatibility Verdict: SDK has better upgrade stability because it uses public APIs with deprecation warnings and migration paths. PX relies more heavily on internal implementation details that can change without notice.
Recommendation: Hybrid Approach
Given your complex requirements, I recommend a hybrid architecture that leverages the strengths of both:
-
Use PX as the trigger point only:
- Lightweight PX on ECN StatusChangeEvent
- PX validates basic prerequisites
- PX calls SDK-based approval routing service via REST API or direct method invocation
- PX handles success/failure response and updates ECN accordingly
-
Implement core logic in SDK:
- Build approval routing engine as standalone Java service
- Use proper design patterns (Strategy for rules, Chain of Responsibility for routing)
- Implement comprehensive unit tests
- Deploy as separate service with its own monitoring
-
Benefits of hybrid approach:
- Real-time execution (PX trigger)
- Complex logic in maintainable code (SDK)
- Testability (SDK unit tests)
- Upgrade resilience (thin PX layer minimizes upgrade risk)
- Operational visibility (SDK service monitoring)
This hybrid model is what we implemented for a similar ECN approval routing project, and it’s survived two Agile upgrades with minimal changes. The PX layer remained stable (just a simple API call), while all the complex logic evolution happened in the SDK service where we had proper development practices.
The key insight: don’t treat this as an either/or decision. Use PX for what it’s good at (real-time event triggering), and SDK for what it’s good at (complex business logic). The thin integration layer between them is easy to maintain and upgrade-resistant.