Files
LWLT-AI/adapter_design.md
2026-07-13 19:57:46 +08:00

102 lines
8.0 KiB
Markdown

# LTJT Adapter Design Principles
## Runtime Principle
Production order creation must not depend on AI/LLM decisions.
AI may be used during discovery to inspect pages, draft schema notes, and propose mappings, but the runtime adapter must be deterministic, testable, and auditable.
The user's own business system and database are the upstream source of truth for pending LTJT input fields. They are expected to maintain customer/product/order/passenger/pricing/status data and emit a validated standard operation object. The LTJT adapter consumes that object; it does not infer missing business facts from chat text at runtime.
## Recommended Architecture
1. Session manager
- Maintains an approved LTJT browser/session context.
- Detects login-expired scripts and permission-alert scripts.
- Never stores raw passwords in adapter logs.
2. Page-context loader
- Opens `/System/Business/orders_add.asp` in a controlled browser context.
- Waits for lookup data and page JavaScript initialization to finish.
- Avoids coordinate-based or visual clicking.
3. Standard data mapper
- Converts a user-owned standard order object from the business system/database into explicit `ListForm` field assignments.
- Uses a versioned mapping table from standard fields to LTJT field names.
- Does not ask an AI model what to fill at runtime.
4. Lookup resolver
- Resolves customer, product, staff, route, fee item, and resource fields using the page's own lookup endpoints.
- Uses exact-match or configured matching rules.
- Fails closed when a lookup is ambiguous.
5. Dry-run serializer
- Fills the page in a controlled context.
- Reads `ListForm.serialize()`.
- Validates required fields, passenger counts, hidden ids, currency/unit metadata, and expected generated fields.
- Produces an audit payload before submission.
6. Submitter
- Disabled by default until a test workflow is approved.
- Submits `Act=DoInfoJH&` plus the serialized form only after deterministic validation passes.
- Records request fingerprint, response classification, and created order identifier if returned.
## Non-Goals
- No AI/LLM in the production decision path.
- No OCR/visual coordinate automation for normal operation.
- No privilege bypass or hidden permission escalation.
- No blind POSTs without first building and validating the browser-form payload.
## Current Build Artifacts
The first deterministic contract and local dry-run artifacts are in place:
- `schemas/standard_system_operation.schema.json`
- `mappings/orders_add.mapping.json`
- `tools/dry_run_order_create.mjs`
- `tools/browser_order_add_dry_run.mjs`
- `tools/browser_order_add_preflight.mjs`
- `samples/team_order_create.dry-run.example.json`
The local dry-run script outputs the `Act=DoInfoJH&...` request body without submitting. The browser dry-run helper has now matched a live `orders_add.asp` `ListForm.serialize()` field set with fake-only sample values: 822 local fields, 822 live browser fields, zero mapped-field mismatches. It redacts `session_id` by default and never clicks submit.
Important correction: serializer compatibility is not enough for production. Many fields are LTJT `SelectBox` widgets, where values must be chosen from existing rows and the page's `SetVal` rules auto-fill linked fields. The adapter must run deterministic lookup validation before browser serialization or submit.
## Next Build Artifact
Build the deterministic lookup resolver:
- resolve customer, route, product, OP, and salesperson through LTJT lookup data/widgets
- enforce exact-match or configured alias rules
- populate hidden metadata such as `zutuansheid`, customer currency/contact fields, route-derived `tuanxuhao1`, and product pricing metadata
- compare browser `ListForm.serialize()` after lookup resolution against the dry-run payload
- keep live submit disabled
New helper scripts:
- `tools/inspect_orders_add_selectboxes.mjs` records SelectBox bindings, endpoints, row/column counts, and linked fields without storing option values.
- `tools/validate_order_add_lookups.mjs` checks a standard operation against existing LTJT options and blocks zero/multiple matches.
- `tools/resolve_order_add_lookups.mjs` applies exact-match SelectBox rows to LTJT `SetVal` rules and can emit actual resolved field patches only when explicitly requested with `--resolved-out`.
- `tools/inspect_order_add_product_effect.mjs` executes the product `Find_product()`/`GetProduct(cpm)` side effect in the browser without submitting and stores only redacted field-change metadata.
- `tools/browser_order_add_preflight.mjs` is the new closest-to-submit dry run: it exact-matches LTJT lookups, executes product side effects, validates product-template consistency, clears/rewrites standard-owned receivable rows, then serializes the live browser form without clicking submit.
- `tools/browser_order_add_submit_intercept.mjs` installs an AJAX intercept before calling the page's `SubmitInfoForm()`, so the page's own validation and submit branch can be tested while preventing `DoInfoJH` from reaching the network.
- `tools/browser_order_add_template_selftest.mjs` uses a real existing LTJT product template in browser memory only, fills obvious `AI-DRYRUN-NO-SUBMIT` markers, and proves the end-to-end non-writing page path can pass with actual SelectBox values.
- `tools/browser_order_add_submit_approved.mjs` is the guarded live-submit tool. It refuses before browser access unless a real preflight report and a separate submit-intercept report both pass and have the same payload hash, plus `--execute-live-submit` and the exact approval token.
- `tools/verify_order_marker.mjs` verifies the submitted test marker through `JH_OrderList` without storing business row values.
## Controlled Submit Evidence
A controlled live test was previously completed for the independent-team order-create path. The detailed report files and test-record identifiers were intentionally removed during the repository cleanup because they were historical validation artifacts, not current contracts.
The result does not constitute permanent production approval. Any future write must produce a new temporary report and pass the lookup, product-side-effect, browser preflight, submit-intercept, approved-submit, and post-operation re-query gates below. The `reports/` directory is an output location only and is not a maintained evidence archive.
Required pipeline before a formal production write:
1. `validate_order_add_lookups.mjs` or `resolve_order_add_lookups.mjs` must pass for the real standard operation so zero/multiple matches are blocked early.
2. `browser_order_add_preflight.mjs --input <real-operation> --open-form` must pass in the logged-in browser. This is the authoritative pre-submit payload path because it runs LTJT's own product-template script.
3. Product-template output must be consistent with the standard operation for product, trip, route, route prefix, customer, and customer id. Mismatch blocks submit.
4. Standard-owned rows such as receivables must be cleared/rebuilt after product side effects so product defaults do not silently leak into the submit payload.
5. `browser_order_add_submit_intercept.mjs --call-submit` should capture exactly one intercepted `DoInfoJH` request with no validation alerts and `DoInfoJH_network_prevented=true`.
6. `browser_order_add_submit_approved.mjs` may be used only when the real preflight approved payload hash equals the real submit-intercept hash, and only with the explicit approval token `APPROVE-LTJT-DOINFOJH-SUBMIT`.
7. After submit, `verify_order_marker.mjs` or an equivalent order-list/detail verification should prove the created/updated order is visible and marked as intended.
The earlier `dry_run_order_create.mjs` and `browser_order_add_dry_run.mjs` remain useful for schema and serializer compatibility checks, but they are no longer sufficient as the final production submit gate because a real product selection can mutate more than 100 form fields.
See [system_operation_scope.md](/Users/inmanx/Documents/lwltAPI/system_operation_scope.md) for the business-action to LTJT-system-operation boundary.