Skip to content

Commit

Permalink
Merge pull request #6 from rushsteve1/main
Browse files Browse the repository at this point in the history
Break up the rcos.sql file
  • Loading branch information
Apexal authored Jan 17, 2021
2 parents 8a9414a + 33df874 commit d448b7f
Show file tree
Hide file tree
Showing 35 changed files with 724 additions and 621 deletions.
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,29 @@
## Overview

This repo holds the SQL for setting up the RCOS database, the database definition, views and triggers, and tools for importing RCOS data from external platforms like Submitty and Venue.
This repo holds the SQL for setting up the RCOS database, the database
definition, views and triggers, and tools for importing RCOS data from external
platforms like Submitty and Venue.

## Database
The RCOS database is a Postgres DB running on our own infrastructure. Access is restricted to coordinators and faculty advisors, but the schema and tools used are open-sourced here.
The RCOS database is a Postgres DB running on our own infrastructure. Access is
restricted to coordinators and faculty advisors, but the schema and tools used
are open-sourced here.

## API

This database is served by a Postgrest API at [TODO: put api url here] that allows access to some resources when unauthenticated for public access, and allows full access to all resources when authenticated. RCOS infrastructure cannot connect to the database directly but must interact through this API.
This database is served by a Postgrest API at [TODO: put api url here] that
allows access to some resources when unauthenticated for public access, and
allows full access to all resources when authenticated. RCOS infrastructure
cannot connect to the database directly but must interact through this API.

## Setup

1. Run `pre.sql` to create database and `api` schema
1. Run `rcos.sql` to create tables and types
1. Run `views.sql` to create views
1. Run `post.sql` to create the roles that Postgrest needs to use
TODO DbMate docs

## Postgrest Deployment

1. Copy and modify `postgrest.conf`
1. Run Postgrest with the .conf file
2. Run Postgrest with the .conf file

TODO docker-compose stuff
5 changes: 5 additions & 0 deletions db/migrations/20210117171055_setup.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- migrate:up

SET TIMEZONE='America/New_york';

-- migrate:down
68 changes: 68 additions & 0 deletions db/migrations/20210117171712_create_types.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
-- migrate:up

CREATE TYPE user_role AS ENUM (
'student',
'faculty',
'faculty_advisor',
'alumn',
'external',
'external_mentor'
);

COMMENT ON TYPE user_role IS 'The user''s position within RCOS';

CREATE TYPE user_account AS ENUM (
'rpi',
'discord',
'mattermost',
'github',
'gitlab',
'bitbucket'
);

COMMENT ON TYPE user_account IS 'The website this account is for';

CREATE TYPE meeting_type AS ENUM (
'large_group',
'small_group',
'presentations',
'bonus_session',
'grading',
'mentors',
'coordinators',
'other'
);

COMMENT ON TYPE meeting_type IS 'The kind of RCOS meeting this was';

CREATE TYPE chat_association_source AS ENUM (
'project',
'small_group'
);

COMMENT ON TYPE chat_association_source IS 'The kind of group this chat is for';

CREATE TYPE chat_association_target AS ENUM (
'discord_server',
'discord_text_channel',
'discord_voice_channel',
'discord_category',
'discord_role'
);

COMMENT ON TYPE chat_association_target IS 'The kind of chat that this refers to';

-- https://www.cybertec-postgresql.com/en/postgresql-useful-new-data-types/
CREATE DOMAIN url AS TEXT
CHECK (VALUE ~ 'https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#()?&//=]*)');

COMMENT ON DOMAIN url IS 'Type that match URLs (http or https)';

-- migrate:down

DROP TYPE user_role;
DROP TYPE user_account;
DROP TYPE meeting_type;
DROP TYPE chat_association_source;
DROP TYPE chat_association_target;
DROP DOMAIN url;
24 changes: 24 additions & 0 deletions db/migrations/20210117172640_create_semesters_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-- migrate:up

CREATE TABLE semesters (
-- Semester ID must be 6 numbers.
-- This assumes all semesters are after the year 999 and before 10,000
semester_id VARCHAR(6) PRIMARY KEY CHECK(semester_id ~ '^\d{6}$'),
title VARCHAR NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL CHECK (end_date > start_date)
);

CREATE INDEX ON semesters (start_date, end_date);

COMMENT ON TABLE semesters IS 'Dates are from official academic calendar:
https://info.rpi.edu/registrar/academic-calendar
A school year has 3 semesters, Spring, Summer, and Fall. Semester IDs are
4-digit starting year + 2-digit start month, e.g. 202009';
COMMENT ON COLUMN semesters.title IS 'Typically season and year, e.g. Fall 2020';
COMMENT ON COLUMN semesters.start_date IS 'Date that classes start';
COMMENT ON COLUMN semesters.end_date IS 'Date that semester ends';

-- migrate:down

DROP TABLE semesters;
19 changes: 19 additions & 0 deletions db/migrations/20210117180501_create_announcements_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-- migrate:up

CREATE TABLE announcements (
announcement_id SERIAL PRIMARY KEY,
semester_id varchar NOT NULL REFERENCES semesters(semester_id),
title varchar NOT NULL,
body_markdown text NOT NULL,
close_date_time TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

COMMENT ON TABLE announcements IS 'Various announcements made by RCOS';
COMMENT ON COLUMN announcements.title IS 'Short title of announcement';
COMMENT ON COLUMN announcements.body_markdown IS 'Markdown-supported announcement content';
COMMENT ON COLUMN announcements.close_date_time IS 'Date and time the announcement ends';

-- migrate:down

DROP TABLE announcements;
25 changes: 25 additions & 0 deletions db/migrations/20210117180543_create_users_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- migrate:up

CREATE TABLE users (
username VARCHAR PRIMARY KEY,
preferred_name VARCHAR,
first_name VARCHAR NOT NULL,
last_name VARCHAR NOT NULL,
cohort INT,
role user_role NOT NULL,
timezone text NOT NULL DEFAULT 'America/New_York',
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

COMMENT ON TABLE users IS 'Users can be students, external mentors, and faculty.
Their user details are not dependent on the semester';
COMMENT ON COLUMN users.preferred_name IS 'Optional preferred first name to use in UIs';
COMMENT ON COLUMN users.first_name IS 'Given name of user';
COMMENT ON COLUMN users.last_name IS 'Family name of user';
COMMENT ON COLUMN users.cohort IS 'Entry year (only set for students)';
COMMENT ON COLUMN users.role IS 'Role of user in RCOS, determines permissions';
COMMENT ON COLUMN users.timezone IS 'Timezone from TZ list';

-- migrate:down

DROP TABLE users;
18 changes: 18 additions & 0 deletions db/migrations/20210117180819_create_user_accounts_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-- migrate:up

CREATE TABLE user_accounts (
username VARCHAR REFERENCES users (username),
type user_account,
account_id VARCHAR NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),

PRIMARY KEY (username, type)
);

COMMENT ON TABLE user_accounts IS 'User accounts such as Discord, GitHub, GitLab, etc.';
COMMENT ON COLUMN user_accounts.type IS 'Type of external account that is connected';
COMMENT ON COLUMN user_accounts.account_id IS 'Unique ID/username of account';

-- migrate:down

DROP TABLE user_accounts;
25 changes: 25 additions & 0 deletions db/migrations/20210117182303_create_projects_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- migrate:up

CREATE TABLE projects (
project_id SERIAL PRIMARY KEY,
title VARCHAR UNIQUE NOT NULL,
description TEXT NOT NULL,
languages VARCHAR[] NOT NULL DEFAULT '{}',
stack VARCHAR[] NOT NULL DEFAULT '{}',
cover_image_url url,
homepage_url url,
repository_urls url[] NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- TODO indexes for searching

COMMENT ON TABLE projects IS 'Project details are not semester dependent';
COMMENT ON COLUMN projects.languages IS 'List of languages used, all lowercase';
COMMENT ON COLUMN projects.stack IS 'List of technologies used';
COMMENT ON COLUMN projects.cover_image_url IS 'URL to logo image';
COMMENT ON COLUMN projects.homepage_url IS 'Optional link to project homepage';

-- migrate:down

DROP TABLE projects;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- migrate:up

CREATE TABLE project_presentations (
project_id INT NOT NULL REFERENCES projects (project_id),
semester_id VARCHAR NOT NULL REFERENCES semesters (semester_id),
presentation_url url NOT NULL,
is_draft boolean NOT NULL DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),

PRIMARY KEY (project_id, semester_id)
);

COMMENT ON TABLE project_presentations IS 'Presentations given by RCOS projects';

-- migrate:down

DROP TABLE project_presentations;
32 changes: 32 additions & 0 deletions db/migrations/20210117183105_create_enrollments_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
-- migrate:up

CREATE TABLE enrollments (
semester_id VARCHAR REFERENCES semesters (semester_id),
username VARCHAR REFERENCES users (username),
project_id INT REFERENCES projects (project_id),
is_project_lead BOOLEAN DEFAULT false,
is_coordinator BOOLEAN DEFAULT false,
credits INT NOT NULL DEFAULT 0,
is_for_pay BOOLEAN DEFAULT false,
mid_year_grade REAL CHECK (mid_year_grade >= 0.0),
final_grade REAL CHECK (final_grade >= 0.0),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),

PRIMARY KEY (semester_id, username)
);

CREATE INDEX ON enrollments (project_id);
CREATE INDEX ON enrollments (credits) WHERE credits > 0;

COMMENT ON TABLE enrollments IS 'An enrollment of a user in RCOS for a specific
semester. They might or might not be on a project and might or might not be
taking RCOS for credit.';
COMMENT ON COLUMN enrollments.is_project_lead IS 'Allows multiple project leads';
COMMENT ON COLUMN enrollments.credits IS '0-4 where 0 means just for experience';
COMMENT ON COLUMN enrollments.is_for_pay IS 'True if taking RCOS for pay';
COMMENT ON COLUMN enrollments.mid_year_grade IS '0.0-100.0';
COMMENT ON COLUMN enrollments.final_grade IS '0.0-100.0';

-- migrate:down

DROP TABLE enrollments;
33 changes: 33 additions & 0 deletions db/migrations/20210117183106_create_mentor_proposals_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- migrate:up

CREATE TABLE mentor_proposals (
semester_id VARCHAR,
username VARCHAR,
reason TEXT NOT NULL,
skillset TEXT NOT NULL,
reviewer_username VARCHAR,
reviewer_comments TEXT,
is_approved boolean DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),

PRIMARY KEY (semester_id, username),

FOREIGN KEY (semester_id, username) REFERENCES enrollments (semester_id, username),
FOREIGN KEY (semester_id, reviewer_username) REFERENCES enrollments (semester_id, username)
);

COMMENT ON TABLE mentor_proposals IS 'Users Interested in mentoring each
semester must submit a proposal and be approved';
COMMENT ON COLUMN mentor_proposals.username IS 'Username of mentor to-be';
COMMENT ON COLUMN mentor_proposals.reason IS 'The reason the user would like to mentor';
COMMENT ON COLUMN mentor_proposals.skillset IS 'Short details of technologies
user can mentor for';
COMMENT ON COLUMN mentor_proposals.reviewer_username IS 'Username of
coordinator/faculty who reviewed proposal';
COMMENT ON COLUMN mentor_proposals.reviewer_comments IS 'Optional comments left by reviewer';
COMMENT ON COLUMN mentor_proposals.is_approved IS 'True if user was approved to
become a mentor for the semester';

-- migrate:down

DROP TABLE mentor_proposals;
39 changes: 39 additions & 0 deletions db/migrations/20210117183107_create_workshop_proposals_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
-- migrate:up

CREATE TABLE workshop_proposals (
workshop_proposal_id SERIAL PRIMARY KEY,
semester_id VARCHAR NOT NULL REFERENCES semesters (semester_id),
username VARCHAR NOT NULL REFERENCES users (username),
topic VARCHAR NOT NULL,
title VARCHAR NOT NULL,
qualifications VARCHAR NOT NULL,
first_choice_at TIMESTAMPTZ NOT NULL CHECK (first_choice_at > now()),
second_choice_at TIMESTAMPTZ NOT NULL CHECK (second_choice_at > now()),
third_choice_at TIMESTAMPTZ NOT NULL CHECK (third_choice_at > now()),
reviewer_username VARCHAR REFERENCES users (username),
reviewer_comments TEXT,
is_approved BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),

FOREIGN KEY (semester_id, username) REFERENCES enrollments (semester_id, username),
FOREIGN KEY (semester_id, reviewer_username) REFERENCES enrollments (semester_id, username)
);

CREATE INDEX ON workshop_proposals (semester_id);
CREATE INDEX ON workshop_proposals (username);

COMMENT ON TABLE workshop_proposals IS 'Users (typically mentors) must submit a
proposal to host a workshop and be approved';
COMMENT ON COLUMN workshop_proposals.first_choice_at IS 'First choice for date
and time to host workshop';
COMMENT ON COLUMN workshop_proposals.second_choice_at IS 'Second choice for date
and time to host workshop';
COMMENT ON COLUMN workshop_proposals.third_choice_at IS 'Third choice for date
and time to host workshop';
COMMENT ON COLUMN workshop_proposals.reviewer_username IS 'Username of
coordinator/faculty who reviewed proposal';
COMMENT ON COLUMN workshop_proposals.reviewer_comments IS 'Optional comments left by reviewer';

-- migrate:down

DROP TABLE workshop_proposals;
21 changes: 21 additions & 0 deletions db/migrations/20210117183108_create_pay_requests_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- migrate:up

CREATE TABLE pay_requests (
semester_id VARCHAR NOT NULL,
username VARCHAR NOT NULL,
reason TEXT NOT NULL,
is_approved BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),

PRIMARY KEY (semester_id, username),

FOREIGN KEY (semester_id, username) REFERENCES enrollments (semester_id, username)
);

COMMENT ON TABLE pay_requests IS 'Users can request to take RCOS for pay INSTEAD
of credit and must be approved';
COMMENT ON COLUMN pay_requests.reason IS 'The justification for being paid';

-- migrate:down

DROP TABLE pay_requests;
Loading

0 comments on commit d448b7f

Please sign in to comment.