Skip to content

feat(trade): add DelayedNotReported order status - #595

Open
sunli829 wants to merge 2 commits into
mainfrom
feat/order-status-delayed-not-reported
Open

sunli829 wants to merge 2 commits into
mainfrom
feat/order-status-delayed-not-reported

Conversation

@sunli829

@sunli829 sunli829 commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

Follows longbridge/developers#1263, which documents the new DelayedNotReported order status — 监控中 (时间条件单), the state a time-conditional order sits in before it is reported to the exchange.

Problem

No SDK enum variant matched that wire value. OrderStatus deserializes through impl_serde_for_enum_string!, which falls back to unwrap_or_default()OrderStatus::Unknown, so nothing failed loudly — monitoring time-conditional orders simply became indistinguishable from a genuinely unrecognized status in today_orders / history_orders / order_detail and the order-changed push.

Changes

All six layers, per the checklist in CLAUDE.md:

Layer File
Rust rust/src/trade/types.rs (#[strum(serialize = "DelayedNotReported")])
C c/src/trade_context/enum_types.rs; longbridge.h regenerated by cbindgen
C++ cpp/include/types.hpp + both conversion directions in cpp/src/convert.hpp
Java java/src/types/enum_types.rs + java/javasrc/.../trade/OrderStatus.java
Node.js nodejs/src/trade/types.rs; index.d.ts regenerated by npm run build:debug
Python python/src/trade/types.rs + the openapi.pyi stub

Why the variant is appended instead of grouped

The natural place would be next to the other *NotReported values, matching the docs table. It is appended after PartialWithdrawal instead, because the C/C++ and Node.js enums use implicit discriminants:

  • lb_order_status_t in longbridge.h has no explicit values — inserting mid-list shifts every following one, an ABI break for anything linked against a prebuilt C/C++ library.
  • nodejs/index.d.ts emits export declare const enum OrderStatus { … Filled = 5 … }, and TypeScript inlines const enum members at the consumer's compile time. A renumbering would make already-compiled application code read its hard-coded 5 as a different status — a silent mismatch rather than a build error.

Appending keeps every existing discriminant stable (DelayedNotReported = 18 in TS). The declaration order does not have to match the docs table.

Second commit: regenerated nodejs/index.js

npm run build:debug regenerates index.js alongside index.d.ts, and the committed copy turns out to predate the @napi-rs/cli@3.8.6 the release workflow pins — so it comes back with ~160 lines of loader churn that has nothing to do with the enum. It is committed separately (38184a7) to bring the two generated files back in step with each other and with CI. Review it as a standalone change; what the newer generator emits:

  • require('node:fs')require('fs'), and the optional chaining in the musl / win32 probes is expanded — older-Node compatibility
  • NAPI_RS_FORCE_WASI becomes tri-state ('true' / 'error' / unset) instead of any-non-empty-string truthy, so NAPI_RS_FORCE_WASI=false or =0 no longer takes the WASI path and fails with ENOENT
  • adds NAPI_RS_WASI_FLAVOR for pinning one exact generated flavor
  • WASI candidates are require.resolve'd before being required, and the load-error chain is built without mutating the original errors; error.cause is assigned rather than passed via the Error options form, which Node < 16.9 ignores

Verification

  • cargo clippy --all --all-features — no new warnings
  • cargo +nightly fmt --all
  • cargo build -p longbridge-c — header regenerated
  • g++ -fsyntax-only -std=c++17 over cpp/src/convert.hpp — both convert() overloads compile
  • npm run build:debugindex.d.ts / index.js regenerated
  • Java classes not compiled locally (no maven available); the change is one enum constant, and the JNI macro maps by static-field name, which matches

🤖 Generated with Claude Code

The gateway reports time-conditional orders that are being monitored,
before they are reported to the exchange, with the order status
`DelayedNotReported` (see longbridge/developers#1263). No SDK enum
matched it, so `impl_serde_for_enum_string!`'s `unwrap_or_default()`
turned it into `OrderStatus::Unknown` — monitoring orders were
indistinguishable from a genuinely unrecognized status in
`today_orders` / `history_orders` / `order_detail` and the
order-changed push.

Added across all six layers: Rust, C (header regenerated by cbindgen),
C++ (enum plus both conversion directions), Java (JNI list plus the
Java enum), Node.js (`index.d.ts` regenerated) and Python (plus the
`openapi.pyi` stub).

The variant is appended after `PartialWithdrawal` rather than placed
next to the other `*NotReported` values: the C/C++ and Node.js enums
use implicit discriminants, so inserting mid-list would renumber every
following value — an ABI break for the C/C++ bindings, and a silent
mismatch for TypeScript code that inlined the old `const enum` values.
The committed index.js was generated by an older CLI than the 3.8.6 the
release workflow pins, so regenerating it alongside index.d.ts produces
loader churn unrelated to the enum change. Committing it here keeps the
two generated files in step with each other and with CI.

What the regenerated loader changes:

- `require('node:fs')` → `require('fs')` and the optional chaining in the
  musl / win32 probes is expanded, restoring older-Node compatibility
- NAPI_RS_FORCE_WASI is now tri-state ('true' / 'error' / unset) instead
  of any-non-empty-string truthy, so NAPI_RS_FORCE_WASI=false or =0 no
  longer takes the WASI path and fails with ENOENT
- adds NAPI_RS_WASI_FLAVOR for selecting one exact generated flavor
- WASI candidates are resolved before being required, and the load-error
  chain is built without mutating the original errors; `error.cause` is
  assigned rather than passed to the Error options form, which Node
  < 16.9 ignores
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant