-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathschema.sql
More file actions
58 lines (51 loc) · 2.28 KB
/
schema.sql
File metadata and controls
58 lines (51 loc) · 2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
-- Blog Comments Table
CREATE TABLE IF NOT EXISTS comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_slug TEXT NOT NULL,
author_name TEXT NOT NULL,
content TEXT NOT NULL,
created_at INTEGER NOT NULL,
ip_address TEXT,
user_agent TEXT,
approved INTEGER DEFAULT 0, -- 0 = pending, 1 = approved, -1 = spam
parent_id INTEGER, -- For nested replies (future feature)
FOREIGN KEY (parent_id) REFERENCES comments(id) ON DELETE CASCADE
);
-- Index for faster queries by post
CREATE INDEX IF NOT EXISTS idx_comments_post_slug ON comments(post_slug);
CREATE INDEX IF NOT EXISTS idx_comments_approved ON comments(approved);
CREATE INDEX IF NOT EXISTS idx_comments_created_at ON comments(created_at);
-- Blog Post Claps Table (like Medium - up to 50 claps per post)
CREATE TABLE IF NOT EXISTS likes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_slug TEXT NOT NULL,
ip_address TEXT NOT NULL,
clap_count INTEGER DEFAULT 1, -- Number of claps (max 50)
created_at INTEGER NOT NULL,
updated_at INTEGER, -- Track when they last clapped
UNIQUE(post_slug, ip_address) -- One entry per IP per post
);
-- Index for faster queries
CREATE INDEX IF NOT EXISTS idx_likes_post_slug ON likes(post_slug);
-- Rate limiting table (simple spam prevention)
CREATE TABLE IF NOT EXISTS rate_limits (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ip_address TEXT NOT NULL,
action_type TEXT NOT NULL, -- 'comment' or 'like'
created_at INTEGER NOT NULL
);
-- Index for rate limit cleanup
CREATE INDEX IF NOT EXISTS idx_rate_limits_ip ON rate_limits(ip_address, action_type);
CREATE INDEX IF NOT EXISTS idx_rate_limits_created_at ON rate_limits(created_at);
-- Post publish status table
CREATE TABLE IF NOT EXISTS post_status (
post_slug TEXT PRIMARY KEY,
published INTEGER DEFAULT 0, -- 0 = unpublished, 1 = published
published_at INTEGER, -- timestamp when first published
updated_at INTEGER -- timestamp of last status change
);
-- Seed existing posts as published (these are already live on main)
INSERT OR IGNORE INTO post_status (post_slug, published, published_at, updated_at)
VALUES ('building-a-zero-cost-blog', 1, 1730073600000, 1730073600000);
INSERT OR IGNORE INTO post_status (post_slug, published, published_at, updated_at)
VALUES ('postgres-cheatsheet', 1, 1730073600000, 1730073600000);