# Document Number to File Retrieval Flow in Aumentum Web Access

## Complete Flow: File Number → Document File

Based on the JavaScript analysis, here's **exactly** how Aumentum retrieves documents from a file/document number:

---

## Step-by-Step Flow

### 1. **User Searches by Document Number**

**User Action**: Enters document number (e.g., `BP3208`) in search form

**Frontend** (`forms.js`):
```javascript
// User submits search form
form.addButton({text: btnSearchText}, function(btn, e){
    var qo = f.getForm().getValues();  // Gets {document_number: "BP3208"}
    qo[doQueryIdName] = '1';
    q = objectValues2String(qo);
    var token = tabResultIdPrefix + tokenDelimiter + fc.type + tokenDelimiter + q;
    historyAdd(token);
});
```

**Backend Request**:
```
POST http://10.10.10.3:8080/lrswa/search.do?entityType=document
Content: {document_number: "BP3208"}
```

---

### 2. **Backend Returns Search Results with UUIDs**

**Backend Query** (Java/Spring server-side):
```sql
-- The backend queries LRSAdmin database
SELECT 
    sd.id,
    sd.document_number,
    sd.document_type,
    sd.acceptance,
    n.uuid  -- THIS IS THE KEY!
FROM LRSAdmin.lr_source_document sd
LEFT JOIN LRSAdmin.alf_node_properties np 
    ON np.string_value = sd.document_number
LEFT JOIN LRSAdmin.alf_qname q 
    ON q.id = np.qname_id 
    AND q.local_name IN ('targetRids','sourceRids')
LEFT JOIN LRSAdmin.alf_node n 
    ON n.id = np.node_id 
    AND n.node_deleted = 0
WHERE sd.document_number LIKE '%BP3208%'
```

**Response** (JSON):
```json
{
  "rows": [
    {
      "id": "10000000023405",
      "document_number": "BP3208",
      "document_type": "127",
      "acceptance": null,
      "uuid": "dcb3a0d9-2a29-4441-afaa-919d32f1826d"  // <-- KEY!
    }
  ],
  "rowCount": 1
}
```

---

### 3. **Grid Displays Results**

**Frontend** (`grids.js`):
```javascript
var jsonStore = new Ext.data.JsonStore({
    autoLoad: false,
    root: 'rows',     
    totalProperty: 'rowCount', 
    remoteSort: true,
    fields: fieldList,  // includes 'id', 'document_number', 'uuid'
    proxy: httpProxy
});

var grid = new Ext.grid.GridPanel({
    store: jsonStore,
    cm: columnModel,  // Shows document_number in grid
    sm: sm
});
```

**User sees**: Grid row showing `BP3208` (but UUID is hidden in row data)

---

### 4. **User Clicks on Grid Row**

**Frontend** (`grids.js`):
```javascript
setClickHandler(grid, function(grid, rowIndex, e){
    ShowProgress();
    var row = grid.getStore().getAt(rowIndex);
    var rowId = row.id;  // Gets "10000000023405"
    loadDetails(type, rowId);  // Opens detail view
});
```

---

### 5. **Detail View Loads**

**Frontend** (`tabs.js`):
```javascript
function detailToTab(type, rowId, rowId2) {
    ShowProgress();
    
    var fc = getFormConfigByType(type);
    var sUrl = (fc && fc.detail) ? fc.detail : 'detail.do';
    var panelId = sID + '-container-panel';
    
    // Request detail page with rowId
    var urlParams = {
        containerId: panelId, 
        id: rowId,  // "10000000023405"
        entityType: type, 
        ticket: alfrescoTicket
    };
    
    var p = new Ext.Panel({
        id: panelId,
        autoLoad: {
            url: sUrl,  // "detail.do"
            params: urlParams,
            scripts: true
        }
    });
}
```

**Backend Request**:
```
GET http://10.10.10.3:8080/lrswa/detail.do?id=10000000023405&entityType=document&ticket=<alfresco_ticket>
```

---

### 6. **Backend Returns Detail HTML with Document Pages/UUIDs**

**Backend Response** (HTML with embedded JavaScript):
```html
<script>
var documentViewer = {
    id: 'docviewer',
    pages: [
        {
            uuid: "dcb3a0d9-2a29-4441-afaa-919d32f1826d",
            pageNumber: 1,
            mimeType: "application/pdf"
        }
        // Could have multiple pages
    ],
    currentPage: 0
};
</script>

<div id="docviewer-container">
    <!-- Document viewer control here -->
</div>
```

---

### 7. **Document Viewer Loads First Page**

**Frontend** (`extJSutils.js`):
```javascript
// Document viewer object
var viewer = {
    pages: [],  // Populated from backend response
    currentPage: 0,
    
    loadPage: function() {
        if (this.currentPage >= 0) {
            // Get UUID from pages array
            this.loadImage(this.pages[this.currentPage].uuid);
        }
    },
    
    loadImage: function(imgId) {  // imgId = UUID
        this.loadingDocument = true;
        var url = getURLById(imgId);  // Generate document URL
        
        // Load in viewer control (ActiveX/Plugin)
        var src = this.getViewer();
        src.LoadDocument(url);
    }
};
```

---

### 8. **Generate Document URL from UUID**

**Frontend** (`imgviewer.js`):
```javascript
function getURLById(imgId) {
    // imgId = "dcb3a0d9-2a29-4441-afaa-919d32f1826d"
    var url = getImageBaseUrl(document.URL) + '/documentPage.do?uuid=' + imgId;
    return url;
    // Returns: "http://10.10.10.3:8080/lrswa/documentPage.do?uuid=dcb3a0d9-2a29-4441-afaa-919d32f1826d"
}
```

---

### 9. **Backend Retrieves and Serves Document Binary**

**Backend Request**:
```
GET http://10.10.10.3:8080/lrswa/documentPage.do?uuid=dcb3a0d9-2a29-4441-afaa-919d32f1826d
```

**Backend Process** (Java/Spring):
```java
@RequestMapping("/documentPage.do")
public void serveDocument(@RequestParam("uuid") String uuid, HttpServletResponse response) {
    // 1. Query database for content URL
    String query = 
        "SELECT cu.content_url " +
        "FROM LRSAdmin.alf_node n " +
        "JOIN LRSAdmin.alf_content_data cd ON cd.id = n.id " +
        "JOIN LRSAdmin.alf_content_url cu ON cu.id = cd.content_url_id " +
        "WHERE n.uuid = ? AND n.node_deleted = 0";
    
    String contentUrl = jdbcTemplate.queryForObject(query, String.class, uuid);
    // contentUrl = "store://2014/12/18/16/20/e03a480a-f6ef-477f-b453-0d9d094dac16.bin"
    
    // 2. Parse store:// URL to filesystem path
    String filePath = parseStoreUrl(contentUrl);
    // filePath = "D:/lsr_storage/contentstore/2014/12/18/16/20/e03a480a-f6ef-477f-b453-0d9d094dac16.bin"
    
    // 3. Read file and stream to response
    File file = new File(filePath);
    response.setContentType("application/pdf");  // or detected mimetype
    Files.copy(file.toPath(), response.getOutputStream());
}
```

---

### 10. **Browser Displays Document**

**Result**: Document is displayed in the Aumentum viewer (ActiveX control or browser plugin)

---

## Complete Flow Diagram

```
┌─────────────────────────────────────────────────────────────┐
│  User enters: BP3208                                         │
└──────────────────┬──────────────────────────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────────────────────────┐
│  POST /lrswa/search.do?entityType=document                  │
│  Body: {document_number: "BP3208"}                          │
└──────────────────┬──────────────────────────────────────────┘
                   │
                   ↓ (Backend queries LRSAdmin DB)
┌─────────────────────────────────────────────────────────────┐
│  Response: {                                                 │
│    rows: [{                                                  │
│      id: "10000000023405",                                  │
│      document_number: "BP3208",                             │
│      uuid: "dcb3a0d9-2a29-4441-afaa-919d32f1826d"          │
│    }]                                                        │
│  }                                                           │
└──────────────────┬──────────────────────────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────────────────────────┐
│  Grid displays: BP3208 (row.id = 10000000023405)           │
└──────────────────┬──────────────────────────────────────────┘
                   │
                   ↓ (User clicks row)
┌─────────────────────────────────────────────────────────────┐
│  GET /lrswa/detail.do?id=10000000023405&entityType=document │
└──────────────────┬──────────────────────────────────────────┘
                   │
                   ↓ (Backend returns HTML with pages array)
┌─────────────────────────────────────────────────────────────┐
│  pages: [{                                                   │
│    uuid: "dcb3a0d9-2a29-4441-afaa-919d32f1826d",           │
│    pageNumber: 1                                            │
│  }]                                                          │
└──────────────────┬──────────────────────────────────────────┘
                   │
                   ↓ (Viewer loads first page)
┌─────────────────────────────────────────────────────────────┐
│  viewer.loadImage(pages[0].uuid)                            │
│  ↓                                                           │
│  getURLById("dcb3a0d9-2a29-4441-afaa-919d32f1826d")        │
└──────────────────┬──────────────────────────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────────────────────────┐
│  GET /lrswa/documentPage.do?uuid=dcb3a0d9-2a29...          │
└──────────────────┬──────────────────────────────────────────┘
                   │
                   ↓ (Backend queries DB, reads file)
┌─────────────────────────────────────────────────────────────┐
│  Backend:                                                    │
│  1. Query: SELECT content_url WHERE uuid = ?                │
│     Result: store://2014/12/18/16/20/e03a480a...bin        │
│  2. Parse to: D:/contentstore/2014/12/18/16/20/e03a480a.bin│
│  3. Read file and stream binary                             │
└──────────────────┬──────────────────────────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────────────────────────┐
│  Browser receives PDF/Image binary                          │
│  Viewer displays document                                   │
└─────────────────────────────────────────────────────────────┘
```

---

## Key Insight: TWO-STEP LOOKUP

Aumentum uses a **two-step lookup**:

1. **First lookup**: `document_number` → `row.id` + `uuid` (via search)
2. **Second lookup**: `uuid` → `store://` → file (via documentPage.do)

### Why Two Steps?

- **Separation of concerns**: Search returns metadata, document viewer retrieves binary
- **Security**: UUID acts as a secure token
- **Alfresco integration**: UUID is Alfresco's native identifier
- **Multi-page documents**: One document_number can have multiple page UUIDs

---

## How Our Implementation Compares

### Aumentum's Flow:
```
document_number → [search.do] → uuid → [documentPage.do] → store:// → file
```

### Our Implementation:
```
document_number → [SQL query] → uuid → store:// → file → PDF conversion
```

**Difference**: We bypass the Java backend entirely by:
1. Querying the database directly
2. Parsing `store://` URLs ourselves
3. Converting `.bin` to PDF on-demand

**Advantage**: No need for Alfresco authentication, simpler architecture

---

## SQL Queries That Mirror Aumentum's Flow

### Step 1: Document Number → UUID (what search.do does)
```sql
SELECT 
    sd.id,
    sd.document_number,
    n.uuid
FROM LRSAdmin.lr_source_document sd
JOIN LRSAdmin.alf_node_properties np 
    ON np.string_value = sd.document_number
JOIN LRSAdmin.alf_qname q 
    ON q.id = np.qname_id 
    AND q.local_name IN ('targetRids','sourceRids')
JOIN LRSAdmin.alf_node n 
    ON n.id = np.node_id 
    AND n.node_deleted = 0
WHERE sd.document_number = 'BP3208'
```

### Step 2: UUID → store:// URL (what documentPage.do does)
```sql
SELECT cu.content_url
FROM LRSAdmin.alf_node n
JOIN LRSAdmin.alf_content_data cd ON cd.id = n.id
JOIN LRSAdmin.alf_content_url cu ON cu.id = cd.content_url_id
WHERE n.uuid = 'dcb3a0d9-2a29-4441-afaa-919d32f1826d'
  AND n.node_deleted = 0
```

### Combined (our optimization):
```sql
SELECT n.uuid, cu.content_url, cu.content_size, mt.mimetype_str
FROM LRSAdmin.alf_node_properties np
JOIN LRSAdmin.alf_qname q ON q.id = np.qname_id
JOIN LRSAdmin.alf_node n ON n.id = np.node_id AND n.node_deleted = 0
JOIN LRSAdmin.alf_content_data cd ON cd.id = n.id
JOIN LRSAdmin.alf_content_url cu ON cu.id = cd.content_url_id
LEFT JOIN LRSAdmin.alf_mimetype mt ON mt.id = cd.content_mimetype_id
WHERE np.string_value = 'BP3208' 
  AND q.local_name IN ('targetRids','sourceRids')
```

---

## Implementation in Our API

### Method 1: By Document Number (what we already have)
```
GET /documents/by-document-number?document_number=BP3208
GET /documents/pdf-by-document-number?document_number=BP3208
```

### Method 2: By UUID (newly added, native Aumentum method)
```
GET /documents/by-uuid?uuid=dcb3a0d9-2a29-4441-afaa-919d32f1826d
GET /documents/pdf-by-uuid?uuid=dcb3a0d9-2a29-4441-afaa-919d32f1826d
```

Both methods achieve the same result, mimicking Aumentum's internal flow!

---

## Summary

**Aumentum's document retrieval from file number**:
1. Search by `document_number` → Get `uuid`
2. Use `uuid` to call `documentPage.do`
3. Backend queries DB for `store://` URL
4. Backend reads file from contentstore
5. Backend streams binary to browser

**Our implementation**: Direct database + filesystem access, skipping the Java middleware!

