Skip to content

Latest commit

 

History

History
446 lines (320 loc) · 13.1 KB

File metadata and controls

446 lines (320 loc) · 13.1 KB

Technical Documentation

This document explains the architecture, integrations, and operational details of the Collaborado course discussion platform so developers can work productively and deploy safely.


Table of Contents


Getting Started

Cloning the Repository

# Clone via HTTPS
git clone https://github.com/tamu-edu-students/606-project3-group5.git

# Or clone via SSH
git clone git@github.com:tamu-edu-students/606-project3-group5.git

# Navigate into the project directory
cd 606-project3-group5

Initial Setup

# Install Ruby dependencies
bundle install

# Set up the database
bundle exec rails db:create db:migrate

# (Optional) Seed the database with sample data
bundle exec rails db:seed

Running the Application

# Start the development server
bin/dev

# Or start Rails server directly
bundle exec rails server

The application will be available at http://localhost:3000.

📖 For step-by-step local setup instructions, see LOCAL_SETUP.md.


Stack and Architecture

Component Technology
Framework Ruby on Rails 8 (MVC architecture)
Ruby See .ruby-version or Gemfile constraints
Database SQLite (development/test), PostgreSQL (production via DATABASE_URL)
Authentication Google OAuth2 via OmniAuth, domain-restricted to @tamu.edu
Assets ERB templates, SCSS compiled with dartsass-rails, Importmaps for JavaScript
Testing RSpec (unit/integration), Cucumber (BDD), SimpleCov (coverage)

MVC Components

Layer Components
Models User, Course, CourseEnrollment, Channel, Post, Comment, PostUpvote, CommentUpvote
Controllers CoursesController, ChannelsController, PostsController, ProfilesController, SessionsController, DashboardController
Views ERB templates under app/views/

Domain Model Overview

User

Field Description
first_name, last_name User's name (required)
email Google-sourced email (unique, required)
google_uid, provider OAuth identifiers
role student, ta, or professor

NetID: Extracted from email (email.split("@").first)

Associations:

  • has_many :course_enrollments — courses joined
  • has_many :courses_created — courses they created
  • has_many :posts, has_many :comments
  • has_many :post_upvotes, has_many :comment_upvotes

Key Method: User.from_google(auth_hash) — creates/finds user from OAuth


Course

Field Description
name Course name (required)
department Must be valid TAMU department code
course_code Course number (required)
instructor Instructor name
description Course description

Associations:

  • belongs_to :creator — User who created it
  • has_many :course_enrollments, has_many :users
  • has_many :channels

Notes:

  • Auto-creates a default "General" channel on creation
  • Provides DEPARTMENTS constant (hash of department codes to names)
  • departments class method returns sorted department codes

CourseEnrollment

Links users to courses (join table with role tracking).

Field Description
user_id Reference to user
course_id Reference to course
role User's role in the course

Students enroll via the "Join" button; professors/TAs don't need to join.


Channel

Field Description
name Channel name
description Channel description
course_id Parent course reference

Associations:

  • belongs_to :course
  • has_many :posts

Groups discussions within a course (e.g., "Homework", "Lectures", "Projects").


Post

Field Description
title Post title (max 255 chars)
content Post body (required)
type question or note
resolved Boolean for questions
upvote_count Number of upvotes
channel_id, user_id References

Associations:

  • belongs_to :channel, belongs_to :user
  • has_many :comments, has_many :post_upvotes

⚠️ Important: self.inheritance_column = :_type_disabled disables Rails STI since we use type column.

Scopes: questions, notes, resolved, unresolved, newest_first, oldest_first, most_upvoted

Methods: question?, note?, upvoted_by?(user)


Comment

Field Description
content Comment text
post_id, user_id References
upvote_count Number of upvotes

Associations:

  • belongs_to :post, belongs_to :user
  • has_many :comment_upvotes

PostUpvote / CommentUpvote

Join tables tracking upvotes.

Field Description
user_id User who upvoted
post_id / comment_id Target reference

One row per upvote; destroying row removes upvote.


API Documentation / Routing

Authentication Routes

Method Path Controller#Action Description
GET /auth/:provider/callback SessionsController#create OAuth callback
GET /auth/failure SessionsController#failure OAuth error
GET /logout SessionsController#destroy Logout
DELETE /logout SessionsController#destroy Logout

Dashboard & Profile

Method Path Controller#Action Description
GET / HomeController#index Landing page
GET /dashboard DashboardController#index User dashboard
GET /role ProfilesController#select_role Role selection
PATCH /role ProfilesController#update Set user role
GET /profile/edit ProfilesController#edit Edit profile
PATCH /profile ProfilesController#update Update profile

Courses API

Method Path Controller#Action Description
GET /courses CoursesController#index List/search/filter
POST /courses CoursesController#create Create course
GET /courses/new CoursesController#new New course form
GET /courses/:id CoursesController#show Show course
GET /courses/:id/edit CoursesController#edit Edit course form
PATCH /courses/:id CoursesController#update Update course
DELETE /courses/:id CoursesController#destroy Delete course
POST /courses/:id/join CoursesController#join Enroll student
DELETE /courses/:id/leave CoursesController#leave Unenroll

Query Parameters for Index:

Parameter Description
department Filter by department code (e.g., CSCE)
search Search by name, course_code, or instructor (case-insensitive)

Authorization:

  • new/create/edit/update/destroy: professor only (require_professor)
  • join: students only
  • leave: any enrolled user

Channels API (nested under courses)

Method Path Controller#Action
GET /courses/:course_id/channels ChannelsController#index
POST /courses/:course_id/channels ChannelsController#create
GET /courses/:course_id/channels/new ChannelsController#new
GET /courses/:course_id/channels/:id ChannelsController#show
GET /courses/:course_id/channels/:id/edit ChannelsController#edit
PATCH /courses/:course_id/channels/:id ChannelsController#update
DELETE /courses/:course_id/channels/:id ChannelsController#destroy

Query Parameters for Show:

Parameter Values Description
type question, note, all Filter posts by type
status resolved, unresolved, all Filter by resolution
sort newest, oldest, most_upvoted Sort posts
page Integer Pagination (10 per page via Kaminari)

Authorization: Create/edit/destroy typically restricted to instructors/admins.


Posts API

Method Path Controller#Action
GET /channels/:channel_id/posts/new PostsController#new
POST /channels/:channel_id/posts PostsController#create
GET /posts/:id/edit PostsController#edit
PATCH /posts/:id PostsController#update
DELETE /posts/:id PostsController#destroy
POST /posts/:id/upvote PostsController#upvote
DELETE /posts/:id/upvote PostsController#remove_upvote

Create Parameters: post[title], post[content], post[type] (question/note), post[resolved] (optional)

Authorization:

  • Edit/update: post owner or admin
  • Delete: post owner or admin
  • Upvote/remove_upvote: any authenticated user

Comments API

Method Path Controller#Action
POST /posts/:post_id/comments CommentsController#create
DELETE /comments/:id CommentsController#destroy
POST /comments/:id/upvote CommentsController#upvote
DELETE /comments/:id/upvote CommentsController#remove_upvote

Authentication and Authorization

Google OAuth Flow

1. User clicks "Sign in with Google"
        ↓
2. Redirects to Google OAuth consent screen (restricted to @tamu.edu)
        ↓
3. Google redirects back to /auth/google_oauth2/callback
        ↓
4. SessionsController#create calls User.from_google(auth_hash)
        ↓
5. User created/found, session established
        ↓
6. Redirected to role selection (if first time) or dashboard

Configuration: config/initializers/omniauth.rb

  • hd: "tamu.edu" — enforces domain restriction
  • provider_ignores_state: true — for callback compatibility
  • Test mode enabled in test environment

Roles and Permissions

Role Permissions
Students Join courses, view enrolled course channels, create posts/comments, upvote
TAs Similar to students but can manage channels (auto-access)
Professors Can create/edit/delete courses and channels, manage all content

Authorization Helpers:

  • require_login — ensures user is authenticated
  • require_professor — restricts to professor role
  • can_edit_post? — checks post edit permissions
  • can_delete_post? — checks post delete permissions

Environments and Configuration

Development

Setting Value
Database SQLite (storage/development.sqlite3)
SCSS bin/rails dartsass:watch

Environment Variables (via .env file):

  • GOOGLE_CLIENT_ID
  • GOOGLE_CLIENT_SECRET

Test

Setting Value
Database SQLite (storage/test.sqlite3)
OmniAuth Test mode enabled

url: null in database.yml prevents DATABASE_URL override.


Production

Setting Value
Database PostgreSQL via DATABASE_URL (Heroku add-on)
Connection Roles primary, cable, queue, cache (all use same URL)

Required Config Vars:

  • DATABASE_URL — auto-set by Heroku Postgres addon
  • GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET
  • RAILS_MASTER_KEY — for encrypted credentials

Known Validations and Constraints

Model Constraint
User Email must be unique and end with @tamu.edu
Course Department must be valid TAMU department code; course_code must be numeric
Post Type must be question or note; STI disabled via inheritance_column = :_type_disabled
Upvotes One upvote per user per post/comment (enforced by unique index on join tables)
Enrollment Students must join courses to access channels; professors/TAs have automatic access

Deployment Notes (Heroku)

Prerequisites

  • Heroku account and CLI installed
  • Git repository pushed to remote

Setup

heroku create your-app-name
heroku addons:create heroku-postgresql:essential-0
heroku config:set GOOGLE_CLIENT_ID=your_client_id
heroku config:set GOOGLE_CLIENT_SECRET=your_client_secret
heroku config:set RAILS_MASTER_KEY=$(cat config/master.key)

Deploy

git push heroku main
heroku run rails db:migrate
heroku run rails db:seed  # optional

Troubleshooting

Issue Solution
OAuth redirect errors Ensure production callback URL is added to Google Cloud Console
Asset issues Precompile assets locally: RAILS_ENV=production rails assets:precompile