Backend Deployed On Heroku https://clone-coding-server.herokuapp.com/
- yarn install to install all required dependencies
- yarn dev to start the local server
- yarn test to start server using testing environment
- yarn db_start_dev to start docker development Postgres database
- yarn db_start_test to start docker testing database
- yarn db_reset_dev to migrate and rollback seeds in developer database
- yarn db_reset_test to migrate and rollback seeds in developer tests
- yarn db_stop_dev burns down development database
- yarn db_stop_test burn down testing database
- Minimal and flexible
- Highly customizable
- Written in Javascript, allowing us to write in same language for frontend and backend
- Compatible with AuthO libraries
- GET /api/users
- Get logged in user profile information
- Can be used to get the role of the user
- Can be used to get the user's picture or nickname
- Get logged in user profile information
- GET /api/categories
- Get an array of categories for:
- Create Challenge Form
- Search Challenges Category Filter
- Use the challenges query param to only get back categories that have been attached to challenges
- Get an array of categories for:
- POST /api/categories/challenges
- Attach categories to challenges:
- Accepts a single category or multiple categories
- Attach categories to challenges:
- POST /api/challenges
- Create a new code challenge
- PUT /api/challenges
- Edit a code challenge
- Admins can approve a challenge
- Edit a code challenge
- GET /api/challenges
- Get code challenge(s)
- All users can get approved challenges
- Filter challenges by numerous query parameters
- Users can get unapproved challenges they created
- Admins can get any unapproved challenges
- Get code challenge(s)
- POST /api/submissions
- Create a new submission
- User is starting a code challenge
- Create a new submission
- GET /api/submissions
- Get submission(s)
- Users can get all submissions they created
- Users can get all submissions they completed
- Users can get all submissions they started
- Users can get a submission for a specific challenge
- Get submission(s)
- PUT /api/submissions/exec
- User executed code client-side while attempting a challenge
- Users can optionally update their answer
- User executed code client-side while attempting a challenge
- PUT /api/submissions/test
- User executed tests client-side while attempting a challenge
- Users can optionally update their answer
- User executed tests client-side while attempting a challenge
- PUT /api/submissions/attempt
- User submitted their solution for a code challenge
- Users can optionally update their answer when validating
- User submitted their solution for a code challenge
- PUT /api/submissions/reset
- User can reset an already completed challenge to retake it
- Get user profile information
- User ID is acquired using the access token in the Authorization header
- Will return an error if token is invalid
- Can be used to confirm user is logged in
{
}
{
id: INTEGER
xp: INTEGER
role: STRING
}
- Get an array of category information
- challenges - BOOLEAN - Optional - Filter for categories that have been attached to challenges. Returns the same whether true or false.
{
}
[
{
id: INTEGER
name: STRING
created_at: DATE
}
]
- Accepts an array of objects (or a single object) containing category and challenge information
[
{
challenge_id: INTEGER - Required
category_id: INTEGER - Required
},
...
]
{
challenge_id: INTEGER - Required
category_id: INTEGER - Required
}
{
id: NUMBER
approved: BOOLEAN
title: STRING
description: STRING
tests: JSON
skeleton_function: STRING
solution: STRING
difficulty: INTEGER
popularity: INTEGER
challenges: [
{
id: NUMBER
name: STRING
},
{
id: NUMBER
name: STRING
},
...
]
}
- Any registered user can create a challenge
- Challenges need to be manually approved by an administrator
{
title: STRING - Required - **Unique**
description: STRING - Required
tests: JSON - Required, [description:STRING,arguementToPass:ARRAY,expectedResult:NOT UNDEFINED]
skeleton_function: STRING - Required
solution: STRING - Required
difficulty: INTEGER - Required - Inbetween 1 to 100 (inclusive)
}
{
id: INTEGER
title: STRING
description: STRING
tests: JSON
skeleton_function: STRING
solution: STRING
difficulty: INTEGER
popularity: INTEGER
challenges: [
{
id: NUMBER
name: STRING
},
{
id: NUMBER
name: STRING
},
...
]
}
- Currently only used for admins to approve challenges
{
id: INTEGER - Required
approved: BOOLEAN - Required
}
{
id: INTEGER
title: STRING
description: STRING
tests: JSON
skeleton_function: STRING
solution: STRING
difficulty: INTEGER
popularity: INTEGER
challenges: [
{
id: NUMBER
name: STRING
},
{
id: NUMBER
name: STRING
},
...
]
}
- Any registered user can access this endpoint
- Returns an array of challenges
- Returns all approved challenges by default
- Query parameters can be used to filter results
- Regular users can only access approved challenges they did not create, and unapproved challenges that they created
- Admins can access all challenges
- difficulty: RANGE (STRING) - Optional - '1-100' (all), '1-33' (easy), '33-66' (medium), or '66-100' (hard)
- approved: BOOLEAN - Optional - Whether the challenge should be approved or unapproved
- id: NUMBER - Optional - ID of challenge
- category_name: STRING - Optional - Search by name of category - Case insensitive and partial match supported
- title: STRING - Optional - Search by title of challenge - Case insensitive and partial match supported
- category_id: NUMBER - Optional - ID of category
- created: Boolean - Optional - Currently only works for true
- completed: Boolean - Optional - Currently only works for true
- started: Boolean - Optional - Currently only works for true
{
}
[
{
id: NUMBER
approved: BOOLEAN
title: STRING
description: STRING
tests: JSON
skeleton_function: STRING
solution: STRING
difficulty: INTEGER
popularity: INTEGER
challenges: [
{
id: NUMBER
name: STRING
},
{
id: NUMBER
name: STRING
},
...
]
}
]
- Needs the ID of the challenge
- Automatically populates a skeleton function
{
challenge_id - INTEGER - Required
}
{
id - INTEGER
challenge_id - INTEGER
attempts - INTEGER
total_attempts - INTEGER
code_execs - INTEGER
total_code_execs - INTEGER
test_execs - INTEGER
total_test_execs - INTEGER
completed - BOOLEAN
solution - STRING
}
- Any registered user can access this endpoint
- Users can only access their own submissions
- Object-literal query parameters located in req.query can be used to filter query results
- Returns an array of submissions
- challenge_id - INTEGER - Optional
- completed - BOOLEAN - Optional
{
}
[
{
id - INTEGER
challenge_id - INTEGER
attempts - INTEGER
total_attempts - INTEGER
code_execs - INTEGER
total_code_execs - INTEGER
test_execs - INTEGER
total_test_execs - INTEGER
completed - BOOLEAN
solution - STRING
}
]
- Requires the ID of the submission
- Saves a user's solution if included in the request
- Users can only update their own submissions
- Increments
code_execsandtotal_code_execsby one
{
id: NUMBER - Required - ID of the submission
solution: STRING - Optional
}
{
id - INTEGER
challenge_id - INTEGER
attempts - INTEGER
total_attempts - INTEGER
code_execs - INTEGER
total_code_execs - INTEGER
test_execs - INTEGER
total_test_execs - INTEGER
completed - BOOLEAN
solution - STRING
}
- Requires the ID of the submission
- Saves a user's solution if included in the request
- Users can only update their own submissions
- Increments
test_execsandtotal_test_execsby one
{
id: NUMBER - Required - ID of the submission
solution: STRING - Optional
}
{
id - INTEGER
challenge_id - INTEGER
attempts - INTEGER
total_attempts - INTEGER
code_execs - INTEGER
total_code_execs - INTEGER
test_execs - INTEGER
total_test_execs - INTEGER
completed - BOOLEAN
solution - STRING
}
- Validates that a user has the correct answer
- Needs the ID of the applicable user_submission entry
- Users can only attempt submissions they created
- Updates users solution if provided in request
- Users can only attempt uncompleted challenges
- If completed, users need to reset their submission in order to attempt the challenge again via PUT /api/submissions/reset
{
id: STRING - Required - ID of the applicable user_submission
solution: STRING - Optional
}
{
id - INTEGER
challenge_id - INTEGER
attempts - INTEGER
total_attempts - INTEGER
code_execs - INTEGER
total_code_execs - INTEGER
test_execs - INTEGER
total_test_execs - INTEGER
completed - BOOLEAN
solution - STRING
}
- Requires the ID of the submission
- Users can only reset their own submissions
- Users can only reset completed challenges
{
id: NUMBER - Required - ID of the submission
}
{
id - INTEGER
challenge_id - INTEGER
attempts - INTEGER
total_attempts - INTEGER
code_execs - INTEGER
total_code_execs - INTEGER
test_execs - INTEGER
total_test_execs - INTEGER
completed - BOOLEAN
solution - STRING
}
{
id: UUID
created_at: DATETIME - Optional - Defaults to current time
sub_id: STRING - Required - Unique - Auth0 sub id
}
{
id: UUID
created_at: DATETIME - Optional - Defaults to current time
name: STRING - Required - Unique
}
{
id: UUID
created_at: DATETIME - Optional - Defaults to current time
created_by: UUID - Required - Foreign key in USERS table
title: STRING - Required - Unique
description: STRING - Required
tests: JSON - Required
skeleton_function: STRING - Required
solution: STRING - Required
difficulty: STRING - Required
approved: BOOLEAN - Optional - Defaults to false
}
{
id: UUID
challenges_id: UUID - Required - Foreign key in CHALLENGES table
category_id: UUID - Required - Foreign key in CATEGORIES table
}
{
id: UUID
created_at: DATETIME - Optional - Defaults to current timestamp
created_by: UUID - Required - Foreign key in USERS table
challenge_id: UUID - Required - Foreign key in CHALLENGES table
code_execs: INTEGER - Required - Defaults to 0
total_code_execs: INTEGER - Required - Defaults to 0
test_execs: INTEGER - Required - Defaults to 0
total_test_execs: INTEGER - Required - Defaults to 0
attempts: INTEGER - Required - Defaults to 0
total_attempts: INTEGER - Required - Defaults to 0
completed: BOOLEAN - Optional - Defaults to false
solution: STRING - Optional - Defaults to skeleton code
}
- DATABASE_URL
- NODE_ENV
- DB_IP
