# Cursor Prompt — Fuel Request Module (Node.js + Express)

Copy everything below into Cursor.

---

## Context

I already have a working **Connections module** in this Node.js + Express project (users can send/accept/reject connection requests, and fetch their accepted connections list).

Now I need to add a **Fuel Request module** on top of it. A user can only send a fuel request to a user who is already in their **accepted connections list**. This module also involves wallet balance transfers between users.

Follow the existing project conventions (folder structure, ORM/DB client, auth middleware, response format, error-handling middleware, transaction handling) if they already exist in the codebase. If not, use the structure described below. Assume Mongoose (MongoDB) and a JWT auth middleware exposing `req.user.id`, unless the codebase shows otherwise — check first.

## Folder Structure

```
src/
  modules/
    fuelRequests/
      fuelRequest.model.js
      fuelRequest.routes.js
      fuelRequest.controller.js
      fuelRequest.service.js
      fuelRequest.validation.js
```

Assume a `Wallet` model/collection already exists (or create one) with at least: `userId`, `balance`. If it doesn't exist, create it with basic `credit`/`debit` service functions.

## Data Model — `FuelRequest`

- `id`
- `senderId` (user who requested fuel/money)
- `receiverId` (user who will pay/transfer)
- `amount` (number, > 0)
- `message` (string, optional, max 255 chars)
- `status` (enum: `pending`, `accepted`, `rejected`) — use `accepted` for when the transfer has completed
- `stationName` / `merchant` field if relevant (e.g. "Aloha Petroleum" shown in the UI) — optional, include if the project already tracks a fuel station/merchant per request
- `createdAt`, `updatedAt`

Add indexes on `senderId`, `receiverId`, and `status`.

## Business Rule (applies to all endpoints below)

Before creating or acting on a fuel request between two users, verify they are connected (i.e., an `accepted` connection exists between `senderId` and `receiverId` in the Connections module). If not connected, return `403 Forbidden` with a clear message like `"You can only send fuel requests to your connections."`

## APIs to Build

### 1. Send Fuel Request
`POST /api/fuel-requests`

- Body:
  ```json
  {
    "receiverUserId": "string (required)",
    "amount": "number (required, > 0)",
    "message": "string (optional, max 255 characters)"
  }
  ```
- Validate:
  - `receiverUserId` exists and is not the same as the logged-in user (`senderId`).
  - `receiverUserId` is in the logged-in user's accepted connections.
  - `amount` is a positive number.
  - `message` length ≤ 255 chars.
- Create the `FuelRequest` with `status = pending`.
- (Optional) Trigger a notification to the receiver.
- Return the created request.

### 2. Sent Fuel Requests (History)
`GET /api/fuel-requests/sent`

- Returns all fuel requests where the logged-in user is the `senderId`, most recent first.
- Include: receiver's basic details (name, profile image), `amount`, `message`, `status`, `createdAt`, merchant/station name if applicable.
- Support pagination (`page`, `limit`) and optional filter by `status` (`?status=pending|accepted|rejected`).

### 3. Received Fuel Requests
`GET /api/fuel-requests/received`

- Returns all fuel requests where the logged-in user is the `receiverId`, most recent first.
- Include: sender's basic details (name, profile image), `amount`, `message`, `status`, `createdAt`.
- Support pagination and optional `status` filter, same as above.

### 4. Transfer Fuel (Accept & Pay)
`PATCH /api/fuel-requests/:requestId/transfer`

- Only the `receiverId` of that specific request can call this (return `403` otherwise).
- Validate the request exists and is currently `pending` (return `409 Conflict` if already `accepted`/`rejected`).
- Fetch the logged-in user's (receiver's) wallet balance.
  - If `wallet.balance < request.amount` → return a validation error, e.g.:
    ```json
    { "success": false, "message": "Please top up your wallet first." }
    ```
    with status code `400`.
  - If sufficient:
    - Run this as an **atomic DB transaction**:
      1. Debit `amount` from receiver's (payer's) wallet.
      2. Credit `amount` to sender's (requester's) wallet.
      3. Update `FuelRequest.status = accepted`.
      4. (Optional) Create a `Transaction`/ledger record for both wallets for audit history.
    - If any step fails, roll back everything.
- Return updated request + new wallet balance of the current user.

### 5. Reject Fuel Payment Request
`PATCH /api/fuel-requests/:requestId/reject`

- Only the `receiverId` of that request can reject it (return `403` otherwise).
- Validate the request exists and is currently `pending` (return `409` if not).
- Update `status = rejected`.
- (Optional) Trigger a notification to the sender.
- Return the updated request.

## Cross-Cutting Requirements

- **Auth**: All routes protected by existing auth middleware; use `req.user.id` as the logged-in user.
- **Validation**: Use the project's existing validation library, or `express-validator`/`Joi`/`Zod` if none exists. Validate body, params, and query on every route.
- **Connection check**: Reusable helper/service function (e.g. `isConnected(userIdA, userIdB)`) shared between the Connections module and this module — don't duplicate logic.
- **Authorization checks**: Every transfer/reject action must confirm the logged-in user is actually the `receiverId` on that specific record.
- **Atomic wallet operations**: Wallet debit/credit + status update must be wrapped in a DB transaction (e.g. Mongoose session, or Sequelize/Prisma transaction) to avoid partial updates if the process fails mid-way.
- **Consistent response format**: `{ success: true, data, message }` for success, `{ success: false, message, statusCode }` for errors.
- **Pagination**: Standard `page` + `limit`, return `total`, `page`, `totalPages` in response meta.
- **Status transitions**: Only allow `pending → accepted` or `pending → rejected`. Reject any other transition attempt with `409 Conflict`.
- **JSDoc/comments**: Short comment block above each route describing method, path, params, and response shape.

## Deliverables

1. All files listed in the folder structure above, fully implemented.
2. `fuelRequest.routes.js` mounted in the main app router as `/api/fuel-requests`.
3. Wallet debit/credit helper functions (in a shared `wallet.service.js` if one doesn't already exist).
4. Input validation and error handling for every endpoint.
5. A short README/comment block listing all endpoints (method, path, description).

Please check the existing codebase first for: the Connections module's accepted-connection check logic, the Wallet model (if any), and the DB transaction pattern already in use — and reuse them instead of creating duplicates. Ask me if any of these don't exist yet.
