Metadata-Version: 2.4
Name: makea-cli
Version: 0.1.24
Summary: Makea admin CLI (browser login + Makea admin HTTP API)
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: platformdirs>=4.2
Requires-Dist: rich>=13.7
Requires-Dist: typer>=0.12
Description-Content-Type: text/markdown

# makea-cli

给 **Makea** 内部同事用的命令行小工具：连的是线上正式环境，**装好就能用，不用配环境变量、不用改配置文件**。

第一次用时在浏览器里登录一次公司账号，之后在本机保存登录状态，即可查询用户、供应商等（具体能执行哪些命令取决于你的账号权限）。

---

## 怎么用（三步）

1. **安装**（本机需要已安装 [Python 3.10 或以上](https://www.python.org/downloads/)）
  - **从本仓库安装（开发 / 内网 clone）：** 在 `makea-cli/` 目录执行  
   `python3 -m pip install -e .`  
   若提示找不到 `python3`，可改用 `python`。
  - **不经过 GitHub：** 把本包的 **Python** 发行版发布到公司私有 PyPI / Artifact Registry 等，同事执行  
  `python3 -m pip install makea-cli`（或 `pipx install makea-cli`）即可；无需 clone 仓库。
  - **可选 — 用 npm 只占一个全局命令名：** 仓库里 `npm/makea-cli/` 是一个 **薄封装**，`npm install -g` 后会把 `makea-cli` 指到 `python3 -m makea_cli`；**仍需**在同一台机器上先用 `pip` 装好同名 Python 包（npm 不会替你安装 Python 依赖）。适合已经用 npm 管理全局工具的团队。
2. **登录（只需做一次，或过期后再做）**
  ```bash
   makea-cli auth
  ```
   会自动打开浏览器，按公司流程登录即可。完成后可以关掉浏览器标签页。
3. **执行功能**（示例）
  ```bash
   makea-cli list-users
   makea-cli list-suppliers
   makea-cli list-product-orders
   makea-cli list-sampling-orders-by-product <product_reference_id>
   makea-cli list-production-orders-by-product <product_reference_id>
  ```
   **从「产品订单」JSON 下载附件：** `list-product-orders` 返回的每条 `result` 里已有 `user_id` 和 `available_documents`（含 `document_id`、`admin_user_id` 等），一般 **不必再调单独的 document metadata API**。可直接：
   若只有 `product_reference_id`，可用（建议加上设计师 `user_id` 避免扫全库）：
   更多子命令与参数：

退出登录（清除本机保存的令牌）：

```bash
makea-cli auth --logout
```

---

## 登录信息保存在哪

保存在本机当前用户下的应用数据目录里（例如 macOS 常见为 `~/Library/Application Support/makea-cli/`，Linux 常见为 `~/.config/makea-cli/`），文件名类似 `credentials.json`。一般不用手动打开。

---

## 给技术同事：可选环境变量

日常同事 **不需要** 看本节。只有要连 **非线上** 或 **自建环境** 时，才用环境变量覆盖内置地址（默认值在 `makea_cli/config.py` 里）：


| 变量                        | 说明                                             |
| ------------------------- | ---------------------------------------------- |
| `MAKEA_API_BASE_URL`      | API 根地址（无末尾 `/`）                               |
| `MAKEA_COGNITO_DOMAIN`    | Cognito Hosted UI 的**主机名**（不要写 `https://`）     |
| `MAKEA_COGNITO_CLIENT_ID` | Cognito 应用客户端 ID                               |
| `MAKEA_REDIRECT_URI`      | OAuth 回调地址，默认 `http://127.0.0.1:8250/callback` |


---

## 命令一览

- `makea-cli auth` — 浏览器登录并保存令牌  
- `makea-cli auth --logout` — 清除本机令牌  
- `makea-cli list-users` — 列出用户（需管理员权限）  
- `makea-cli create-user <email> --user-type "<type>" [--password ...] [--name ...] [--company-name ...] [--username ...]` — 注册用户并直接确认 Cognito 账号（POST `/admin/users/create`，不发验证码邮件，创建后即可用该密码登录）  
- `makea-cli list-suppliers` — 列出供应商（需管理员权限）  
- `makea-cli create-quote-request -s <supplier_id> -p <product_reference_id> [--quote-type SAMPLING|PRODUCTION] [--message ...] [--due-date YYYY-MM-DD]` — 创建并发送 quote request（POST `/admin/supplier/create_quote_request`）  
- `makea-cli get-quote-requests [--product-id <product_id>] [--quote-request-id <id>]` — 列某个产品下的 quote requests，或读单条完整内容（GET `/admin/quote_requests`）  
- `makea-cli update-quote-request <quote_request_id> [--stage SAMPLING] [--status PENDING_SUPPLIER] [--due-date YYYY-MM-DD | --clear-due-date]` — 改 quote request 的 stage / status / 截止日（PATCH `/admin/quote_requests/{id}/update`）。**代供应商报价前常常要先用它**：quote request 停在 ENGAGEMENT（供应商还没接单）时 `submit-supplier-quote` 会被拒；过了 due date 也会被拒  
- `makea-cli get-quote-requests-by-supplier-id <supplier_id> [--status <status>] [-n <limit>]` — 直连后端按 supplier_id 查询 quote requests  
- `makea-cli get-supplier-links-by-supplier-id <supplier_id> [--link-type SAMPLING|PRODUCTION]` — 直连后端按 supplier_id 查询 supplier links  
- `makea-cli submit-supplier-quote <quote_request_id> --link-name ... --currency ... --sampling-price-value ... --sampling-price-valid-until ... --sample-lead-time ... --deliverables-json ... --customer-note ...` — 以 admin 身份代供应商向指定 quote request 新增 quote。大货阶梯价（`--production-price-tiers-json`）和 `--lead-time` 现在是可选的；样衣加做费、MOQ 口径、寄料地址（CMT / full package 打样报价必填）、可选尺码颜色、规格行、typed link 等字段见 `--help`。pricing groups 提交时给不进去，提交完用 `update-supplier-quote` 补  
- `makea-cli update-supplier-quote <product_id> <link_id> [--sampling-price-value ... --sampling-price-valid-until ...] [--production-price-tiers-json ...] [--pricing-groups-json ...] [...]` — 改一条已提交的 quote（supplier link）：只发你传的字段，没传的后端不动；pricing groups（多套阶梯价）只有这条命令能写（POST `/admin/product/edit_supplier_link_override_info`）  
- `makea-cli list-product-orders` — 列出所有设计师产品订单（GET `/admin/designer/get_all_product_orders`）  
- `makea-cli list-sampling-orders-by-product <id>` — 按产品 reference id 列打样单  
- `makea-cli list-production-orders-by-product <id>` — 按产品 reference id 列大货单  
- `makea-cli production-pricing-show <production_order_id>` — 看一张大货单的定价现状：币种、MOQ、阶梯价、尺码/颜色、pricing groups、购物车覆盖情况（加 `--json` 出原始字段）  
- `makea-cli production-variants-set <production_order_id> --sizes S,M,L --color "Black:#000000"` — 改这张单的可选尺码和颜色（cart key 就是由它们拼出来的）  
- `makea-cli production-tiers-set <production_order_id> --tier 100-199:7.50 --tier 500+:7.20 --moq 100` — 改整单口径的阶梯价 / MOQ / incoterm / 币种  
- `makea-cli production-groups-generate <production_order_id> --by style|colour|variant|all` — 按某个轴生成 pricing groups，连带每组的阶梯价和 MOQ  
- `makea-cli production-groups-set <production_order_id> --file groups.json | --from-quote | --clear` — 整体写入 pricing groups：文件回放、从供应商报价拷贝、或清空回退到整单阶梯价  
- `makea-cli download-document <document_id> -u <user_id>` — 下载单个文件（GET `/admin/document/download`）  
- `makea-cli download-product-document <product_reference_id> <document_id> -d <designer_user_id>` — 按产品行 + 文档 id 下载（内部用订单列表 JSON，不额外查 metadata）  
- `makea-cli upload-product-document -u <designer_user_id> -p <product_id> -f <path>` — 通用产品文档上传（不限 quote 流程）：上传到 AWS S3 并挂到产品（POST `/admin/designer/upload_document`），返回 document domain 元数据供其它命令使用  
- `makea-cli upload-supplier-document -s <supplier_id> -f <path>` — 上传 supplier 文档到 AWS S3（POST `/admin/supplier/upload_document`），返回 document domain 元数据  
- `makea-cli upload-sampling-order-document <sampling_order_id> -f <path>` — 上传 sampling order 文档到 AWS S3（POST `/admin/sampling_orders/{id}/documents`），返回 document domain 元数据  
- `makea-cli upload-production-order-document <production_order_id> -f <path>` — 上传到 AWS S3 并挂到 production order（POST `/admin/production_orders/{id}/documents`），返回 document domain 元数据  
- `makea-cli upload-production-progress-document <production_order_id> <progress_id> -f <path>` — 上传 production progress 文档到 AWS S3（POST `/admin/production_orders/{id}/progress/{progress_id}/upload`），返回 document domain 元数据  
- `makea-cli upload-financial-documents <product_id> -f <path1> -f <path2>` — 上传一个或多个 financial documents（POST `/admin/products/{product_id}/financial_documents`），返回 financial document 元数据  
- `makea-cli upload-link-document -f <path>` — 上传文件到 AWS S3（POST `/admin/upload_link_document`），返回 document domain 元数据（可作为其它命令的 document 输入）  
- `makea-cli backfill-supplier-id --user-id <cognito_sub> --old-supplier-id <wrong_uuid>` — 供应商 `supplier_id` 迁到 Cognito `sub`（默认 dry-run，加 `--apply` 才写入；详见 `makea-cli backfill-supplier-id --help`）  
- `makea-cli version` — 打印版本号

---

## 大货定价（price tier / 颜色尺码 / pricing group）

一张 production order 的价格由三部分组成：

1. `available_sizes` / `available_colors` — 买家购物车的网格。cart key 是 `"{尺码},{颜色}"`，颜色段有 hex 就用 `hex_code`，没有才退回 `color_name`。所以颜色尽量都给 hex。
2. `production_price_tiers` + `moq` — 整单一套阶梯价。**只在这张单没有 pricing group 时生效**。
3. `pricing_groups` — 若干个各自计价的 cart key 分组。分组回答"谁共用一套价目表"，`tier_basis` / `moq_basis` 回答"按什么量去查这套表"（VARIANT 每个 cart key 各算各的，GROUP 按组内合计，ORDER 按全单合计）。

MOQ 的几种配法就是这两个旋钮的组合：

| 想要的效果 | 命令 |
|---|---|
| 每个 style 自己的阶梯价 + 自己的 MOQ | `--by style --moq-basis group` |
| 每个颜色一个 MOQ，跨所有 style 累计 | `--by colour --moq-basis group` |
| 每个颜色 × 尺码单独计价 | `--by variant --moq-basis group` |
| 全单一套价，MOQ 看全单总量 | `--by all --moq-basis order` |

阶梯写法：`--tier 100-199:7.50 --tier 200-499:7.40 --tier 500+:7.20`。结尾的 `+`（或只写下限）表示不封顶，存成 `max_qty=0`；后端从低到高选，最后一个够 `min_qty` 的档位胜出。

单组覆盖：`--tier-for 'S=100-199:22.45'`、`--moq-for 'S=100'`，等号左边可以写组名、尺码、颜色名或 hex。

例（参考 Lacati 毯子那张报价的形态：三个尺寸各一套价，MOQ 100/组）：

```bash
makea-cli production-variants-set <po_id> --sizes S,M,L --customized-color
makea-cli production-groups-generate <po_id> --by style \
  --tier-for 'S=100-199:7.50'  --tier-for 'S=300+:7.20' \
  --tier-for 'M=100-199:22.45' --tier-for 'M=300+:21.85' \
  --tier-for 'L=100-199:33.05' --tier-for 'L=300+:32.25' \
  --moq 100 --moq-basis group --tier-basis VARIANT --dry-run
```

几条要记住的：

- 写命令都先打印 plan 再问一次；`--dry-run` 只看不发，`--yes` 跳过确认。默认打的是**生产环境**。
- 购物车里有、却没被任何组认领的 cart key，付款时会整单失败（不是按 0 计价）。plan 和保存结果都会把这些 key 列出来。
- 重跑 `production-groups-generate` 会保留同名/同变体旧组的 `group_id` 和这次没指定的字段，所以"只改 MOQ"是安全的。
- 已经付过款的单，改这里不会动已经收的钱（发票读冻结值），只影响之后的扣款。

---

## Claude / Cursor skills（可选）

仓库内 `.claude/skills/` 下放有面向 agent 的操作说明，例如：

- `supplier-user-id-migration` — 供应商 ID 与 Cognito sub 对齐、与 `backfill-supplier-id` 配套

