@sonicjs-cms/core 2.0.0-alpha.1 → 2.0.0-alpha.10
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.
- package/dist/chunk-3MNMOLSA.js +133 -0
- package/dist/chunk-3MNMOLSA.js.map +1 -0
- package/dist/chunk-4USDL3UP.cjs +15565 -0
- package/dist/chunk-4USDL3UP.cjs.map +1 -0
- package/dist/{chunk-CXZDAR6S.js → chunk-7N3HK7ZK.js} +3 -3
- package/dist/{chunk-CXZDAR6S.js.map → chunk-7N3HK7ZK.js.map} +1 -1
- package/dist/chunk-AGOE25LF.cjs +137 -0
- package/dist/chunk-AGOE25LF.cjs.map +1 -0
- package/dist/{chunk-NRSL6BQI.js → chunk-BITQ4MFX.js} +3 -3
- package/dist/{chunk-NRSL6BQI.js.map → chunk-BITQ4MFX.js.map} +1 -1
- package/dist/{chunk-24PWAFUT.cjs → chunk-BUKT6HP5.cjs} +13 -13
- package/dist/{chunk-24PWAFUT.cjs.map → chunk-BUKT6HP5.cjs.map} +1 -1
- package/dist/{chunk-L3NXO7Y4.cjs → chunk-FVMV5DKA.cjs} +49 -49
- package/dist/{chunk-L3NXO7Y4.cjs.map → chunk-FVMV5DKA.cjs.map} +1 -1
- package/dist/chunk-GGBHOIDD.js +15552 -0
- package/dist/chunk-GGBHOIDD.js.map +1 -0
- package/dist/{chunk-EMMSS5I5.cjs → chunk-IGJUBJBW.cjs} +8 -2
- package/dist/{chunk-ALTMI5Y2.cjs.map → chunk-IGJUBJBW.cjs.map} +1 -1
- package/dist/{chunk-WJ7QYVR2.cjs → chunk-RNR4HA23.cjs} +4 -4
- package/dist/{chunk-WJ7QYVR2.cjs.map → chunk-RNR4HA23.cjs.map} +1 -1
- package/dist/{chunk-G3PMV62Z.js → chunk-V4OQ3NZ2.js} +7 -3
- package/dist/{chunk-G3PMV62Z.js.map → chunk-V4OQ3NZ2.js.map} +1 -1
- package/dist/{chunk-PTQZ5FEI.js → chunk-WESS2U3K.js} +3 -3
- package/dist/{chunk-PTQZ5FEI.js.map → chunk-WESS2U3K.js.map} +1 -1
- package/dist/index.cjs +105 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +22 -8
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +23 -23
- package/dist/middleware.js +3 -3
- package/dist/plugins.cjs +8 -8
- package/dist/plugins.js +2 -2
- package/dist/routes.cjs +51 -3
- package/dist/routes.js +6 -2
- package/dist/services.cjs +31 -19
- package/dist/services.js +3 -3
- package/dist/templates.cjs +1 -1
- package/dist/templates.js +1 -1
- package/dist/types.cjs +1 -1
- package/dist/types.js +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +1 -1
- package/migrations/001_initial_schema.sql +198 -0
- package/migrations/002_faq_plugin.sql +86 -0
- package/migrations/003_stage5_enhancements.sql +121 -0
- package/migrations/004_stage6_user_management.sql +183 -0
- package/migrations/005_stage7_workflow_automation.sql +294 -0
- package/migrations/006_plugin_system.sql +155 -0
- package/migrations/007_demo_login_plugin.sql +23 -0
- package/migrations/008_fix_slug_validation.sql +22 -0
- package/migrations/009_system_logging.sql +57 -0
- package/migrations/011_config_managed_collections.sql +14 -0
- package/migrations/012_testimonials_plugin.sql +80 -0
- package/migrations/013_code_examples_plugin.sql +177 -0
- package/migrations/014_fix_plugin_registry.sql +88 -0
- package/migrations/015_add_remaining_plugins.sql +89 -0
- package/migrations/016_remove_duplicate_cache_plugin.sql +17 -0
- package/migrations/017_auth_configurable_fields.sql +49 -0
- package/package.json +1 -1
- package/dist/chunk-4URGXJP7.js +0 -3
- package/dist/chunk-4URGXJP7.js.map +0 -1
- package/dist/chunk-ALTMI5Y2.cjs +0 -4
- package/dist/chunk-BOLQHE4J.cjs +0 -11
- package/dist/chunk-BOLQHE4J.cjs.map +0 -1
- package/dist/chunk-EMMSS5I5.cjs.map +0 -1
- package/dist/chunk-HD7R6T6I.js +0 -9
- package/dist/chunk-HD7R6T6I.js.map +0 -1
- package/dist/collection-config-FLlGtsh9.d.cts +0 -107
- package/dist/collection-config-FLlGtsh9.d.ts +0 -107
- package/dist/index-BlsY5XNH.d.ts +0 -8333
- package/dist/index-D45jaIlr.d.cts +0 -8333
- package/dist/index.d.cts +0 -136
- package/dist/index.d.ts +0 -136
- package/dist/middleware.d.cts +0 -206
- package/dist/middleware.d.ts +0 -206
- package/dist/plugin-UzmDImQc.d.cts +0 -357
- package/dist/plugin-UzmDImQc.d.ts +0 -357
- package/dist/plugins.d.cts +0 -330
- package/dist/plugins.d.ts +0 -330
- package/dist/routes.d.cts +0 -17
- package/dist/routes.d.ts +0 -17
- package/dist/services.d.cts +0 -5
- package/dist/services.d.ts +0 -5
- package/dist/templates.d.cts +0 -140
- package/dist/templates.d.ts +0 -140
- package/dist/types.d.cts +0 -41
- package/dist/types.d.ts +0 -41
- package/dist/utils.d.cts +0 -184
- package/dist/utils.d.ts +0 -184
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
-- Stage 7: Workflow & Automation Migration
|
|
2
|
+
-- This migration adds workflow and automation capabilities to SonicJS
|
|
3
|
+
|
|
4
|
+
-- Workflow States Table
|
|
5
|
+
CREATE TABLE IF NOT EXISTS workflow_states (
|
|
6
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
7
|
+
name TEXT NOT NULL,
|
|
8
|
+
description TEXT,
|
|
9
|
+
color TEXT DEFAULT '#6B7280',
|
|
10
|
+
is_initial INTEGER DEFAULT 0,
|
|
11
|
+
is_final INTEGER DEFAULT 0,
|
|
12
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
-- Insert default workflow states
|
|
16
|
+
INSERT OR IGNORE INTO workflow_states (id, name, description, color, is_initial, is_final) VALUES
|
|
17
|
+
('draft', 'Draft', 'Content is being worked on', '#F59E0B', 1, 0),
|
|
18
|
+
('pending-review', 'Pending Review', 'Content is waiting for review', '#3B82F6', 0, 0),
|
|
19
|
+
('approved', 'Approved', 'Content has been approved', '#10B981', 0, 0),
|
|
20
|
+
('published', 'Published', 'Content is live', '#059669', 0, 1),
|
|
21
|
+
('rejected', 'Rejected', 'Content was rejected', '#EF4444', 0, 1),
|
|
22
|
+
('archived', 'Archived', 'Content has been archived', '#6B7280', 0, 1);
|
|
23
|
+
|
|
24
|
+
-- Workflows Table
|
|
25
|
+
CREATE TABLE IF NOT EXISTS workflows (
|
|
26
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
27
|
+
name TEXT NOT NULL,
|
|
28
|
+
description TEXT,
|
|
29
|
+
collection_id TEXT,
|
|
30
|
+
is_active INTEGER DEFAULT 1,
|
|
31
|
+
auto_publish INTEGER DEFAULT 0,
|
|
32
|
+
require_approval INTEGER DEFAULT 1,
|
|
33
|
+
approval_levels INTEGER DEFAULT 1,
|
|
34
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
35
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
36
|
+
FOREIGN KEY (collection_id) REFERENCES collections(id) ON DELETE CASCADE
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
-- Workflow Transitions Table
|
|
40
|
+
CREATE TABLE IF NOT EXISTS workflow_transitions (
|
|
41
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
42
|
+
workflow_id TEXT NOT NULL,
|
|
43
|
+
from_state_id TEXT NOT NULL,
|
|
44
|
+
to_state_id TEXT NOT NULL,
|
|
45
|
+
required_permission TEXT,
|
|
46
|
+
auto_transition INTEGER DEFAULT 0,
|
|
47
|
+
transition_conditions TEXT, -- JSON
|
|
48
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
49
|
+
FOREIGN KEY (workflow_id) REFERENCES workflows(id) ON DELETE CASCADE,
|
|
50
|
+
FOREIGN KEY (from_state_id) REFERENCES workflow_states(id),
|
|
51
|
+
FOREIGN KEY (to_state_id) REFERENCES workflow_states(id)
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
-- Content Workflow Status Table
|
|
55
|
+
CREATE TABLE IF NOT EXISTS content_workflow_status (
|
|
56
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
57
|
+
content_id TEXT NOT NULL,
|
|
58
|
+
workflow_id TEXT NOT NULL,
|
|
59
|
+
current_state_id TEXT NOT NULL,
|
|
60
|
+
assigned_to TEXT,
|
|
61
|
+
due_date DATETIME,
|
|
62
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
63
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
64
|
+
FOREIGN KEY (content_id) REFERENCES content(id) ON DELETE CASCADE,
|
|
65
|
+
FOREIGN KEY (workflow_id) REFERENCES workflows(id),
|
|
66
|
+
FOREIGN KEY (current_state_id) REFERENCES workflow_states(id),
|
|
67
|
+
FOREIGN KEY (assigned_to) REFERENCES users(id),
|
|
68
|
+
UNIQUE(content_id, workflow_id)
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
-- Workflow History Table
|
|
72
|
+
CREATE TABLE IF NOT EXISTS workflow_history (
|
|
73
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
74
|
+
content_id TEXT NOT NULL,
|
|
75
|
+
workflow_id TEXT NOT NULL,
|
|
76
|
+
from_state_id TEXT,
|
|
77
|
+
to_state_id TEXT NOT NULL,
|
|
78
|
+
user_id TEXT NOT NULL,
|
|
79
|
+
comment TEXT,
|
|
80
|
+
metadata TEXT, -- JSON
|
|
81
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
82
|
+
FOREIGN KEY (content_id) REFERENCES content(id) ON DELETE CASCADE,
|
|
83
|
+
FOREIGN KEY (workflow_id) REFERENCES workflows(id),
|
|
84
|
+
FOREIGN KEY (from_state_id) REFERENCES workflow_states(id),
|
|
85
|
+
FOREIGN KEY (to_state_id) REFERENCES workflow_states(id),
|
|
86
|
+
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
-- Scheduled Content Table
|
|
90
|
+
CREATE TABLE IF NOT EXISTS scheduled_content (
|
|
91
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
92
|
+
content_id TEXT NOT NULL,
|
|
93
|
+
action TEXT NOT NULL, -- 'publish', 'unpublish', 'archive'
|
|
94
|
+
scheduled_at DATETIME NOT NULL,
|
|
95
|
+
timezone TEXT DEFAULT 'UTC',
|
|
96
|
+
user_id TEXT NOT NULL,
|
|
97
|
+
status TEXT DEFAULT 'pending', -- 'pending', 'completed', 'failed', 'cancelled'
|
|
98
|
+
executed_at DATETIME,
|
|
99
|
+
error_message TEXT,
|
|
100
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
101
|
+
FOREIGN KEY (content_id) REFERENCES content(id) ON DELETE CASCADE,
|
|
102
|
+
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
-- Notifications Table
|
|
106
|
+
CREATE TABLE IF NOT EXISTS notifications (
|
|
107
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
108
|
+
user_id TEXT NOT NULL,
|
|
109
|
+
type TEXT NOT NULL, -- 'workflow', 'schedule', 'system'
|
|
110
|
+
title TEXT NOT NULL,
|
|
111
|
+
message TEXT NOT NULL,
|
|
112
|
+
data TEXT, -- JSON
|
|
113
|
+
is_read INTEGER DEFAULT 0,
|
|
114
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
115
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
-- Notification Preferences Table
|
|
119
|
+
CREATE TABLE IF NOT EXISTS notification_preferences (
|
|
120
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
121
|
+
user_id TEXT NOT NULL,
|
|
122
|
+
notification_type TEXT NOT NULL,
|
|
123
|
+
email_enabled INTEGER DEFAULT 1,
|
|
124
|
+
in_app_enabled INTEGER DEFAULT 1,
|
|
125
|
+
digest_frequency TEXT DEFAULT 'daily', -- 'immediate', 'hourly', 'daily', 'weekly'
|
|
126
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
127
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
128
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
129
|
+
UNIQUE(user_id, notification_type)
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
-- Webhooks Table
|
|
133
|
+
CREATE TABLE IF NOT EXISTS webhooks (
|
|
134
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
135
|
+
name TEXT NOT NULL,
|
|
136
|
+
url TEXT NOT NULL,
|
|
137
|
+
secret TEXT,
|
|
138
|
+
events TEXT NOT NULL, -- JSON array of event types
|
|
139
|
+
is_active INTEGER DEFAULT 1,
|
|
140
|
+
retry_count INTEGER DEFAULT 3,
|
|
141
|
+
timeout_seconds INTEGER DEFAULT 30,
|
|
142
|
+
last_success_at DATETIME,
|
|
143
|
+
last_failure_at DATETIME,
|
|
144
|
+
failure_count INTEGER DEFAULT 0,
|
|
145
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
146
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
-- Webhook Deliveries Table
|
|
150
|
+
CREATE TABLE IF NOT EXISTS webhook_deliveries (
|
|
151
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
152
|
+
webhook_id TEXT NOT NULL,
|
|
153
|
+
event_type TEXT NOT NULL,
|
|
154
|
+
payload TEXT NOT NULL, -- JSON
|
|
155
|
+
response_status INTEGER,
|
|
156
|
+
response_body TEXT,
|
|
157
|
+
attempt_count INTEGER DEFAULT 1,
|
|
158
|
+
delivered_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
159
|
+
FOREIGN KEY (webhook_id) REFERENCES webhooks(id) ON DELETE CASCADE
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
-- Content Versions Table (for rollback functionality)
|
|
163
|
+
CREATE TABLE IF NOT EXISTS content_versions (
|
|
164
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
165
|
+
content_id TEXT NOT NULL,
|
|
166
|
+
version_number INTEGER NOT NULL,
|
|
167
|
+
title TEXT NOT NULL,
|
|
168
|
+
content TEXT NOT NULL,
|
|
169
|
+
fields TEXT, -- JSON
|
|
170
|
+
user_id TEXT NOT NULL,
|
|
171
|
+
change_summary TEXT,
|
|
172
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
173
|
+
FOREIGN KEY (content_id) REFERENCES content(id) ON DELETE CASCADE,
|
|
174
|
+
FOREIGN KEY (user_id) REFERENCES users(id),
|
|
175
|
+
UNIQUE(content_id, version_number)
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
-- Automation Rules Table
|
|
179
|
+
CREATE TABLE IF NOT EXISTS automation_rules (
|
|
180
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
181
|
+
name TEXT NOT NULL,
|
|
182
|
+
description TEXT,
|
|
183
|
+
trigger_type TEXT NOT NULL, -- 'content_created', 'content_updated', 'workflow_transition', 'schedule'
|
|
184
|
+
trigger_conditions TEXT, -- JSON
|
|
185
|
+
action_type TEXT NOT NULL, -- 'workflow_transition', 'send_notification', 'webhook_call', 'auto_save'
|
|
186
|
+
action_config TEXT, -- JSON
|
|
187
|
+
is_active INTEGER DEFAULT 1,
|
|
188
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
189
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
-- Auto-save Drafts Table
|
|
193
|
+
CREATE TABLE IF NOT EXISTS auto_save_drafts (
|
|
194
|
+
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
|
|
195
|
+
content_id TEXT,
|
|
196
|
+
user_id TEXT NOT NULL,
|
|
197
|
+
title TEXT,
|
|
198
|
+
content TEXT,
|
|
199
|
+
fields TEXT, -- JSON
|
|
200
|
+
last_saved_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
201
|
+
FOREIGN KEY (content_id) REFERENCES content(id) ON DELETE CASCADE,
|
|
202
|
+
FOREIGN KEY (user_id) REFERENCES users(id),
|
|
203
|
+
UNIQUE(content_id, user_id)
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
-- Add workflow-related columns to existing content table (skip existing columns)
|
|
207
|
+
ALTER TABLE content ADD COLUMN workflow_state_id TEXT DEFAULT 'draft';
|
|
208
|
+
ALTER TABLE content ADD COLUMN embargo_until DATETIME;
|
|
209
|
+
ALTER TABLE content ADD COLUMN expires_at DATETIME;
|
|
210
|
+
ALTER TABLE content ADD COLUMN version_number INTEGER DEFAULT 1;
|
|
211
|
+
ALTER TABLE content ADD COLUMN is_auto_saved INTEGER DEFAULT 0;
|
|
212
|
+
|
|
213
|
+
-- Create indexes for performance
|
|
214
|
+
CREATE INDEX IF NOT EXISTS idx_content_workflow_status_content_id ON content_workflow_status(content_id);
|
|
215
|
+
CREATE INDEX IF NOT EXISTS idx_content_workflow_status_workflow_id ON content_workflow_status(workflow_id);
|
|
216
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_history_content_id ON workflow_history(content_id);
|
|
217
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_content_scheduled_at ON scheduled_content(scheduled_at);
|
|
218
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_content_status ON scheduled_content(status);
|
|
219
|
+
CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON notifications(user_id);
|
|
220
|
+
CREATE INDEX IF NOT EXISTS idx_notifications_is_read ON notifications(is_read);
|
|
221
|
+
CREATE INDEX IF NOT EXISTS idx_content_versions_content_id ON content_versions(content_id);
|
|
222
|
+
CREATE INDEX IF NOT EXISTS idx_auto_save_drafts_user_id ON auto_save_drafts(user_id);
|
|
223
|
+
CREATE INDEX IF NOT EXISTS idx_content_workflow_state ON content(workflow_state_id);
|
|
224
|
+
CREATE INDEX IF NOT EXISTS idx_content_scheduled_publish ON content(scheduled_publish_at);
|
|
225
|
+
|
|
226
|
+
-- Insert default workflow for collections
|
|
227
|
+
INSERT OR IGNORE INTO workflows (id, name, description, collection_id, is_active, require_approval, approval_levels)
|
|
228
|
+
SELECT
|
|
229
|
+
'default-' || id,
|
|
230
|
+
'Default Workflow for ' || name,
|
|
231
|
+
'Standard content approval workflow',
|
|
232
|
+
id,
|
|
233
|
+
1,
|
|
234
|
+
1,
|
|
235
|
+
1
|
|
236
|
+
FROM collections;
|
|
237
|
+
|
|
238
|
+
-- Insert default workflow transitions
|
|
239
|
+
INSERT OR IGNORE INTO workflow_transitions (workflow_id, from_state_id, to_state_id, required_permission)
|
|
240
|
+
SELECT
|
|
241
|
+
w.id,
|
|
242
|
+
'draft',
|
|
243
|
+
'pending-review',
|
|
244
|
+
'content:submit'
|
|
245
|
+
FROM workflows w;
|
|
246
|
+
|
|
247
|
+
INSERT OR IGNORE INTO workflow_transitions (workflow_id, from_state_id, to_state_id, required_permission)
|
|
248
|
+
SELECT
|
|
249
|
+
w.id,
|
|
250
|
+
'pending-review',
|
|
251
|
+
'approved',
|
|
252
|
+
'content:approve'
|
|
253
|
+
FROM workflows w;
|
|
254
|
+
|
|
255
|
+
INSERT OR IGNORE INTO workflow_transitions (workflow_id, from_state_id, to_state_id, required_permission)
|
|
256
|
+
SELECT
|
|
257
|
+
w.id,
|
|
258
|
+
'approved',
|
|
259
|
+
'published',
|
|
260
|
+
'content:publish'
|
|
261
|
+
FROM workflows w;
|
|
262
|
+
|
|
263
|
+
INSERT OR IGNORE INTO workflow_transitions (workflow_id, from_state_id, to_state_id, required_permission)
|
|
264
|
+
SELECT
|
|
265
|
+
w.id,
|
|
266
|
+
'pending-review',
|
|
267
|
+
'rejected',
|
|
268
|
+
'content:approve'
|
|
269
|
+
FROM workflows w;
|
|
270
|
+
|
|
271
|
+
-- Insert default notification preferences for all users
|
|
272
|
+
INSERT OR IGNORE INTO notification_preferences (user_id, notification_type, email_enabled, in_app_enabled)
|
|
273
|
+
SELECT
|
|
274
|
+
id,
|
|
275
|
+
'workflow_assigned',
|
|
276
|
+
1,
|
|
277
|
+
1
|
|
278
|
+
FROM users;
|
|
279
|
+
|
|
280
|
+
INSERT OR IGNORE INTO notification_preferences (user_id, notification_type, email_enabled, in_app_enabled)
|
|
281
|
+
SELECT
|
|
282
|
+
id,
|
|
283
|
+
'workflow_status_change',
|
|
284
|
+
1,
|
|
285
|
+
1
|
|
286
|
+
FROM users;
|
|
287
|
+
|
|
288
|
+
INSERT OR IGNORE INTO notification_preferences (user_id, notification_type, email_enabled, in_app_enabled)
|
|
289
|
+
SELECT
|
|
290
|
+
id,
|
|
291
|
+
'content_scheduled',
|
|
292
|
+
1,
|
|
293
|
+
1
|
|
294
|
+
FROM users;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
-- Plugin System Tables
|
|
2
|
+
-- Migration: 006_plugin_system
|
|
3
|
+
-- Description: Add plugin management system tables
|
|
4
|
+
|
|
5
|
+
-- Plugins table
|
|
6
|
+
CREATE TABLE IF NOT EXISTS plugins (
|
|
7
|
+
id TEXT PRIMARY KEY,
|
|
8
|
+
name TEXT NOT NULL UNIQUE,
|
|
9
|
+
display_name TEXT NOT NULL,
|
|
10
|
+
description TEXT,
|
|
11
|
+
version TEXT NOT NULL,
|
|
12
|
+
author TEXT NOT NULL,
|
|
13
|
+
category TEXT NOT NULL,
|
|
14
|
+
icon TEXT,
|
|
15
|
+
status TEXT DEFAULT 'inactive' CHECK (status IN ('active', 'inactive', 'error')),
|
|
16
|
+
is_core BOOLEAN DEFAULT FALSE,
|
|
17
|
+
settings JSON,
|
|
18
|
+
permissions JSON,
|
|
19
|
+
dependencies JSON,
|
|
20
|
+
download_count INTEGER DEFAULT 0,
|
|
21
|
+
rating REAL DEFAULT 0,
|
|
22
|
+
installed_at INTEGER NOT NULL,
|
|
23
|
+
activated_at INTEGER,
|
|
24
|
+
last_updated INTEGER NOT NULL,
|
|
25
|
+
error_message TEXT,
|
|
26
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
27
|
+
updated_at INTEGER DEFAULT (unixepoch())
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
-- Plugin hooks table (registered hooks by plugins)
|
|
31
|
+
CREATE TABLE IF NOT EXISTS plugin_hooks (
|
|
32
|
+
id TEXT PRIMARY KEY,
|
|
33
|
+
plugin_id TEXT NOT NULL,
|
|
34
|
+
hook_name TEXT NOT NULL,
|
|
35
|
+
handler_name TEXT NOT NULL,
|
|
36
|
+
priority INTEGER DEFAULT 10,
|
|
37
|
+
is_active BOOLEAN DEFAULT TRUE,
|
|
38
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
39
|
+
FOREIGN KEY (plugin_id) REFERENCES plugins(id) ON DELETE CASCADE,
|
|
40
|
+
UNIQUE(plugin_id, hook_name, handler_name)
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
-- Plugin routes table
|
|
44
|
+
CREATE TABLE IF NOT EXISTS plugin_routes (
|
|
45
|
+
id TEXT PRIMARY KEY,
|
|
46
|
+
plugin_id TEXT NOT NULL,
|
|
47
|
+
path TEXT NOT NULL,
|
|
48
|
+
method TEXT NOT NULL,
|
|
49
|
+
handler_name TEXT NOT NULL,
|
|
50
|
+
middleware JSON,
|
|
51
|
+
is_active BOOLEAN DEFAULT TRUE,
|
|
52
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
53
|
+
FOREIGN KEY (plugin_id) REFERENCES plugins(id) ON DELETE CASCADE,
|
|
54
|
+
UNIQUE(plugin_id, path, method)
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
-- Plugin assets table (CSS, JS files provided by plugins)
|
|
58
|
+
CREATE TABLE IF NOT EXISTS plugin_assets (
|
|
59
|
+
id TEXT PRIMARY KEY,
|
|
60
|
+
plugin_id TEXT NOT NULL,
|
|
61
|
+
asset_type TEXT NOT NULL CHECK (asset_type IN ('css', 'js', 'image', 'font')),
|
|
62
|
+
asset_path TEXT NOT NULL,
|
|
63
|
+
load_order INTEGER DEFAULT 100,
|
|
64
|
+
load_location TEXT DEFAULT 'footer' CHECK (load_location IN ('header', 'footer')),
|
|
65
|
+
is_active BOOLEAN DEFAULT TRUE,
|
|
66
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
67
|
+
FOREIGN KEY (plugin_id) REFERENCES plugins(id) ON DELETE CASCADE
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
-- Plugin activity log
|
|
71
|
+
CREATE TABLE IF NOT EXISTS plugin_activity_log (
|
|
72
|
+
id TEXT PRIMARY KEY,
|
|
73
|
+
plugin_id TEXT NOT NULL,
|
|
74
|
+
action TEXT NOT NULL,
|
|
75
|
+
user_id TEXT,
|
|
76
|
+
details JSON,
|
|
77
|
+
timestamp INTEGER DEFAULT (unixepoch()),
|
|
78
|
+
FOREIGN KEY (plugin_id) REFERENCES plugins(id) ON DELETE CASCADE
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
-- Create indexes
|
|
82
|
+
CREATE INDEX IF NOT EXISTS idx_plugins_status ON plugins(status);
|
|
83
|
+
CREATE INDEX IF NOT EXISTS idx_plugins_category ON plugins(category);
|
|
84
|
+
CREATE INDEX IF NOT EXISTS idx_plugin_hooks_plugin ON plugin_hooks(plugin_id);
|
|
85
|
+
CREATE INDEX IF NOT EXISTS idx_plugin_routes_plugin ON plugin_routes(plugin_id);
|
|
86
|
+
CREATE INDEX IF NOT EXISTS idx_plugin_assets_plugin ON plugin_assets(plugin_id);
|
|
87
|
+
CREATE INDEX IF NOT EXISTS idx_plugin_activity_plugin ON plugin_activity_log(plugin_id);
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_plugin_activity_timestamp ON plugin_activity_log(timestamp);
|
|
89
|
+
|
|
90
|
+
-- Insert core plugins
|
|
91
|
+
INSERT INTO plugins (
|
|
92
|
+
id, name, display_name, description, version, author, category, icon,
|
|
93
|
+
status, is_core, permissions, installed_at, last_updated
|
|
94
|
+
) VALUES
|
|
95
|
+
(
|
|
96
|
+
'core-auth',
|
|
97
|
+
'core-auth',
|
|
98
|
+
'Authentication System',
|
|
99
|
+
'Core authentication and user management system',
|
|
100
|
+
'1.0.0',
|
|
101
|
+
'SonicJS Team',
|
|
102
|
+
'security',
|
|
103
|
+
'🔐',
|
|
104
|
+
'active',
|
|
105
|
+
TRUE,
|
|
106
|
+
'["manage:users", "manage:roles", "manage:permissions"]',
|
|
107
|
+
unixepoch(),
|
|
108
|
+
unixepoch()
|
|
109
|
+
),
|
|
110
|
+
(
|
|
111
|
+
'core-media',
|
|
112
|
+
'core-media',
|
|
113
|
+
'Media Manager',
|
|
114
|
+
'Core media upload and management system',
|
|
115
|
+
'1.0.0',
|
|
116
|
+
'SonicJS Team',
|
|
117
|
+
'media',
|
|
118
|
+
'📸',
|
|
119
|
+
'active',
|
|
120
|
+
TRUE,
|
|
121
|
+
'["manage:media", "upload:files"]',
|
|
122
|
+
unixepoch(),
|
|
123
|
+
unixepoch()
|
|
124
|
+
),
|
|
125
|
+
(
|
|
126
|
+
'core-workflow',
|
|
127
|
+
'core-workflow',
|
|
128
|
+
'Workflow Engine',
|
|
129
|
+
'Content workflow and approval system',
|
|
130
|
+
'1.0.0',
|
|
131
|
+
'SonicJS Team',
|
|
132
|
+
'content',
|
|
133
|
+
'🔄',
|
|
134
|
+
'active',
|
|
135
|
+
TRUE,
|
|
136
|
+
'["manage:workflows", "approve:content"]',
|
|
137
|
+
unixepoch(),
|
|
138
|
+
unixepoch()
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
-- FAQ Plugin will be added as a third-party plugin through the admin interface
|
|
142
|
+
|
|
143
|
+
-- Add plugin management permission
|
|
144
|
+
INSERT OR IGNORE INTO permissions (id, name, description, category, created_at)
|
|
145
|
+
VALUES (
|
|
146
|
+
'manage:plugins',
|
|
147
|
+
'Manage Plugins',
|
|
148
|
+
'Install, uninstall, activate, and configure plugins',
|
|
149
|
+
'system',
|
|
150
|
+
unixepoch()
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
-- Grant plugin management permission to admin role
|
|
154
|
+
INSERT OR IGNORE INTO role_permissions (id, role, permission_id, created_at)
|
|
155
|
+
VALUES ('role-perm-manage-plugins', 'admin', 'manage:plugins', unixepoch());
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
-- Demo Login Plugin Migration
|
|
2
|
+
-- Migration: 007_demo_login_plugin
|
|
3
|
+
-- Description: Add demo login prefill plugin to the plugin registry
|
|
4
|
+
|
|
5
|
+
-- Insert demo login plugin
|
|
6
|
+
INSERT INTO plugins (
|
|
7
|
+
id, name, display_name, description, version, author, category, icon,
|
|
8
|
+
status, is_core, permissions, installed_at, last_updated
|
|
9
|
+
) VALUES (
|
|
10
|
+
'demo-login-prefill',
|
|
11
|
+
'demo-login-plugin',
|
|
12
|
+
'Demo Login Prefill',
|
|
13
|
+
'Prefills login form with demo credentials (admin@sonicjs.com/admin123) for easy site demonstration',
|
|
14
|
+
'1.0.0',
|
|
15
|
+
'SonicJS',
|
|
16
|
+
'demo',
|
|
17
|
+
'🎯',
|
|
18
|
+
'inactive',
|
|
19
|
+
TRUE,
|
|
20
|
+
'[]',
|
|
21
|
+
unixepoch(),
|
|
22
|
+
unixepoch()
|
|
23
|
+
);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- Migration: Fix overly restrictive slug validation patterns
|
|
2
|
+
-- This migration relaxes the slug field validation to be more user-friendly
|
|
3
|
+
|
|
4
|
+
-- Update the pages collection slug field to allow underscores and be less restrictive
|
|
5
|
+
UPDATE content_fields
|
|
6
|
+
SET field_options = '{"pattern": "^[a-zA-Z0-9_-]+$", "placeholder": "url-friendly-slug", "help": "Use letters, numbers, underscores, and hyphens only"}'
|
|
7
|
+
WHERE field_name = 'slug' AND collection_id = 'pages-collection';
|
|
8
|
+
|
|
9
|
+
-- Update blog posts slug field if it exists
|
|
10
|
+
UPDATE content_fields
|
|
11
|
+
SET field_options = '{"pattern": "^[a-zA-Z0-9_-]+$", "placeholder": "url-friendly-slug", "help": "Use letters, numbers, underscores, and hyphens only"}'
|
|
12
|
+
WHERE field_name = 'slug' AND collection_id = 'blog-posts-collection';
|
|
13
|
+
|
|
14
|
+
-- Update news slug field if it exists
|
|
15
|
+
UPDATE content_fields
|
|
16
|
+
SET field_options = '{"pattern": "^[a-zA-Z0-9_-]+$", "placeholder": "url-friendly-slug", "help": "Use letters, numbers, underscores, and hyphens only"}'
|
|
17
|
+
WHERE field_name = 'slug' AND collection_id = 'news-collection';
|
|
18
|
+
|
|
19
|
+
-- Update any other slug fields with the restrictive pattern
|
|
20
|
+
UPDATE content_fields
|
|
21
|
+
SET field_options = REPLACE(field_options, '"pattern": "^[a-z0-9-]+$"', '"pattern": "^[a-zA-Z0-9_-]+$"')
|
|
22
|
+
WHERE field_options LIKE '%"pattern": "^[a-z0-9-]+$"%';
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
-- System Logging Tables
|
|
2
|
+
-- Migration: 009_system_logging
|
|
3
|
+
-- Description: Add system logging and configuration tables
|
|
4
|
+
|
|
5
|
+
-- System logs table for tracking application events
|
|
6
|
+
CREATE TABLE IF NOT EXISTS system_logs (
|
|
7
|
+
id TEXT PRIMARY KEY,
|
|
8
|
+
level TEXT NOT NULL CHECK (level IN ('debug', 'info', 'warn', 'error', 'fatal')),
|
|
9
|
+
category TEXT NOT NULL CHECK (category IN ('auth', 'api', 'workflow', 'plugin', 'media', 'system', 'security', 'error')),
|
|
10
|
+
message TEXT NOT NULL,
|
|
11
|
+
data TEXT, -- JSON data
|
|
12
|
+
user_id TEXT,
|
|
13
|
+
session_id TEXT,
|
|
14
|
+
request_id TEXT,
|
|
15
|
+
ip_address TEXT,
|
|
16
|
+
user_agent TEXT,
|
|
17
|
+
method TEXT,
|
|
18
|
+
url TEXT,
|
|
19
|
+
status_code INTEGER,
|
|
20
|
+
duration INTEGER, -- milliseconds
|
|
21
|
+
stack_trace TEXT,
|
|
22
|
+
tags TEXT, -- JSON array
|
|
23
|
+
source TEXT, -- source of the log entry
|
|
24
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
25
|
+
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
-- Log configuration table for managing log settings per category
|
|
29
|
+
CREATE TABLE IF NOT EXISTS log_config (
|
|
30
|
+
id TEXT PRIMARY KEY,
|
|
31
|
+
category TEXT NOT NULL UNIQUE CHECK (category IN ('auth', 'api', 'workflow', 'plugin', 'media', 'system', 'security', 'error')),
|
|
32
|
+
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
|
33
|
+
level TEXT NOT NULL DEFAULT 'info' CHECK (level IN ('debug', 'info', 'warn', 'error', 'fatal')),
|
|
34
|
+
retention_days INTEGER NOT NULL DEFAULT 30,
|
|
35
|
+
max_size_mb INTEGER NOT NULL DEFAULT 100,
|
|
36
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
37
|
+
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
-- Create indexes for better performance
|
|
41
|
+
CREATE INDEX IF NOT EXISTS idx_system_logs_level ON system_logs(level);
|
|
42
|
+
CREATE INDEX IF NOT EXISTS idx_system_logs_category ON system_logs(category);
|
|
43
|
+
CREATE INDEX IF NOT EXISTS idx_system_logs_created_at ON system_logs(created_at);
|
|
44
|
+
CREATE INDEX IF NOT EXISTS idx_system_logs_user_id ON system_logs(user_id);
|
|
45
|
+
CREATE INDEX IF NOT EXISTS idx_system_logs_status_code ON system_logs(status_code);
|
|
46
|
+
CREATE INDEX IF NOT EXISTS idx_system_logs_source ON system_logs(source);
|
|
47
|
+
|
|
48
|
+
-- Insert default log configurations
|
|
49
|
+
INSERT OR IGNORE INTO log_config (id, category, enabled, level, retention_days, max_size_mb) VALUES
|
|
50
|
+
('log-config-auth', 'auth', TRUE, 'info', 90, 50),
|
|
51
|
+
('log-config-api', 'api', TRUE, 'info', 30, 100),
|
|
52
|
+
('log-config-workflow', 'workflow', TRUE, 'info', 60, 50),
|
|
53
|
+
('log-config-plugin', 'plugin', TRUE, 'warn', 30, 25),
|
|
54
|
+
('log-config-media', 'media', TRUE, 'info', 30, 50),
|
|
55
|
+
('log-config-system', 'system', TRUE, 'info', 90, 100),
|
|
56
|
+
('log-config-security', 'security', TRUE, 'warn', 180, 100),
|
|
57
|
+
('log-config-error', 'error', TRUE, 'error', 90, 200);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
-- Migration: Add Config-Managed Collections Support
|
|
2
|
+
-- Description: Add 'managed' column to collections table to support config-based collection definitions
|
|
3
|
+
-- Created: 2025-10-03
|
|
4
|
+
|
|
5
|
+
-- Add 'managed' column to collections table
|
|
6
|
+
-- This column indicates whether a collection is managed by configuration files (true) or user-created (false)
|
|
7
|
+
-- Managed collections cannot be edited through the admin UI
|
|
8
|
+
ALTER TABLE collections ADD COLUMN managed INTEGER DEFAULT 0 NOT NULL;
|
|
9
|
+
|
|
10
|
+
-- Create an index on the managed column for faster queries
|
|
11
|
+
CREATE INDEX IF NOT EXISTS idx_collections_managed ON collections(managed);
|
|
12
|
+
|
|
13
|
+
-- Create an index on managed + is_active for efficient filtering
|
|
14
|
+
CREATE INDEX IF NOT EXISTS idx_collections_managed_active ON collections(managed, is_active);
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
-- Testimonials Plugin Migration
|
|
2
|
+
-- Creates testimonials table for the testimonials plugin
|
|
3
|
+
-- This demonstrates a code-based collection defined in src/plugins/core-plugins/testimonials-plugin.ts
|
|
4
|
+
|
|
5
|
+
CREATE TABLE IF NOT EXISTS testimonials (
|
|
6
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
7
|
+
author_name TEXT NOT NULL,
|
|
8
|
+
author_title TEXT,
|
|
9
|
+
author_company TEXT,
|
|
10
|
+
testimonial_text TEXT NOT NULL,
|
|
11
|
+
rating INTEGER CHECK(rating >= 1 AND rating <= 5),
|
|
12
|
+
isPublished INTEGER NOT NULL DEFAULT 1,
|
|
13
|
+
sortOrder INTEGER NOT NULL DEFAULT 0,
|
|
14
|
+
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
|
|
15
|
+
updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
-- Create indexes for better performance
|
|
19
|
+
CREATE INDEX IF NOT EXISTS idx_testimonials_published ON testimonials(isPublished);
|
|
20
|
+
CREATE INDEX IF NOT EXISTS idx_testimonials_sort_order ON testimonials(sortOrder);
|
|
21
|
+
CREATE INDEX IF NOT EXISTS idx_testimonials_rating ON testimonials(rating);
|
|
22
|
+
|
|
23
|
+
-- Create trigger to update updated_at timestamp
|
|
24
|
+
CREATE TRIGGER IF NOT EXISTS testimonials_updated_at
|
|
25
|
+
AFTER UPDATE ON testimonials
|
|
26
|
+
BEGIN
|
|
27
|
+
UPDATE testimonials SET updated_at = strftime('%s', 'now') WHERE id = NEW.id;
|
|
28
|
+
END;
|
|
29
|
+
|
|
30
|
+
-- Insert plugin record
|
|
31
|
+
INSERT OR IGNORE INTO plugins (name, display_name, description, version, status, category, settings) VALUES
|
|
32
|
+
('testimonials',
|
|
33
|
+
'Customer Testimonials',
|
|
34
|
+
'Manage customer testimonials and reviews with rating support. This is a code-based collection example.',
|
|
35
|
+
'1.0.0',
|
|
36
|
+
'active',
|
|
37
|
+
'content',
|
|
38
|
+
'{"defaultPublished": true, "requireRating": false}');
|
|
39
|
+
|
|
40
|
+
-- Insert sample testimonial data
|
|
41
|
+
INSERT OR IGNORE INTO testimonials (author_name, author_title, author_company, testimonial_text, rating, isPublished, sortOrder) VALUES
|
|
42
|
+
('Jane Smith',
|
|
43
|
+
'CTO',
|
|
44
|
+
'TechStartup Inc',
|
|
45
|
+
'SonicJS AI has transformed how we manage our content. The plugin architecture is brilliant and the edge deployment is blazing fast.',
|
|
46
|
+
5,
|
|
47
|
+
1,
|
|
48
|
+
1),
|
|
49
|
+
|
|
50
|
+
('Michael Chen',
|
|
51
|
+
'Lead Developer',
|
|
52
|
+
'Digital Agency Co',
|
|
53
|
+
'We migrated from WordPress to SonicJS AI and couldn''t be happier. The TypeScript-first approach and modern tooling make development a joy.',
|
|
54
|
+
5,
|
|
55
|
+
1,
|
|
56
|
+
2),
|
|
57
|
+
|
|
58
|
+
('Sarah Johnson',
|
|
59
|
+
'Product Manager',
|
|
60
|
+
'E-commerce Solutions',
|
|
61
|
+
'The headless CMS approach combined with Cloudflare Workers gives us unmatched performance. Our content is served globally with minimal latency.',
|
|
62
|
+
4,
|
|
63
|
+
1,
|
|
64
|
+
3),
|
|
65
|
+
|
|
66
|
+
('David Rodriguez',
|
|
67
|
+
'Full Stack Developer',
|
|
68
|
+
'Creative Studio',
|
|
69
|
+
'Great CMS for modern web applications. The admin interface is clean and the API is well-designed. Plugin system is very flexible.',
|
|
70
|
+
5,
|
|
71
|
+
1,
|
|
72
|
+
4),
|
|
73
|
+
|
|
74
|
+
('Emily Watson',
|
|
75
|
+
'Technical Director',
|
|
76
|
+
'Media Company',
|
|
77
|
+
'SonicJS AI solved our content distribution challenges. The R2 integration for media storage works flawlessly and scales effortlessly.',
|
|
78
|
+
4,
|
|
79
|
+
1,
|
|
80
|
+
5);
|