HackmanCMS/sql/009_scheduled_posts.sql
Bashy 30b21b6214 Add scheduled social posts, Discord channels config, and LinkedIn personal posting fix
- Scheduled posts: new Schedule tab with multi-platform post scheduling (Discord,
  Mastodon, LinkedIn); SQLite queue with per-target delivery tracking and retry;
  cron script in bin/process-scheduled-posts.php processes due targets inline
- Discord channels: new config section for webhook-based channels used as scheduled
  post targets; webhook URLs stored in .env as DISCORD_WEBHOOK_<KEY>
- LinkedIn: fix botcompose_post to use member_id (urn:li:person) for personal
  profiles instead of hardcoded org author; filter org pages out of compose UI
  and RSS modal picker since org posting is unsupported; label org pages clearly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 15:14:03 +03:00

26 lines
1.2 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Scheduled social posts campaign (one row = one scheduled send)
CREATE TABLE IF NOT EXISTS scheduled_posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
content TEXT NOT NULL,
url TEXT,
scheduled_at DATETIME NOT NULL,
status TEXT NOT NULL DEFAULT 'pending', -- pending | processing | done | partial
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Per-platform delivery target (one row per platform × target per post)
CREATE TABLE IF NOT EXISTS scheduled_post_targets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_id INTEGER NOT NULL REFERENCES scheduled_posts(id) ON DELETE CASCADE,
platform TEXT NOT NULL, -- discord | mastodon | linkedin
target TEXT NOT NULL, -- channel key (discord) | account key (mastodon) | page key (linkedin)
status TEXT NOT NULL DEFAULT 'pending', -- pending | sent | failed
error TEXT,
sent_at DATETIME
);
CREATE INDEX IF NOT EXISTS idx_scheduled_posts_project_status
ON scheduled_posts(project_id, status, scheduled_at);
CREATE INDEX IF NOT EXISTS idx_scheduled_post_targets_post
ON scheduled_post_targets(post_id, status);