magpie/app/db/migrations/007_opportunities.sql
pyr0ball 2822d36bad feat(#9): opportunities queue — manual posting workflow UI and API
Adds the full signal-to-post pipeline for non-automated opportunities:
- SQLite migration 007: opportunities table (platform, community, thread_url,
  draft title/body, post_type, status, campaign_id, dismiss_note)
- FastAPI endpoints: GET/POST /opportunities, GET/PATCH /{id}, /{id}/approve,
  /{id}/mark-posted, /{id}/dismiss
- approve() returns auto_post_ready (Reddit) or manual_handoff (Lemmy/LinkedIn/etc)
  with clipboard-ready draft and instructions
- OpportunitiesView.vue: status-filtered queue, slide-over detail panel with
  inline draft editor, approve/dismiss actions, manual handoff copy+open flow
- Opportunities now default landing route; nav link added
- MCP tools: list_opportunities, create_opportunity, approve_opportunity,
  dismiss_opportunity, update_opportunity

Closes #9
2026-04-21 16:51:34 -07:00

23 lines
1.4 KiB
SQL

-- Opportunities: flagged threads/posts queued for human review before posting.
-- Covers both auto-post (Reddit via Playwright) and manual handoff (Lemmy, LinkedIn, etc.)
CREATE TABLE IF NOT EXISTS opportunities (
id INTEGER PRIMARY KEY AUTOINCREMENT,
platform TEXT NOT NULL DEFAULT 'reddit',
community TEXT NOT NULL, -- sub name, lemmy community, etc.
thread_url TEXT NOT NULL,
thread_title TEXT,
thread_body TEXT, -- snippet of original post for context
signal_reason TEXT, -- why this was flagged
product TEXT, -- peregrine, kiwi, snipe, circuitforge
draft_title TEXT, -- for new_post type; NULL for replies
draft_body TEXT NOT NULL DEFAULT '',
post_type TEXT NOT NULL DEFAULT 'reply_to_thread', -- reply_to_thread | new_post
status TEXT NOT NULL DEFAULT 'pending_review', -- pending_review | approved | posted | manual_posted | dismissed
campaign_id INTEGER REFERENCES campaigns(id) ON DELETE SET NULL,
dismiss_note TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_opportunities_status ON opportunities(status);
CREATE INDEX IF NOT EXISTS idx_opportunities_platform ON opportunities(platform, community);