@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.
Files changed (47) hide show
  1. package/CLAUDE.md +23 -23
  2. package/LICENSE +21 -21
  3. package/README.md +85 -85
  4. package/build/index.d.ts +3 -0
  5. package/build/index.js +1 -1
  6. package/dev/.stfolder/syncthing-folder-9a95b7.txt +5 -0
  7. package/dev/98894488.xlsx +0 -0
  8. package/dev/HappyThaiSembawang.csv +336 -0
  9. package/dev/KB/create-new-model.md +34 -0
  10. package/dev/KB/markdown-lint.md +14 -0
  11. package/dev/KB/readmefirst.md +6 -0
  12. package/dev/Merchants/HappyThaiSembawang.csv +400 -0
  13. package/dev/Merchants/HappyThaiSembawang.xlsx +0 -0
  14. package/dev/Product_Import_Template.xlsx +0 -0
  15. package/dev/XPOS Invoice Module.pdf +232 -0
  16. package/dev/escpos/receipt.bin +0 -0
  17. package/dev/escpos/receipt.hex +1 -0
  18. package/dev/escpos/receipt.json +1 -0
  19. package/dev/escpos-cli-usage.md +103 -0
  20. package/dev/harbor-harness-deployment.md +78 -0
  21. package/dev/nginx-harbor-harness.conf +84 -0
  22. package/dev/px-cli.md +99 -0
  23. package/dev/test-logs/2026-02.md +5 -0
  24. package/dev/tmp/xpos_product_import(1).csv +338 -0
  25. package/dev/tmp/xpos_product_import_fixed.csv +338 -0
  26. package/dev//344/272/247/345/223/201/345/257/274/345/205/245/346/250/241/346/235/277.xlsx +0 -0
  27. package/jest.config.cjs +36 -36
  28. package/jest.setup.cjs +80 -80
  29. package/package.json +1 -1
  30. package/package.publish.json +121 -121
  31. package/px/.env.example +3 -0
  32. package/px/commands/category.ts +47 -0
  33. package/px/commands/product.ts +51 -0
  34. package/px/http.ts +40 -0
  35. package/px/index.ts +35 -0
  36. package/tsdown.config.ts +21 -21
  37. package/vite.config.ts +86 -86
  38. package/memo/technical-docs/01_ARCHITECTURE.md +0 -147
  39. package/memo/technical-docs/02_CORE_BUSINESS.md +0 -292
  40. package/memo/technical-docs/03_UI_COMPONENTS.md +0 -59
  41. package/memo/technical-docs/04_VIEWS.md +0 -82
  42. package/memo/technical-docs/05_DATA_LAYER.md +0 -375
  43. package/memo/technical-docs/06_CROSS_PLATFORM.md +0 -246
  44. package/memo/technical-docs/07_SIMILARITY_INDEX.md +0 -195
  45. package/memo/technical-docs/CHECKPOINT.md +0 -46
  46. package/memo/technical-docs/PROJECT_OVERVIEW.md +0 -122
  47. 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 | 🔧 需修复 |