## Autoclicker module – current behavior

This document captures how the refactored autoclicker works today: UI, background watchers, database interactions, and logging.

### Overview
- The app is a Tk-based desktop UI (`autoclicker/app.py`, class `ClickRecorderApp`).
- Core managers live under `autoclicker/`: `ui_components.py`, `recording.py`, `playback.py`, `playlist_manager.py`, `auto_extractor.py`.
- Two background integrations:
  - Auto Extractor watcher (existing),
  - Direct Integration watcher (`autoclicker/direct_integration.py`), which polls MySQL for S3 Excel uploads to ingest and preview.

### Environment and configuration
- Environment is read from `.env` (project root) with override, defaulting to QA when missing/invalid.
  - Keys used: `ENV` (`qa` or `dev`), `AWS_REGION` (default `ap-southeast-2`).
  - Place `.env` in project root alongside `main.py`.
- MySQL credentials resolve via AWS Secrets Manager and SSM parameters in `mysql/config.py` and are exposed as `MYSQL_CONFIG`.
- Effective environment and target DB are logged at startup to `mysql_debug.log`.

### Running
- Local/manual:
  ```bash
  cd ~/auto_clicker
  python3 main.py
  ```
- On EC2 as a service (if provisioned by `deploy_ec2.sh`):
  - Unit name: `autoclicker`
  - Start/Follow logs:
    ```bash
    sudo systemctl restart autoclicker
    sudo journalctl -u autoclicker -f | cat
    ```
- Headless Linux uses `start_app.sh` to start Xvfb and export `ENV=qa`.

### UI summary (full view)
- Buttons: Record, Stop, Play, Save, Screenshot, Export, Delete, Check Queue, Min/Max.
- Fields:
  - Application (read-only label when auto-selected by integration),
  - Recording Name (hidden when auto-filled by Direct Integration in "new" mode),
  - Playlist:
    - Dropdown when user-driven/manual,
    - Read-only label when set by integration (both "new" and "existing").
- Live Clicks pane shows previews and playback/action summaries.

### Direct Integration flow (MySQL + S3 Excel)
- Table: `direct_integration_uploads` (polled by `DirectIntegrationWatcher`).
- Poll interval: `AUTO_EXTRACTOR_CHECK_INTERVAL` (see `autoclicker/constants.py`).
- Columns used (must exist):
  - `id, filename, original_filename, s3_bucket, s3_key,
     application_id, playlist_id, playlist_mode, playlist_name,
     processed, extracted_data, step_details, error_message, created_at, updated_at, user_id`.
- Behavior per row (processed = 0):
  1. UI reflects `application_id` (name/platform) if present.
  2. Playlist selection logic:
     - `playlist_mode = 'new'` and `playlist_name` provided:
       - Sets `selected_playlist = playlist_name`.
       - Hides the playlist dropdown (shows read-only label).
       - Sets `recording_name = playlist_name` and hides the Recording Name field.
     - `playlist_mode = 'existing'` and `playlist_id` provided:
       - Looks up name, sets `selected_playlist`.
       - Hides the playlist dropdown (shows read-only label).
       - Recording Name remains visible.
  3. The S3 Excel file is downloaded and parsed; first 5 rows are previewed in Live Clicks.
  4. Row is updated with `extracted_data` and `step_details` but kept `processed = 0` (not marked complete).

Notes:
- Marking complete is explicit. When downstream processing is finished, call:
  ```python
  from mysql.mysql_client import mark_direct_upload_processed
  mark_direct_upload_processed(upload_id, processed=1, step_details={...}, error_message=None)
  ```
- To re-queue a row that was marked processed by mistake:
  ```sql
  UPDATE direct_integration_uploads
  SET processed = 0, extracted_data = NULL, step_details = NULL, error_message = NULL, updated_at = NOW()
  WHERE id = <id>;
  ```

### Save button behavior (playlists)
- Manual/standard flow:
  - Requires Recording Name; saves to local SQLite (`Playlists` table) and to MySQL via `save_playlist_to_mysql`.
- Direct Integration `playlist_mode='new'`:
  - `recording_name` is auto-filled with `playlist_name` and the field is hidden.
  - Clicking Save performs a direct MySQL insert (duplicate-checked) and skips local SQLite.
- Direct Integration `playlist_mode='existing'`:
  - Uses the existing playlist; standard save flow remains available if needed.

### Logging
- File: `mysql_debug.log` in project root.
- Key entries:
  - Startup: `[MySQL] Effective ENV=... target host=... db=...`.
  - Direct Integration polling: `[DirectIntegration] Unprocessed rows fetched (count=...): [...]`.
  - Snapshot each poll: `[DirectIntegration] row id=... processed=... mode=... name=...`.
  - Update results: `[DirectIntegration] Updated upload id=... set processed=...`.
- Quick viewing:
  ```bash
  cd ~/auto_clicker
  tail -F mysql_debug.log | grep -E "DirectIntegration|Effective ENV|Updated upload"
  ```

### Troubleshooting
- Not picking up uploads:
  - Ensure `processed = 0`.
  - Check logs for snapshot and fetched IDs.
  - Verify AWS IAM allows access to Secrets/SSM and S3 object.
- Wrong environment:
  - `.env` at project root with `ENV=qa`.
  - Confirm with `grep "Effective ENV" mysql_debug.log`.
- Playlist name prompt while using new mode:
  - Ensure the row has `playlist_mode='new'` and a non-empty `playlist_name`.


