About This Schema
Auth is GitHub OAuth only, so users has no password column. Roles are stored as a single tinyint type — member, moderator, or admin — rather than a separate roles table.
Threads work like Stack Overflow questions: solution_reply_id points to the accepted answer, while locked_at and locked_by track when a thread was closed and by whom.
Replies use Laravel’s SoftDeletes (deleted_at) plus custom deleted_by and deleted_reason columns, so every moderator removal records who did it and why.
Replies, likes, tags, subscriptions, and spam reports all attach to content through the same polymorphic pattern. Subscriptions and spam reports also use composite unique keys, so you can’t follow the same thread twice or report the same target twice.
Article state is modeled with timestamps instead of an enum: submitted_at, then approved_at or declined_at, then shared_at. Approved articles auto-share to Bluesky; tweet_id is a leftover from the old X integration and is no longer written.