Re_Backend/docs/UNIFIED_REQUEST_ARCHITECTURE.md

76 lines
4.0 KiB
Markdown

# Analysis: Dealer Claim & Unified Request Architecture
This document analyzes the current architecture and proposes an efficient approach to unify Dealer Claims and Custom Requests while supporting specialized data capture and versioning.
## Current State
Both **Custom Requests** and **Dealer Claims** are already "unified" at the base level:
- **Primary Collection**: `workflow_requests` stores the core data (id, requestNumber, initiator, status, currentLevel).
- **Secondary Collection**: `dealer_claims` stores the business-specific metadata (proposal, expenses, invoices, etc.) and is linked via `requestId`.
This architecture naturally supports showing both in the same list.
## Proposed Efficient Approach
To make these two paths truly "inline" and handle specialized steps efficiently, we recommend a **Metadata-Driven Activity System**.
### 1. Unified Listing
The UI should continue to use the existing `listWorkflows` endpoints. The backend already returns `templateType`, which the frontend can use to decide which icon or detail view to render.
### 2. Specialized Step Identification (Dual-Tag System)
To handle dynamic level shifts and accurately recognize the purpose of each step, we use two categories of tags on each `ApprovalLevel`.
#### Category A: Action Tags (`stepAction`)
Defines **what** special behavior is required in this step.
- `DEALER_PROPOSAL`: Show proposal submission form.
- `EXPENSE_CAPTURE`: Show expense document upload form.
- `PROPOSAL_EVALUATION`: Show evaluation tools for the initiator/manager.
- `NONE`: Standard approve/reject UI.
#### Category B: Persona Tags (`stepPersona`)
Defines **who** is acting in this step (role-based logic).
- `INITIATOR`: Used when the initiator acts as an approver (e.g., evaluating a dealer proposal).
- `DEPARTMENT_LEAD`: Standard leadership approval.
- `ADDITIONAL_APPROVER`: Distinguishes steps added manually from the template.
#### How it works together:
| Level | Level Name | `stepAction` | `stepPersona` | UI Behavior |
| :--- | :--- | :--- | :--- | :--- |
| **1** | Dealer Proposal | `DEALER_PROPOSAL` | `DEALER` | Full Proposal Form |
| **2** | Initiator Review | `PROPOSAL_EVALUATION` | `INITIATOR` | Inline evaluation checklist |
| **3** | Lead Approval | `NONE` | `DEPARTMENT_LEAD` | Simple Approve/Reject |
| **3b** | Extra Check | `NONE` | `ADDITIONAL_APPROVER` | Manual Approval UI |
- **Dynamic Insertions**: If `Extra Check` is added, the following levels shift, but their `stepAction` tags remain, so the UI NEVER breaks.
- **Resubmission**: Rejection logic targets the latest completed level with `stepAction: 'DEALER_PROPOSAL'`.
### 3. Versioning & Iterations
The user's requirement to track previous proposals during resubmission is handled via the **Snapshotted Revisions** pattern:
- **The Main Store**: `DealerClaim.proposal` and `DealerClaim.completion` always hold the **active/latest** values.
- **The Revision Store**: `DealerClaim.revisions[]` acts as an append-only audit trail.
**Resubmission Flow:**
1. Request is rejected at Level 2/3/5.
2. Workflow moves back to Level 1 or 4 (Dealer).
3. Dealer edits the data.
4. **On Submit**:
- Backend takes the *current* `proposal` or `completion` data.
- Pushes it into `revisions` with a timestamp and `triggeredBy: 'SYSTEM_VERSION_SNAPSHOT'`.
- Overwrites the main object with the *new* data.
- Advances the workflow.
### 4. Implementation Strategy
| Feature | Custom Request Path | Dealer Claim Path |
| :--- | :--- | :--- |
| **Listing** | Unified `listWorkflows` | Unified `listWorkflows` |
| **Details View** | Standard UI | Enhanced UI (tabs for Expenses/Proposal) |
| **Logic** | Generic `approveRequest` | `approveRequest` + `DealerClaimService` hook |
| **Versioning** | Activity Logs only | Snapshotted Revisions for re-submissions |
---
### Key Advantage
This approach avoids creating "two separate systems". It treats a Dealer Claim as a "Custom Request with a specific metadata payload". The UI remains cohesive, and the backend logic for TAT, notifications, and status transitions stays shared.