
# 📘 Enterprise Transaction Platform

## Scalable Architecture for Large Document Entry (PO, GRN, etc.)

---

# 1. Executive Summary

Modern enterprise systems (ERP, procurement, inventory, finance) require handling **large transactional documents** such as:

* Purchase Orders (PO)
* Goods Receipt Notes (GRN)
* Invoices, Requisitions, etc.

These documents often contain:

* 100–1000+ line items
* Multiple sub-structures (tax, batch, schedules, attachments)
* Complex validations and calculations
* Cross-document derivations (PO → GRN → Invoice)

Traditional approaches (single form + single save API) **fail at scale**.

---

## 🎯 Objective

Design a **robust, scalable, reusable Transaction Platform** that:

* Handles large datasets efficiently
* Supports auto-save and draft recovery
* Enables multi-user safe operations
* Prevents data conflicts and duplication
* Provides consistent UX across 25+ modules
* Can be reused and extended across the product

---

# 2. Problem Statement

Without a proper architecture, systems face:

## ⚠️ Performance Issues

* Slow UI with 500+ rows
* API timeouts during save
* Browser freezes due to large forms

## ⚠️ Data Integrity Issues

* Duplicate consumption (PO used twice)
* Lost updates (multi-user edits)
* Partial or corrupted saves

## ⚠️ User Experience Issues

* No auto-save → data loss
* No resume capability
* Long wait times

---

# 3. Design Principles

The system is built on the following principles:

### 1. **Chunk, Don’t Bulk**

Never process entire document at once.

### 2. **Draft First**

Every transaction starts as a **draft**, not final.

### 3. **Backend is Source of Truth**

Frontend is only a working layer.

### 4. **Set-Based Operations**

Database handles bulk logic efficiently.

### 5. **Identity over Position**

Rows are identified by IDs, not index.

### 6. **Lazy Loading**

Load only what is needed, when needed.

---

# 4. High-Level Architecture

## 🧩 Components

### Frontend (Angular)

* Transaction Engine (Reusable)
* Config-driven forms
* State management (row-level)
* Chunked save manager

### Backend (.NET)

* Draft service
* Bulk save APIs (TVP)
* Validation engine
* Allocation engine

### Database (SQL Server)

* Draft tables
* Main transaction tables
* Reservation tables

---

# 5. Functional Architecture

---

## 5.1 Draft-Based Workflow

### Concept

Every transaction exists as:

```
Draft → Submit → Final Document
```

### Why?

* Prevent data loss
* Allow partial work
* Enable resume

---

## 5.2 Example Flow (PO → GRN)

1. User loads PO
2. Selects lines → creates GRN draft
3. Edits quantities
4. System auto-saves
5. User leaves
6. Later resumes
7. Submits → validation → final save

---

# 6. Frontend Design (Angular)

---

## 6.1 Row Data Model

```ts
interface Row {
  clientRowId: string;      // GUID
  serverRowId?: number;     // DB ID

  state: 'new' | 'modified' | 'deleted' | 'unchanged';

  data: {
    itemId: number;
    qty: number;
    rate: number;
    amount: number;
  };

  subData?: {
    taxes?: any[];
    schedules?: any[];
  };

  meta?: {
    rowVersion?: number;
    errors?: any;
  };
}
```

---

## 6.2 Key Concepts

### 🔹 ClientRowId

* Generated in FE
* Stable identity

### 🔹 ServerRowId

* Assigned by DB

### 🔹 State Tracking

* Controls what to send to backend

---

## 6.3 UI Strategy

### ❌ Avoid

* Rendering 500+ rows at once

### ✅ Use

* Virtual scrolling OR pagination
* Lazy sub-tab loading

---

## 6.4 Save Strategy

### ❌ Bad

* Save entire document every time

### ✅ Good

* Save only changed rows

### Trigger:

* Every 5–10 sec
* Tab change
* Manual save

---

## 6.5 Example Save Payload

```json
{
  "draftId": "GUID",
  "rows": [
    { "clientRowId": "1", "state": "new", "qty": 10 },
    { "clientRowId": "2", "state": "modified", "qty": 20 },
    { "clientRowId": "3", "state": "deleted" }
  ]
}
```

---

# 7. Backend Design (.NET + SQL)

---

## 7.1 Draft Tables

```sql
TxnDraftHeader
- DraftId
- UserId
- Status
- LastActivityTime

TxnDraftLine
- DraftLineId
- DraftId
- ClientRowId
- ServerRowId
- State
- Qty
- Rate
- IsDeleted
```

---

## 7.2 Bulk Save using TVP

### TVP Definition

```sql
CREATE TYPE TxnLineType AS TABLE
(
  DraftId UNIQUEIDENTIFIER,
  ClientRowId UNIQUEIDENTIFIER,
  ServerRowId INT,
  State VARCHAR(10),
  Qty DECIMAL(18,4)
)
```

---

## 7.3 Save Logic

### Insert

```sql
INSERT INTO TxnDraftLine
SELECT * FROM @TVP WHERE State='new'
```

### Update

```sql
UPDATE T
SET Qty = S.Qty
FROM TxnDraftLine T
JOIN @TVP S ON T.ServerRowId = S.ServerRowId
WHERE S.State='modified'
```

### Delete (Soft)

```sql
UPDATE T
SET IsDeleted=1
FROM TxnDraftLine T
JOIN @TVP S ON T.ServerRowId = S.ServerRowId
WHERE S.State='deleted'
```

---

# 8. Source Document Handling (PO → GRN)

---

## Problem

Two users may:

* Load same PO
* Create GRN
* Over-consume quantity

---

## Solution: Reservation System

---

## 8.1 Reservation Table

```sql
PO_Line_Reservation
- PoLineId
- DraftId
- ReservedQty
- Status
```

---

## 8.2 Available Quantity

```sql
AvailableQty =
  OrderedQty
  - ReceivedQty
  - ReservedQty (active drafts)
```

---

## 8.3 Example

| Ordered | Received | Reserved | Available |
| ------- | -------- | -------- | --------- |
| 100     | 40       | 30       | 30        |

---

## 8.4 On Submit

```sql
IF (NewQty + ReceivedQty > OrderedQty)
  THROW ERROR
```

---

# 9. Orphan Draft Handling

---

## Problem

User creates draft but abandons it.

---

## Solution: Expiry

### Draft fields:

* LastActivityTime

### Rule:

* If inactive for X hours:

  * Mark as expired
  * Release reservations

---

## UX

* “Resume draft?”
* “Draft expired, restore?”

---

# 10. Concurrency Handling

---

## 10.1 Row Versioning

* Each row has version
* Reject stale updates

---

## 10.2 Optional Locking

* Show:

  * “User X is editing”

---

# 11. Loading Strategy

---

## Default

| Data      | Strategy |
| --------- | -------- |
| Header    | Full     |
| Lines     | Paged    |
| Subtables | Lazy     |

---

## Example APIs

```http
GET /txn/{id}
GET /txn/{id}/lines?skip=0&take=50
GET /txn/{id}/line/{id}/details
```

---

# 12. Draft Resume

---

## Flow

1. User opens screen
2. System checks draft
3. Prompt:

   * Resume
   * Discard
   * New

---

## Cross-device

Because draft is in backend:

* Resume from any device

---

# 13. Advanced Features

---

## 13.1 Bulk Operations

* Multi-row edit
* Copy/paste Excel
* Fill down

---

## 13.2 Validation Engine

* Config-driven rules
* Soft + hard validation

---

## 13.3 Calculation Engine

* Amount
* Taxes
* Allocation

---

## 13.4 Audit Trail

* Who changed what
* When

---

## 13.5 Notifications

* Save complete
* Validation errors

---

# 14. Performance Strategy

---

## Frontend

* Virtual scroll
* Lazy loading
* Minimal DOM

---

## Backend

* TVP bulk operations
* Set-based SQL
* Minimal indexes on draft

---

# 15. Reusability Strategy

---

## FE

| Component   | Reuse      |
| ----------- | ---------- |
| Grid Engine | Yes        |
| State Store | Yes        |
| Config      | Per module |
| Hooks       | Per module |

---

## BE

| Component       | Reuse           |
| --------------- | --------------- |
| Draft Framework | Yes             |
| Save API        | Yes             |
| Validation      | Module-specific |

---

# 16. What NOT to Do

---

❌ Save every row immediately
❌ Load full document always
❌ Use index as identity
❌ Ignore draft conflicts
❌ Depend on user discipline

---

# 17. End-to-End Example

---

## Scenario

User creates GRN from PO with 500 lines

### Steps

1. Load first 50 lines
2. Select 20 lines
3. Edit quantities
4. Auto-save (TVP)
5. Leave system
6. Resume next day
7. Submit
8. Validation passes
9. Final save
10. Reservation released

---

# 18. Final Conclusion

This architecture provides:

### ✅ Performance

Handles large documents efficiently

### ✅ Reliability

No data loss, safe concurrency

### ✅ Scalability

Reusable across modules

### ✅ User Experience

Auto-save, resume, fast UI

 
---

This document can serve as:

* **Architecture blueprint**
* **Developer guide**
* **Implementation reference**
* **Input to code generation tools**

---
 