# API Specification

Values wrapped in `< >` are placeholders for what the field values should be. Also be sure to read the request route carefully when you implement it. Error responses should be provided as before.

## Expected Functionality

### Get all users

**`GET`**`/api/users/`

{% code title="Response" %}

```javascript
<HTTP STATUS CODE 200>
{
    "users": [
        {
            "id" 1,
            "name": "Conner",
            "username": "cswenberg"
        },
        {
            "id": 2,
            "name": "Alicia",
            "username": "aawang"
        },
        ...
    ]
}
```

{% endcode %}

Note: Make sure not to include each user’s balance or transactions when getting all users - this would be a confidentiality issue in real life!

### Create a user

**`POST`**`/api/users/`

{% code title="Request" %}

```javascript
{
    "name": "Raahi Menon",
    "username": "raahi014",
    "balance": <USER INPUT (OPTIONAL INTEGER)>
}
```

{% endcode %}

{% code title="Response" %}

```javascript
<HTTP STATUS CODE 201>
{
    "id": <ID>
    "name": "Raahi Menon",
    "username": "raahi014",
    "balance": <USER INPUT, OR 0 IF NOT PROVIDED>,
    "transactions": []
}
```

{% endcode %}

### Get a specific user

**`GET`**`/api/users/{id}/`

{% code title="Response" %}

```javascript
<HTTP STATUS CODE 200>
{
    "id": <ID>,
    "name": <STORED NAME FOR USER WITH ID {id}>,
    "username": <STORED USERNAME FOR USER WITH ID {id}>,
    "balance": <STORED BALANCE FOR USER WITH ID {id}>,
    "transactions": [
        <TRANSACTION>,
        <TRANSACTION>,
        ...
    ]
}
```

{% endcode %}

See the below routes for what data `<TRANSACTION>` should contain.

### Delete a specific user

**`DELETE`**`/api/users/{id}/`

{% code title="Response" %}

```javascript
<HTTP STATUS CODE 200>

<DELETED USER, INCLUDING BALANCE AND TRANSACTIONS, EXAMPLE BELOW>
{
    "id": <ID>,
    "name": <STORED NAME FOR USER WITH ID {id}>,
    "username": <STORED USERNAME FOR USER WITH ID {id}>,
    "balance": <STORED BALANCE FOR USER WITH ID {id}>,
    "transactions": [
        <TRANSACTION>,
        <TRANSACTION>,
        ...
    ]
}
```

{% endcode %}

### Create a transaction by sending or requesting money

**`POST`**`/api/transactions/`

{% code title="Request" %}

```javascript
{
    "sender_id": <USER INPUT>,
    "receiver_id": <USER INPUT>,
    "amount": <USER INPUT>,
    "message": <USER INPUT>,
    "accepted": true or null 
     // if accepted is null, record the transaction in database but don't update any balances
     // if accepted is true, update the balances if sender has sufficient funds
}
```

{% endcode %}

{% code title="Response" %}

```javascript
<HTTP STATUS CODE 201>
{
    "id": <ID>,
    "timestamp": <NOW>,
    "sender_id": <USER INPUT FOR SENDER_ID>,
    "receiver_id": <USER INPUT FOR RECEIVER_ID>,
    "amount": <USER INPUT FOR AMOUNT>,
    "message": <USER INPUT FOR MESSAGE>,
    "accepted": <USER INPUT FOR ACCEPTED>
}
```

{% endcode %}

**Note:** If the `accepted` field is true, then carry out the transaction. This means that if the transaction amount is more than the sender's balance, return an error response with status code 403. In the case of creating a payment request, the `sender_id` refers to the id of the user that will eventually send the money. Therefore, the `receiver_id` is the id of the user making the request for money. For help with `timestamp`, look into the [datetime library](https://docs.python.org/3/library/datetime.html).

### Accept or Deny a payment request

**`POST`**`/api/transactions/{id}/`

{% code title="Request" %}

```javascript
{
    "accepted": true or false
}
```

{% endcode %}

{% code title="Response" %}

```javascript
<HTTP STATUS CODE 200>
{
    "id": <ID>,
    "timestamp": <NOW>,  // update timestamp to time of accept/deny
    "sender_id": <USER INPUT FOR SENDER_ID>,
    "receiver_id": <USER INPUT FOR RECEIVER_ID>,
    "amount": <USER INPUT FOR AMOUNT>,
    "message": <USER INPUT FOR MESSAGE>,
    "accepted": <USER INPUT FOR ACCEPTED>  
}
```

{% endcode %}

If `accepted` is currently `None` and the post body request's new `accepted` is `True`, check if the user has enough money in their balance. If this is satisfied, then update the transaction's `accepted` to be `True` and update the balances. If the user does not have enough money in their balance, return an error response with status code 403 (forbidden) and a relevant error message saying this.

If `accepted` is currently `None` and the post body request's new `accepted` is `False`, update the transaction's `accepted` to be `False`.

If `accepted` currently has some value, be it `True` or `False`, then return an error response with status code 403 (forbidden) saying that you cannot change transaction's `accepted` field if the transaction has already been accepted or denied.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://backend-course.cornellappdev.com/chapters/relational-databases/api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
