Lab 3 – MarieDB/React Mini Message board

GitHub Classroom link

You must write all code for this assignment yourself; AI may be used only to explain concepts, suggest debugging strategies, or help you understand errors—not to generate solution code.

Use of AI on This Assignment (Read Carefully)

For this lab, you must write the code yourself.

This assignment is designed to assess your ability to:

  • design a database-backed web application,
  • implement authentication and authorization,
  • connect frontend and backend logic, and
  • debug real systems.

If AI writes the code for you, you are skipping the learning goal.

That said, AI is allowed in a limited, specific way.


✅ Allowed uses of AI (encouraged)

You may use AI as a tutor, not as a coder. Examples:

  • Conceptual explanations
    • “Explain how cookie-based sessions work in Express.”
    • “What is bcrypt doing when hashing a password?”
    • “Why do we store sessions server-side instead of in the browser?”
  • Understanding existing code
    • “Explain what this middleware function is doing line by line.”
    • “Why does this SQL query fail when ONLY_FULL_GROUP_BY is enabled?”
  • Debugging help
    • “I’m getting ERR_HTTP_HEADERS_SENT. What does that usually mean?”
    • “Why might my React component re-render infinitely?”
    • “This MariaDB foreign key constraint is failing—what are common causes?”
  • Design advice
    • “What tables do I need to support threads and posts?”
    • “What fields should be indexed for this query?”
    • “What API routes make sense for a threaded messageboard?”
  • Small, isolated syntax questions
    • “How do I read a cookie in Express?”
    • “What does credentials: 'include' do in fetch?”

These uses help you think, not copy.


❌ Not allowed uses of AI

You may not use AI to generate substantial parts of your solution. Examples:

  • ❌ “Write the Express routes for login and registration.”
  • ❌ “Generate the React components for the thread list and thread view.”
  • ❌ “Create the SQL schema for users, sessions, threads, and posts.”
  • ❌ “Write the authentication middleware.”
  • ❌ Copy-pasting AI-generated code and making small edits.

If your submission looks like it was produced by an AI system, you will be asked to explain it. If you cannot, it will be treated as unauthorized assistance.


A good rule of thumb

Ask yourself:

“Could I explain every line of this code, out loud, on a whiteboard?”

If the answer is no, you should not submit it.


What we will do if something looks off

  • We may ask you to:
    • explain a function,
    • modify a piece of your code in real time,
    • or answer questions about design decisions you made.

This is not a “gotcha.”
It’s how we distinguish learning from outsourcing.


Bottom line

  • You write the code.
  • AI can help you understand, debug, and think.
  • AI must not do the work for you.

Used correctly, AI will make you a better developer, not a faster copy-and-paste machine.

0) What you start with (given)

You already have a working v1 demo:

  • Backend
    • GET /api/health
    • GET /api/posts (public)
    • POST /api/posts (public)
  • Frontend
    • shows posts
    • allows anyone to post

There is no users, no login, no authorization, no threads.


1) What you will build

After your changes:

Required features

  1. Register
    • User provides: name, email, password
    • No email verification. Trust the user input.
  2. Login / Logout
    • Login creates a cookie-based session
    • Logout clears the session
  3. Threads
    • When logged in, the user sees a list of threads
    • They can:
      • click a thread to view it + its posts
      • post a reply to that thread
      • create a new thread
  4. Authorization
    • Only logged-in users can:
      • view the thread list
      • view a thread
      • create threads
      • create posts (replies)

Bonus (optional)

  • Search
    • Search threads by keyword (title + optional body/content)
    • Or search posts within a thread

2) Environment assumptions (must follow)

Same as the starter:

  • Linux username is your email prefix
    • jsmith@kenyon.edujsmith
  • MariaDB database name is db_username
  • Both linux and database password are Sxxxx, your student ID.
  • Express server port is 41xx where xx is last 2 digits of student ID

If you use the wrong DB name or port, your app won’t be graded correctly.

To create the VERSION 1 database table:
mysql -u username -p db_username < docs/schema_v1.sql

To log in look at you data base:
mysql -u username -p db_username

Set up server/.env

DB_HOST=localhost
DB_USER=username
DB_PASSWORD=Sxxxx (sudent id)
DB_NAME=db_username

PORT=4101
SESSION_SECRET=SomeRandomString

3) Database schema

Required tables

users

  • id (PK, auto increment)
  • name (varchar)
  • email (varchar, unique, required)
  • password_hash (varchar, required)
  • created_at

sessions

  • id (PK, random string OR auto id + separate token; your choice)
  • user_id (FK → users.id)
  • expires_at (datetime)
  • created_at

threads

  • id (PK)
  • title (varchar, required)
  • created_by (FK → users.id)
  • created_at
  • (recommended) last_post_at (datetime) for sorting

posts

  • id (PK)
  • thread_id (FK → threads.id)
  • user_id (FK → users.id)
  • content (text)
  • created_at

Notes (required behavior)

  • Deleting is not required.
  • You do not need “edit post”.
  • Passwords must not be stored in plain text.

4) Backend API contract (v2)

Create:

  • docs/API_CONTRACT_v2.md

Your backend must implement these routes exactly.

Auth

POST /api/auth/register

Creates a new user and starts a session.

Request JSON:

{ "name": "Alice", "email": "alice@kenyon.edu", "password": "secret123" }

Response JSON (201):

{ "user": { "id": 3, "name": "Alice", "email": "alice@kenyon.edu" } }

Errors:

  • 400 if missing fields
  • 409 if email already exists

Also:

  • Must set a session cookie (HTTP-only)

POST /api/auth/login

Request JSON:

{ "email": "alice@kenyon.edu", "password": "secret123" }

Response JSON:

{ "user": { "id": 3, "name": "Alice", "email": "alice@kenyon.edu" } }

Errors:

  • 400 missing fields
  • 401 invalid credentials

Also:

  • Must set a session cookie (HTTP-only)

POST /api/auth/logout

Response JSON:

{ "ok": true }

Also:

  • Must clear/expire the cookie

GET /api/auth/me

Returns the logged-in user.

Response JSON (200):

{ "user": { "id": 3, "name": "Alice", "email": "alice@kenyon.edu" } }

If not logged in (200):

{ "user": null }

Threads (all require login)

GET /api/threads

Returns thread list, newest activity first.

Response JSON:

{
  "threads": [
    {
      "id": 10,
      "title": "Best pizza in Gambier?",
      "created_at": "2026-02-04T14:12:00.000Z",
      "last_post_at": "2026-02-04T15:30:00.000Z",
      "created_by": { "id": 3, "name": "Alice" },
      "post_count": 5
    }
  ]
}

POST /api/threads

Creates a new thread and its first post.

Request JSON:

{ "title": "My new thread", "content": "First message in the thread" }

Response JSON (201):

{ "thread_id": 11 }

Errors:

  • 400 missing fields
  • 401 not logged in

GET /api/threads/:id

Returns one thread and its posts.

Response JSON:

{
  "thread": {
    "id": 10,
    "title": "Best pizza in Gambier?",
    "created_at": "2026-02-04T14:12:00.000Z",
    "created_by": { "id": 3, "name": "Alice" }
  },
  "posts": [
    {
      "id": 77,
      "content": "I like Village Inn.",
      "created_at": "2026-02-04T15:30:00.000Z",
      "author": { "id": 4, "name": "Bob" }
    }
  ]
}

Errors:

  • 401 not logged in
  • 404 if thread doesn’t exist

POST /api/threads/:id/posts

Adds a reply to a thread.

Request JSON:

{ "content": "Here is my reply" }

Response JSON (201):

{ "post_id": 123 }

Errors:

  • 400 missing content
  • 401 not logged in
  • 404 thread not found

Bonus: Search (optional)

GET /api/threads/search?q=keyword

Response JSON:

{ "threads": [ /* same shape as GET /api/threads */ ] }

5) Frontend behavior contract (v2)

Create:

  • docs/FRONTEND_CONTRACT_v2.md

Your React app must behave like this:

Pages / views

A) Logged-out

  • Show Login form
  • Show link/button to Register
  • If user visits any “thread” route while logged out:
    • redirect back to Login

B) Register page

  • Fields: name, email, password
  • On success:
    • user becomes logged in
    • redirect to Thread List

C) Login page

  • Fields: email, password
  • On success:
    • redirect to Thread List

D) Thread List page (logged in)

  • Shows list of thread titles
  • Each thread shows at least:
    • title
    • creator name
    • last_post_at
    • post_count
  • Has a “New Thread” button

E) Thread View page (logged in)

  • Shows thread title + posts
  • Has a reply textarea + submit button
  • Posts show: author name + timestamp + content

F) New Thread page (logged in)

  • Fields: title + content
  • Submitting creates the thread + first post
  • Redirect to the new thread view

G) Logout

  • A logout button visible when logged in
  • On logout:
    • redirect to Login

Technical requirements

  • Use cookie-based sessions (credentials included in fetch)
  • On app start, call /api/auth/me to determine whether logged in

6) Implementation requirements (grading-critical)

  1. Passwords
    • Must be hashed (example: bcrypt)
  2. Sessions
    • Must be server-side sessions stored in DB table sessions
    • Cookie stores a session token/id (not the user id)
  3. Authorization
    • Every /api/threads* route must require login
  4. No hidden “magic state”
    • The backend is the source of truth
    • The frontend should not “pretend” it is logged in without /api/auth/me

7) Deliverables

You will submit:

  1. A link to your GitHub repo
  2. Your completed:
    • docs/schema_v2.sql
    • docs/API_CONTRACT_v2.md
    • docs/FRONTEND_CONTRACT_v2.md
  3. Your updated backend + frontend code
  4. A short README.md section describing:
    • how to init DB for v1 (make initdb-v1)
    • how to run server/client
    • any bonus features implemented

8) Suggested checkpoints

  1. Create schema v1 and confirm make initdb-v1 work
  2. Implement register/login/logout/me (test with curl or Postman)
  3. Implement GET /api/threads and display in React
  4. Implement thread view + replying
  5. Implement new thread creation
  6. Bonus: search

9) Grading rubric (example)

  • 40% Backend correctness (routes + auth + sessions + DB)
  • 40% Frontend behavior contract compliance
  • 10% Code quality (structure, naming, error handling)
  • 10% Documentation (v1 schema + contracts + README)
  • Bonus up to +10% for search
Scroll to Top