-
Notifications
You must be signed in to change notification settings - Fork 0
Home
The Flickshare App is directed for anyone who really has a hard time finding suggestions on what to watch next! The app allows users to create an account and custom lists of movie interests, which may then be used to generated a list of suggestions and store them for coming back to it later.
This API stop represents a way for the app to communicate with the list of users, movie lists and movies. The user data contains full name, email, username, password and admin privileges. The list data contains a name and an associated user.
https://cryptic-badlands-24275.herokuapp.com/ - (Landing)
(Pending)
https://github.com/dionisggr/flickshare-client/
- As a prospective user
- I am landed in the Welcome Page
- I can see the week's top movie suggestions per category
- I can navigate to the Register and Login pages
- As a registered user
- I can create and name a list
- I can search for a movie to select for a list
- I can search, edit and delete my list
- I can browse my friends' top public lists
- I can send friends movie suggestions
- I can like movies in lists
- I can dislike movie suggestions directed to me
- I can select a movie to learn more details about it
- As an Admin
- I can see, edit and delete users
- I can see, edit and delete movies
- I can see, edit and delete lists
- I can reset likes in movies
- I can reset suggestion algorithms for users
- Front-End:
- Back-End: Javascript, Node.js, Express.js, Knex.js, PostgreSQL, Mocha, Chai, Supertest, Nodemon, Postgrator, Dotenv, JWT, Bcrypt, Morgan, XSS, CORS, Helmet, HTML5, CI scripts
- Development Environment: Heroku, DBeaver, Postman
The app's functionality includes:
- Every User
- May create an account
- May browse public suggestion lists
- May read full movie information
- Registered User
- May edit and delete their account
- May create, edit and delete their lists
- May generate suggestions from other lists
- May search for any movie
- Admin
- May see a list of all users
- May create, edit and delete any user
- May see a list of all lists
- May create, edit and delete any list
- May see a list of all users
-
Index.js - (stateless)
-
App.js - (stateful)
- Header.js - (stateless)
- MainMenu.js - (stateless)
- Register.js - (stateless)
- Login.js - (stateless)
-
WelcomePage.js - (stateful)
- Login.js - (stateful)
- Register.js - (stateful)
- Lists.js - (stateful)
- List.js - (stateful)
- Suggestions.js - (stateful)
-
Movie.js - (stateful)
-
MoviePreview.js - (stateful)
- MovieOptions.js - (stateful)
-
MoviePreview.js - (stateful)
- MovieSearch.js - (stateful)
-
Admin.js - (stateful)
- Users.js - (stateful)
-
User.js - (stateful)
- UserPreview.js - (stateless)
- UserEdit.js - (stateful)
- Error.js - (stateless)
- ErrorBoundary.js - (stateful)
- Footer.js - (stateless)
-
App.js - (stateful)
- Users (database table)
- user_id (integer, auto-generated)
- first_name (text, not null)
- last_name (text, not null)
- email (text, unique)
- username (text, unique)
- password (text, hashed)
- admin (boolean, default false)
- Lists (database table)
- list_id (integer, auto-generated)
- name (text, not null)
- user_id (integer, optional)
- Movies (database table)
- movie_id (integer, auto-generated)
- name (text, not null)
- tmdb_id (integer, id from tmdb API)
- description (text, maximum 150 characters)
- release_date (text, not date)
- popularity (numeric, decimal)
- poster (text, poster image URL)
- avg_vote (numeric)
- vote_count (integer)
- List Movies (database table)
- list_id (references lists.list_id)
- movie_id (references movies.movie_id)
Closed endpoints that require a valid username and password to be included in the header body of the request.
- Step 1: (Generate JSON Web Token)
-
POST /api/login
- 'Admin' credentials
- Username:
admin
- Password:
password
- Username:
- 'Admin' credentials
-
- Step 2: <Use generated JSON Web Token (3 hrs)>
- Step 3 (Optional): Refresh JSON Web Token
POST /api/token
Closed endpoints that require a valid JSON Web Token to be inlcuded in the header 'Authorization' of the request.
// Add to request header
headers: {'Authorization': 'Bearer <JSON Web Token>'}
If sending content through request body (POST
), don't forget to add the following in the headers:
// Add to request header
headers" {'Content-Type': 'application/json'}
Each endpoint manipulates information related to users.
-
Create User (Register):
POST /api/users
-
Get User:
GET /api/users/:user
-
Edit User:
PATCH /api/users/:user
-
Delete User:
DELETE /api/users/:user
URL: /api/users
Method: GET
Auth required: Yes
Bearer my-secret-admin
Code: 200 OK
Content example
[
{
"username": "dschrute",
"first_name": "Dwight",
"last_name": "Schrute",
"email": "schrutefarms@creedmail.com",
"admin": false
},
...
]
URL: /api/users
Method: POST
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Requires headers: {'Content-Type': 'application/json'}
{
"username": "rhoward",
"password": "password",
"first_name": "Ryan",
"last_name": "Howard",
"email": "commited@wuphf.com",
"admin": false
}
Name | Type | In | Description |
---|---|---|---|
username |
string | header | Unique username |
password |
string | header | User password |
first_name |
string | header | First name of user |
last_name |
string | header | Last name of user |
email |
string | header | User email |
admin |
boolean | header | Admin privileges |
Code: 201 Created
Content example
{
"user_id": 4
"username": "rhoward",
"first_name": "Ryan",
"last_name": "Howard",
"email": "commited@wuphf.com",
"admin": false
}
URL: /users/:userID
Method: PATCH
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Requires headers: {'Content-Type': 'application/json'}
{
// All optional, at least one required.
"username": "rhoward",
"first_name": "Ryan",
"last_name": "Kapoor", // Edited
"email": "taken@wuphf.com", // Edited
"admin": false
}
Name | Type | In | Description |
---|---|---|---|
user |
integer | path | User ID |
username |
string | header | Unique username |
first_name |
string | header | First name of user |
last_name |
string | header | Last name of user |
email |
string | header | User email |
admin |
boolean | header | Admin privileges |
Code: 201 Created
(Resource updated successfully, and refreshes.)
Content example
{
"user_id": 4
"username": "rhoward",
"first_name": "Ryan",
"last_name": "Kapoor",
"email": "taken@wuphf.com",
"admin": false
}
All values will be necessary in Update due to previous empty field validation
URL: /users/:user
Method: DELETE
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
-
Bearer <JSON Web Token>
(Generated at Login. See above for instructions)
Name | Type | In | Description |
---|---|---|---|
user |
integer | path | User ID |
Code: 301 Moved Permanently
Content example
<No Content>
Each endpoint manipulates information of general and user lists.
-
Get Main Lists:
GET /api/lists/main
(General suggestion/category lists not associated to users) -
Create List:
POST /api/lists
-
Get List:
GET /api/lists/:list
-
Edit List:
PATCH /api/lists/:list
-
Delete List:
DELETE /api/lists/:list
Each endpoint manipulates information related to movie data.
-
Get All Movies:
GET /api/movies
-
Add Movie to Database:
POST /api/movies
-
Get Movie:
GET /api/movies/:movie
URL: /api/movies
Method: GET
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Code: 200 OK
Content example
[
{
"movie_id": 1,
"name": "Man of Steel",
"description": "Come on, it's Man of Steel.",
"tmdb_id": 99999,
"releaste_date": 2013,
"popularity": 987.72
"avg_vote": 7.4,
"vote_count": 9,876
"poster": "https://image.tmdb.org/t/p/original/manofsteel.jpg",
},
...
]
URL: /api/movies/:movie
Method: GET
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Code: 200 OK
Content example
[
{
"movie_id": 1,
"name": "Man of Steel",
"description": "Come on, it's Man of Steel.",
"tmdb_id": 99999,
"releaste_date": 2013,
"popularity": 987.72
"avg_vote": 7.4,
"vote_count": 9,876
"poster": "https://image.tmdb.org/t/p/original/manofsteel.jpg",
},
...
]
URL: /api/movies
Method: POST
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Requires headers: {'Content-Type': 'application/json'}
{
"name": "The Dark Knight",
"description": "No description necessary.",
"tmdb_id": 99998,
"release_date": 2008,
"popularity": 985.27
"avg_vote": 6.9,
"vote_count": 8,517
"poster": "https://image.tmdb.org/t/p/original/thedarkknight.jpg"
}
Name | Type | In | Description |
---|---|---|---|
name |
string | header | Name of project |
description |
string | header | Description of project |
tmdb_id |
string | header | Languages/Tools required |
release_date |
string | header | Project Phase |
popularity |
string | header | Project Phase status |
avg_vote |
string | header | Creator of project |
vote_count |
string | header | Date created |
poster |
boolean | header | Accepts collaboration |
Code: 201 Created
Content example
{
"movie_id": 2,
"name": "The Dark Knight",
"description": "No description necessary.",
"tmdb_id": 99998,
"releaste_date": 2008,
"popularity": 985.27
"avg_vote": 6.9,
"vote_count": 8,517
"poster": "https://image.tmdb.org/t/p/original/thedarkknight.jpg"
}
URL: /api/movies/lists/:list
Method: POST
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Requires headers: {'Content-Type': 'application/json'}
{
"movie_id": 1
}
Name | Type | In | Description |
---|---|---|---|
list |
integer | path | List ID |
movie_id |
integer | header | Movie ID |
Code: 201 Created
Content example
<No Content>
URL: /api/movies/:movie
Method: DELETE
Auth required: Yes
Bearer my-secret-admin
Name | Type | In | Description |
---|---|---|---|
movie |
integer | path | Movie ID |
Code: 301 Moved Permanently
Content example
<No Content>
URL: /api/movies/:movie/lists/:list
Method: DELETE
Auth required: Yes
Bearer my-secret-admin
Bearer <JSON Web Token>
Name | Type | In | Description |
---|---|---|---|
movie |
integer | path | Movie ID |
list |
integer | path | List ID |
Code: 301 Moved Permanently
Content example
<No Content>
Each endpoint manipulates information related to the movies in lists.
-
Get List Movies:
GET /api/movies/lists/:list
-
Add Movie to list:
POST /api/movies/lists/:list
-
Delete Movie from list:
DELETE /api/movies/:movie/lists/:list
URL: /api/lists
Method: GET
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Code: 200 OK
Content example
[
{
"list_id": "1",
"name": "Admin list",
"user_id": 1,
"movies": [...]
},
{
"list_id": "2",
"name": "Top Rated",
"user_id": null,
"movies": [...]
}
...
]
URL: /api/lists/main
Method: GET
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Code: 200 OK
Content example
[
{
"list_id": "2",
"name": "Top Rated",
"user_id": null,
"movies": [...]
},
{
"list_id": "3",
"name": "Popular",
"user_id": null,
"movies": [...]
}
...
]
URL: /api/lists
Method: POST
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Requires headers: {'Content-Type': 'application/json'}
{
"name": "New List Name",
"user_id": 1 // Optional
}
Name | Type | In | Description |
---|---|---|---|
name |
string | header | Name of list |
user_id |
integer | header | Description of list |
Code: 201 Created
Content example
{
"list_id": 3,
"name": "New List Name",
"user_id": 1
}
URL: /api/lists/:list
Method: PATCH
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Requires headers: {'Content-Type': 'application/json'}
{
"name": "New Name"
}
Name | Type | In | Description |
---|---|---|---|
list |
integer | path | List ID |
name |
string | header | Name of list |
Code: 201 Created
(Resource updated successfully, and refreshes.)
Content example
{
"list_id": 3,
"name": "New Name",
"user_id": 2
}
All values will be necessary in Update due to previous empty field validation
URL: /api/lists/:list
Method: DELETE
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Name | Type | In | Description |
---|---|---|---|
list |
integer | path | LIst ID |
Code: 301 Moved Permanently
Content example
<No Content>
Each endpoint manipulates information related access / token management.
-
Login:
POST /api/login
-
Register:
POST /api/users
-
Refresh JWT Token:
PATCH /api/token
URL: /api/login
Method: POST
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
####### Request Body
{
"username": "admin",
"password": "password",
}
Name | Type | In | Description |
---|---|---|---|
username |
string | header | Unique username |
password |
string | header | User password |
Code: 200 OK
Content example
{
"flickshareToken": <JSON Web Token>
}
URL: /api/token
Method: GET
Auth required: Yes
Bearer <JSON Web Token>
Code: 200 OK
Content example
{
"flickshareToken": <JSON Web Token>
}
URL: /api/users
Method: POST
Auth required: Yes
Bearer my-secret-key
Bearer my-secret-admin
Bearer <JSON Web Token>
Requires headers: {'Content-Type': 'application/json'}
{
"username": "rhoward",
"password": "password",
"first_name": "Ryan",
"last_name": "Howard",
"email": "commited@wuphf.com",
"admin": false
}
Name | Type | In | Description |
---|---|---|---|
username |
string | header | Unique username |
password |
string | header | User password |
first_name |
string | header | First name of user |
last_name |
string | header | Last name of user |
email |
string | header | User email |
admin |
string | header | Admin privileges |
Code: 201 Created
Content example
[
{
"user_id": "4"
"username": "rhoward",
"first_name": "Ryan",
"last_name": "Howard",
"email": "commited@wuphf.com",
"admin": false
},
...
]
Each endpoint manipulates information related to all data, only able to be accessed by an Admin user. Admins can manipulate all previous endpoints as well.
-
Get All Users:
GET /api/users
-
Get All Lists:
GET /api/lists
This is v1.0 of the app, but future enhancements are expected to include:
- Implementation of movie likes
- Implementation of list likes
- Sending movie-list suggestions
- Copy other user's lists
Start a database server with pg_ctl start
.
If using user admin
:
mv example.env .env
createdb -U admin flickshare
createdb -U admin flickshare-test
If your admin
user has a password be sure to set it in .env
for all appropriate fields. Or if using a different user, update appropriately.
npm install
npm run migrate
env MIGRATION_DB_NAME=flickshare-test npm run migrate
To start the application, use npm start
. Tests will run automatically.
Alternatively, to run development mode, use npm run dev
. Tests will not run.
To seed the database: psql -U admin -d flickshare -f ./seeds/seed.flickshare.sql
.
And npm test
should work at this point.
For tests involving time to run properly, configure your Postgres database to run in the UTC timezone.
- Locate the
postgresql.conf
file for your Postgres installation.- E.g. for an OS X, Homebrew install:
/usr/local/var/postgres/postgresql.conf
- E.g. on Windows, maybe:
C:\Program Files\PostgreSQL\11.2\data\postgresql.conf
- E.g on Ubuntu 18.04 probably: '/etc/postgresql/10/main/postgresql.conf'
- E.g. for an OS X, Homebrew install:
- Find the
timezone
line and set it toUTC
:
# - Locale and Formatting -
datestyle = 'iso, mdy'
#intervalstyle = 'postgres'
timezone = 'UTC'
#timezone_abbreviations = 'Default' # Select the set of available time zone