380 lines
8.5 KiB
Markdown
380 lines
8.5 KiB
Markdown
# 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.
|