142 lines
7.8 KiB
Markdown
142 lines
7.8 KiB
Markdown
---
|
||
name: rpa-run-tab
|
||
description: Adds a Tebra-style Run tab to a desktop RPA bot in about 5 minutes. The Run tab is a PyQt6 window (or a tab in an existing PyQt web page) with a Trigger button, an Excel input card (drop zone, sheet tabs, preview with masked passwords, sample download), a progress bar with a timer, a step list, a friendly live log, checkpoint boxes with time limits, and green/amber/red endings. It also wires the real bot to the page. Use when the user asks for a "Run tab", "run screen", "trigger screen", "start/run page for my bot", or "the Tebra run tab" for an RPA or automation project. For a whole dashboard (KPIs, report table), use rpa-dashboard-no-ai.
|
||
---
|
||
|
||
# RPA Run tab
|
||
|
||
Build the Run tab, wire the real bot to it and check it with the fake bot. The whole job should take about 5 minutes.
|
||
The look is fixed. It is Tebra Auto Post's Run tab, and only the colours change.
|
||
Everything needed is in `templates/`. Never read the original Tebra projects.
|
||
|
||
| File | What it is |
|
||
|---|---|
|
||
| `templates/run_tab.html` | The page. Its config comes from `run_tab.py`, and its theme is between `THEME:START` and `THEME:END`. Each part is fenced with `RUN-TAB:CSS`, `TOPBAR`, `MARKUP` and `JS` markers. |
|
||
| `templates/run_tab.py` | The PyQt6 window and bridge. It is also the bot's process (`--run-bot`, which loads no Qt). It holds the **CONFIG** block you fill in and `--selfcheck`. |
|
||
| `templates/runner.py` | Qt-free. It starts the bot, reads its log file every 0.2 s, turns lines into events, kills stuck runs and decides the ending. |
|
||
| `templates/rt.py` | The protocol helpers the bot calls: `checkpoint`, `checkpoint_done`, `ui`, `result`, `summary`. |
|
||
| `templates/fake_bot.py` | Prints the protocol for the endings complete, partial, stuck and crash. Used only by the self-check. |
|
||
| `templates/palette.py` | Theme: `sky`, `teal` or a brand hex. Use `--write` to put it into the page. It checks contrast. |
|
||
|
||
The rules come from the repo's ADRs. Keep to them:
|
||
- One checkpoint list drives the steps, the boxes and the progress %.
|
||
- The bot talks only through tagged lines in a log file.
|
||
- A stuck checkpoint kills the run, and the run fails.
|
||
- There is no auto-restart and no Stop or Pause button.
|
||
- There is no database, no resume and no roles.
|
||
|
||
## 1. Scan (about 1 minute, ask nothing yet)
|
||
|
||
**Never run the bot.** Real bots act on live systems.
|
||
|
||
1. **Bot entry point.**
|
||
- Look for a `main(...)` function, an `if __name__ == "__main__"` script, or a `run_*` function.
|
||
- Note its loop over input rows or items. Those become the summary's `total` and `failed`.
|
||
- Note its big stages, such as sign in, open a page, process rows, export. Those become the checkpoints.
|
||
2. **Input.**
|
||
- Does the bot read an Excel file (`openpyxl`, `pandas.read_excel`, `xlrd`)?
|
||
- If yes, note the sheet names and column names it reads, for `SAMPLE_SHEETS`.
|
||
- No Excel file means `HAS_INPUT = False`.
|
||
3. **Host.** Search for `QWebEngineView`, `setHtml` or a `.html` page loaded by PyQt, or an `rpa-dashboard-no-ai` `dashboard.html`. If you find one, the Run tab becomes a tab in it (step 4b). Otherwise it gets its own window (step 4a).
|
||
4. **Processes.** Note any extra programs the bot starts and that must die with it, such as `chromedriver.exe` or a desktop app. These go in `KILL_ALSO`.
|
||
|
||
## 2. Ask once (one message, at most 3 questions)
|
||
|
||
Send the scan result and these questions in one message, then wait:
|
||
1. **Colour:**
|
||
- 1) Tebra Sky (blue)
|
||
- 2) TVL Teal (green)
|
||
- 3) Custom: send one brand hex
|
||
2. **Checkpoints:** propose 3–8, each with a name of 2–3 plain words and a time limit, for example `Sign in, max 5 min`. Use `no limit` for long loops over rows. The user confirms or edits the list.
|
||
3. **Input:** "Excel input, or no input file?" Skip this question when the scan already answered it.
|
||
|
||
Default the title and subtitle from the project name, for example `Run automation` and `Upload the input Excel and start <project>`. Don't ask about them.
|
||
|
||
## 3. Build
|
||
|
||
1. Copy `run_tab.html`, `run_tab.py`, `runner.py` and `fake_bot.py` into `<project>/run_tab/`.
|
||
2. Copy `rt.py` there and next to the bot's entry file.
|
||
3. Fill the **CONFIG** block at the top of `run_tab/run_tab.py`:
|
||
- `TITLE`, `SUBTITLE`
|
||
- `BOT`: `"bot.py"` relative to the project root, or `"package.module:function"`
|
||
- `HAS_INPUT`, `INPUT_HINT`
|
||
- `CHECKPOINTS`
|
||
- `SAMPLE_SHEETS`
|
||
- `KILL_ALSO`
|
||
- `APP_ID`: the project name, no spaces
|
||
4. Apply the theme: `python <skill>/templates/palette.py <sky|teal|#hex> --write <project>/run_tab/run_tab.html`.
|
||
- It must print PASS for every row.
|
||
- If a row fails, tell the user and suggest a darker hex.
|
||
5. Make sure `openpyxl`, `PyQt6` and `PyQt6-WebEngine` are in the project's requirements.
|
||
|
||
## 4. Wire the bot
|
||
|
||
Keep the bot's logic as it is. Only add these lines:
|
||
|
||
```python
|
||
import rt
|
||
|
||
def main(excel_path): # BOT = "bot:main"; the Run tab passes the Excel path
|
||
rt.checkpoint(1); rt.ui("Signing in"); ...; rt.ui("Signed in", "ok"); rt.checkpoint_done(1)
|
||
failed = []
|
||
rt.checkpoint(2)
|
||
for i, row in enumerate(rows, start=2):
|
||
try: process(row)
|
||
except Exception as e: failed.append((f"Row {i}", str(e))); rt.ui(f"Row {i} failed", "warn")
|
||
rt.checkpoint_done(2)
|
||
return rt.result(total=len(rows), failed=failed)
|
||
```
|
||
|
||
- **Checkpoint numbers** are 1-based positions in `CHECKPOINTS`. A loop may go back to an earlier checkpoint for the next item; the later boxes reset and the bar never moves back.
|
||
- **Returning a summary.** A plain script with no entry function prints `rt.summary(total, failed)` as its last line instead. If no summary arrives, the run counts as **failed**.
|
||
- **What the operator sees.** Only `[UI]` lines and error lines reach the screen. Everything else goes only to `logs/run_<time>.log`.
|
||
- Keep `[UI]` text to progress words and row numbers.
|
||
- **Never put** patient or customer names, amounts, account numbers, passwords or other PHI or secrets on screen, or in the failed reasons.
|
||
- **Bot output.** Leave the bot's existing prints. They go to the run log.
|
||
|
||
### 4a. Its own window
|
||
There is nothing more to do. Start it with `python run_tab/run_tab.py`.
|
||
|
||
### 4b. A tab in an existing PyQt page
|
||
Copy the four fenced parts of `run_tab.html` into the host page:
|
||
- `RUN-TAB:CSS`, `RUN-TAB:TOPBAR`, `RUN-TAB:MARKUP`, `RUN-TAB:JS`
|
||
- the `THEME` block, if the host has no tokens of its own
|
||
|
||
Then wire the host:
|
||
- **Page config:** add `const CFG = ...` to the host page; `page_html()` in `run_tab.py` shows its shape.
|
||
- **Messages:** route the host's Python→page messages through one `window.__pyMsg`, and merge the `handlePyMessage` branches.
|
||
- **Bridge:** give the host's bridge the `Bridge` slots from `run_tab.py`. They are `browse_file`, `process_dropped_path`, `read_sheet`, `download_sample_input`, `start_automation` and `set_dark`.
|
||
- **Window:** add the close guard from `RunTabWindow.closeEvent`.
|
||
- **Don't connect `js_message` in the page** as well as using `__pyMsg`. Doing both shows every message twice.
|
||
|
||
## 5. Verify with the fake bot
|
||
|
||
```
|
||
python run_tab/run_tab.py --selfcheck
|
||
```
|
||
|
||
It runs the fake bot through the real runner four times:
|
||
- complete → green
|
||
- partial → amber
|
||
- stuck → red, with box 2 marked stuck
|
||
- crash → red
|
||
|
||
Each line must print `ok`. It then saves the window as `logs/selfcheck_complete_light.png`, `logs/selfcheck_partial_dark.png` and `logs/selfcheck_stuck_light.png`. **Look at all three.** Check:
|
||
- the Tebra layout
|
||
- your colours, readable in both themes
|
||
- the checkpoint names
|
||
- no horizontal scroll
|
||
|
||
**Never press Trigger on the real bot yourself.** Tell the user to start the first real run.
|
||
|
||
## 6. Hand over (two lines)
|
||
|
||
Tell the user:
|
||
- how to start it (`python run_tab/run_tab.py`)
|
||
- where raw run logs go (`logs/`)
|
||
|
||
If the project ships as a PyInstaller exe:
|
||
- the entry point is `run_tab/run_tab.py`
|
||
- add `run_tab/run_tab.html` as data
|
||
- add the bot module as a hidden import, because the exe starts itself with `--run-bot`
|