Design and Iterative Refactoring of a Permission Application Workflow on the Do Platform
This article describes the business flow, storage schema, template‑method based code framework, workflow integration, Redis‑based lock mechanism, and two major refactoring iterations that improve the permission‑application approval process for the Do platform.
The Do platform hosts many resources (e.g., 任性, 驾驶舱, 烽火, 数据集市) and roles, requiring fine‑grained permission control. Previously, permission requests were submitted via email, making approval cumbersome and error‑prone. A dedicated permission‑application product was designed to standardize the process and enable one‑click approval or rejection.
Business Process Overview : Users submit requests through a portal, selecting a request type (agent, RD, non‑RD). The request is saved as a snapshot to simplify front‑back interaction. An approval workflow is then dynamically created based on the request content.
Approval Process Design :
Approvers can act via the Do platform (My Approvals), Workflow service, or HI.
When Workflow or HI is used, the system cannot receive immediate callbacks, so a CT task periodically scans request status and syncs it.
Storage Design : Two MySQL tables are used – auth_apply (one record per request) and auth_approve (one record per approval node). This satisfies current needs but does not support multiple approvers per node, limiting future extensibility.
Code Framework : Because the overall flow is similar across request types, the Template Method pattern is applied. An abstract base class Service_Data_ApplySave defines createApplyAndApprove() with abstract steps such as genAuditors() , createApplyWorkFlow() , saveApply() , and createApprove() . Subclasses (e.g., Service_Data_AgentApplySave , Service_Data_RdApplySave ) implement these steps.
Workflow Integration : Workflow requires pre‑configured templates. To support dynamic approval nodes, a lock mechanism based on Redis is introduced to avoid concurrent modifications of templates.
Redis Lock Implementation :
$get = hincrby($key, $processId, 1); // acquire lock; success if $get == 1 $get = hincrby($key, $processId, -1); // release lockProcess B retries until it acquires the lock.
Iteration 1.0 (requirements):
Support multiple approvers per final node (any‑one approval passes).
Add supervisors of hosted tables to the approval chain.
Solution: add auth_approve_user table for per‑node approvers and a mode field in auth_approve to indicate "AND" or "OR" logic. Data migration required a service downtime.
Iteration 2.0 (requirements):
Add VP approval node for special flows.
Enable delegation (A can delegate to B).
Solution: refactor the approval‑creation code to decouple business logic from Workflow integration, splitting methods such as genAuditors() into finer steps and isolating Workflow‑related calls. This reduces future maintenance cost.
Benefits of Refactoring :
Business logic and Workflow integration are decoupled.
Future extensions require only changes to approver generation, not Workflow handling.
Drawbacks :
Performance impact due to updating Workflow templates for each request.
Additional Redis‑based lock adds complexity.
Conclusion : Repeated large‑scale code changes signal the need for refactoring. Anticipating future requirements and designing for flexibility can minimize costly rewrites, though refactoring itself incurs development effort.
References: UML class diagram, Template Method pattern analysis.
Baidu Waimai Technology Team
The Baidu Waimai Technology Team supports and drives the company's business growth. This account provides a platform for engineers to communicate, share, and learn. Follow us for team updates, top technical articles, and internal/external open courses.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.