https://teammate-app.herokuapp.com/
Type | URL | Methods | Description |
---|---|---|---|
Authentication | /auth/users/ | POST | Create User |
Authentication | /auth/token/login/ | POST | Login |
Authentication | /auth/token/logout/ | POST | Logout |
User Profile | /profile/ | GET, PATCH | List, Create (where None), Patch Profile |
User Details | /str:username | GET | List User Details |
User’s Game Sessions | /str:username/games/?my-games= | GET | Several My Games List Returned |
Game Sessions | /session/ | GET, POST, | List All & Create Game Session |
Game Sessions | /session/?search | Filter Game Sessions | |
Game Sessions | /session/int:pk | GET, PATCH, DELETE | Get, Update, Destroy Game Session |
Game Sessions | /session/int:pk/guest/ | GET, POST, DELETE | List, Create Guest for Game session |
Game Sessions | /session/int:pk/guest/int:guest_pk/ | GET, PATCH | Change Guest Status, Delete Guest |
Survey | /session/int:session_pk/survey | GET, POST | List & Create Survey |
Survey Responses | /session/int:session_pk/survey/response/ | POST | Create Survey Response |
Court | /court/ | GET, POST | List & Create Court |
Court Address | /court/int:pk/address/ | GET, POST, PATCH | List & Create Court Address |
Notification | notification/check/ | GET | View All New Notifications, Only called once |
Notification | notification/count/ | GET | List All New Notifications to count |
Notification | notification/all/ | GET | List All Past Notifications |
/auth/users/
- Method: POST
- Data json:
{
"username": "<username>",
"password": "<password>",
"first_name": "<firstname>",
"last_name": "<lastname>"
}
- Response: User json object
/auth/token/login/
- Method: POST
- Data json:
{
"username": "<username>",
"password": "<password>"
}
- Response: Example Authentication Token
{
"auth_token": "a65751fc4fa58a41cce703fb4deee8a9fe367618"
}
/auth/token/logout/
- Method: POST
- Data: Authentication Token (See Example Auth Token in Login Section)
- Response: No Data
/str:username
-
Method: GET
-
Response: User JSON Object, with Profile, GameSession, and Guest data, 200_OK
{ "id": 5, "username": "SillyJoe", "first_name": "Silly", "last_name": "Joe", "profile": { "id": 48, "user": "SillyJoe", "profile_pic": null, "ntrp_rating": "5" }, "game_session": [ { "game_session_id": 6, "confirmed": true, "datetime": "2022-08-03T23:31:59Z", "endtime": "2022-08-04T00:31:59Z", "session_type": "Casual", "match_type": "Singles", "host": "SillyJoe", "host_info": { "user_id": 2, "username": "SillyJoe", "first_name": "", "last_name": "", "profile": { "profile_id": 2, "user": "SillyJoe", "profile_pic": null, "ntrp_rating": "2.5", "profile_image_file": null } }, "guest": [ 6 ], "guest_info": [ { "guest_id": 6, "status": "Host", "game_session": 6, "user": "SillyJoe", "user_info": { "user_id": 2, "username": "SillyJoe", "first_name": "", "last_name": "", "profile": { "profile_id": 2, "user": "SillyJoe", "profile_pic": null, "ntrp_rating": "2.5", "profile_image_file": null } } } ], "location": 1, "location_info": { "id": 1, "park_name": "Sandeford Park", "court_count": 2, "court_surface": "Hard Court", "address": { "id": 1, "court": "Sandeford Park", "address1": "Sanderford Rd", "address2": null, "city": "Raleigh", "state": "North Carolina", "zipcode": "27610" } } }... ]
/str:username/games/?my-games=
- Method: GET
- Search Options
- AllConfirmed : All confirmed games
- HostUnconfirmed : Unconfirmed games that I host that have a pending request, aka games I need to respond to.
- GuestPending : games that I have requested to join and those requests haven't been accepted/rejected yet, aka pending sent requests
- HostNoGuest : games that I host that have no guests (pending or accepted, etc) so that I can delete this game session and no one needs to be notified. I could also edit this game
- HostNotPendingUnconfirmedDoubles : doubles games that I host with other accepted guest but not confirmed yet and No pending guest
- GuestAcceptedUnconfirmedDoubles : doubles games that I am an accepted guest (not the host), but aren't confirmed yet. So I could cancel my request to join this game after I'm accepted
- MyPreviousGames : List all users previous games as Host or Guest
/profile/
-
Method: GET
-
Data JSON:
- profile_pic: feature not yet built
- If user profile does not exist, one will be created
- ntrp_rating: 2.5 - 7, increments of .5, defaults to 2.5 (when creating)
- A user can only have one profile
-
Response: Profile JSON Object, 200_OK :
{ "id": 27, "user": 5, "profile_pic": null, "ntrp_rating": "3.5", "wins_losses": "1 - 1", "profile_image_file": "https://teammate-momentum-team-13.s3.amazonaws.com/static/profile_images/Diego_Profile.jpg" }
-
Method: PATCH
-
Data JSON:
- profile_image_file: Link on how to implement on front end https://momentum-team-13.github.io/2022/08/01/fe-search-and-file-upload/
- ntrp_rating: 2.5 - 7, increments of .5, defaults to 2.5 if request body is empty
- A user can only have one profile
{ "ntrp_rating": 4 }
-
Response: Profile JSON Object, 202_ACCEPTED:
{ "id": 27, "user": 5, "profile_pic": null, "ntrp_rating": "4" "wins_losses": "1 - 1", "profile_image_file": "https://teammate-momentum-team-13.s3.amazonaws.com/static/profile_images/Diego_Profile.jpg" }
/session/
-
Method: GET
-
Data json:
-
Response: Game Session list json object filtered by games after current date
[ { "game_session_id": 6, "confirmed": true, "datetime": "2022-08-03T23:31:59Z", "endtime": "2022-08-04T00:31:59Z", "session_type": "Casual", "match_type": "Singles", "host": "SillyJoe", "host_info": { "user_id": 2, "username": "SillyJoe", "first_name": "", "last_name": "", "profile": { "profile_id": 2, "user": "SillyJoe", "profile_pic": null, "ntrp_rating": "2.5", "profile_image_file": null } }, "guest": [ 6 ], "guest_info": [ { "guest_id": 6, "status": "Host", "game_session": 6, "user": "SillyJoe", "user_info": { "user_id": 2, "username": "SillyJoe", "first_name": "", "last_name": "", "profile": { "profile_id": 2, "user": "SillyJoe", "profile_pic": null, "ntrp_rating": "2.5", "profile_image_file": null } } } ], "location": 1, "location_info": { "id": 1, "park_name": "Sandeford Park", "court_count": 2, "court_surface": "Hard Court", "address": { "id": 1, "court": "Sandeford Park", "address1": "Sanderford Rd", "address2": null, "city": "Raleigh", "state": "North Carolina", "zipcode": "27610" } } }... ]
/session/?searchterm
- Method: GET
- SearchTerms: location-id , date, match-type, session-type
- note you can chain search terms
- Example /session/?match-type=Singles&session-type=Casual
- Data json:
- Response: Filtered Game Session List
/session/
-
Method: POST
-
Data json:
- Session Type has 2 options: Competitive, Casual
- Match Type has 2 options: (Doubles, Singles) Defaults is singles if no option provided
{ "datetime": "2022-08-03T23:31:59Z", "session_type": "Competitive", "match_type": "Doubles", "location": 1 }
-
Response: Game Session list json object
[
{
"game_session_id": 6,
"confirmed": true,
"datetime": "2022-08-03T23:31:59Z",
"endtime": "2022-08-04T00:31:59Z",
"session_type": "Casual",
"match_type": "Singles",
"host": "SillyJoe",
"host_info": {
"user_id": 2,
"username": "SillyJoe",
"first_name": "",
"last_name": "",
"profile": {
"profile_id": 2,
"user": "SillyJoe",
"profile_pic": null,
"ntrp_rating": "2.5",
"profile_image_file": null
}
},
"guest": [
6
],
"guest_info": [
{
"guest_id": 6,
"status": "Host",
"game_session": 6,
"user": "SillyJoe",
"user_info": {
"user_id": 2,
"username": "SillyJoe",
"first_name": "",
"last_name": "",
"profile": {
"profile_id": 2,
"user": "SillyJoe",
"profile_pic": null,
"ntrp_rating": "2.5",
"profile_image_file": null
}
}
}
],
"location": 1,
"location_info": {
"id": 1,
"park_name": "Sandeford Park",
"court_count": 2,
"court_surface": "Hard Court",
"address": {
"id": 1,
"court": "Sandeford Park",
"address1": "Sanderford Rd",
"address2": null,
"city": "Raleigh",
"state": "North Carolina",
"zipcode": "27610"
}
}
}...
]
/session/int:pk
- Method: DELETE
- Note: pk is the id of the game session
- Data json:
- Response: 204 No Content
/session/int:pk
- Method: PATCH
- Note: pk is the id of the game session
- Data json:
- PATCH fields to update
{
"datetime": "2022-08-03T23:31:59Z",
}
- Response: 200_OK
/session/int:pk
-
Method: GET
- Note: pk is the id of the game session
-
Data json:
-
Response: 200_OK
[ { "game_session_id": 6, "confirmed": true, "datetime": "2022-08-03T23:31:59Z", "endtime": "2022-08-04T00:31:59Z", "session_type": "Casual", "match_type": "Singles", "host": "SillyJoe", "host_info": { "user_id": 2, "username": "SillyJoe", "first_name": "", "last_name": "", "profile": { "profile_id": 2, "user": "SillyJoe", "profile_pic": null, "ntrp_rating": "2.5", "profile_image_file": null } }, "guest": [ 6 ], "guest_info": [ { "guest_id": 6, "status": "Host", "game_session": 6, "user": "SillyJoe", "user_info": { "user_id": 2, "username": "SillyJoe", "first_name": "", "last_name": "", "profile": { "profile_id": 2, "user": "SillyJoe", "profile_pic": null, "ntrp_rating": "2.5", "profile_image_file": null } } } ], "location": 1, "location_info": { "id": 1, "park_name": "Sandeford Park", "court_count": 2, "court_surface": "Hard Court", "address": { "id": 1, "court": "Sandeford Park", "address1": "Sanderford Rd", "address2": null, "city": "Raleigh", "state": "North Carolina", "zipcode": "27610" } } }... ]
/session/int:pk/guest/
- Method: POST
- Note: pk is the id of the game session
- Data json:
- Response: 200_OK
/session/int:pk/guest/
-
Method: GET
- Note: pk is the id of the game session
-
Data json:
-
Response: 200_OK
[ { "guest_id": 6, "status": "Host", "game_session": 6, "user": "SillyJoe", "user_info": { "user_id": 2, "username": "SillyJoe", "first_name": "", "last_name": "", "profile": { "profile_id": 2, "user": "SillyJoe", "profile_pic": null, "ntrp_rating": "2.5", "profile_image_file": null } } ]
/session/int:pk/guest/int:guest_pk
-
Method: PATCH
- Note: pk is the id of the game session instance and guest_pk is the id of guest instance
-
Permissions: Game Session Owners or Admins can make this request
-
Data json:
- Status Options: Accepted, Wait Listed, Rejected, Pending (Default)
{ "status":"Accepted" }
-
Response: 200_OK
/session/int:pk/guest/
- Method: DELETE
- Note: pk is the id of the game session instance and guest_pk is the id of guest instance
- Permissions: Guest Instance Owner or Admins can make this request
- Data json:
- Status Options: Accepted, Wait
- Response: 204 No Content
-
- Method: POST
-
A POST request to /session/int:session_pk/survey/ must be made in order to initialize the survey. Ideally this will be done when you hit the “start survey” button
-
For every affirmative response you make a POST request to /session/int:session_pk/survey/response/ otherwise you simply don’t make a post request.
- EXAMPLE 1: POST the Winner, the loser does not need a post request
{ "about_user": 8, <---- this is the user_id "response": "Winner" }
- EXAMPLE 2: POST if you DO want to block a user, If you DON’T wan’t to block user do not make a POST request
{ "about_user": 8,<---- this is the user_id "response": "Block User" }
- EXAMPLE 3: POST location review
{
"about_court": 2,<---- this is the location_id
"response": "High Quality"
}
/session/int:session_pk/survey/
-
Method: POST
-
Permissions: Authenticated or Read-Only
-
Data:
- The game session PK is passed via the URL
- The “respondent” is the user making the request
- Thus, the body can remain empty
-
POST:
No Body
-
Response: JSON Object, 201_CREATED
{ "id": 7, "respondent": "ChaseTheLegend", "game_session": 8 }
/session/int:session_pk/survey/response/
-
Method: POST
- NOTE: about_user is the user_id
-
Permissions: Authenticated or Read-Only
-
Data:
- The game session PK is passed via the URL
- The survey PK is passed via the URL
- The request body must include:
- PK for a “about_user” or “about_court”
- “response” string
- “about_user”: “No Show” | “Winner” | “Block User”
- “about_court”: “High Quality” | “Average Quality” | “Poor Quality”
-
Request:
{ "about_user": 8, "response": "Block User" }
-
Response: JSON Object, 201_CREATED
{ "id": 29, "survey": 7, "about_user": 8, "about_user_username": "Chad_the_GOAT", "about_court": null, "response": "Block User" }
---
### List Courts
> /court/
>
- Method: GET
- Permissions: Authenticated or Read-Only
- Response: 200_OK
```json
{
"id": 1,
"park_name": "State Road Park",
"court_count": 2,
"court_surface": "Hard Court",
"address": {
"id": 1,
"court": "State Road Park",
"address1": "123 State Rd",
"address2": null,
"city": "Durham",
"state": "NC",
"zipcode": "27705"
}
}
```
### Create Court
> /court/
>
- Method: POST
- Permissions: Authenticated or Read-Only
- Request:
```json
{
"park_name": "Big Oaks Park",
"court_count": 6,
"court_surface": "Hard Court"
}
```
- Response: JSON Object, 201_CREATED
```json
{
"id": 2,
"park_name": "Big Oaks Park",
"court_count": 6,
"court_surface": "Hard Court",
"address": null
}
```
### List Court Address
> /court/<int:pk>/address/
>
- Method: GET
- Permissions: Authenticated or Read-Only
- Response: 200_OK
```json
{
"id": 1,
"court": "State Road Park",
"address1": "123 State Rd",
"address2": null,
"city": "Durham",
"state": "NC",
"zipcode": "27705"
}
```
### Create Court Address
> /court/<int:pk>/address/
>
- Method: POST
- Permissions: Authenticated or Read-Only
- Request:
```json
{
"address1": "5578 Main St",
"address2": null,
"city": "Cary",
"state": "NC",
"zipcode": "90210"
}
```
- Response: JSON Object, 201_CREATED
```json
{
"id": 2,
"court": "Big Oaks Park",
"address1": "5578 Main St",
"address2": null,
"city": "Cary",
"state": "NC",
"zipcode": "90210"
}
```
### Update Court Address
> /court/<int:pk>/address/
>
- Method: PATCH
- Permissions: Authenticated or Read-Only
- Request:
```json
{
"zipcode": "90210"
}
```
# Notifications
---
### Notification Events
The following conditions will trigger a notification to be sent to…
- Guest when game session host has changed their status
- Game session host when guest has signed up
- Guests when game session host cancels game
- Game session host when accepted guest backs out
### Check Notifications
> /notification/check/
>
- Method: GET
- NOTE: This endpoint changes notification “read” status to true and can only be called once for unread notifications
- Permissions: Authenticated
- Response: 200_OK
```json
[
{
"id": 12,
"sender": 4,
"reciever": 2,
"message": "Sam Has backed out of the game",
"game_session": 11,
"read": true
}
]
```
### Count Notifications
> /notification/count/
>
- Method: GET
- NOTE: This endpoint should be called frequently to check count of new notifications by taking the length of the returned array
- Permissions: Authenticated
- Response: 200_OK
```json
[
{
"id": 12,
"sender": 4,
"reciever": 2,
"message": "Sam Has backed out of the game",
"game_session": 11,
"read": false
}
]
```
### List All Previous Notifications
> /notification/all/
>
- Method: GET
- Permissions: Authenticated
- Response: 200_OK
```json
[
{
"id": 12,
"sender": 4,
"reciever": 2,
"message": "Sam Has backed out of the game",
"game_session": 11,
"read": true
}
]
```
..
This project uses PostgreSQL 14.4.
Install PostgreSQL:
brew install postgresql
Start PostgreSQL:
brew services start postgresql
When creating a local database, it is generally considered good practice to use the same name for username and database name.
Create a user:
createuser -d <username>
Create a database:
createdb -U <username> <dbname>
Install a Python PostgreSQL adapter:
pipenv install psycopg2-binary
Create a .env file in /core directory:
touch ./core/.env
Refer to .env.sample for how to configure your local copy of .env. Include a database url with the following syntax:
DATABASE_URL=postgres://<username>:@127.0.0.1:5432/<dbname>
python manage.py runserver
Postico and Dbeaver are great tools to that provide a GUI to interact with your database. Insomnia is a great way to query your server, whether local or remote. All three are available on Homebrew.