Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/Components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Components & Data

### `public/js/teamData.js`
- Exports `teamInfo` array containing team member metadata used by `aboutRouter`.
- Shape:
```js
[
{ id: number, name: string, role: string, bio: string, type: string }
]
```
- Usage:
```js
const teamInfo = require('../public/js/teamData');
res.render('member', { data: teamInfo[0], categories });
```
44 changes: 44 additions & 0 deletions docs/Controllers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
## Controllers Reference

### `controllers/userController.js`

- `signUp(req, res)`
- Input: `firstName, lastName, email, password` (body)
- Validates input, ensures email uniqueness via `userModel.findUserByEmail`, creates user via `userModel.createUser`, initializes session, redirects to `/dashboard`.

- `login(req, res)`
- Input: `email, password` (body)
- Validates credentials using `bcrypt.compare` and `userModel.findUserByEmail`, sets session, redirects to `/dashboard`, or returns 401 on failure.

- `logout(req, res)`
- Destroys the session and redirects to `/`.

Example usage in a router:
```js
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');

router.post('/signup', userController.signUp);
router.post('/login', userController.login);
router.post('/logout', userController.logout);
```

### `controllers/fileUploadController.js`

- `uploadImage` (Multer instance)
- Use as `uploadImage.single('image')` in a route to accept an uploaded file.
- Side effects: populates `req.body.imagePathForDb` and `req.body.thumbnailPathForDb` with paths to store in DB.

- `generateAndUploadThumbnail(sourceImagePath, targetImagePath)`
- Creates a 200x200 thumbnail using Sharp.

Example usage in a route:
```js
const { uploadImage, generateAndUploadThumbnail } = require('../controllers/fileUploadController');
const { ensureUserIsLoggedIn } = require('../middleware/authentication');

router.post('/submit', uploadImage.single('image'), ensureUserIsLoggedIn, async (req, res) => {
// use req.body.imagePathForDb and req.body.thumbnailPathForDb
});
```
59 changes: 59 additions & 0 deletions docs/Middleware.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
## Middleware Reference

All middleware are CommonJS modules exported from files in `application/middleware/`.

### `authentication.ensureUserIsLoggedIn(req, res, next)`
- Redirects to `/` if `req.session.userID` is missing; otherwise calls `next()`.
- Use to protect routes that require authentication.
- Example:
```js
const { ensureUserIsLoggedIn } = require('../middleware/authentication');
app.get('/dashboard', ensureUserIsLoggedIn, handler);
```

### `getCategories.getCategories(req, res, next)`
- Returns `Promise<Array<{categoryName:string}>>` with category names.
- Intended for navbar usage.

### `getCategories.getCategoriesWithPictures(req, res, next)`
- Returns `Promise<Array<{categoryName:string, categoryPicture:string}>>` for homepage display.

### `posts.getPostInfo(req, res, next)`
- Reads `req.params.postId` and returns a single post joined with seller data, or `null` if not found.

### `posts.getUserPosts(userID, req, res, next)`
- Returns an array of posts for the given `userID`, ordered by `postDate DESC`.

### `posts.createPost(title, course, category, price, location, description, image, thumbnail, userID, req, res, next)`
- Inserts a new post. Handles presence/absence of `course`. Resolves on success, rejects on error.

### `posts.deletePost(postID, req, res, next)`
- Deletes a post by id. Resolves on success, rejects on error.

### `posts.updatePost(title, course, category, price, location, description, postID, req, res, next)`
- Updates a post record. Returns 404 on errors via response.

### `messages.getUserMessages(userID, req, res, next)`
- Returns a user’s received messages with item and sender info, ordered by `sendTime DESC`.

### `messages.getMessageDetails(req, res, next)`
- Expects `req.params.messageId`. On success sets `res.locals.message` and calls `next()`; 404 if not found.

### `messages.messageUser(req, res, next)`
- Expects `req.params.postId`. On success sets `res.locals.postDetails` and calls `next()`.

### `messages.sendMessage(recipientID, senderID, content, postID, req, res, next)`
- Inserts a message. Resolves on success, throws on error.

### `messages.deleteMessage(msgID, req, res, next)`
- Deletes a message by id. Resolves on success, rejects on error.

### `search.searchItems(req, res, next)`
- Reads `query` and `category` from `req.query`. Sets `res.locals.items` and `res.locals.message` then calls `next()`.
- Supports sorting via `sort` query param and returns curated items if there are no results.

### `search.getRecentPosts(req, res, next)`
- Sets `res.locals.recentPosts` to the last 9 authorized, unsold items.

### `dashboard.fetchUserInfo(userID, req, res, next)`
- Returns an array with `{ firstName, lastName, email, bio }` for the given user.
12 changes: 12 additions & 0 deletions docs/Models.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## Models Reference

### `models/userModel.js`

- `createUser(firstName, lastName, email, password) -> Promise<number>`
- Hashes `password` with bcrypt, inserts a new user, and returns the new `userID`.

- `findUserByEmail(email) -> Promise<object|null>`
- Returns the user row if found, otherwise `null`.

### Database Connection
- `conf/database.js` creates a mysql2 connection pool using env vars: `DB_HOST`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`.
16 changes: 16 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Project Documentation

Welcome. This folder contains comprehensive documentation for all public APIs, functions, and components in this codebase.

- REST API: see `REST_API.md`
- Routes overview: see `Routes.md`
- Middleware reference: see `Middleware.md`
- Controllers reference: see `Controllers.md`
- Models reference: see `Models.md`
- OpenAPI spec (for tooling): see `openapi.yaml`

Quick start
- Base URL: `http://localhost:3000`
- Auth base: `http://localhost:3000/auth`
- Search base: `http://localhost:3000/search`
- HTML pages are rendered via EJS; JSON APIs are noted explicitly in the docs.
112 changes: 112 additions & 0 deletions docs/REST_API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
## REST API

Base URL: `http://localhost:3000`

Authentication & Sessions
- Session cookie is set after successful login or signup. Some endpoints require a valid session.
- Content types supported: `application/json` and `application/x-www-form-urlencoded` unless otherwise stated.

### Auth

- POST `/auth/signup`
- Body: `{ firstName, lastName, email, password }`
- 302 → Redirect to `/dashboard` on success
- 400 → Missing fields or email in use; 500 on DB error
- Example:
```bash
curl -i -X POST http://localhost:3000/auth/signup \
-H 'Content-Type: application/json' \
-d '{"firstName":"Ada","lastName":"Lovelace","email":"ada@example.com","password":"Secret123!"}'
```

- POST `/auth/login`
- Body: `{ email, password }`
- 302 → Redirect to `/dashboard` on success; sets session
- 401 → Invalid credentials; 500 on DB error
- Example:
```bash
curl -i -X POST http://localhost:3000/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"ada@example.com","password":"Secret123!"}'
```

- POST `/auth/logout`
- Ends the session; clears cookie if present
- 302 → Redirect to `/`
- Example:
```bash
curl -i -X POST http://localhost:3000/auth/logout
```

### Search

- GET `/search`
- Query params: `query` (string), `category` (string or "all"), `sort` ("default"|"price_asc"|"price_desc"|"alpha_asc"|"alpha_desc"), `page` (int, default 1), `limit` (int, default 9)
- Renders HTML page `search.ejs` with paginated, sorted results
- Example:
```bash
curl 'http://localhost:3000/search?query=laptop&category=Electronics&sort=price_desc&page=1&limit=9'
```

### Posts

- POST `/submit` (multipart/form-data, requires session)
- Fields: `title`, `course` (optional), `category` (categoryId), `price`, `location`, `description`, `image` (file)
- Behavior: stores image under `public/img/items`, generates 200x200 thumbnail under `public/img/thumbnails`, inserts post in DB
- 302 → Redirect to `/dashboard` on success; 400 on validation errors; 500 on failures
- Example:
```bash
curl -i -X POST http://localhost:3000/submit \
-H 'Cookie: connect.sid=YOUR_SESSION_COOKIE' \
-F 'title=Textbook' \
-F 'course=CSC648' \
-F 'category=3' \
-F 'price=25.00' \
-F 'location=Campus' \
-F 'description=Gently used' \
-F 'image=@/path/to/photo.jpg'
```

- DELETE `/delete-post/:id`
- Deletes the post by id; returns text
- 200 on success, 500 on failure
- Example:
```bash
curl -i -X DELETE http://localhost:3000/delete-post/123
```

### Messaging

- GET `/message/:postId`
- Returns JSON with post details for composing a message
- Response: `{ postDetails: { ... } }`
- Example:
```bash
curl -s http://localhost:3000/message/42 | jq .
```

- POST `/send-message` (requires session)
- Body: `{ recipientId, content, postId }`
- 200 → "Message sent successfully"; 500 on error
- Example:
```bash
curl -i -X POST http://localhost:3000/send-message \
-H 'Content-Type: application/json' \
-H 'Cookie: connect.sid=YOUR_SESSION_COOKIE' \
-d '{"recipientId":7,"content":"Is this still available?","postId":42}'
```

- DELETE `/delete-message/:id`
- Deletes a message by id; returns text
- 200 on success, 500 on failure
- Example:
```bash
curl -i -X DELETE http://localhost:3000/delete-message/987
```

### Pages (HTML)
- GET `/` → Home
- GET `/dashboard` (requires session)
- GET `/createpost`
- GET `/about`, `/about/1..6`
- GET `/members`
28 changes: 28 additions & 0 deletions docs/Routes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
### Route Modules and Endpoints

- `routes/homeRouter.js` (mounted at `/`)
- GET `/` → Renders home with recent posts and categories.

- `routes/aboutRouter.js` (mounted at `/about`)
- GET `/about` → Renders About page with `teamInfo` and categories.
- GET `/about/1..6` → Renders specific team member page.

- `routes/authRouter.js` (mounted at `/auth`)
- POST `/auth/signup` → Sign up.
- POST `/auth/login` → Log in.
- POST `/auth/logout` → Log out.

- `routes/searchRouter.js` (mounted at `/search`)
- GET `/search` → Search items with query params; renders results.

- `routes/submitRouter.js` (mounted at `/`)
- POST `/submit` → Create a new post (multipart/form-data). Requires login.

Additional endpoints defined in `server.js`
- GET `/dashboard` → Requires login. Renders dashboard with categories, messages, and posts.
- GET `/createpost` → Renders create-post page.
- GET `/members` → Renders member listing using `teamData`.
- GET `/message/:postId` → Returns JSON `{ postDetails }` for a post.
- POST `/send-message` → Requires login. Sends a message.
- DELETE `/delete-post/:id` → Deletes a post by id.
- DELETE `/delete-message/:id` → Deletes a message by id.
Loading
Loading