Add quote bridge and quote handoff flow
This commit is contained in:
@@ -0,0 +1,379 @@
|
||||
# Quote Bridge Automation Design
|
||||
|
||||
## Goal
|
||||
|
||||
Extend `quote-bridge` so it can do more than move quote files. The target design is a helper app that:
|
||||
|
||||
1. watches for quote JSON files,
|
||||
2. selects the correct location profile,
|
||||
3. launches the DOS app through DOSBox,
|
||||
4. simulates user input,
|
||||
5. enters quote data into the DOS application,
|
||||
6. records success or failure.
|
||||
|
||||
## Recommended Design
|
||||
|
||||
Keep the automation separated into four layers:
|
||||
|
||||
1. `quote` JSON
|
||||
- Business data coming from the Flask app.
|
||||
2. `profile` JSON
|
||||
- Machine and location configuration.
|
||||
3. `instruction set` JSON
|
||||
- The keystroke workflow for the DOS app.
|
||||
4. `executor`
|
||||
- Python code that reads the quote, profile, and instruction set and sends keys to the DOS app.
|
||||
|
||||
This separation keeps machine config, business data, and workflow logic from getting mixed together.
|
||||
|
||||
## Why Not Put Everything In The Profile
|
||||
|
||||
The location profile should define:
|
||||
- where the remote share is mounted,
|
||||
- which DOS app folder to use,
|
||||
- which DOSBox binary/config to use,
|
||||
- which instruction set to execute,
|
||||
- which location-specific values apply.
|
||||
|
||||
It should not hold the full keystroke workflow. If the whole flow lives in the profile, each location file becomes hard to maintain.
|
||||
|
||||
## Recommended Folder Structure
|
||||
|
||||
```text
|
||||
quote-bridge/
|
||||
├── listener.py
|
||||
├── dosbox_processor.py
|
||||
├── profiles/
|
||||
│ ├── default.json
|
||||
│ ├── IOLA.json
|
||||
│ ├── KC.json
|
||||
│ └── LINDS.json
|
||||
├── instruction-sets/
|
||||
│ ├── create-quote-v1.json
|
||||
│ └── create-quote-iola-v1.json
|
||||
└── value-maps/
|
||||
└── optional-future-files.json
|
||||
```
|
||||
|
||||
## Profile Responsibilities
|
||||
|
||||
Profiles should define environment and per-location values.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"profileName": "IOLA",
|
||||
"dosboxBin": "dosbox-x",
|
||||
"mountPath": "/mnt/iola-cgw",
|
||||
"mountDrive": "C",
|
||||
"workingDirectory": "CGWAPP",
|
||||
"bridgeCommand": "BRIDGE.BAT",
|
||||
"instructionSet": "create-quote-v1",
|
||||
"variables": {
|
||||
"taxCode": "ABC",
|
||||
"locationCode": "IOLA"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use the profile for:
|
||||
- DOSBox path/config
|
||||
- remote mount path
|
||||
- DOS working directory
|
||||
- instruction set selection
|
||||
- per-location values like tax code, warehouse, location code, salesperson, or other defaults
|
||||
|
||||
## Instruction Set Responsibilities
|
||||
|
||||
Instruction sets should define the interactive workflow.
|
||||
|
||||
Instead of using only freeform key strings, use a small action DSL.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "create-quote-v1",
|
||||
"version": 1,
|
||||
"steps": [
|
||||
{
|
||||
"action": "text",
|
||||
"value": "${secrets.username}"
|
||||
},
|
||||
{
|
||||
"action": "key",
|
||||
"value": "ENTER"
|
||||
},
|
||||
{
|
||||
"action": "text",
|
||||
"value": "${secrets.password}"
|
||||
},
|
||||
{
|
||||
"action": "key",
|
||||
"value": "ENTER"
|
||||
},
|
||||
{
|
||||
"action": "text",
|
||||
"value": "${runtime.today}"
|
||||
},
|
||||
{
|
||||
"action": "key",
|
||||
"value": "ENTER"
|
||||
},
|
||||
{
|
||||
"action": "loop",
|
||||
"source": "items",
|
||||
"steps": [
|
||||
{
|
||||
"action": "text",
|
||||
"value": "${item.productCode}"
|
||||
},
|
||||
{
|
||||
"action": "key",
|
||||
"value": "ENTER"
|
||||
},
|
||||
{
|
||||
"action": "text",
|
||||
"value": "${item.quantity}"
|
||||
},
|
||||
{
|
||||
"action": "key",
|
||||
"value": "ENTER"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Recommended Action Types
|
||||
|
||||
The executor should support a small set of explicit actions:
|
||||
- `text`
|
||||
- `key`
|
||||
- `combo`
|
||||
- `sleep`
|
||||
- `wait`
|
||||
- `loop`
|
||||
- `conditional`
|
||||
- `set-variable`
|
||||
- optional future `assert`
|
||||
|
||||
This is better than a plain `keys: "abc"` design because real workflows need timing, branching, loops, and variable substitution.
|
||||
|
||||
## Special Keys And Combos
|
||||
|
||||
Use symbolic key names for special keys:
|
||||
- `ENTER`
|
||||
- `ESC`
|
||||
- `UP`
|
||||
- `DOWN`
|
||||
- `LEFT`
|
||||
- `RIGHT`
|
||||
- `TAB`
|
||||
- `BACKSPACE`
|
||||
- `F1` through `F12`
|
||||
|
||||
For combos, prefer an array form.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "combo",
|
||||
"keys": ["SHIFT", "~"]
|
||||
}
|
||||
```
|
||||
|
||||
That is less ambiguous than a single string.
|
||||
|
||||
## Handling Location-Specific Differences
|
||||
|
||||
There are two kinds of per-location differences.
|
||||
|
||||
### 1. Data Differences
|
||||
|
||||
Examples:
|
||||
- tax value
|
||||
- warehouse code
|
||||
- location code
|
||||
- default salesperson
|
||||
|
||||
These should stay in the profile:
|
||||
|
||||
```json
|
||||
{
|
||||
"variables": {
|
||||
"taxCode": "IOLA-TAX",
|
||||
"warehouseCode": "01"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Flow Differences
|
||||
|
||||
Examples:
|
||||
- one location needs two extra keys
|
||||
- one location lands on a different screen
|
||||
- one location skips a field
|
||||
|
||||
If the difference is small, use the same instruction set and substitute different values.
|
||||
|
||||
If the difference is structural, create a separate instruction set.
|
||||
|
||||
Examples:
|
||||
- `create-quote-v1`
|
||||
- `create-quote-iola-v1`
|
||||
|
||||
That is cleaner than putting location branches on every single step.
|
||||
|
||||
## Suggested Runtime Context
|
||||
|
||||
When the executor runs, it should build a context containing:
|
||||
- `quote`
|
||||
- `items`
|
||||
- `profile.variables`
|
||||
- `runtime.today`
|
||||
- `secrets.username`
|
||||
- `secrets.password`
|
||||
|
||||
Then placeholders such as `${item.productCode}` or `${profile.variables.taxCode}` can be resolved during execution.
|
||||
|
||||
## How The Executor Should Work
|
||||
|
||||
At runtime:
|
||||
|
||||
1. Read quote file.
|
||||
2. Read `createdBy.location` from the quote.
|
||||
3. Load matching location profile.
|
||||
4. Load the instruction set named by the profile.
|
||||
5. Build runtime context.
|
||||
6. Launch DOSBox.
|
||||
7. Focus the DOSBox window if needed.
|
||||
8. Execute steps sequentially.
|
||||
9. Log each action.
|
||||
10. On success, move file to `processed`.
|
||||
11. On failure, move file to `failed`.
|
||||
|
||||
## How To Actually Send Keys
|
||||
|
||||
DOSBox runs the DOS app, but a separate automation backend is usually needed to send dynamic interactive keys.
|
||||
|
||||
On Ubuntu, the likely choices are:
|
||||
- `xdotool` for X11
|
||||
- `ydotool` for Wayland
|
||||
|
||||
That means the likely stack is:
|
||||
- DOSBox-X runs the DOS app
|
||||
- Python executor controls the DOSBox window
|
||||
- `xdotool` or `ydotool` sends keystrokes
|
||||
|
||||
## Installation Requirements
|
||||
|
||||
Minimum:
|
||||
- DOSBox or preferably DOSBox-X
|
||||
- access to the DOS application files from Ubuntu
|
||||
- Python
|
||||
|
||||
Useful additions:
|
||||
- `xdotool` for X11-based key injection
|
||||
- `ydotool` for Wayland-based key injection if needed
|
||||
- `cifs-utils` for mounting Windows shares on Ubuntu
|
||||
|
||||
## Security Note
|
||||
|
||||
Do not store real usernames and passwords in committed profile JSON files.
|
||||
|
||||
Better options:
|
||||
- environment variables
|
||||
- a local untracked secrets JSON file
|
||||
- a machine-local config file ignored by git
|
||||
|
||||
Example approach:
|
||||
|
||||
```json
|
||||
{
|
||||
"usernameEnv": "IOLA_DOS_USERNAME",
|
||||
"passwordEnv": "IOLA_DOS_PASSWORD"
|
||||
}
|
||||
```
|
||||
|
||||
## Constraints And Risks
|
||||
|
||||
The hardest part is not the JSON format. The difficult part is making the execution deterministic enough that the DOS app is always on the expected screen.
|
||||
|
||||
Main risks:
|
||||
- timing drift
|
||||
- focus problems
|
||||
- unexpected dialogs
|
||||
- location-specific screen differences
|
||||
- item mapping differences between web app and DOS app
|
||||
|
||||
Because of that, start small and keep logging detailed.
|
||||
|
||||
## Recommended First Implementation Scope
|
||||
|
||||
Start with a narrow slice:
|
||||
|
||||
1. one instruction set for login + single item entry
|
||||
2. one location profile
|
||||
3. one automation backend using `xdotool`
|
||||
4. fixed waits only, no screen-reading yet
|
||||
5. detailed action logging
|
||||
|
||||
After that works, extend to:
|
||||
|
||||
1. multi-item loops
|
||||
2. per-location variables
|
||||
3. per-location alternate flows
|
||||
4. optional checkpoints/assertions
|
||||
5. result files with external quote/order references
|
||||
|
||||
## Next Steps For quote-bridge
|
||||
|
||||
### Phase 1: Structure
|
||||
|
||||
1. Add `instruction-sets/` folder.
|
||||
2. Add one starter instruction set file such as `create-quote-v1.json`.
|
||||
3. Extend location profiles to include `instructionSet` and optional `variables`.
|
||||
4. Add a local secrets mechanism for usernames/passwords.
|
||||
|
||||
### Phase 2: Execution Engine
|
||||
|
||||
1. Create an automation executor module.
|
||||
2. Implement action handlers for:
|
||||
- `text`
|
||||
- `key`
|
||||
- `combo`
|
||||
- `sleep`
|
||||
- `loop`
|
||||
3. Add placeholder resolution for quote/profile/runtime values.
|
||||
4. Add step-by-step logging.
|
||||
|
||||
### Phase 3: Input Backend
|
||||
|
||||
1. Decide whether Ubuntu is running X11 or Wayland.
|
||||
2. If X11, install and integrate `xdotool`.
|
||||
3. If Wayland, evaluate `ydotool`.
|
||||
4. Add DOSBox window targeting/focus handling.
|
||||
|
||||
### Phase 4: DOS App Integration
|
||||
|
||||
1. Build a real `BRIDGE.BAT` startup contract.
|
||||
2. Define the login sequence.
|
||||
3. Define single-item quote entry.
|
||||
4. Test with one known product and one location.
|
||||
|
||||
### Phase 5: Expansion
|
||||
|
||||
1. Add multi-item support.
|
||||
2. Add value/code translation maps if needed.
|
||||
3. Add location-specific instruction set variants only where necessary.
|
||||
4. Add result file generation with success/failure metadata.
|
||||
|
||||
## Recommendation
|
||||
|
||||
Keep workflow logic in instruction sets, keep environment/location settings in profiles, and keep secrets out of tracked JSON files.
|
||||
|
||||
That will give `quote-bridge` the best chance of staying maintainable as the DOS automation grows.
|
||||
Reference in New Issue
Block a user