Task 7 of the autotrade foundation: five new async functions and one struct added to repo.rs to support the upcoming exit-monitoring pass (Task 8). All items are annotated #[allow(dead_code)] until Task 8 wires them into the exit-detection loop.
File
crates/polymarket-fetch/src/pmv2/repo.rs lines 1270–1359 — branch autotrade-foundation
New Items
AutotradeExitEventRow (struct)
Derives sqlx::FromRow. Maps a row from the pmv2_position_events ⋈ pmv2_autotrade_orders join used by autotrade_exit_events:
| Field | Type | Source column |
|---|---|---|
proxy_wallet | String | pmv2_position_events.proxy_wallet |
condition_id | String | pmv2_position_events.condition_id |
outcome_index | i32 | pmv2_position_events.outcome_index |
event_slug | String | pmv2_position_events.event_slug |
slug | String | pmv2_position_events.slug |
detected_ts | i64 | pmv2_position_events.detected_ts |
For Agents
pmv2_position_eventscolumn set confirmed from the watcher migration (20260603000000_pmv2_overlap) plus the overlap/pnl extension migrations:proxy_wallet, condition_id, outcome_index, event_slug, slug, detected_tsare all present.AutotradeExitEventRowselects exactly this set — do not assume additional columns exist without checking migrations.
autotrade_exits_cursor
pub async fn autotrade_exits_cursor(pool: &PgPool) -> Result<i64>Reads the last_check_at value for key 'autotrade_exits' from pm_detection_cursors. Returns 0 if no row exists yet (first run). This cursor is separate from:
'pmv2_exit_alert'— used by the notifier inexits.rs'overlap_watcher'— used by the overlap detector inoverlap_watcher.rs
advance_autotrade_exits_cursor
pub async fn advance_autotrade_exits_cursor(pool: &PgPool, ts: i64) -> Result<()>Upserts pm_detection_cursors with detector = 'autotrade_exits' and the given timestamp. Uses ON CONFLICT (detector) DO UPDATE SET last_check_at = EXCLUDED.last_check_at — the EXCLUDED. alias pattern that matches the rest of this codebase (not $1).
Upsert style
This codebase uses
EXCLUDED.<column>in ON CONFLICT DO UPDATE, not a$Nre-bind. Deviating from this breaks codebase consistency and risks confusion with the parameter index.
autotrade_exit_events
pub async fn autotrade_exit_events(pool: &PgPool, since_ts: i64) -> Result<Vec<AutotradeExitEventRow>>Reads pmv2_position_events rows with kind = 'EXITED' and detected_ts > since_ts, joined to pmv2_autotrade_orders on (condition_id, outcome_index) to confirm an autotrade order exists for that position. Returns Vec<AutotradeExitEventRow> ordered by detected_ts ASC.
autotrade_open_orders_for_origin
pub async fn autotrade_open_orders_for_origin(
pool: &PgPool,
condition_id: &str,
outcome_index: i32,
origin_ref: &str,
) -> Result<Vec<AutotradeOrderRow>>Fetches rows from pmv2_autotrade_orders where condition_id = $1 AND outcome_index = $2 AND origin_ref = $3 AND status = 'open'. Used to look up live orders that need to be closed when an exit event fires. AutotradeOrderRow is an existing type in repo.rs (not introduced in T7).
For Agents
pmv2_autotrade_orderscolumn set confirmed from20260614000000_pmv2_autotrade.sql:origin_ref,condition_id,outcome_index,statusare all present.origin_refis the tracker key linking an autotrade order back to the source signal’sorigin_reffield onTradeSignal.
autotrade_source_enabled
pub async fn autotrade_source_enabled(pool: &PgPool, source_id: &str) -> Result<bool>Returns the enabled flag for a given source_id from pmv2_autotrade_sources. Returns false if no row exists (fail-closed). pmv2_autotrade_sources has columns source_id (TEXT PK) and enabled (BOOL), confirmed from 20260614000000_pmv2_autotrade.sql.
#[allow(dead_code)] Annotation
All five functions and the struct carry #[allow(dead_code)]. This is a temporary suppression — Task 8 will wire these into the exit-detection loop at which point the allows are removed. The same pattern was used for the category resolver in T3.
Cursor Key Separation
Three separate cursor keys coexist in pm_detection_cursors:
| Key | Owned by | Purpose |
|---|---|---|
'overlap_watcher' | overlap_watcher.rs | Cohort ENTER/EXIT events for operator overlap alerts |
'pmv2_exit_alert' | exits.rs | Exit events for Telegram “TRADE EXITED” alerts to operator |
'autotrade_exits' | T7/T8 (upcoming) | Exit events for the autotrade engine to close its own orders |
These cursors advance independently so the notifier and the autotrade engine can run at different cadences without interfering.
Gate
253 polymarket-fetch tests + 87 polymarket-data tests, 0 failures, 0 clippy errors. No commits made.