Changes this iteration:
- Changed the naming convention from PascalCase to snake_case
- Added a reference tables for social media for the members table.
member
This table will hold the global user records for an Codidact Instance. A user should only have one email to login with, that would be stored here. I am leaving the password storage and hashing to the experts.
display_name (text 100)
bio (text)
email (text 255) UNQIUE
gravatar_hash (text)
location (text 100)
is_from_stack_exchange (boolean default FALSE)
stack_exchange_id (bigint)
stack_exchange_validated (date)
stack_exchange_last_imported (date)
is_email_verified (boolean default FALSE)
is_suspended (boolean default FALSE)
suspension_end_date (date)
community
Table for each of the individual sites inside of a Codidact installation
name (text 40) UNQIUE
tagline (text 100) UNQIUE
url (text 255) UNQIUE
help_text (text)
faq (text)
status (enum)
trust_level
This needs to be specific to a site for when we get different language sites and it needs to be localized.
name (text 100) UNQIUE
explanation (text) UNQIUE
trust_level_community
community_id (bigserial)
is_same_as_instance (boolean default TRUE)
name (text 100) UNQIUE
explanation (text) UNQIUE
member_community
A user may want to join one site and not another, and having a join table between users and sites allows a user to be suspended or gain/lose privileges on a single site. I listed the privilege booleans in the order of lowest to highest, the privileges after is_moderator aren’t listed because we probably are going to take any of moderator’s lower privileges away without demodding them.
member_id (bigserial)
community_id (bigserial)
display_name (text 100)
bio (text)
email (text 255) UNQIUE
gravatar_hash (text)
location (text 100)
is_from_stack_exchange (boolean default FALSE)
stack_exchange_id (bigint)
is_same_as_instance (boolean default TRUE)
stack_exchange_validated (date)
stack_exchange_last_imported (date)
is_suspended (boolean default FALSE)
suspension_end_date (date)
trust_level_community_id (bigserial)
is_moderator (boolean default FALSE)
is_deleted (boolean default FALSE)
UNIQUE CONSTRAINT (member_id, community_id)
social_media
The types of social media that the member can display in his profile
name (text 100)
member_social_media
The social media that the member would like to display in his profile per community
social_media_id (bigserial)
member_id (bigserial)
community_id (bigserial NULL)
url (text)
UNIQUE CONSTRAINT (community_id,member_id,social_media_id)
privilege
Table for privileges
name (text 100)
description (text)
member_community_privilege
For recording which members have which privilege in a community. If a member has a privilege suspended, then that is also recorded here, and a nightly task will auto undo the suspension once the privelege_suspension_end_date has passed.
community_id (bigserial)
member_id (bigserial)
privilege_id (bigserial)
is_suspended (boolean default FALSE)
privilege_suspension_start_date (date)
privelege_suspension_end_date (date)
UNIQUE CONSTRAINT (community_id,member_id, privilege_id)
post_type
Records the type of post, question/answer/blog etc
name (text 100)
description (text)
post
I thought about splitting into a answers table and and questions_table but doing it in the same table lets comments have a post_id instead of a questions_id and a answers_id. Meta posts are denoted by the is_meta column. Type of post is determined by the post_type_id
member_id (bigserial)
community_id (bigserial)
title (text 255 default NULL)
body (text)
upvotes (bigint)
downvotes (bigint)
net_votes (bigint)
score (decimal)
is_accepted (boolean default FALSE)
post_type_id (bigserial)
is_closed (boolean default FALSE)
is_protected (boolean default FALSE)
parent_id (bigserial FK to post default NULL)
is_meta (boolean default FALSE)
is_deleted (boolean default FALSE)
UNIQUE CONSTRAINT (community_id, title)
comment
Table for the comments on posts, both questions and answers.
member_id (bigserial)
post_id (bigserial)
parent_comment_id (bigserial FK to comment default NULL)
body (text)
upvotes (bigint default 0)
downvotes (bigint) default 0)
net_votes (bigint) default 0
score (decimal default 0)
is_deleted (boolean Default FALSE)
deleted_at (date)
comment_votes
comment_id (bigserial)
member_id (bigserial)
vote_types_id (bigserial)
UNIQUE CONSTRAINT (comment_id, member_id)
tag
Table for all of the tags
community_id (bigserial)
name (text 100)
description (text)
tag_wiki (text default NULL)
is_active (boolean default TRUE)
tag_synonym_id (bigserial FK to tag default NULL)
usages (bigint)
UNIQUE CONSTRAINT (community_id, name)
post_tag
post_id (bigserial)
tag_id (bigserial)
UNIQUE CONSTRAINT (post_id, tag_id)
vote_type
Table for the vote types, upvote/downvote.
name (text) UNIQUE
post_vote
The reason for this table is so that votes by spammers/serial voters can be undone.
post_id (bigserial)
vote_type_id (bigserial)
member_id (bigserial)
UNIQUE CONSTRAINT (post_id, member_id)