|
| 1 | +--- |
| 2 | +name: postman-api-testing |
| 3 | +description: Guide for using Postman to test and interact with the FinishLine API during development. Use when testing API endpoints, debugging backend issues, verifying request/response formats, or when asked how to use Postman with the local development environment. |
| 4 | +--- |
| 5 | + |
| 6 | +# Postman API Testing |
| 7 | + |
| 8 | +> **Summary:** Postman enables developers to test API endpoints locally during development. This guide covers setup, authentication, common workflows, and troubleshooting for the FinishLine API running on localhost:3001. |
| 9 | +
|
| 10 | +## Overview |
| 11 | + |
| 12 | +Postman is an API development tool that allows you to make HTTP requests to the FinishLine backend without needing the frontend interface. This is particularly useful for: |
| 13 | + |
| 14 | +- Testing new endpoints during development |
| 15 | +- Debugging backend issues in isolation |
| 16 | +- Verifying request and response formats |
| 17 | +- Exploring available API data without UI constraints |
| 18 | + |
| 19 | +All API requests in local development target `http://localhost:3001`, which is the Express server running on your machine. Many endpoints require authentication using a user ID obtained from the `/users` endpoint. |
| 20 | + |
| 21 | +## Prerequisites |
| 22 | + |
| 23 | +Before you begin, ensure you have: |
| 24 | + |
| 25 | +- [Postman](https://www.postman.com/downloads/) installed |
| 26 | +- The FinishLine backend running locally |
| 27 | +- The PostgreSQL database running in Docker with seeded data |
| 28 | + |
| 29 | +## Verifying the API is Running |
| 30 | + |
| 31 | +Before making requests, confirm the backend is accessible: |
| 32 | + |
| 33 | +1. Start the backend server if not already running: |
| 34 | + |
| 35 | + ```bash |
| 36 | + yarn backend:dev |
| 37 | + ``` |
| 38 | + |
| 39 | +2. The console should show the server listening on port 3001 |
| 40 | + |
| 41 | +3. Make a test request to the base URL in Postman: `GET http://localhost:3001` |
| 42 | + |
| 43 | +If you receive a "Welcome to NER" message, your backend is running and listening on port 3001. This is also the default message you will see if the router cannot resolve the url you requested, so if you get this while trying to test an endpoint it is likely that you have a typo in the url or are using the wrong HTTP method (e.g. POST instead of GET). |
| 44 | + |
| 45 | +## Base URL |
| 46 | + |
| 47 | +All API requests in local development should be made to: |
| 48 | + |
| 49 | +``` |
| 50 | +http://localhost:3001 |
| 51 | +``` |
| 52 | + |
| 53 | +This is the Express server listening for HTTP requests. The backend handles routing, authentication, and business logic before querying the PostgreSQL database. |
| 54 | + |
| 55 | +## Authentication |
| 56 | + |
| 57 | +Many endpoints in the FinishLine API require authentication to enforce permission checks and organization scoping. Here's how to authenticate your Postman requests: |
| 58 | + |
| 59 | +### Step 1: Get a User ID |
| 60 | + |
| 61 | +First, fetch a user from the `/users` endpoint: |
| 62 | + |
| 63 | +1. Create a new GET request in Postman |
| 64 | +2. Enter URL: `http://localhost:3001/users` |
| 65 | +3. Click **Send** |
| 66 | +4. The response contains an array of users with their `userId` fields |
| 67 | +5. Copy a `userId` from any user in the response (typically a string like `"abc-123-def"`) |
| 68 | + |
| 69 | +### Step 2: Add Authorization Header |
| 70 | + |
| 71 | +For endpoints requiring authentication: |
| 72 | + |
| 73 | +1. Navigate to the **Headers** tab in your request |
| 74 | +2. Add a new header with: |
| 75 | + - **Key:** `authorization` |
| 76 | + - **Value:** `<paste-the-user-id-here>` |
| 77 | +3. Send your request |
| 78 | + |
| 79 | +Without proper authorization, protected endpoints will return `401 Unauthorized` or `403 Forbidden` responses depending on the permission level required. |
| 80 | + |
| 81 | +## Common Workflows |
| 82 | + |
| 83 | +### Fetching All Users |
| 84 | + |
| 85 | +**Endpoint:** `GET http://localhost:3001/users` |
| 86 | + |
| 87 | +**Purpose:** Retrieve all users in the system. Use this to find user IDs for authentication in other requests. |
| 88 | + |
| 89 | +**Authentication:** Not required |
| 90 | + |
| 91 | +**Steps:** |
| 92 | + |
| 93 | +1. Create a new request in Postman |
| 94 | +2. Set method to **GET** using the dropdown menu |
| 95 | +3. Enter URL: `http://localhost:3001/users` |
| 96 | +4. Click **Send** |
| 97 | + |
| 98 | +**Response:** Array of user objects with `userId`, `firstName`, `lastName`, `email`, and role information. |
| 99 | + |
| 100 | +### Fetching All Projects |
| 101 | + |
| 102 | +**Endpoint:** `GET http://localhost:3001/project` |
| 103 | + |
| 104 | +**Purpose:** Retrieve all projects in the system. Useful for finding existing project data, WBS numbers, or materials associated with projects. |
| 105 | + |
| 106 | +**Authentication:** Check the route definition to confirm if required |
| 107 | + |
| 108 | +**Steps:** |
| 109 | + |
| 110 | +1. Create a new request |
| 111 | +2. Set method to **GET** |
| 112 | +3. Enter URL: `http://localhost:3001/project` |
| 113 | +4. Add authorization header if needed (see Authentication section) |
| 114 | +5. Click **Send** |
| 115 | + |
| 116 | +**Response:** Array of project objects with details like `projectId`, `name`, `wbsNum`, `status`, `teams`, and nested data. |
| 117 | + |
| 118 | +### Making Authenticated Requests |
| 119 | + |
| 120 | +For any endpoint that requires authentication: |
| 121 | + |
| 122 | +1. Fetch a user ID from `GET /users` (see above) |
| 123 | +2. Add the `authorization` header with the user ID as the value |
| 124 | +3. Make your request normally |
| 125 | + |
| 126 | +If you forget authorization on a protected route, the response will include an error message indicating permission denied or unauthorized access. |
| 127 | + |
| 128 | +### Creating or Updating Data (POST Requests) |
| 129 | + |
| 130 | +When testing endpoints that create or modify data: |
| 131 | + |
| 132 | +1. Set request method to **POST** |
| 133 | +2. Add authentication header with a valid user ID |
| 134 | +3. Navigate to the **Body** tab |
| 135 | +4. Select **raw** and **JSON** format from the dropdown |
| 136 | +5. Enter the request payload as valid JSON |
| 137 | +6. Click **Send** |
| 138 | + |
| 139 | +Example JSON body structure (varies by endpoint): |
| 140 | + |
| 141 | +```json |
| 142 | +{ |
| 143 | + "name": "New Project", |
| 144 | + "description": "Project description", |
| 145 | + "leadId": "user-id-here" |
| 146 | +} |
| 147 | +``` |
| 148 | + |
| 149 | +Refer to the backend route validation rules in `src/backend/src/routes/` to determine required fields and formats. |
| 150 | + |
| 151 | +## Using Postman Features |
| 152 | + |
| 153 | +### Request Type Selection |
| 154 | + |
| 155 | +The dropdown menu to the left of the URL field allows you to select the HTTP request method. FinishLine follows this convention: |
| 156 | + |
| 157 | +- **GET** — Retrieve data (read operations) |
| 158 | +- **POST** — Create new data, update existing data, or delete data |
| 159 | + |
| 160 | +Note: FinishLine does not use `PUT`, `PATCH`, or `DELETE` HTTP methods. All mutations use `POST`. |
| 161 | + |
| 162 | +### Key Tabs in Postman |
| 163 | + |
| 164 | +Postman provides several tabs for configuring requests: |
| 165 | + |
| 166 | +- **Params** — Add query parameters to your URL (e.g., `?limit=10&offset=0`) |
| 167 | +- **Authorization** — Alternative way to set auth (use Headers tab for FinishLine) |
| 168 | +- **Headers** — Add HTTP headers like `authorization`, `Content-Type`, `organizationId` |
| 169 | +- **Body** — Include request payload for POST requests (select raw → JSON format) |
| 170 | + |
| 171 | +## Finding Endpoint URLs |
| 172 | + |
| 173 | +To discover available endpoints and their paths: |
| 174 | + |
| 175 | +1. **Check route files:** Backend routes are defined in `src/backend/src/routes/{feature}.routes.ts` |
| 176 | +2. **Combine base paths:** The full URL is `index.ts` base path + route path |
| 177 | + - Example: If `index.ts` has `app.use('/calendar', calendarRouter)` and the route defines `POST /shop/create`, the full endpoint is `POST /calendar/shop/create` |
| 178 | +3. **Review validation:** Route files show which fields are required and their validation rules using `express-validator` |
| 179 | + |
| 180 | +## Organization Scoping |
| 181 | + |
| 182 | +FinishLine is a multi-tenant application. Most endpoints filter data by `organizationId`. In local development with seed data, the organization ID is typically included automatically via middleware. |
| 183 | + |
| 184 | +If an endpoint requires an explicit `organizationId` header: |
| 185 | + |
| 186 | +1. Go to the **Headers** tab |
| 187 | +2. Add key: `organizationId` |
| 188 | +3. Set value to a valid organization ID (check your seed data or database) |
| 189 | + |
| 190 | +## Troubleshooting |
| 191 | + |
| 192 | +### "Welcome to NER" Message |
| 193 | + |
| 194 | +**Problem:** You receive a plain text "Welcome to NER" response. |
| 195 | + |
| 196 | +**Cause:** The endpoint URL is incorrect or the route doesn't exist. This is the default response when Express can't find a matching route handler. |
| 197 | + |
| 198 | +**Solution:** |
| 199 | + |
| 200 | +- Double-check the endpoint URL for typos |
| 201 | +- Verify the HTTP method matches the route definition (GET vs POST) |
| 202 | +- Confirm the route is registered in `src/backend/index.ts` |
| 203 | +- Check that the feature router is imported and mounted on the correct base path |
| 204 | + |
| 205 | +### Connection Refused or Network Error |
| 206 | + |
| 207 | +**Problem:** Postman cannot connect to `http://localhost:3001`. |
| 208 | + |
| 209 | +**Cause:** The backend server is not running. |
| 210 | + |
| 211 | +**Solution:** |
| 212 | + |
| 213 | +- Start the backend: `yarn backend:dev` or `yarn start` |
| 214 | +- Verify the console shows "Server listening on port 3001" |
| 215 | +- Check no other process is using port 3001 |
| 216 | +- Wait a few seconds for the server to fully start after running the command |
| 217 | + |
| 218 | +### 401 Unauthorized or 403 Forbidden |
| 219 | + |
| 220 | +**Problem:** The endpoint returns a 401 or 403 error. |
| 221 | + |
| 222 | +**Cause:** Missing or invalid authentication, or insufficient permissions. |
| 223 | + |
| 224 | +**Solution:** |
| 225 | + |
| 226 | +- Ensure you've added the `authorization` header with a valid user ID |
| 227 | +- Verify the user ID exists in the database (check `/users` response) |
| 228 | +- Confirm the user has sufficient permissions for the operation (check the service method's permission check) |
| 229 | +- Try using a different user with higher privileges (e.g., an admin user) |
| 230 | + |
| 231 | +### 400 Bad Request |
| 232 | + |
| 233 | +**Problem:** The endpoint returns a 400 error with validation messages. |
| 234 | + |
| 235 | +**Cause:** The request payload doesn't match the validation rules defined in the route. |
| 236 | + |
| 237 | +**Solution:** |
| 238 | + |
| 239 | +- Check the route file (`src/backend/src/routes/`) for validation rules |
| 240 | +- Verify all required fields are present in the request body |
| 241 | +- Ensure field types match expectations (string, number, date, boolean) |
| 242 | +- Check for typos in field names |
| 243 | +- Review the error response for specific validation failure details |
| 244 | + |
| 245 | +### Date Format Issues |
| 246 | + |
| 247 | +**Problem:** Date fields are rejected or cause errors. |
| 248 | + |
| 249 | +**Cause:** Invalid date string format. |
| 250 | + |
| 251 | +**Solution:** |
| 252 | + |
| 253 | +- Use ISO 8601 date format: `"2025-02-16T12:00:00.000Z"` |
| 254 | +- Or use a simpler format: `"2025-02-16"` |
| 255 | +- Avoid relative dates like "yesterday" or "last week" |
| 256 | +- The backend controller parses date strings with `new Date()`, so any format recognized by JavaScript's Date constructor works |
| 257 | + |
| 258 | +### Empty or Unexpected Response |
| 259 | + |
| 260 | +**Problem:** The endpoint returns 200 OK but the data is empty or not what you expected. |
| 261 | + |
| 262 | +**Cause:** Data may be filtered by organization scope, soft-deleted, or the query returned no matches. |
| 263 | + |
| 264 | +**Solution:** |
| 265 | + |
| 266 | +- Check the database for relevant data: `yarn prisma:studio` |
| 267 | +- Verify `dateDeleted` is `null` on the records you expect to see |
| 268 | +- Confirm the records belong to the organization you're querying |
| 269 | +- Review the service method's query filters and transformers |
| 270 | + |
| 271 | +## Available Endpoints Reference |
| 272 | + |
| 273 | +This table lists some core endpoints available in the FinishLine API. For a complete list, review the route files in `src/backend/src/routes/`. |
| 274 | + |
| 275 | +| Endpoint | Method | Description | Auth Required | |
| 276 | +| ---------- | ------ | ----------------------------------------- | ------------- | |
| 277 | +| `/users` | GET | Fetch all users with roles and settings | False | |
| 278 | +| `/project` | GET | Fetch all projects with WBS and team data | True | |
| 279 | + |
| 280 | +_Note: This table is incomplete. When discovering new endpoints, add them here with their method, purpose, and authentication requirements._ |
| 281 | + |
| 282 | +## Key Rules |
| 283 | + |
| 284 | +- The base URL is always `http://localhost:3001` for local development |
| 285 | +- Use **GET** for reads and **POST** for all mutations (create, update, delete) |
| 286 | +- Authentication uses the `authorization` header with a user ID value |
| 287 | +- Fetch user IDs from the `/users` endpoint before testing protected routes |
| 288 | +- Full endpoint URLs combine the base path from `index.ts` and the route path |
| 289 | +- Expect "Welcome to NER" for non-existent or incorrectly typed endpoints |
| 290 | +- Validate request payloads against the route's `express-validator` rules |
| 291 | +- Organization scoping is enforced — data is filtered by `organizationId` |
| 292 | + |
| 293 | +## Common Mistakes |
| 294 | + |
| 295 | +- **Not starting the backend server** before making requests |
| 296 | +- **Forgetting the authorization header** on protected endpoints |
| 297 | +- **Using incorrect HTTP methods** (e.g., PUT or DELETE instead of POST) |
| 298 | +- **Mistyping the endpoint URL** (check the full path: base + route) |
| 299 | +- **Not checking route validation rules** before constructing POST request bodies |
| 300 | +- **Assuming all endpoints require authentication** — check the route definition |
| 301 | +- **Ignoring 400 error details** — the response usually explains what's invalid |
| 302 | + |
| 303 | +## Reference Files |
| 304 | + |
| 305 | +- `src/backend/index.ts` — Route registration and middleware setup |
| 306 | +- `src/backend/src/routes/{feature}.routes.ts` — Route definitions with HTTP methods and validation rules |
| 307 | +- `src/backend/src/controllers/{feature}.controllers.ts` — Request handling logic |
| 308 | +- `src/backend/src/services/{feature}.services.ts` — Business logic and permission checks |
| 309 | + |
| 310 | +## Tips for Efficient Testing |
| 311 | + |
| 312 | +- **Save requests in collections:** Organize related endpoints into Postman collections for easy reuse |
| 313 | +- **Use environments:** Create a Postman environment with variables like `baseUrl` and `userId` to avoid repetitive typing |
| 314 | +- **Inspect responses:** Check the response status, headers, and body to verify expected behavior |
| 315 | +- **Test edge cases:** Try invalid inputs, missing fields, and unauthorized access to verify error handling |
| 316 | +- **Review console logs:** The backend terminal shows request logs and error stack traces |
| 317 | + |
| 318 | +## Contributing to This Documentation |
| 319 | + |
| 320 | +If you discover additional endpoints, common workflows, or troubleshooting tips, please update this document following the same structure. Add new endpoints to the reference table, new workflows under Common Workflows, and new issues under Troubleshooting. |
0 commit comments