Skip to content

Routes & Views Reference

Complete reference for all routes in the School Clubs Management System.

Overview

The application has two main blueprints:

  • auth: Authentication routes (/login_modal, /logout, /sign_up)
  • main: Application routes (clubs, posts, memberships, etc.)

Authentication Routes

All routes in auth.py.

POST /login_modal

Process login form submission.

Authentication: No

Form Data:

Field Type Required Description
email String Yes User email
password String Yes Plain text password

Response:

  • Success: Redirect to / (landing page)
  • Failure: 204 No Content with Turbo error update

Example:

# From form submission
POST /login_modal
email=student@example.com
password=mypassword

Validation:

  1. User exists with given email
  2. Password hash matches

Error Messages:

  • "No account found with this email"
  • "Incorrect password"

GET /logout

Log out current user.

Authentication: Required

Response:

  • Redirect to / (landing page)

Example:

# User clicks logout button
GET /logout

# Session cleared, redirected to landing

POST /sign_up

Register new user account.

Authentication: No

Form Data:

Field Type Required Description
first_name String Yes First name
last_name String Yes Last name
email String Yes Email (must be unique)
password String Yes Password (min 8 chars)

Response:

  • Success: Redirect to / (landing page)
  • Failure: 204 No Content with Turbo error update

Validation:

  • All fields required
  • Email must be unique
  • Password minimum 8 characters

Error Messages:

  • "Please fill in all fields"
  • "Email already registered"
  • "Password must be at least 8 characters"

Example:

POST /sign_up
first_name=John
last_name=Doe
email=john.doe@example.com
password=securepass123

Main Routes

All routes in main.py.

GET /

Landing page.

Authentication: No (but shows different content when authenticated)

Query Parameters: None

Response: Rendered landing.html template

Template Context:

Variable Type Description
posts List[Post] Posts from followed clubs (if authenticated)
is_member Function Check if user is club member
is_president Function Check if user is club president
is_admin Function Check if user is admin
from_admin Boolean If coming from admin panel

Logic:

  1. Check if user authenticated
  2. Get IDs of followed clubs
  3. Query pinned posts from followed clubs
  4. Query regular posts from followed clubs
  5. Combine: pinned first, then regular
  6. Render template

Example:

# Anonymous user
GET /
# Shows general landing page

# Authenticated user
GET /
# Shows posts from clubs they follow

GET /browse

Browse clubs or events.

Authentication: Required

Query Parameters:

Parameter Values Default Description
type clubs, events clubs What to browse

Response: Rendered browse.html template

Template Context:

Variable Type Description
items List Clubs or Events
browse_type String 'clubs' or 'events'
is_member Function Member check function
is_president Function President check function
is_admin Function Admin check function

Examples:

# Browse clubs
GET /browse?type=clubs
# Returns all clubs

# Browse events
GET /browse?type=events
# Returns all upcoming events

GET /club/\<int:club_id>

Club detail page.

Authentication: Required

URL Parameters:

Parameter Type Description
club_id Integer Club identifier

Response: Rendered club-detail.html template or 404

Template Context:

Variable Type Description
club Club Club object
members_count Integer Number of members
posts List[Post] Recent posts
president User Club president (if any)
pending_count Integer Pending applications (presidents only)
user_application Application User's application (if exists)
is_member Function Member check function
is_president Function President check function
is_admin Function Admin check function

Logic:

  1. Get club or return 404
  2. Count members
  3. Get recent posts
  4. Find president
  5. Count pending applications (if president/admin)
  6. Get user's application status
  7. Render template

Example:

GET /club/1
# Returns Chess Club detail page

GET/POST /post/create

Create new post.

Authentication: Required

Methods:

  • GET: Show creation form
  • POST: Process form submission

Form Data (POST):

Field Type Required Description
title String Yes Post title
content String Yes Post content
post_type String Yes 'post', 'event', or 'galerie'
club_id Integer Yes Target club
is_pinned Checkbox No Pin to top (presidents only)
event_date DateTime Conditional Required for events
location String Conditional Required for events
gallery_files Files Conditional Required for gallery

Authorization:

Must be member, president, or admin of the target club.

Response:

  • GET: Rendered modify_post.html with empty form
  • POST Success: Redirect to club detail page
  • POST Failure: Flash error and redirect

Template Context (GET):

Variable Type Description
clubs List[Club] Clubs user can post to
preselected_club_id Integer Pre-selected club (from query param)
post None Empty for create
is_member Function Member check function
is_president Function President check function
is_admin Function Admin check function

Example:

# Show create form
GET /post/create?club_id=1

# Submit post
POST /post/create
title=Welcome Message
content=Welcome to our club!
post_type=post
club_id=1
is_pinned=on

GET/POST /post/\<int:post_id>/edit

Edit existing post.

Authentication: Required

URL Parameters:

Parameter Type Description
post_id Integer Post identifier

Methods:

  • GET: Show edit form
  • POST: Process updates

Form Data (POST):

Same as /post/create

Authorization:

Must be post creator, club president, or admin.

Response:

  • GET: Rendered modify_post.html with post data
  • POST Success: Redirect to club posts page
  • POST Failure: Flash error and redirect

Template Context (GET):

Variable Type Description
post Post Post being edited
clubs List[Club] Clubs user can post to
is_member Function Member check function
is_president Function President check function
is_admin Function Admin check function

Example:

# Show edit form
GET /post/5/edit

# Update post
POST /post/5/edit
title=Updated Title
content=Updated content
post_type=post
club_id=1

POST /post/\<int:post_id>/delete

Delete post.

Authentication: Required

URL Parameters:

Parameter Type Description
post_id Integer Post identifier

Authorization:

Must be post creator or admin.

Response:

  • Success: Flash success message and redirect to referrer or landing
  • Failure: Flash error and redirect

Example:

POST /post/5/delete
# Deletes post 5 if authorized

POST /remove/\<int:club_id>/\<int:user_id>

Remove member from club.

Authentication: Required

URL Parameters:

Parameter Type Description
club_id Integer Club identifier
user_id Integer User to remove

Authorization:

Must be club president or admin.

Restrictions:

  • Cannot remove yourself
  • Cannot remove the president

Response:

  • Flash message and redirect to club detail

Error Messages:

  • "Only presidents can remove members."
  • "You cannot remove yourself."
  • "Cannot remove the president."
  • "Member not found."

Example:

POST /remove/1/5
# Remove user 5 from club 1

POST /promote/\<int:club_id>/\<int:user_id>

Promote member to president.

Authentication: Required

URL Parameters:

Parameter Type Description
club_id Integer Club identifier
user_id Integer User to promote

Authorization:

Must be current president or admin.

Logic:

  1. Demote current president to regular member
  2. Promote target member to president
  3. Commit changes

Response:

  • Flash message and redirect to club detail

Example:

POST /promote/1/5
# Make user 5 president of club 1

GET /club/\<int:club_id>/posts

View all posts for a club.

Authentication: Required

URL Parameters:

Parameter Type Description
club_id Integer Club identifier

Response: Rendered posts.html template

Template Context:

Variable Type Description
club Club Club object
posts List[Post] All posts for club
is_member Function Member check function
is_president Function President check function
is_admin Function Admin check function

Example:

GET /club/1/posts
# Shows all posts for club 1

GET /club/\<int:club_id>/\<int:post_id>

View single post.

Authentication: Required

URL Parameters:

Parameter Type Description
club_id Integer Club identifier
post_id Integer Post identifier

Response: Rendered posts.html template with single post

Example:

GET /club/1/5
# Shows post 5 from club 1

POST /clubs/\<int:club_id>/follow

Follow a club.

Authentication: Required

URL Parameters:

Parameter Type Description
club_id Integer Club identifier

Logic:

  1. Get club or 404
  2. Check if already following
  3. Add to followed clubs
  4. Commit

Response:

  • Flash message and redirect to club detail

Error Messages:

  • "You are already following this club."

Example:

POST /clubs/1/follow
# Start following club 1

POST /clubs/\<int:club_id>/unfollow

Unfollow a club.

Authentication: Required

URL Parameters:

Parameter Type Description
club_id Integer Club identifier

Logic:

  1. Get club or 404
  2. Check if following
  3. Remove from followed clubs
  4. Commit

Response:

  • Flash message and redirect to club detail

Error Messages:

  • "You are not following this club."

Example:

POST /clubs/1/unfollow
# Stop following club 1

POST /clubs/\<int:club_id>/join

Apply for club membership.

Authentication: Required

URL Parameters:

Parameter Type Description
club_id Integer Club identifier

Logic:

  1. Check if already a member
  2. Check if pending application exists
  3. Create application with status='pending'
  4. Commit

Response:

  • Flash message and redirect to club detail

Error Messages:

  • "You are already a member of this club."
  • "You already have a pending application."

Success Message:

  • "Your application has been submitted!"

Example:

POST /clubs/1/join
# Apply to join club 1

GET /clubs/\<int:club_id>/applications

View pending applications for a club.

Authentication: Required

URL Parameters:

Parameter Type Description
club_id Integer Club identifier

Authorization:

Must be club president or admin.

Response: Rendered club_applications.html template

Template Context:

Variable Type Description
club Club Club object
pending_applications List[Application] Pending applications
is_president Function President check function
is_admin Function Admin check function

Example:

GET /clubs/1/applications
# View pending applications for club 1

POST /clubs/\<int:club_id>/applications/\<int:student_id>/accept

Accept membership application.

Authentication: Required

URL Parameters:

Parameter Type Description
club_id Integer Club identifier
student_id Integer Applicant user ID

Authorization:

Must be club president or admin.

Logic:

  1. Find application or 404
  2. Update status to 'accepted'
  3. Create membership record
  4. If no president exists, make this member president
  5. Commit

Response:

  • Flash success message and redirect to applications page

Example:

POST /clubs/1/applications/5/accept
# Accept user 5's application to club 1

POST /clubs/\<int:club_id>/applications/\<int:student_id>/deny

Deny membership application.

Authentication: Required

URL Parameters:

Parameter Type Description
club_id Integer Club identifier
student_id Integer Applicant user ID

Authorization:

Must be club president or admin.

Logic:

  1. Find application or 404
  2. Update status to 'denied'
  3. Commit

Response:

  • Flash message and redirect to applications page

Example:

POST /clubs/1/applications/5/deny
# Deny user 5's application to club 1

Utility Functions

is_member(current_user, club_id)

Check if user is a member of a club.

Parameters:

  • current_user: Flask-Login current_user proxy
  • club_id: Integer club identifier

Returns: True if user is member, president, or admin

Logic:

def is_member(current_user, club_id):
    if current_user.user_type == "admin":
        return True
    return Membership.query.filter_by(
        student_id=current_user.user_id, 
        club_id=club_id
    ).first() is not None

is_president(current_user, club_id)

Check if user is president of a club.

Parameters:

  • current_user: Flask-Login current_user proxy
  • club_id: Integer club identifier

Returns: True if user is president or admin

Logic:

def is_president(current_user, club_id):
    if current_user.user_type == "admin":
        return True
    membership = Membership.query.filter_by(
        student_id=current_user.user_id, 
        club_id=club_id
    ).first()
    return membership and membership.is_president

is_admin(current_user)

Check if user is an administrator.

Parameters:

  • current_user: Flask-Login current_user proxy

Returns: True if user is admin

Logic:

def is_admin(current_user):
    return current_user.user_type == "admin"

Route Summary Table

Route Method Auth Purpose
/login_modal POST No Process login
/logout GET Yes Log out
/sign_up POST No Register account
/ GET No* Landing page
/browse GET Yes Browse clubs/events
/club/<id> GET Yes Club detail
/club/<id>/posts GET Yes All club posts
/club/<id>/<post_id> GET Yes Single post
/post/create GET/POST Yes Create post
/post/<id>/edit GET/POST Yes Edit post
/post/<id>/delete POST Yes Delete post
/clubs/<id>/follow POST Yes Follow club
/clubs/<id>/unfollow POST Yes Unfollow club
/clubs/<id>/join POST Yes Apply to join
/clubs/<id>/applications GET Yes View applications
/clubs/<id>/applications/<uid>/accept POST Yes Accept application
/clubs/<id>/applications/<uid>/deny POST Yes Deny application
/remove/<cid>/<uid> POST Yes Remove member
/promote/<cid>/<uid> POST Yes Promote president

* Landing page accessible without auth but shows different content.


HTTP Status Codes

Code Meaning Usage
200 OK Successful GET requests
204 No Content Turbo updates without redirect
302 Found Redirects after POST
403 Forbidden Unauthorized access
404 Not Found Resource doesn't exist
500 Server Error Unhandled exceptions

Flash Message Categories

Category Bootstrap Class Usage
success alert-success Successful operations
danger alert-danger Errors and failures
warning alert-warning Warnings and cautions
info alert-info Informational messages

Example:

flash("Post created successfully!", "success")
flash("You don't have permission.", "danger")
flash("This action cannot be undone.", "warning")
flash("Application pending review.", "info")

Next Steps