返回 DeepSeek-Reasonix
schema.sql
根目录 / workers / forum / schema.sql
1 -- Reasonix Community forum. Identity comes from id.reasonix.io; this DB holds
2 -- forum content plus the anti-abuse state (trust levels, flags, silences).
3 -- Apply: wrangler d1 execute reasonix-forum --remote --file=schema.sql
4
5 -- A member is a signed-in identity that has interacted with the forum. Trust
6 -- level is the primary anti-spam lever: new members (trust 0) are throttled and
7 -- can't post links/images; trust rises with real participation.
8 CREATE TABLE IF NOT EXISTS members (
9 email TEXT PRIMARY KEY, -- lowercased id.reasonix.io identity
10 handle TEXT NOT NULL,
11 trust INTEGER NOT NULL DEFAULT 0, -- 0 new · 1 basic · 2 member · 3 regular · 4 leader
12 role TEXT NOT NULL DEFAULT 'member',-- member · moderator · admin
13 post_count INTEGER NOT NULL DEFAULT 0,
14 likes_received INTEGER NOT NULL DEFAULT 0,
15 flagged_count INTEGER NOT NULL DEFAULT 0, -- times this member's content was actioned
16 silenced_until TEXT, -- spam containment; NULL = not silenced
17 created_at TEXT NOT NULL,
18 last_seen_at TEXT
19 );
20
21 CREATE TABLE IF NOT EXISTS categories (
22 id INTEGER PRIMARY KEY AUTOINCREMENT,
23 slug TEXT NOT NULL UNIQUE,
24 name TEXT NOT NULL,
25 description TEXT NOT NULL DEFAULT '',
26 position INTEGER NOT NULL DEFAULT 0,
27 min_trust_to_post INTEGER NOT NULL DEFAULT 0 -- e.g. Announcements = staff-only via a high value
28 );
29
30 CREATE TABLE IF NOT EXISTS topics (
31 id INTEGER PRIMARY KEY AUTOINCREMENT,
32 category_id INTEGER NOT NULL,
33 author TEXT NOT NULL, -- members.email
34 title TEXT NOT NULL,
35 slug TEXT NOT NULL,
36 status TEXT NOT NULL DEFAULT 'open',-- open · solved · closed · hidden
37 pinned INTEGER NOT NULL DEFAULT 0,
38 reply_count INTEGER NOT NULL DEFAULT 0,
39 view_count INTEGER NOT NULL DEFAULT 0,
40 accepted_post_id INTEGER,
41 created_at TEXT NOT NULL,
42 last_post_at TEXT NOT NULL
43 );
44 CREATE INDEX IF NOT EXISTS topics_category ON topics (category_id, pinned DESC, last_post_at DESC);
45 CREATE INDEX IF NOT EXISTS topics_recent ON topics (last_post_at DESC);
46
47 CREATE TABLE IF NOT EXISTS posts (
48 id INTEGER PRIMARY KEY AUTOINCREMENT,
49 topic_id INTEGER NOT NULL,
50 author TEXT NOT NULL,
51 body TEXT NOT NULL, -- markdown source
52 status TEXT NOT NULL DEFAULT 'visible', -- visible · pending (held for review) · hidden · deleted
53 like_count INTEGER NOT NULL DEFAULT 0,
54 flag_count INTEGER NOT NULL DEFAULT 0, -- auto-hides at a threshold
55 created_at TEXT NOT NULL,
56 edited_at TEXT
57 );
58 CREATE INDEX IF NOT EXISTS posts_topic ON posts (topic_id, created_at);
59
60 CREATE TABLE IF NOT EXISTS reactions (
61 post_id INTEGER NOT NULL,
62 member TEXT NOT NULL,
63 emoji TEXT NOT NULL,
64 created_at TEXT NOT NULL,
65 PRIMARY KEY (post_id, member, emoji)
66 );
67
68 -- Abuse reports. One flag per reporter per post; flag_count on posts is derived
69 -- from these and drives auto-hide + the moderation queue.
70 CREATE TABLE IF NOT EXISTS flags (
71 post_id INTEGER NOT NULL,
72 reporter TEXT NOT NULL,
73 reason TEXT NOT NULL, -- spam · offensive · off_topic · other
74 note TEXT NOT NULL DEFAULT '',
75 status TEXT NOT NULL DEFAULT 'open', -- open · actioned · dismissed
76 created_at TEXT NOT NULL,
77 PRIMARY KEY (post_id, reporter)
78 );
79 CREATE INDEX IF NOT EXISTS flags_open ON flags (status, created_at);
80
81 -- Moderator actions, for accountability.
82 CREATE TABLE IF NOT EXISTS mod_log (
83 id INTEGER PRIMARY KEY AUTOINCREMENT,
84 at TEXT NOT NULL,
85 actor TEXT NOT NULL,
86 action TEXT NOT NULL, -- hide_post · silence_member · set_trust · resolve_flag · ...
87 target TEXT NOT NULL DEFAULT '',
88 detail TEXT NOT NULL DEFAULT ''
89 );
90
90 lines SQL