@jiggai/kitchen-plugin-marketing 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,146 @@
1
+ -- Migration: Initial schema for kitchen-plugin-marketing
2
+ -- Created: 2026-04-05
3
+ -- Description: Create tables for posts, media, templates, social accounts, metrics, and webhooks
4
+
5
+ -- Posts table
6
+ CREATE TABLE IF NOT EXISTS posts (
7
+ id TEXT PRIMARY KEY,
8
+ team_id TEXT NOT NULL,
9
+ content TEXT NOT NULL,
10
+ platforms TEXT NOT NULL, -- JSON array of platform names
11
+ status TEXT NOT NULL CHECK (status IN ('draft', 'scheduled', 'published', 'failed')),
12
+ scheduled_at TEXT, -- ISO 8601 timestamp
13
+ published_at TEXT, -- ISO 8601 timestamp
14
+ tags TEXT, -- JSON array of tags
15
+ media_ids TEXT, -- JSON array of media IDs
16
+ template_id TEXT,
17
+ created_at TEXT NOT NULL,
18
+ updated_at TEXT NOT NULL,
19
+ created_by TEXT NOT NULL
20
+ );
21
+
22
+ -- Media/Assets table
23
+ CREATE TABLE IF NOT EXISTS media (
24
+ id TEXT PRIMARY KEY,
25
+ team_id TEXT NOT NULL,
26
+ filename TEXT NOT NULL,
27
+ original_name TEXT NOT NULL,
28
+ mime_type TEXT NOT NULL,
29
+ size INTEGER NOT NULL,
30
+ width INTEGER,
31
+ height INTEGER,
32
+ alt TEXT,
33
+ tags TEXT, -- JSON array of tags
34
+ url TEXT NOT NULL,
35
+ thumbnail_url TEXT,
36
+ created_at TEXT NOT NULL,
37
+ created_by TEXT NOT NULL
38
+ );
39
+
40
+ -- Templates table
41
+ CREATE TABLE IF NOT EXISTS templates (
42
+ id TEXT PRIMARY KEY,
43
+ team_id TEXT NOT NULL,
44
+ name TEXT NOT NULL,
45
+ content TEXT NOT NULL,
46
+ variables TEXT, -- JSON array of variable definitions
47
+ tags TEXT, -- JSON array of tags
48
+ created_at TEXT NOT NULL,
49
+ updated_at TEXT NOT NULL,
50
+ created_by TEXT NOT NULL
51
+ );
52
+
53
+ -- Social accounts table
54
+ CREATE TABLE IF NOT EXISTS social_accounts (
55
+ id TEXT PRIMARY KEY,
56
+ team_id TEXT NOT NULL,
57
+ platform TEXT NOT NULL CHECK (platform IN ('twitter', 'linkedin', 'instagram', 'facebook', 'tiktok', 'youtube')),
58
+ display_name TEXT NOT NULL,
59
+ username TEXT,
60
+ avatar TEXT,
61
+ is_active INTEGER DEFAULT 1 CHECK (is_active IN (0, 1)),
62
+ credentials BLOB NOT NULL, -- Encrypted JSON credentials
63
+ settings TEXT, -- JSON object for platform-specific settings
64
+ last_sync TEXT, -- ISO 8601 timestamp
65
+ created_at TEXT NOT NULL,
66
+ updated_at TEXT NOT NULL
67
+ );
68
+
69
+ -- Post metrics table
70
+ CREATE TABLE IF NOT EXISTS post_metrics (
71
+ id TEXT PRIMARY KEY,
72
+ post_id TEXT NOT NULL,
73
+ platform TEXT NOT NULL,
74
+ impressions INTEGER DEFAULT 0,
75
+ likes INTEGER DEFAULT 0,
76
+ shares INTEGER DEFAULT 0,
77
+ comments INTEGER DEFAULT 0,
78
+ clicks INTEGER DEFAULT 0,
79
+ engagement_rate TEXT, -- Stored as string to avoid float precision issues
80
+ synced_at TEXT NOT NULL, -- When metrics were last fetched
81
+ FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE
82
+ );
83
+
84
+ -- Account metrics table (daily snapshots)
85
+ CREATE TABLE IF NOT EXISTS account_metrics (
86
+ id TEXT PRIMARY KEY,
87
+ account_id TEXT NOT NULL,
88
+ date TEXT NOT NULL, -- YYYY-MM-DD format
89
+ followers INTEGER DEFAULT 0,
90
+ following INTEGER DEFAULT 0,
91
+ posts INTEGER DEFAULT 0,
92
+ engagement INTEGER DEFAULT 0,
93
+ reach INTEGER DEFAULT 0,
94
+ synced_at TEXT NOT NULL,
95
+ FOREIGN KEY (account_id) REFERENCES social_accounts(id) ON DELETE CASCADE,
96
+ UNIQUE(account_id, date)
97
+ );
98
+
99
+ -- Webhooks table
100
+ CREATE TABLE IF NOT EXISTS webhooks (
101
+ id TEXT PRIMARY KEY,
102
+ team_id TEXT NOT NULL,
103
+ url TEXT NOT NULL,
104
+ events TEXT NOT NULL, -- JSON array of event types
105
+ secret TEXT, -- Webhook signature secret
106
+ is_active INTEGER DEFAULT 1 CHECK (is_active IN (0, 1)),
107
+ created_at TEXT NOT NULL,
108
+ last_triggered TEXT -- ISO 8601 timestamp
109
+ );
110
+
111
+ -- Create indexes for better query performance
112
+
113
+ -- Posts indexes
114
+ CREATE INDEX IF NOT EXISTS idx_posts_team_id ON posts(team_id);
115
+ CREATE INDEX IF NOT EXISTS idx_posts_status ON posts(status);
116
+ CREATE INDEX IF NOT EXISTS idx_posts_scheduled_at ON posts(scheduled_at) WHERE scheduled_at IS NOT NULL;
117
+ CREATE INDEX IF NOT EXISTS idx_posts_published_at ON posts(published_at) WHERE published_at IS NOT NULL;
118
+ CREATE INDEX IF NOT EXISTS idx_posts_created_at ON posts(created_at);
119
+ CREATE INDEX IF NOT EXISTS idx_posts_template_id ON posts(template_id) WHERE template_id IS NOT NULL;
120
+
121
+ -- Media indexes
122
+ CREATE INDEX IF NOT EXISTS idx_media_team_id ON media(team_id);
123
+ CREATE INDEX IF NOT EXISTS idx_media_created_at ON media(created_at);
124
+ CREATE INDEX IF NOT EXISTS idx_media_mime_type ON media(mime_type);
125
+
126
+ -- Templates indexes
127
+ CREATE INDEX IF NOT EXISTS idx_templates_team_id ON templates(team_id);
128
+ CREATE INDEX IF NOT EXISTS idx_templates_name ON templates(name);
129
+
130
+ -- Social accounts indexes
131
+ CREATE INDEX IF NOT EXISTS idx_social_accounts_team_id ON social_accounts(team_id);
132
+ CREATE INDEX IF NOT EXISTS idx_social_accounts_platform ON social_accounts(platform);
133
+ CREATE INDEX IF NOT EXISTS idx_social_accounts_active ON social_accounts(is_active);
134
+
135
+ -- Post metrics indexes
136
+ CREATE INDEX IF NOT EXISTS idx_post_metrics_post_id ON post_metrics(post_id);
137
+ CREATE INDEX IF NOT EXISTS idx_post_metrics_platform ON post_metrics(platform);
138
+ CREATE INDEX IF NOT EXISTS idx_post_metrics_synced_at ON post_metrics(synced_at);
139
+
140
+ -- Account metrics indexes
141
+ CREATE INDEX IF NOT EXISTS idx_account_metrics_account_id ON account_metrics(account_id);
142
+ CREATE INDEX IF NOT EXISTS idx_account_metrics_date ON account_metrics(date);
143
+
144
+ -- Webhooks indexes
145
+ CREATE INDEX IF NOT EXISTS idx_webhooks_team_id ON webhooks(team_id);
146
+ CREATE INDEX IF NOT EXISTS idx_webhooks_active ON webhooks(is_active);