makea-cli 0.2.4__tar.gz → 0.2.6__tar.gz

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 (66) hide show
  1. {makea_cli-0.2.4 → makea_cli-0.2.6}/CHANGELOG.md +22 -0
  2. {makea_cli-0.2.4 → makea_cli-0.2.6}/PKG-INFO +5 -1
  3. {makea_cli-0.2.4 → makea_cli-0.2.6}/README.md +4 -0
  4. makea_cli-0.2.6/makea_cli/__init__.py +1 -0
  5. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/api_client.py +21 -0
  6. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/brand/cmd.py +96 -0
  7. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/orders/cmd.py +63 -0
  8. {makea_cli-0.2.4 → makea_cli-0.2.6}/pyproject.toml +1 -1
  9. {makea_cli-0.2.4 → makea_cli-0.2.6}/tests/golden_manifest.json +252 -0
  10. makea_cli-0.2.4/makea_cli/__init__.py +0 -1
  11. {makea_cli-0.2.4 → makea_cli-0.2.6}/.claude/skills/create-supplier-profile/SKILL.md +0 -0
  12. {makea_cli-0.2.4 → makea_cli-0.2.6}/.claude/skills/lark-cli-setup/SKILL.md +0 -0
  13. {makea_cli-0.2.4 → makea_cli-0.2.6}/.claude/skills/link-supplier-user/SKILL.md +0 -0
  14. {makea_cli-0.2.4 → makea_cli-0.2.6}/.claude/skills/makea-cli-setup/SKILL.md +0 -0
  15. {makea_cli-0.2.4 → makea_cli-0.2.6}/.claude/skills/payment-revenue-report/SKILL.md +0 -0
  16. {makea_cli-0.2.4 → makea_cli-0.2.6}/.claude/skills/supplier-user-id-migration/SKILL.md +0 -0
  17. {makea_cli-0.2.4 → makea_cli-0.2.6}/.gitignore +0 -0
  18. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea-collection-upload/SKILL.md +0 -0
  19. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea-collection-upload/scripts/create_products.py +0 -0
  20. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/__main__.py +0 -0
  21. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/auth_pkce.py +0 -0
  22. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/broker.py +0 -0
  23. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/__init__.py +0 -0
  24. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/_util.py +0 -0
  25. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/analytics/__init__.py +0 -0
  26. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/analytics/cmd.py +0 -0
  27. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/auth/__init__.py +0 -0
  28. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/auth/cmd.py +0 -0
  29. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/brand/__init__.py +0 -0
  30. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/designer/__init__.py +0 -0
  31. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/designer/cmd.py +0 -0
  32. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/directory/__init__.py +0 -0
  33. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/directory/cmd.py +0 -0
  34. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/document/__init__.py +0 -0
  35. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/document/cmd.py +0 -0
  36. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/email/__init__.py +0 -0
  37. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/email/cmd.py +0 -0
  38. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/factory/__init__.py +0 -0
  39. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/factory/cmd.py +0 -0
  40. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/library/__init__.py +0 -0
  41. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/library/cmd.py +0 -0
  42. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/metrics/__init__.py +0 -0
  43. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/metrics/cmd.py +0 -0
  44. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/orders/__init__.py +0 -0
  45. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/product/__init__.py +0 -0
  46. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/product/cmd.py +0 -0
  47. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/production/__init__.py +0 -0
  48. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/production/cmd.py +0 -0
  49. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/production/pricing_spec.py +0 -0
  50. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/supplier/__init__.py +0 -0
  51. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/commands/supplier/cmd.py +0 -0
  52. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/config.py +0 -0
  53. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/errors.py +0 -0
  54. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/identity.py +0 -0
  55. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/main.py +0 -0
  56. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/output.py +0 -0
  57. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/posthog_client.py +0 -0
  58. {makea_cli-0.2.4 → makea_cli-0.2.6}/makea_cli/registry.py +0 -0
  59. {makea_cli-0.2.4 → makea_cli-0.2.6}/npm/makea-cli/README.md +0 -0
  60. {makea_cli-0.2.4 → makea_cli-0.2.6}/npm/makea-cli/makea-cli.mjs +0 -0
  61. {makea_cli-0.2.4 → makea_cli-0.2.6}/npm/makea-cli/package.json +0 -0
  62. {makea_cli-0.2.4 → makea_cli-0.2.6}/tests/test_broker.py +0 -0
  63. {makea_cli-0.2.4 → makea_cli-0.2.6}/tests/test_output_contract.py +0 -0
  64. {makea_cli-0.2.4 → makea_cli-0.2.6}/tests/test_persona_commands.py +0 -0
  65. {makea_cli-0.2.4 → makea_cli-0.2.6}/tests/test_registry.py +0 -0
  66. {makea_cli-0.2.4 → makea_cli-0.2.6}/uv.lock +0 -0
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.6
4
+
5
+ - `admin update tracking-status <kind> <order_id> <tracking_number> --status Delivered`
6
+ (`ask`): tell Makea what the carrier says about one parcel. The 17track API
7
+ is off, so the daily tracking-sweep skill reads the public 17track page and
8
+ posts each delivered parcel here. The backend runs the same path the 17track
9
+ webhook did: status, fan-out to every order sharing the number, and the
10
+ delivered emails. Repeating a Delivered update is a no-op.
11
+
12
+ ## 0.2.5
13
+
14
+ The production journey, for the Claude agent on the product channel.
15
+
16
+ - `designer set production-cart <production_order_id> --qty 'SIZE,#RRGGBB=COUNT' …`
17
+ (`auto`): the run's size x colour quantities. Replaces the whole cart, and is
18
+ refused once the run is locked.
19
+ - `designer set production-lock <production_order_id> [--unlock]` (`ask`):
20
+ place the order. Locking is what makes the deposit payable; it can be
21
+ reopened until the deposit is paid.
22
+ - `designer get production-price <production_order_id> [--phase final]`: the
23
+ deposit (or balance) for the quantities on the run now, line by line.
24
+
3
25
  ## 0.2.4
4
26
 
5
27
  For Beeboo acting for a brand through the CLI (the Claude agent on the product
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: makea-cli
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: Makea admin CLI (browser login + Makea admin HTTP API)
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: click<9,>=8.1
@@ -131,6 +131,7 @@ exit code:`0` 成功 · `2` 用法错 · `3` 未登录或身份与 persona 不
131
131
  | `makea-cli admin update quote-request` | write(ask) | `PATCH /admin/quote_requests/{quote_request_id}/update` | set a quote request's stage, status and/or due date. Only what you pass is changed. This is the door that unblocks a … | `update-quote-request` |
132
132
  | `makea-cli admin update supplier` | write(ask) | `PUT /admin/supplier/update_supplier` | update an existing supplier from a JSON file (admin). Run `makea-cli get-supplier-profile-schema` FIRST to get the fi… | `update-supplier` |
133
133
  | `makea-cli admin update tech-spec` | write(ask) | `POST /admin/products/{id}/technical-specifications` | persist specs from a JSON file. | `save-product-tech-spec` |
134
+ | `makea-cli admin update tracking-status` | write(ask) | `POST /admin/tracking/carrier_status` | apply a carrier status looked up by hand (tracking-sweep skill) to one order. Runs the 17track webhook path: status, fan-out, delivered emails. | — |
134
135
  | `makea-cli admin update user` | write(ask) | `PUT /admin/user-profiles/{user_id}/update` | admin updates DynamoDB user profile fields and/or Cognito custom:userType. Allowed --user-type values: "Fashion brand… | `update-user-profile` |
135
136
  | `makea-cli admin upload financial-document` | write(auto) | `POST /admin/products/{product_id}/financial_documents` | upload one or more files to AWS S3 and return financial document metadata. | `upload-financial-documents` |
136
137
  | `makea-cli admin upload link-document` | write(auto) | `POST /admin/upload_link_document` | upload a file to AWS S3 and return document domain metadata for reuse as input in other commands. | `upload-link-document` |
@@ -157,6 +158,7 @@ exit code:`0` 成功 · `2` 用法错 · `3` 未登录或身份与 persona 不
157
158
  | `makea-cli designer get collection` | read | `GET /designer/collections/{collection_id}/overview` | one collection with its products, orders and lifecycle in a single read. | — |
158
159
  | `makea-cli designer get lifecycle` | read | `GET /designer/product_orders/{product_order_id}/lifecycle` | which stage this product is in. | — |
159
160
  | `makea-cli designer get product` | read | `GET /designer/get_product` | one product: status, documents, prices, links. | — |
161
+ | `makea-cli designer get production-price` | read | `GET /designer/production_orders/{production_order_id}/calculate_price` | what the deposit (or the balance, --phase final) comes to for the quantities on the run right now, line by line. | — |
160
162
  | `makea-cli designer get quote-advice` | read | `GET /designer/product/quote_advice` | which quote to award and why, from cache. Reading never spends a model call; the web app is what asks for a fresh one. | — |
161
163
  | `makea-cli designer get tech-pack` | read | `GET /designer/products/{product_id}/technical-specifications` | the product's tech pack. | — |
162
164
  | `makea-cli designer get tech-pack-history` | read | `GET /designer/products/{product_id}/specification-change-history` | who changed which spec field, when, and from what. | — |
@@ -173,6 +175,8 @@ exit code:`0` 成功 · `2` 用法错 · `3` 未登录或身份与 persona 不
173
175
  | `makea-cli designer list task` | read | `GET /designer/tasks` | what the platform is waiting on you for. | — |
174
176
  | `makea-cli designer search note` | read | `GET /designer/products/{product_id}/channel_search` | full-text search across a product's conversation; --channel narrows to one channel key. | — |
175
177
  | `makea-cli designer set product-collection` | write(auto) | `POST /designer/products/{id}/link-to-collection` | assign product to a collection. | `designer-link-product-to-collection` |
178
+ | `makea-cli designer set production-cart` | write(auto) | `PUT /designer/production_orders/{production_order_id}/cart` | the quantity of every size and colour on the run. Replaces the whole cart: pass every cell you want kept. --qty repea… | — |
179
+ | `makea-cli designer set production-lock` | write(ask) | `POST /designer/production_orders/{production_order_id}/configuration-lock` | place the order with the quantities on the run (--unlock to reopen them). Locking is what makes the deposit payable: … | — |
176
180
  | `makea-cli designer submit production-order` | write(ask) | `POST /designer/production_orders/{production_order_id}/submit` | submit a 大货 order. This is the commitment, so --dry-run and confirm with the user first. | — |
177
181
  | `makea-cli designer submit sampling-order` | write(ask) | `POST /designer/sampling_orders/{sampling_order_id}/confirm` | confirm a sample order so the supplier starts. Run --dry-run first and read it back to the user. | — |
178
182
  | `makea-cli designer submit tech-pack` | write(ask) | `POST /designer/products/{product_id}/technical-specifications/confirm` | confirm the tech pack, the step before anyone is asked to quote. | — |
@@ -119,6 +119,7 @@ exit code:`0` 成功 · `2` 用法错 · `3` 未登录或身份与 persona 不
119
119
  | `makea-cli admin update quote-request` | write(ask) | `PATCH /admin/quote_requests/{quote_request_id}/update` | set a quote request's stage, status and/or due date. Only what you pass is changed. This is the door that unblocks a … | `update-quote-request` |
120
120
  | `makea-cli admin update supplier` | write(ask) | `PUT /admin/supplier/update_supplier` | update an existing supplier from a JSON file (admin). Run `makea-cli get-supplier-profile-schema` FIRST to get the fi… | `update-supplier` |
121
121
  | `makea-cli admin update tech-spec` | write(ask) | `POST /admin/products/{id}/technical-specifications` | persist specs from a JSON file. | `save-product-tech-spec` |
122
+ | `makea-cli admin update tracking-status` | write(ask) | `POST /admin/tracking/carrier_status` | apply a carrier status looked up by hand (tracking-sweep skill) to one order. Runs the 17track webhook path: status, fan-out, delivered emails. | — |
122
123
  | `makea-cli admin update user` | write(ask) | `PUT /admin/user-profiles/{user_id}/update` | admin updates DynamoDB user profile fields and/or Cognito custom:userType. Allowed --user-type values: "Fashion brand… | `update-user-profile` |
123
124
  | `makea-cli admin upload financial-document` | write(auto) | `POST /admin/products/{product_id}/financial_documents` | upload one or more files to AWS S3 and return financial document metadata. | `upload-financial-documents` |
124
125
  | `makea-cli admin upload link-document` | write(auto) | `POST /admin/upload_link_document` | upload a file to AWS S3 and return document domain metadata for reuse as input in other commands. | `upload-link-document` |
@@ -145,6 +146,7 @@ exit code:`0` 成功 · `2` 用法错 · `3` 未登录或身份与 persona 不
145
146
  | `makea-cli designer get collection` | read | `GET /designer/collections/{collection_id}/overview` | one collection with its products, orders and lifecycle in a single read. | — |
146
147
  | `makea-cli designer get lifecycle` | read | `GET /designer/product_orders/{product_order_id}/lifecycle` | which stage this product is in. | — |
147
148
  | `makea-cli designer get product` | read | `GET /designer/get_product` | one product: status, documents, prices, links. | — |
149
+ | `makea-cli designer get production-price` | read | `GET /designer/production_orders/{production_order_id}/calculate_price` | what the deposit (or the balance, --phase final) comes to for the quantities on the run right now, line by line. | — |
148
150
  | `makea-cli designer get quote-advice` | read | `GET /designer/product/quote_advice` | which quote to award and why, from cache. Reading never spends a model call; the web app is what asks for a fresh one. | — |
149
151
  | `makea-cli designer get tech-pack` | read | `GET /designer/products/{product_id}/technical-specifications` | the product's tech pack. | — |
150
152
  | `makea-cli designer get tech-pack-history` | read | `GET /designer/products/{product_id}/specification-change-history` | who changed which spec field, when, and from what. | — |
@@ -161,6 +163,8 @@ exit code:`0` 成功 · `2` 用法错 · `3` 未登录或身份与 persona 不
161
163
  | `makea-cli designer list task` | read | `GET /designer/tasks` | what the platform is waiting on you for. | — |
162
164
  | `makea-cli designer search note` | read | `GET /designer/products/{product_id}/channel_search` | full-text search across a product's conversation; --channel narrows to one channel key. | — |
163
165
  | `makea-cli designer set product-collection` | write(auto) | `POST /designer/products/{id}/link-to-collection` | assign product to a collection. | `designer-link-product-to-collection` |
166
+ | `makea-cli designer set production-cart` | write(auto) | `PUT /designer/production_orders/{production_order_id}/cart` | the quantity of every size and colour on the run. Replaces the whole cart: pass every cell you want kept. --qty repea… | — |
167
+ | `makea-cli designer set production-lock` | write(ask) | `POST /designer/production_orders/{production_order_id}/configuration-lock` | place the order with the quantities on the run (--unlock to reopen them). Locking is what makes the deposit payable: … | — |
164
168
  | `makea-cli designer submit production-order` | write(ask) | `POST /designer/production_orders/{production_order_id}/submit` | submit a 大货 order. This is the commitment, so --dry-run and confirm with the user first. | — |
165
169
  | `makea-cli designer submit sampling-order` | write(ask) | `POST /designer/sampling_orders/{sampling_order_id}/confirm` | confirm a sample order so the supplier starts. Run --dry-run first and read it back to the user. | — |
166
170
  | `makea-cli designer submit tech-pack` | write(ask) | `POST /designer/products/{product_id}/technical-specifications/confirm` | confirm the tech pack, the step before anyone is asked to quote. | — |
@@ -0,0 +1 @@
1
+ __version__ = "0.2.6"
@@ -1213,6 +1213,27 @@ def designer_create_checkout(body: dict[str, Any]) -> Any:
1213
1213
  return post_json("/designer/payments/basket/create-session", body)
1214
1214
 
1215
1215
 
1216
+ def designer_production_price(production_order_id: str, phase: str) -> Any:
1217
+ """GET /designer/production_orders/{id}/calculate_price — deposit or balance, itemised."""
1218
+ return get_json(
1219
+ f"/designer/production_orders/{production_order_id}/calculate_price",
1220
+ params={"payment_type": phase},
1221
+ )
1222
+
1223
+
1224
+ def designer_set_production_cart(production_order_id: str, cart: dict[str, int]) -> Any:
1225
+ """PUT /designer/production_orders/{id}/cart — replace the size x colour quantities."""
1226
+ return put_json(f"/designer/production_orders/{production_order_id}/cart", {"cart_items": cart})
1227
+
1228
+
1229
+ def designer_set_production_lock(production_order_id: str, locked: bool) -> Any:
1230
+ """POST /designer/production_orders/{id}/configuration-lock — place or reopen the run."""
1231
+ return post_json(
1232
+ f"/designer/production_orders/{production_order_id}/configuration-lock",
1233
+ {"locked": locked},
1234
+ )
1235
+
1236
+
1216
1237
  def designer_list_collections() -> Any:
1217
1238
  """GET /designer/collections — the brand's collections."""
1218
1239
  return get_json("/designer/collections")
@@ -914,3 +914,99 @@ def register(app: typer.Typer) -> None:
914
914
  if accept_terms:
915
915
  body["terms_accepted"] = True
916
916
  print_json_or_exit(console, lambda: api_client.designer_create_checkout(body))
917
+
918
+ # --- the production journey: quantities, place the order, pay the deposit ---
919
+
920
+ @command(
921
+ app,
922
+ "designer",
923
+ "get",
924
+ "production-price",
925
+ api="GET /designer/production_orders/{production_order_id}/calculate_price",
926
+ help=(
927
+ "GET /designer/production_orders/{id}/calculate_price — what the deposit (or the "
928
+ "balance, --phase final) comes to for the quantities on the run right now, line "
929
+ "by line."
930
+ ),
931
+ )
932
+ def get_production_price(
933
+ production_order_id: str = typer.Argument(..., help="Production order id."),
934
+ phase: str = typer.Option("deposit", "--phase", help="deposit or final."),
935
+ ) -> None:
936
+ """Price a production order's deposit or balance."""
937
+ if phase not in ("deposit", "final"):
938
+ raise typer.BadParameter("--phase is deposit or final")
939
+ print_json_or_exit(
940
+ console,
941
+ lambda: api_client.designer_production_price(production_order_id, phase),
942
+ )
943
+
944
+ @command(
945
+ app,
946
+ "designer",
947
+ "set",
948
+ "production-cart",
949
+ api="PUT /designer/production_orders/{production_order_id}/cart",
950
+ side_effects=["replaces the run's quantities; nothing is ordered until it is locked"],
951
+ approval="auto",
952
+ help=(
953
+ "PUT /designer/production_orders/{id}/cart — the quantity of every size and "
954
+ "colour on the run. Replaces the whole cart: pass every cell you want kept. "
955
+ "--qty repeats as 'SIZE,#RRGGBB=COUNT' (quote it: # starts a shell comment), "
956
+ "with the sizes and colour hex codes from "
957
+ "the order's available_sizes / available_colors (`designer list "
958
+ "production-order --product <id>`). Refused once the run is locked."
959
+ ),
960
+ )
961
+ def set_production_cart(
962
+ production_order_id: str = typer.Argument(..., help="Production order id."),
963
+ qty: list[str] = typer.Option(
964
+ ..., "--qty", help="SIZE,#RRGGBB=COUNT for one cell (repeat)."
965
+ ),
966
+ ) -> None:
967
+ """Set a production order's size x colour quantities."""
968
+ cart: dict[str, int] = {}
969
+ for cell in qty:
970
+ key, sep, count = cell.rpartition("=")
971
+ if not sep or "," not in key:
972
+ raise typer.BadParameter(f"--qty {cell!r}: expected SIZE,#RRGGBB=COUNT")
973
+ try:
974
+ n = int(count)
975
+ except ValueError as e:
976
+ raise typer.BadParameter(f"--qty {cell!r}: COUNT must be a whole number") from e
977
+ if n < 0:
978
+ raise typer.BadParameter(f"--qty {cell!r}: COUNT cannot be negative")
979
+ size, _, colour = key.partition(",")
980
+ cart[f"{size.strip()},{colour.strip()}"] = n
981
+ print_json_or_exit(
982
+ console,
983
+ lambda: api_client.designer_set_production_cart(production_order_id, cart),
984
+ )
985
+
986
+ @command(
987
+ app,
988
+ "designer",
989
+ "set",
990
+ "production-lock",
991
+ api="POST /designer/production_orders/{production_order_id}/configuration-lock",
992
+ side_effects=[
993
+ "places the order: the quantities are final and the deposit becomes payable",
994
+ "can be unlocked again until the deposit is paid",
995
+ ],
996
+ approval="ask",
997
+ help=(
998
+ "POST /designer/production_orders/{id}/configuration-lock — place the order "
999
+ "with the quantities on the run (--unlock to reopen them). Locking is what makes "
1000
+ "the deposit payable: `designer create checkout --key "
1001
+ "production:<id>:deposit --accept-terms`."
1002
+ ),
1003
+ )
1004
+ def set_production_lock(
1005
+ production_order_id: str = typer.Argument(..., help="Production order id."),
1006
+ unlock: bool = typer.Option(False, "--unlock", help="Reopen the quantities instead."),
1007
+ ) -> None:
1008
+ """Lock (place) or unlock a production order's configuration."""
1009
+ print_json_or_exit(
1010
+ console,
1011
+ lambda: api_client.designer_set_production_lock(production_order_id, not unlock),
1012
+ )
@@ -314,3 +314,66 @@ def register(app: typer.Typer) -> None:
314
314
  offset=offset,
315
315
  ),
316
316
  )
317
+
318
+ @command(
319
+ app,
320
+ "admin",
321
+ "update",
322
+ "tracking-status",
323
+ api="POST /admin/tracking/carrier_status",
324
+ side_effects=[
325
+ "moves the order to delivered when the status says so",
326
+ "emails and messages the designer, supplier and admins as the 17track webhook did",
327
+ ],
328
+ approval="ask",
329
+ idempotent=True,
330
+ help=(
331
+ "POST /admin/tracking/carrier_status — apply a carrier status looked up by hand "
332
+ "(the tracking-sweep skill) to one order. Runs the 17track webhook path: status, "
333
+ "fan-out to every order sharing the number, and the delivered emails."
334
+ ),
335
+ )
336
+ def update_tracking_status(
337
+ kind: str = typer.Argument(
338
+ ...,
339
+ help="sampling | production | restock | shipping | material | reference_sample",
340
+ ),
341
+ order_id: str = typer.Argument(..., help="Order id (product id for reference_sample)."),
342
+ tracking_number: str = typer.Argument(..., help="The parcel's tracking number."),
343
+ status: str = typer.Option(
344
+ ..., "--status", help="17track status, e.g. Delivered, InTransit."
345
+ ),
346
+ sub_status: str | None = typer.Option(None, "--sub-status"),
347
+ event: str | None = typer.Option(None, "--event", help="Latest carrier event text."),
348
+ location: str | None = typer.Option(None, "--location"),
349
+ time_utc: str | None = typer.Option(
350
+ None, "--time", help="Latest event time, ISO 8601 UTC."
351
+ ),
352
+ ) -> None:
353
+ """
354
+ Tell Makea what the carrier says about one parcel.
355
+
356
+ Output: JSON from the webhook path: success, status, and one entry per
357
+ order the number was fanned out to. Repeating a Delivered update is a
358
+ no-op (no second email).
359
+ """
360
+ track_info = {
361
+ "latest_status": {"status": status, "sub_status": sub_status},
362
+ "latest_event": {
363
+ "description": event,
364
+ "location": location,
365
+ "time_utc": time_utc,
366
+ },
367
+ }
368
+ print_json_or_exit(
369
+ console,
370
+ lambda: api_client.post_json(
371
+ "/admin/tracking/carrier_status",
372
+ {
373
+ "kind": kind,
374
+ "order_id": order_id,
375
+ "tracking_number": tracking_number,
376
+ "track_info": track_info,
377
+ },
378
+ ),
379
+ )
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "makea-cli"
7
- version = "0.2.4"
7
+ version = "0.2.6"
8
8
  description = "Makea admin CLI (browser login + Makea admin HTTP API)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -3564,6 +3564,124 @@
3564
3564
  }
3565
3565
  ]
3566
3566
  },
3567
+ {
3568
+ "name": "admin update tracking-status",
3569
+ "persona": "admin",
3570
+ "verb": "update",
3571
+ "noun": "tracking-status",
3572
+ "access": "write",
3573
+ "api": "POST /admin/tracking/carrier_status",
3574
+ "external": null,
3575
+ "side_effects": [
3576
+ "moves the order to delivered when the status says so",
3577
+ "emails and messages the designer, supplier and admins as the 17track webhook did"
3578
+ ],
3579
+ "approval": "ask",
3580
+ "reversible": null,
3581
+ "idempotent": true,
3582
+ "limit": null,
3583
+ "legacy": [],
3584
+ "help": "POST /admin/tracking/carrier_status — apply a carrier status looked up by hand (the tracking-sweep skill) to one order. Runs the 17track webhook path: status, fan-out to every order sharing the number, and the delivered emails.",
3585
+ "function": "makea_cli.commands.orders.cmd.register.<locals>.update_tracking_status",
3586
+ "flags": [
3587
+ {
3588
+ "name": "kind",
3589
+ "kind": "argument",
3590
+ "opts": [
3591
+ "kind"
3592
+ ],
3593
+ "type": "text",
3594
+ "required": true,
3595
+ "multiple": false,
3596
+ "default": null,
3597
+ "help": "sampling | production | restock | shipping | material | reference_sample"
3598
+ },
3599
+ {
3600
+ "name": "order_id",
3601
+ "kind": "argument",
3602
+ "opts": [
3603
+ "order_id"
3604
+ ],
3605
+ "type": "text",
3606
+ "required": true,
3607
+ "multiple": false,
3608
+ "default": null,
3609
+ "help": "Order id (product id for reference_sample)."
3610
+ },
3611
+ {
3612
+ "name": "tracking_number",
3613
+ "kind": "argument",
3614
+ "opts": [
3615
+ "tracking_number"
3616
+ ],
3617
+ "type": "text",
3618
+ "required": true,
3619
+ "multiple": false,
3620
+ "default": null,
3621
+ "help": "The parcel's tracking number."
3622
+ },
3623
+ {
3624
+ "name": "status",
3625
+ "kind": "option",
3626
+ "opts": [
3627
+ "--status"
3628
+ ],
3629
+ "type": "text",
3630
+ "required": true,
3631
+ "multiple": false,
3632
+ "default": null,
3633
+ "help": "17track status, e.g. Delivered, InTransit."
3634
+ },
3635
+ {
3636
+ "name": "sub_status",
3637
+ "kind": "option",
3638
+ "opts": [
3639
+ "--sub-status"
3640
+ ],
3641
+ "type": "text",
3642
+ "required": false,
3643
+ "multiple": false,
3644
+ "default": null,
3645
+ "help": null
3646
+ },
3647
+ {
3648
+ "name": "event",
3649
+ "kind": "option",
3650
+ "opts": [
3651
+ "--event"
3652
+ ],
3653
+ "type": "text",
3654
+ "required": false,
3655
+ "multiple": false,
3656
+ "default": null,
3657
+ "help": "Latest carrier event text."
3658
+ },
3659
+ {
3660
+ "name": "location",
3661
+ "kind": "option",
3662
+ "opts": [
3663
+ "--location"
3664
+ ],
3665
+ "type": "text",
3666
+ "required": false,
3667
+ "multiple": false,
3668
+ "default": null,
3669
+ "help": null
3670
+ },
3671
+ {
3672
+ "name": "time_utc",
3673
+ "kind": "option",
3674
+ "opts": [
3675
+ "--time"
3676
+ ],
3677
+ "type": "text",
3678
+ "required": false,
3679
+ "multiple": false,
3680
+ "default": null,
3681
+ "help": "Latest event time, ISO 8601 UTC."
3682
+ }
3683
+ ]
3684
+ },
3567
3685
  {
3568
3686
  "name": "admin update user",
3569
3687
  "persona": "admin",
@@ -5201,6 +5319,49 @@
5201
5319
  }
5202
5320
  ]
5203
5321
  },
5322
+ {
5323
+ "name": "designer get production-price",
5324
+ "persona": "designer",
5325
+ "verb": "get",
5326
+ "noun": "production-price",
5327
+ "access": "read",
5328
+ "api": "GET /designer/production_orders/{production_order_id}/calculate_price",
5329
+ "external": null,
5330
+ "side_effects": [],
5331
+ "approval": "auto",
5332
+ "reversible": null,
5333
+ "idempotent": null,
5334
+ "limit": null,
5335
+ "legacy": [],
5336
+ "help": "GET /designer/production_orders/{id}/calculate_price — what the deposit (or the balance, --phase final) comes to for the quantities on the run right now, line by line.",
5337
+ "function": "makea_cli.commands.brand.cmd.register.<locals>.get_production_price",
5338
+ "flags": [
5339
+ {
5340
+ "name": "production_order_id",
5341
+ "kind": "argument",
5342
+ "opts": [
5343
+ "production_order_id"
5344
+ ],
5345
+ "type": "text",
5346
+ "required": true,
5347
+ "multiple": false,
5348
+ "default": null,
5349
+ "help": "Production order id."
5350
+ },
5351
+ {
5352
+ "name": "phase",
5353
+ "kind": "option",
5354
+ "opts": [
5355
+ "--phase"
5356
+ ],
5357
+ "type": "text",
5358
+ "required": false,
5359
+ "multiple": false,
5360
+ "default": "deposit",
5361
+ "help": "deposit or final."
5362
+ }
5363
+ ]
5364
+ },
5204
5365
  {
5205
5366
  "name": "designer get quote-advice",
5206
5367
  "persona": "designer",
@@ -5739,6 +5900,97 @@
5739
5900
  }
5740
5901
  ]
5741
5902
  },
5903
+ {
5904
+ "name": "designer set production-cart",
5905
+ "persona": "designer",
5906
+ "verb": "set",
5907
+ "noun": "production-cart",
5908
+ "access": "write",
5909
+ "api": "PUT /designer/production_orders/{production_order_id}/cart",
5910
+ "external": null,
5911
+ "side_effects": [
5912
+ "replaces the run's quantities; nothing is ordered until it is locked"
5913
+ ],
5914
+ "approval": "auto",
5915
+ "reversible": null,
5916
+ "idempotent": null,
5917
+ "limit": null,
5918
+ "legacy": [],
5919
+ "help": "PUT /designer/production_orders/{id}/cart — the quantity of every size and colour on the run. Replaces the whole cart: pass every cell you want kept. --qty repeats as 'SIZE,#RRGGBB=COUNT' (quote it: # starts a shell comment), with the sizes and colour hex codes from the order's available_sizes / available_colors (`designer list production-order --product <id>`). Refused once the run is locked.",
5920
+ "function": "makea_cli.commands.brand.cmd.register.<locals>.set_production_cart",
5921
+ "flags": [
5922
+ {
5923
+ "name": "production_order_id",
5924
+ "kind": "argument",
5925
+ "opts": [
5926
+ "production_order_id"
5927
+ ],
5928
+ "type": "text",
5929
+ "required": true,
5930
+ "multiple": false,
5931
+ "default": null,
5932
+ "help": "Production order id."
5933
+ },
5934
+ {
5935
+ "name": "qty",
5936
+ "kind": "option",
5937
+ "opts": [
5938
+ "--qty"
5939
+ ],
5940
+ "type": "text",
5941
+ "required": true,
5942
+ "multiple": true,
5943
+ "default": null,
5944
+ "help": "SIZE,#RRGGBB=COUNT for one cell (repeat)."
5945
+ }
5946
+ ]
5947
+ },
5948
+ {
5949
+ "name": "designer set production-lock",
5950
+ "persona": "designer",
5951
+ "verb": "set",
5952
+ "noun": "production-lock",
5953
+ "access": "write",
5954
+ "api": "POST /designer/production_orders/{production_order_id}/configuration-lock",
5955
+ "external": null,
5956
+ "side_effects": [
5957
+ "places the order: the quantities are final and the deposit becomes payable",
5958
+ "can be unlocked again until the deposit is paid"
5959
+ ],
5960
+ "approval": "ask",
5961
+ "reversible": null,
5962
+ "idempotent": null,
5963
+ "limit": null,
5964
+ "legacy": [],
5965
+ "help": "POST /designer/production_orders/{id}/configuration-lock — place the order with the quantities on the run (--unlock to reopen them). Locking is what makes the deposit payable: `designer create checkout --key production:<id>:deposit --accept-terms`.",
5966
+ "function": "makea_cli.commands.brand.cmd.register.<locals>.set_production_lock",
5967
+ "flags": [
5968
+ {
5969
+ "name": "production_order_id",
5970
+ "kind": "argument",
5971
+ "opts": [
5972
+ "production_order_id"
5973
+ ],
5974
+ "type": "text",
5975
+ "required": true,
5976
+ "multiple": false,
5977
+ "default": null,
5978
+ "help": "Production order id."
5979
+ },
5980
+ {
5981
+ "name": "unlock",
5982
+ "kind": "option",
5983
+ "opts": [
5984
+ "--unlock"
5985
+ ],
5986
+ "type": "flag",
5987
+ "required": false,
5988
+ "multiple": false,
5989
+ "default": false,
5990
+ "help": "Reopen the quantities instead."
5991
+ }
5992
+ ]
5993
+ },
5742
5994
  {
5743
5995
  "name": "designer submit production-order",
5744
5996
  "persona": "designer",
@@ -1 +0,0 @@
1
- __version__ = "0.2.4"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes