---
# System prepended metadata

title: Retail 交接文件
tags: [aira]

---

---
tags: aira
---
## 說明
1. .env 可以參考 49 的 `/opt/aira/airaRetail`。
2. 除了 airaTrack Adapter 用的 nodejs 版本是 12.22.9 以外，其餘專案用的 nodejs 版本都是 18.20.2。
3. [Postman 設定檔](https://drive.google.com/file/d/1eyA-30UuXBvWWtuw392ethbUz0WxB77E/view?usp=sharing)。

## 專案清單
| 客戶   | 專案                                                                                        | 前一手 |
| ------ | ------------------------------------------------------------------------------------------- | ------ |
| 台茂   | [先前的 Retail](https://github.com/airaTaiwan/old-aira-retail)                              | 玉清   |
| AWS    | [2024 AWS AI Summit](https://github.com/airaTaiwan/aws-ai-summit-2024-be)                   | -      |
| 特力屋 | [Retail - AgServer Adapter](https://github.com/airaTaiwan/agServer-adapter)                 | -      |
| 特力屋 | [Retail - AiMediaConnector Adapter](https://github.com/airaTaiwan/aiMediaConnector-adapter) | -      |     |
| 特力屋 | [Retail - Livecapture Adapter](https://github.com/airaTaiwan/livecapture-adapter)           | -      |
| 特力屋 | [Retail - Track Adapter](https://github.com/airaTaiwan/track-adapter)                       | -      |
| 特力屋 | [Retail - UDP Forwarder](https://github.com/airaTaiwan/udpForward)                          | - |
| 特力屋 | [Retail](https://github.com/airaTaiwan/aira-retail) | - |
| -     | [批次改檔名](https://github.com/airaTaiwan/renamer)     | - |


## 交接情形
- [ ] 1. AgServer Adapter
    - [ ] 確保拉得到專案
    - [ ] 確保可以在 [100](http://192.168.10.100:3001/?folder=/opt/aira/agServer) 運行
    > 因為要跑 model 應該無法直接在本機執行
    - [ ] 確保可以用 Postman 測試
- [ ] 2. AiMediaConnector Adapter
    - [ ] 確保拉得到專案
    - [ ] 確保可以在 [100](http://192.168.10.100:3001/?folder=/opt/aira/airaRetail/aiMediaConnector) 運行
    > 因為要跑 model 應該無法直接在本機執行
- [ ] 3. Livecapture Adapter
    - [ ] 確保確保拉得到專案
    - [ ] 確保可以在 [100](http://192.168.10.100:3001/?folder=/opt/aira/airaRetail/livecapture) 運行
    > 因為要跑 model 應該無法直接在本機執行
- [ ] 4. Track Adapter
    - [ ] 確保確保拉得到專案
    - [ ] 確保可以在 [100](http://192.168.10.100:3001/?folder=/opt/aira/airaTrack) 運行
    > 因為要跑 model 應該無法直接在本機執行
- [ ] 5. UDP Forwarder
    - [ ] 確保拉得到專案
    - [ ] 確保可以在 [100](http://192.168.10.100:3001/?folder=/opt/aira/udpForwarder) 運行
    > 因為 livecapture、aiMediaConnector 預設只打到目標主機的某個 UDP Port，需要這層 forwarding 將資料直接打到本機
- [ ] 6. Retail
    - [ ] 確保拉得到專案
    - [ ] 確保本機可以運行
        - [x] 交接 .env
        - [x] 在本機開放 API Endpoint 但使用 192.168.10.49 作為資料中心
    - [x] 確保可以用 Postman 測試
    - [x] 確保專案可以修改並且修改會生效
        - [x] `npm run watch`
        - [x] `npm run api`
        - [x] `npm run build`
        - [x] `npm run deploy`
    - [ ] 確保知道如何確認基礎設施狀態並查看工作日誌
        - [ ] RabbitMQ
        - [ ] QDrant
        - [ ] Mongo
        - [ ] Minio
        - [ ] ETCD
    - [ ] Known Issues
        - [ ] 請參考[這份文件](https://hackmd.io/@aira/rJcccK8h0)。
    - [ ] Todos
        - [ ] `feature/允許scheme指定正負號` 還未合併進 main 分支，要待 Matt 驗證功能沒問題後，再合併回 main 分支。
- [ ] 7. AWS
    - [ ] 確保拉得到專案
    - [ ] 確保本機可以運行
        - [ ] 交接 .env
        - [ ] 在本機開放 API Endpoint 但使用 192.168.10.100 作為資料中心
    - [ ] 確保可以用 Postman 測試
    - [ ] 確保專案可以修改並且修改會生效
        - [ ] `npm run watch`
        - [ ] `npm run api`
        - [ ] `npm run build`
        - [ ] `npm run deploy`
    - [ ] 確保知道如何確認基礎設施狀態並查看工作日誌
        - [ ] [RabbitMQ](http://192.168.10.49:15672/)
        - [ ] [QDrant](http://192.168.10.49:6333/dashboard)
        - [ ] Mongo
        - [ ] [Minio](http://192.168.10.49:9001)
        - [ ] ETCD

## 驗證運作狀態
1. top (shift p)
    ![image](https://hackmd.io/_uploads/SyG1SiqTR.png)
    - %Cpu(s)
    - avail Mem
2. 看 Queue 有沒有塞車
![image](https://hackmd.io/_uploads/HJkHrs5aC.png)
3. df -h 看磁碟用量
![image](https://hackmd.io/_uploads/BJVcBj5TR.png)



## 其他文件
1. 新機安裝 track 的[注意事項](https://hackmd.io/-AgvCthVT4mzWt2kIsbQ9A)。
2. 新機安裝 aiMediaConnector的[注意事項](https://hackmd.io/fz0Y5D80ToGXbaGEMvQ33A)。
3. [如何解決 make 指令 .ONESHELL 沒有作用的問題](https://hackmd.io/an4yDG7BQrS7u58mC_ALng)。
4. [啟用 license 的方法](https://hackmd.io/UVKjnLP_RceglPu4uOLo2w)。
5. [nx digest 的認證協定設定方式](https://hackmd.io/JRQrmKH0R_qccgytgBBIFA)。
6. Retail 批次匯入員工的腳本：
    ```bash
    #!/bin/bash
    let index=-1
    for image in $(ls *.jp*g)
    do
        index=$((index+1))
        code=$(printf "%04d" $index)
        name=${image%.*}
        photo=$(base64 -i $image)
        echo "正在匯入 ${name}"
            # 請將 http://192.168.10.226:8082 換成你要呼叫的 Retail 服務的 endpoint
        curl --header "Content-Type: application/json" \
            --request POST \
            --data '{"name":"'$name'","photo":"'$photo'", "code": "'$code'"}' \
            http://192.168.10.226:8082/api/albums/675412cd-2847-5b6b-8585-da610a36193a/staff
        echo ""
    done
    ```
7. 計算平均執行時間的方法：
    > #### 倒出 logs
    > ```bash
    > docker compose logs > docker-compose.log
    > ```
    > #### 計算平均執行時間
    > ```bash
    > node parse-log.js
    > ```


## 備註
### 關於設計上的一些問題
#### 1. 關於 API 欄位命名的問題
請找 Matt。

#### 2. 關於入口攝影機、出口攝影機 dwell、stops 計算方式的問題
請找 Matt。

#### 3. 為什麼用 traefik：
因為想要 api 也可以開 replica（nginx 的 streaming + reverse proxy 會設定得比較複雜）。

#### 4. 為什麼用 nginx 放靜態檔案（而不是讓 express 直接吐）：
可以設定靜態檔案的快取並且讓讀取動作由多個 workers 去幫忙做

#### 5. 為什麼要在 Service 外再掛一層 reverse proxy (traefik、nginx)？
- 譬如憑證，可以統一由 traefik 或 nginx 管理，就不用每一個 app 都要知道怎麼處理 SSL 的事情，憑證也比較好自動更新。
- 幫忙作 load balance，可以讓一個 endpoint 背後有多個 replicas 幫忙服務，增加吞吐量。

#### 6. 為什麼選用 etcd 而不是 redis？
- redis 每次讀取都會重拉一次資料，這個拉的過程還是有 latency。
- etcd 可以做到一旦有更新才拉取資料，可以大幅減少拉取的次數。且拉取完的資料是直接存放在記憶體，從記憶體取出的話速度會快很多。

#### 7. 為什麼要使用 QDrant？
請參考[這份文件](https://hackmd.io/cNU1z4w5QnGuolgP2Yx2mA)。

### Mongo Collections 介紹
#### albums
其實我不知道這是幹嘛用的，可能類似員工的群組之類的。
![image](https://hackmd.io/_uploads/HJWd5gQhA.png)
![image](https://hackmd.io/_uploads/rky_ilQhA.png)

#### staff
登記員工資料的資料表。
如果有上傳臉照，會額外儲存向量至 QDrant 的 staffFaces 資料表中。
![image](https://hackmd.io/_uploads/HkmvqgmnC.png)
![image](https://hackmd.io/_uploads/S1spoemhR.png)

#### analysisSchemes
airaRetail 會監控 `analysisSchemes` 和 `cameras` 這兩個 collection，一有變動時就寫入 livecature 執行時所需要的 `airatrack.conf` 設定檔（同時在原本 livecature 外包裹了一層檔案監聽並自動重啟的邏輯。）

![image](https://hackmd.io/_uploads/S1E55xQn0.png)
![image](https://hackmd.io/_uploads/rJLFol73C.png)

#### cameras
![image](https://hackmd.io/_uploads/SyIo5eQ20.png)
![image](https://hackmd.io/_uploads/rJY9jgm3C.png)

#### dailyStats
![image](https://hackmd.io/_uploads/H1-a5e720.png)
![image](https://hackmd.io/_uploads/HJX2og7h0.png)


#### groups
每個群組及辨識設定都會產生日報表。
辨識設定有人臉、人形、區域偵測三種類型，都存在在這個表中。

人臉類的數值因為重複人臉（相似的人臉向量）只算一次，這邊是用 Map/Object/Dictionary 的形式儲存在資料表中。
![image](https://hackmd.io/_uploads/SkNCcx7hA.png)
![image](https://hackmd.io/_uploads/rky5J-73A.png)

#### stores
用來儲存分店的名字及營業時間。
![image](https://hackmd.io/_uploads/BJIxsgmn0.png)
![image](https://hackmd.io/_uploads/ByOCoxX3A.png)


#### trackingRecords
人臉識別後的原始資料儲存在這個地方。
![image](https://hackmd.io/_uploads/HJczigQ2A.png)
![image](https://hackmd.io/_uploads/HkHynxX2R.png)

#### users
儲存某個向量的性別、年齡層、對應的員工編號等。
![image](https://hackmd.io/_uploads/BJjXox73R.png)
![image](https://hackmd.io/_uploads/S1fxnemnR.png)

#### visits
用來儲存使用者的訪問狀態。
在還沒有被入口攝影機捕捉前，不會有離開的紀錄。
系統會以第一次進入的資訊來作各種統計（age1, age2, age3, male, female ...）。
![image](https://hackmd.io/_uploads/ByoHox72R.png)
![image](https://hackmd.io/_uploads/HJo-nlmhC.png)

### QDrant Collections 介紹
#### nes
儲存從系統開始運作到目前為止所有辨識到的特徵向量，相似的向量只算一筆。

#### faces_{日期}
譬如 `faces_2024-09-02`。
儲存某日辨識到的人臉特徵向量，相似的向量只算一筆。
![image](https://hackmd.io/_uploads/HkRkI-73C.png)