@posx/core 5.5.395 → 5.5.396
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +23 -23
- package/LICENSE +21 -21
- package/README.md +85 -85
- package/build/index.d.ts +3 -0
- package/build/index.js +1 -1
- package/dev/.stfolder/syncthing-folder-9a95b7.txt +5 -0
- package/dev/98894488.xlsx +0 -0
- package/dev/HappyThaiSembawang.csv +336 -0
- package/dev/KB/create-new-model.md +34 -0
- package/dev/KB/markdown-lint.md +14 -0
- package/dev/KB/readmefirst.md +6 -0
- package/dev/Merchants/HappyThaiSembawang.csv +400 -0
- package/dev/Merchants/HappyThaiSembawang.xlsx +0 -0
- package/dev/Product_Import_Template.xlsx +0 -0
- package/dev/XPOS Invoice Module.pdf +232 -0
- package/dev/escpos/receipt.bin +0 -0
- package/dev/escpos/receipt.hex +1 -0
- package/dev/escpos/receipt.json +1 -0
- package/dev/escpos-cli-usage.md +103 -0
- package/dev/harbor-harness-deployment.md +78 -0
- package/dev/nginx-harbor-harness.conf +84 -0
- package/dev/px-cli.md +99 -0
- package/dev/test-logs/2026-02.md +5 -0
- package/dev/tmp/xpos_product_import(1).csv +338 -0
- package/dev/tmp/xpos_product_import_fixed.csv +338 -0
- package/dev//344/272/247/345/223/201/345/257/274/345/205/245/346/250/241/346/235/277.xlsx +0 -0
- package/jest.config.cjs +36 -36
- package/jest.setup.cjs +80 -80
- package/package.json +1 -1
- package/package.publish.json +121 -121
- package/px/.env.example +3 -0
- package/px/commands/category.ts +47 -0
- package/px/commands/product.ts +51 -0
- package/px/http.ts +40 -0
- package/px/index.ts +35 -0
- package/tsdown.config.ts +21 -21
- package/vite.config.ts +86 -86
- package/memo/technical-docs/01_ARCHITECTURE.md +0 -147
- package/memo/technical-docs/02_CORE_BUSINESS.md +0 -292
- package/memo/technical-docs/03_UI_COMPONENTS.md +0 -59
- package/memo/technical-docs/04_VIEWS.md +0 -82
- package/memo/technical-docs/05_DATA_LAYER.md +0 -375
- package/memo/technical-docs/06_CROSS_PLATFORM.md +0 -246
- package/memo/technical-docs/07_SIMILARITY_INDEX.md +0 -195
- package/memo/technical-docs/CHECKPOINT.md +0 -46
- package/memo/technical-docs/PROJECT_OVERVIEW.md +0 -122
- package/memo/technical-docs/TECHNICAL_DOCS_PLAN.md +0 -77
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"uid": "pjb_I8RJcR0Hm6iMsYSzmIDRd", "updated_at": "2026-02-10T05:41:54.209Z", "created_at": "2026-02-10T05:41:54.356Z", "created_at_timestamp": 1770702114356, "deleted_at": null, "name_translations": {}, "printer_name": "Receipt Printer", "driver_printer_name": "Receipt Printer", "printer_ip": "0.0.0.0", "printer_uid": "prt_eJ5yITaByzBnAXSz1IvhF", "printer_type": "receipt_printer", "protocol": "ESC/POS", "connection_type": "WINDOWS_DRIVER", "data": {"codepage": "cp936", "items": [{"type": "newline", "repeat": 1}, {"type": "text", "align": "center", "style": "bold", "item": {"size": "custom", "width": 1, "height": 1, "text": " Happy Thai Food - Victory 8"}}, {"type": "newline", "repeat": 1}, {"type": "text", "align": "center", "style": "bold", "item": {"text": "8 Jalan Legundi #01-10 Victory 8"}}, {"type": "newline", "repeat": 1}, {"type": "text", "align": "center", "style": "bold", "item": {"text": "Tel: 67146682"}}, {"type": "newline", "repeat": 1}, {"type": "text", "align": "left", "style": "bold", "item": {"text": "Dine-In"}}, {"type": "newline", "repeat": 1}, {"type": "text", "align": "left", "style": "bold", "item": {"text": "# 01260210000001472"}}, {"type": "newline", "repeat": 1}, {"type": "text", "align": "left", "style": "bold", "item": {"size": "custom", "width": 1, "height": 1, "text": "Table:15"}}, {"type": "newline", "repeat": 1}, {"type": "text", "align": "left", "style": "bold", "item": {"size": "custom", "width": 1, "height": 1, "text": "ORDER NO.: 472"}}, {"type": "newline", "repeat": 1}, {"type": "text", "align": "left", "style": "bold", "item": {"text": "Served By:admin"}}, {"type": "newline", "repeat": 1}, {"type": "text", "align": "left", "style": "bold", "item": {"text": "Date:2026-Feb-10 13:41:54"}}, {"type": "newline", "repeat": 1}, {"type": "line"}, {"type": "table", "style": "bold", "table": {"items": [{"text": "ITEM", "column_width": 50}, {"text": "", "column_width": 10}, {"text": "QTY", "column_width": 15}, {"text": "AMT", "column_width": 25}]}}, {"type": "line"}, {"type": "table", "align": "left", "style": "bold", "table": {"items": [{"text": "M3. Garlic Fried Pork ", "column_width": 50}, {"text": "", "column_width": 10}, {"text": "x1", "column_width": 15}, {"text": "$13.90", "column_width": 25}]}}, {"type": "table", "align": "left", "style": "bold", "table": {"items": [{"text": "TE5. Chicken Omelette ", "column_width": 50}, {"text": "", "column_width": 10}, {"text": "x1", "column_width": 15}, {"text": "$7.90", "column_width": 25}]}}, {"type": "table", "align": "left", "style": "bold", "table": {"items": [{"text": "ND2. Phad see Ew (Kway Teow) Seafood ", "column_width": 50}, {"text": "", "column_width": 10}, {"text": "x1", "column_width": 15}, {"text": "$9.90", "column_width": 25}]}}, {"type": "table", "align": "left", "style": "bold", "table": {"items": [{"text": "A4. Thai Prawn Cake (4 Pieces) ", "column_width": 50}, {"text": "", "column_width": 10}, {"text": "x1", "column_width": 15}, {"text": "$13.90", "column_width": 25}]}}, {"type": "table", "align": "left", "style": "bold", "table": {"items": [{"text": "DR11. Thai Milk Tea ", "column_width": 50}, {"text": "", "column_width": 10}, {"text": "x1", "column_width": 15}, {"text": "$4.50", "column_width": 25}]}}, {"type": "table", "align": "left", "style": "bold", "table": {"items": [{"text": "DR7. Lemongrass Drink ", "column_width": 50}, {"text": "", "column_width": 10}, {"text": "x1", "column_width": 15}, {"text": "$3.90", "column_width": 25}]}}, {"type": "table", "align": "left", "table": {"items": [{"text": "- Cold ", "column_width": 50}, {"text": "", "column_width": 10}, {"text": "{{}}", "column_width": 15}, {"text": "", "column_width": 25}]}}, {"type": "newline", "repeat": 1}, {"type": "line"}, {"codepage": "cp437", "type": "table", "align": "left", "style": "bold", "table": {"items": [{"text": "SUBTOTAL", "column_width": 50}, {"text": "", "column_width": 25}, {"text": "$54.00", "column_width": 25}]}}, {"codepage": "cp437", "type": "table", "style": "bold", "table": {"items": [{"text": "10% SERVICE CHARGE", "column_width": 50}, {"text": "", "column_width": 25}, {"text": "$5.40", "column_width": 25}]}}, {"codepage": "cp437", "type": "table", "style": "bold", "size": "custom", "width": 1, "height": 1, "table": {"items": [{"text": "TOTAL", "column_width": 50}, {"text": "", "column_width": 25}, {"text": "$59.40", "column_width": 25}]}}, {"type": "line"}, {"codepage": "cp437", "type": "table", "style": "bold", "table": {"items": [{"text": "PAYMENT BY:Fiuu", "column_width": 50}, {"text": "", "column_width": 25}, {"text": "$59.40", "column_width": 25}]}}, {"type": "line"}, {"codepage": "cp437", "type": "table", "style": "bold", "table": {"items": [{"text": "PAYMENT TYPE", "column_width": 50}, {"text": "MASTERCARD", "column_width": 50}]}}, {"codepage": "cp437", "type": "table", "style": "bold", "table": {"items": [{"text": "REF", "column_width": 50}, {"text": "3487260943", "column_width": 50}]}}, {"codepage": "cp437", "type": "table", "style": "bold", "table": {"items": [{"text": "CARD NUM", "column_width": 50}, {"text": "**** **** **** 1040", "column_width": 50}]}}, {"type": "table", "style": "bold", "table": {"items": [{"text": "CUSTOMER TEL", "column_width": 50}, {"text": "", "column_width": 25}, {"text": "\u002B65****4846", "column_width": 25}]}}, {"type": "table", "style": "bold", "table": {"items": [{"text": "Cash Back", "column_width": 50}, {"text": "", "column_width": 25}, {"text": "$1.78", "column_width": 25}]}}, {"type": "table", "style": "bold", "table": {"items": [{"text": "Credit Balance", "column_width": 50}, {"text": "", "column_width": 25}, {"text": "$1.78", "column_width": 25}]}}, {"type": "table", "style": "bold", "table": {"items": [{"text": "Point Balance", "column_width": 50}, {"text": "", "column_width": 25}, {"text": "pt", "column_width": 25}]}}, {"type": "line"}, {"type": "text", "align": "center", "style": "bold", "item": {"text": "8 Jalan Legundi #01-10 Victory 8"}}, {"type": "newline", "repeat": 5}, {"type": "newline", "repeat": 1}, {"type": "newline", "repeat": 1}, {"type": "newline", "repeat": 1}, {"type": "cut"}]}, "status": "printed", "retries": 0, "commands": "", "save_only": false, "print_times": 1, "printed": 1, "device_uid_to_print": "", "designated_table_section_uids": [], "job_id": 0, "print_sequence": 0, "meta": {}, "id_in_server": 1044494, "_timestamp": 1770702115370025}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# ESC/POS CLI Tool Usage Manual
|
|
2
|
+
|
|
3
|
+
Generate ESC/POS byte files from print job JSON definitions.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
- `scripts/generate-escpos-bytes.mjs` - ESC/POS byte generator with built-in encoder
|
|
8
|
+
- `scripts/example-print-job.json` - Example print job for testing
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm run escpos -- <input.json> <output.bin>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Example
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm run escpos -- ./scripts/example-print-job.json ./receipt.bin
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Supported Features
|
|
23
|
+
|
|
24
|
+
| Feature | Description |
|
|
25
|
+
|---------|-------------|
|
|
26
|
+
| Text | With size, bold, italic, underline, alignment |
|
|
27
|
+
| Tables | With column widths and text wrapping |
|
|
28
|
+
| Lines | Separators |
|
|
29
|
+
| QR codes | Model, size, error level configurable |
|
|
30
|
+
| Barcodes | EAN13, UPC-A, UPC-E, EAN8, Code39, ITF, Codabar |
|
|
31
|
+
| Newlines | With repeat count |
|
|
32
|
+
| Cut | Full or partial |
|
|
33
|
+
| Beeper | Audible alert |
|
|
34
|
+
| Cash drawer | Open cash drawer command |
|
|
35
|
+
| VISCII codepage | Vietnamese support |
|
|
36
|
+
| Multiple codepages | cp437, cp850, cp936, etc. |
|
|
37
|
+
|
|
38
|
+
## Not Supported
|
|
39
|
+
|
|
40
|
+
- **Image printing** - Requires browser APIs, not available in CLI mode
|
|
41
|
+
|
|
42
|
+
## Print Job JSON Format
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"codepage": "cp936",
|
|
47
|
+
"items": [
|
|
48
|
+
{
|
|
49
|
+
"type": "text",
|
|
50
|
+
"align": "center",
|
|
51
|
+
"style": "bold",
|
|
52
|
+
"item": {
|
|
53
|
+
"text": "RECEIPT",
|
|
54
|
+
"size": "normal",
|
|
55
|
+
"line_width": 48
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"type": "table",
|
|
60
|
+
"table": {
|
|
61
|
+
"size": "normal",
|
|
62
|
+
"line_width": 48,
|
|
63
|
+
"items": [
|
|
64
|
+
{ "text": "Item", "column_width": 50 },
|
|
65
|
+
{ "text": "Qty", "column_width": 20 },
|
|
66
|
+
{ "text": "Price", "column_width": 30 }
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"type": "qrcode",
|
|
72
|
+
"align": "center",
|
|
73
|
+
"qrcode": {
|
|
74
|
+
"data": "https://example.com",
|
|
75
|
+
"model": 2,
|
|
76
|
+
"size": 6,
|
|
77
|
+
"errorlevel": "m"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"type": "cut"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Available Types
|
|
88
|
+
|
|
89
|
+
| Type | Properties |
|
|
90
|
+
|------|------------|
|
|
91
|
+
| `text` | `item.text`, `item.size`, `item.line_width`, `item.width`, `item.height` |
|
|
92
|
+
| `table` | `table.items[]`, `table.size`, `table.line_width` |
|
|
93
|
+
| `line` | `item.text` (character to repeat) |
|
|
94
|
+
| `newline` | `repeat` (number of lines) |
|
|
95
|
+
| `qrcode` | `qrcode.data`, `qrcode.model`, `qrcode.size`, `qrcode.errorlevel` |
|
|
96
|
+
| `barcode` | `barcode.data`, `barcode.symbology`, `barcode.height` |
|
|
97
|
+
| `cut` | `item.text` ("full" or "partial") |
|
|
98
|
+
| `beeper` | - |
|
|
99
|
+
| `open_cash_drawer` | - |
|
|
100
|
+
|
|
101
|
+
## Available Codepages
|
|
102
|
+
|
|
103
|
+
`cp437`, `cp850`, `cp860`, `cp863`, `cp865`, `cp857`, `cp737`, `cp866`, `cp862`, `cp864`, `cp874`, `cp936`, `cp949`, `cp950`, `shiftjis`, `windows1252`, `69` (VISCII)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Harbor + Harness 部署总结
|
|
2
|
+
|
|
3
|
+
## 服务端口
|
|
4
|
+
|
|
5
|
+
| 服务 | 端口 | 说明 |
|
|
6
|
+
|-------------|------|----------------|
|
|
7
|
+
| Harbor | 8081 | 容器镜像仓库 |
|
|
8
|
+
| Harness | 8082 | Git 代码托管 |
|
|
9
|
+
| Harness SSH | 3022 | Git SSH |
|
|
10
|
+
| PostgreSQL | 5433 | 数据库 |
|
|
11
|
+
| Redis | 6380 | 缓存 |
|
|
12
|
+
|
|
13
|
+
## 外部访问
|
|
14
|
+
|
|
15
|
+
| 服务 | 外部地址 | 内部地址 |
|
|
16
|
+
|---------|-------------------------|--------------|
|
|
17
|
+
| Harbor | https://harbor.wyo.sg | LAN_IP:8081 |
|
|
18
|
+
| Harness | https://harness.wyo.sg | LAN_IP:8082 |
|
|
19
|
+
|
|
20
|
+
## Harbor 登录
|
|
21
|
+
|
|
22
|
+
- URL: https://harbor.wyo.sg
|
|
23
|
+
- 用户名: `admin`
|
|
24
|
+
- 密码: `Harbor@2024!`
|
|
25
|
+
|
|
26
|
+
## Harness 登录
|
|
27
|
+
|
|
28
|
+
- URL: https://harness.wyo.sg
|
|
29
|
+
- 用户名: `admin@harness.local`
|
|
30
|
+
- 密码: `Harness@2024!`
|
|
31
|
+
|
|
32
|
+
## PostgreSQL
|
|
33
|
+
|
|
34
|
+
Host: `127.0.0.1:5433`
|
|
35
|
+
|
|
36
|
+
| 数据库 | 用户名 | 密码 |
|
|
37
|
+
|----------|----------|----------------|
|
|
38
|
+
| postgres | postgres | Postgres@2024! |
|
|
39
|
+
| harbor | harbor | Harbor@2024! |
|
|
40
|
+
| harness | harness | Harness@2024! |
|
|
41
|
+
|
|
42
|
+
## Redis
|
|
43
|
+
|
|
44
|
+
- Host: `127.0.0.1:6380`
|
|
45
|
+
- 密码: (无)
|
|
46
|
+
- Harbor DB Index: 1, 2, 5, 6, 7
|
|
47
|
+
|
|
48
|
+
## 文件位置
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
/opt/infra/docker-compose.yml # PostgreSQL + Redis
|
|
52
|
+
/opt/infra/config/postgresql.conf # PostgreSQL 配置
|
|
53
|
+
/opt/infra/config/redis.conf # Redis 配置
|
|
54
|
+
/opt/harbor/harbor.yml # Harbor 配置
|
|
55
|
+
/opt/harness/docker-compose.yml # Harness 配置
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 管理命令
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# 基础设施
|
|
62
|
+
cd /opt/infra && docker compose up -d
|
|
63
|
+
cd /opt/infra && docker compose down
|
|
64
|
+
|
|
65
|
+
# Harbor
|
|
66
|
+
cd /opt/harbor && docker compose up -d
|
|
67
|
+
cd /opt/harbor && docker compose down
|
|
68
|
+
|
|
69
|
+
# Harness
|
|
70
|
+
cd /opt/harness && docker compose up -d
|
|
71
|
+
cd /opt/harness && docker compose down
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Docker 登录 Harbor
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
docker login harbor.wyo.sg
|
|
78
|
+
```
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Harbor - 容器镜像仓库
|
|
2
|
+
server {
|
|
3
|
+
listen 80;
|
|
4
|
+
server_name harbor.wyo.sg;
|
|
5
|
+
return 301 https://$server_name$request_uri;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
server {
|
|
9
|
+
listen 443 ssl http2;
|
|
10
|
+
server_name harbor.wyo.sg;
|
|
11
|
+
|
|
12
|
+
ssl_certificate /etc/nginx/ssl/wyo.sg/fullchain.pem;
|
|
13
|
+
ssl_certificate_key /etc/nginx/ssl/wyo.sg/privkey.pem;
|
|
14
|
+
|
|
15
|
+
# SSL 配置
|
|
16
|
+
ssl_protocols TLSv1.2 TLSv1.3;
|
|
17
|
+
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
|
18
|
+
ssl_prefer_server_ciphers off;
|
|
19
|
+
ssl_session_cache shared:SSL:10m;
|
|
20
|
+
ssl_session_timeout 1d;
|
|
21
|
+
|
|
22
|
+
# 重要:Docker 镜像上传无大小限制
|
|
23
|
+
client_max_body_size 0;
|
|
24
|
+
chunked_transfer_encoding on;
|
|
25
|
+
|
|
26
|
+
# 禁用缓冲,支持大文件流式传输
|
|
27
|
+
proxy_buffering off;
|
|
28
|
+
proxy_request_buffering off;
|
|
29
|
+
|
|
30
|
+
location / {
|
|
31
|
+
proxy_pass http://LAN_IP:8081;
|
|
32
|
+
proxy_set_header Host $host;
|
|
33
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
34
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
35
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
36
|
+
|
|
37
|
+
# 超时设置(镜像推送可能耗时较长)
|
|
38
|
+
proxy_connect_timeout 900;
|
|
39
|
+
proxy_send_timeout 900;
|
|
40
|
+
proxy_read_timeout 900;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Harness - Git 代码托管
|
|
45
|
+
server {
|
|
46
|
+
listen 80;
|
|
47
|
+
server_name harness.wyo.sg;
|
|
48
|
+
return 301 https://$server_name$request_uri;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
server {
|
|
52
|
+
listen 443 ssl http2;
|
|
53
|
+
server_name harness.wyo.sg;
|
|
54
|
+
|
|
55
|
+
ssl_certificate /etc/nginx/ssl/wyo.sg/fullchain.pem;
|
|
56
|
+
ssl_certificate_key /etc/nginx/ssl/wyo.sg/privkey.pem;
|
|
57
|
+
|
|
58
|
+
ssl_protocols TLSv1.2 TLSv1.3;
|
|
59
|
+
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
|
60
|
+
ssl_prefer_server_ciphers off;
|
|
61
|
+
ssl_session_cache shared:SSL:10m;
|
|
62
|
+
ssl_session_timeout 1d;
|
|
63
|
+
|
|
64
|
+
# Git 仓库可能较大
|
|
65
|
+
client_max_body_size 0;
|
|
66
|
+
|
|
67
|
+
location / {
|
|
68
|
+
proxy_pass http://LAN_IP:8082;
|
|
69
|
+
proxy_set_header Host $host;
|
|
70
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
71
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
72
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
73
|
+
|
|
74
|
+
# WebSocket 支持(实时日志、通知等)
|
|
75
|
+
proxy_http_version 1.1;
|
|
76
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
77
|
+
proxy_set_header Connection "upgrade";
|
|
78
|
+
|
|
79
|
+
# 超时设置
|
|
80
|
+
proxy_connect_timeout 300;
|
|
81
|
+
proxy_send_timeout 300;
|
|
82
|
+
proxy_read_timeout 300;
|
|
83
|
+
}
|
|
84
|
+
}
|
package/dev/px-cli.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# px-cli
|
|
2
|
+
|
|
3
|
+
Bun CLI project to interact with server using x-api-key method
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cd px
|
|
9
|
+
bun install
|
|
10
|
+
cp .env.example .env # fill in PX_BASE_URL, PX_API_KEY, PX_MERCHANT_UID
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Structure
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
px/
|
|
17
|
+
├── package.json # bun project, depends on @posx/core
|
|
18
|
+
├── tsconfig.json
|
|
19
|
+
├── .env.example
|
|
20
|
+
├── index.ts # entry point & router (cac)
|
|
21
|
+
├── http.ts # HTTP client with x-api-key auth
|
|
22
|
+
├── .changes.json # staged CUD changes (auto-generated)
|
|
23
|
+
└── commands/
|
|
24
|
+
├── category.ts # Category CRUD (types: ICategory)
|
|
25
|
+
└── product.ts # Product CRUD (types: IItem)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Dependencies
|
|
29
|
+
|
|
30
|
+
- `@posx/core` — import types only (no service layer — no Dexie/IndexedDB in Bun):
|
|
31
|
+
- `IServiceOptions` — config typing in `http.ts`
|
|
32
|
+
- `ICategory` — category request/response typing
|
|
33
|
+
- `IItem` — product request/response typing
|
|
34
|
+
- `@litepos/autoquery` — `QueryBuilder` for `list` action (autoquery via `sapi` endpoint)
|
|
35
|
+
- `cac` — lightweight CLI framework (arg parsing, help text, subcommands)
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
### Read (immediate)
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# List via autoquery (sapi)
|
|
43
|
+
px category list
|
|
44
|
+
px category list --nameContains Drinks --take 10
|
|
45
|
+
px product list
|
|
46
|
+
px product list --nameContains Latte --take 10
|
|
47
|
+
|
|
48
|
+
# Get by ID
|
|
49
|
+
px category get --id 123
|
|
50
|
+
px product get --id 456
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### CUD — two-step workflow (stage → commit)
|
|
54
|
+
|
|
55
|
+
CUD operations stage changes locally before applying to server.
|
|
56
|
+
|
|
57
|
+
**Step 1: Stage changes** — fetches latest data, displays diff, saves to `.changes.json`
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Add (shows new record fields)
|
|
61
|
+
px category add --name "Drinks" --type product --color "#ff0000" --icon "🍹"
|
|
62
|
+
|
|
63
|
+
# Update (fetches current record, shows old → new diff)
|
|
64
|
+
# Pattern: GET → merge changes → PATCH
|
|
65
|
+
px category update --id 123 --name "Beverages"
|
|
66
|
+
px product update --id 456 --price 6.00
|
|
67
|
+
|
|
68
|
+
# Delete (fetches current record, shows record to be removed)
|
|
69
|
+
px category delete --id 123
|
|
70
|
+
px product delete --id 456
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Step 2: Review & apply**
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
px status # show all staged changes
|
|
77
|
+
px commit # apply all staged changes to server
|
|
78
|
+
px reset # discard all staged changes
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## API
|
|
82
|
+
|
|
83
|
+
- **Base**: `https://lite-dev.posx.ai`
|
|
84
|
+
- **Auth**: `x-api-key` header
|
|
85
|
+
|
|
86
|
+
| Method | Route | Action |
|
|
87
|
+
|----------|-----------------------------------------------------|------------------|
|
|
88
|
+
| `GET` | `sapi/v5/merchants/{merchant_uid}/{module}` | list (autoquery) |
|
|
89
|
+
| `GET` | `api/v5/merchants/{merchant_uid}/{module}/{id}` | get |
|
|
90
|
+
| `PUT` | `api/v5/merchants/{merchant_uid}/{module}/{method}` | add |
|
|
91
|
+
| `PATCH` | `api/v5/merchants/{merchant_uid}/{module}/{id}` | update |
|
|
92
|
+
| `DELETE` | `api/v5/merchants/{merchant_uid}/{module}/{id}` | delete |
|
|
93
|
+
|
|
94
|
+
## Ref
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
curl -H "x-api-key: p8Hwl4A7ewynszODOOc05SJcqSP6YZDo2pevtZ" \
|
|
98
|
+
"https://lite-dev.posx.ai/api/v5/merchants/by-whatsapp-jid/6590992059@s.whatsapp.net"
|
|
99
|
+
```
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# 2026-02 测试日志
|
|
2
|
+
|
|
3
|
+
| # | 分支 | 时间 | 变更 | 测试 | 🌐 | 问题 | 状态 |
|
|
4
|
+
|---|------|------|------|------|:--:|------|------|
|
|
5
|
+
| 1 | bugfix/rounding-half-up-51 | 02-03 10:45 | roundingStep 实现 round half up | 19/20 passed | ✗ | `service-charge-and-tax-exempt.test.ts` 期望值需更新 5877→5876.9 | 🔧 需修复 |
|