diff --git a/requirements/100.md b/requirements/100.md deleted file mode 100644 index 2ec988ef7c..0000000000 --- a/requirements/100.md +++ /dev/null @@ -1,33 +0,0 @@ -# Level 100 - Week 1 - Defining requirements - -In the first week, we will build an MVP - a **Minimum Viable Product**. This is a product with the bare minimum of features to demonstrate a concept to an end user. It will likely not be nice, but it can already be shown to your peers to check and comment on. The MVP for the project we are doing is the ability to show a list of pre-defined videos to the user. - -We will split this MVP into three sections - the data model, the API and the frontend. We will work on these sections separately in the `requirements`. - -## User stories - -Both before we start we need to describe what we want to achieve. One way to do that is using user stories. - -A definition of user stories from [Atlassian](https://www.atlassian.com/agile/project-management/user-stories) is the following: - -> A user story is an informal, general explanation of a software feature written from the perspective of the end user or customer. The purpose of a user story is to articulate how a piece of work will deliver a particular value back to the customer. -> -> User stories are often expressed in a simple sentence, structured as follows: -> -> `As a [persona], I [want to], [so that].` - -Let's try to define user stories for our MVP: - -- As a CYF trainee, I want to show my favourite videos so my friends know what videos I like -- As an end user, I want to see my friend's recommended videos so I can watch them myself - -You can also go down with a bit more detail: - -- As an end user, I want to see the title of each video so I know what the video is about -- As an end user, I want to be able to go to YouTube by clicking any of the titles so I can watch the recommendation - -This is what we will define as the MVP and what we will try to implement during the first week - -## Next Level - -Once finished you can go to [Level 105](./105.md) diff --git a/requirements/105.md b/requirements/105.md deleted file mode 100644 index 275984bb3b..0000000000 --- a/requirements/105.md +++ /dev/null @@ -1,56 +0,0 @@ -## Level 105 - Week 1 - Setting up the project 🧰 - -We have set up an initial project for you to help with some of the complexities of the assessment. This project requires Node.JS version 20 or later. Make sure you have at least Node version 20 running: - -```sh -node -v -``` - -The version number should be `v20.6.0` or higher: - -``` -v20.8.0 -``` - -If this is lower, like `v18.18.2`, or `v20.5.5` you will need to install a more recent version of Node.JS. Refer to the [node installation guides](https://nodejs.org/en/download/package-manager) for your operating system. For Ubuntu based systems [NodeSource](https://github.com/nodesource/distributions) is usually a good way to do it. - -Once you have confirmed that your node version is recent enough you can install the requirements. Change directory to the root of your monorepo. Then run the following commands: - -```sh -npm install -``` - -Then to start up your frontend and backend locally, you can run - -```sh -npm run dev -``` - -To confirm your server is running go to - -```url -http://127.0.0.1:3100/health -``` - -in your browser. If the server is running you'll see a message saying - -```json -OK -``` - -## Before you commit your changes - -Read this [article on .gitignore](https://sabe.io/blog/git-ignore-node_modules). We have set up a basic `.gitignore` file for you. - -## Monorepo - -The project is set up to run as a monorepo, where both the [`client`](../client/) and [`server`](../server/) source code are in the same git repository and are linked together. When using monorepos, there is some boilerplate code required to make sure both the frontend and the backend application can work at the same time and are accessible on the same URL. To kickstart your development we have set up this boilerplate code for you already. Feel free to look at the code, but generally you won't need to edit them if you follow the proposals in this guide. - -If you are interested you can read more about what they do in the following places: - -- [Client vite settings](../client/vite.config.js) -- [Server frontend middleware](../server/app.js) - -## Next Level - -Once finished you can go to [Level 110](./110.md) diff --git a/requirements/110.md b/requirements/110.md deleted file mode 100644 index 6fb7300fad..0000000000 --- a/requirements/110.md +++ /dev/null @@ -1,58 +0,0 @@ -# Level 110 - Week 1 - Data Model 📊 - -Level 110 will start the MVP of our small site that shows video links to the user. The first step is designing how we will store these videos in the database. - -## Designing the data model - -Make sure you design the data model that will hold the video recommendations. You need to make sure that you can store the following details: - -- Name of the video -- Link to the video - -You also need to make sure that each of the video can be uniquely addressed by some kind of an `ID`. - -Inside the `db` directory you will need to create a script called `initdb.sql`. Add any relevant `CREATE TABLE` calls that you need. We will call this your schema. - -## Initiating local database - -Once you have your schema ready, make sure you create a new database for yourself locally. For example, let's call it `videorec`. From a shell use `createdb` to create a new database for yourself: - -```bash -createdb videorec -``` - -Once it is created you can now try to load your file into the database using `psql`: - -```bash -psql -d videorec < db/initdb.sql -``` - -**Note:** Depending on how postgresql was installed for you, you might need to add some connectivity details to both `createdb` and `psql`: - -```bash -psql -h localhost -U username -d videorec < db/initdb.sql -``` - -In this example, we ask postgres to connect to your local database through `localhost` and use `username` as the user. - -## Re-running the script - -It is advised to make sure that the `initdb.sql` script can be run multiple times, and each run would reset the database to a known initial state. One way to do it is to add some SQL code to the start that would delete tables in case they exist, something like: - -```sql -DROP TABLE IF EXISTS videos CASCADE; -``` - -Try running your `initdb.sql` script multiple times with the `psql` code above to make sure every time you get a fresh and clean database without errors. - -## Sample data - -You will need some example video data in your database. Please check [the example data](./data/example_data.csv), and modify your `initdb.sql`. Add the relevant `INSERT INTO` calls that will add all of this example data every time you run `initdb.sql`. - -## Deploying the database - -Please follow the [Supabase deployment guide](https://cyf-curriculum.netlify.app/guides/deployment/supabase/) in the curriculum to register and deploy your database. After finishing the steps make sure you load up the `db/initdb.sql` there as well. You should also take note of the `DATABASE_URL` as you will require it during the deployment of the next level. - -## Next Level - -Once finished you can go to [Level 120](./120.md) diff --git a/requirements/120.md b/requirements/120.md deleted file mode 100644 index 4a604e3b80..0000000000 --- a/requirements/120.md +++ /dev/null @@ -1,77 +0,0 @@ -# Level 120 - Week 1 - Backend - -Level 120 will continue the MVP of our small site that shows video links to the user. The next step is getting our backend working. - -For this level, you need to design an endpoint that will list all videos. Endpoint designs are usually separated into the `HTTP Request Method` type and the route that the endpoint should exist on. For a recap on HTTP Request Methods you can read this guide here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods - -## Endpoint Definition - -### HTTP Method: `GET` - -### Route: `/api/videos` - -#### Acceptance criteria - -- The endpoint successfully connects to the configured database. -- The endpoint fetches and responds with all video records from the database. -- The endpoint returns a status code of 200 - -#### Example Response - -See [`example_response.json`](../data/example_response.json) as an example. This should be returned with a HTTP `200` status code. - -Inside `api.js` you can find an example of the first endpoint that you will need to make. - -**Note:** The project is set up so all backend endpoints will have `/api` as a prefix. This means for example that if you are asked to create a `GET /videos` endpoint that will be available at `http://127.0.0.1:3000/api/videos` - -**Note:** The example above is the most simple one that you can implement. If you wish to implement some optional features later, like error handling, you can deviate from it as you like. - -## Setup steps 🧰 - -Your server is expected to read data from the database we have set up earlier. To make sure it works you will need to make sure that the backend is configured for database access. - -There are two steps you need to do: - -1. Copy the `.env.example` file over to `.env` - -This file contains the settings for your application. Currently, the only environment variable you need is `DATABASE_URL` which looks as follows: - -``` -postgres://username:password@localhost:5432/database_name -``` - -Make sure you swap the `username`, `password` and `database_name` values with the database details that you have set up _locally_ during the Initiating local database step in level 110. - -2. Start using queries inside the api. - -The `api.js` file is already set up to connect to the database if the config is done properly. To query the database you can use requests like: - -```js -const response = await db.query("SELECT * FROM videos WHERE id = $1", [id]); -``` - -## Running locally - -Don't forget you can start up your server locally by running - -```sh -npm run dev -``` - -at the root of your repo. Your endpoint should be accessible at `http://127.0.0.1/3000/api/videos` - -**Note:** the backend will not automatically restart whenever you change your code, you need to stop the server running and restart it every time you want to see your changes. - -## Deployment - -Finally you will need to deploy your application. The demo project is already set up to work with Netlify, so please follow the [Netlify deployment guide](https://cyf-curriculum.netlify.app/guides/deployment/netlify/) to deploy your app. Make sure to read the notes on backend deployment as well. - -Don't forget to set up the database access during setup - you should connect the deployed app with the Supabase database you deployed during [level 110](./110.md). - -## Example - -Please check https://lvl120--cyf-fsa-solution.netlify.app/api/videos for an example solution of this level - -## Next Level - -Once finished you can go to [Level 130](./130.md) diff --git a/requirements/130.md b/requirements/130.md deleted file mode 100644 index 0dc5e84ac2..0000000000 --- a/requirements/130.md +++ /dev/null @@ -1,44 +0,0 @@ -# Level 130 - Week 1 - Frontend - -Level 130 will finalize our MVP by creating the frontend part, making sure that you have a simple page that displays the videos from your database. - -## Project setup - -Since we are using a monorepo, you can launch the frontend the same way you launch the backend. Run the following command in the root of your repo: - -```sh -npm run dev -``` - -The code you put under `client/src` will then be accessible on http://localhost:3000 - -## Implementing your frontend - -### Acceptance criteria - -- On page load, the website should display a list of video recommendations -- For each video recommendation: - - It should show the video's title - - If you click on the title it it should redirect you to the YouTube page for that video - -## API access from React - -Since we are using a monorepo, the API is accessible on the same base domain as the frontend. This means you can use calls like `fetch("/api/videos")` and it will call the endpoint you created in your backend. You don't need to worry about CORS requirements either. - -Checkout this cheat sheet to help you with the types of requests you'll need to be using with `fetch`: https://www.freecodecamp.org/news/fetch-api-cheatsheet/ - -## Styling - -While you are free to do styling on the result, as this is only an MVP you shouldn't spend too much time making the website look nice. - -## Deployment - -If you have set up Netlify deployment in [level 120](./120.md) this should now work automatically for the frontend as well. Make sure to test it out though. Once you have the url to your deployed frontend, add it to the **About** section on your Github repo ![about settings for github repo](about-githubrepo.png). Paste the URL to your deployed frontend into the website section. - -## Example - -Please check https://lvl130--cyf-fsa-solution.netlify.app for an example solution of this level - -## Next Level - -Once finished you can go to [Level 150](./150.md) diff --git a/requirements/150.md b/requirements/150.md deleted file mode 100644 index 14ff47daba..0000000000 --- a/requirements/150.md +++ /dev/null @@ -1,23 +0,0 @@ -# Level 150 - Week 1 - Checking Acceptance criteria - -Once you finish your work it is always good to go through what you have done and verify it. - -For this step let's revisit the user stories from Level 100: - -- As a CYF trainee, I want to show my favourite videos so my friends know what videos I like -- As end user, I want to see the trainee's recommended videos so I can watch them myself -- As end user, I want to see the title of each video so I know what the video is about -- As end user, I want to be able to go to YouTube by clicking any of the titles so I can actually watch the recommendation - -To check that your implementation adheres to the user stories above make sure to: - -### Acceptance criteria 📝 - -- [ ] Check that the website shows your favourite videos -- [ ] Check that you can send the website to your friends -- [ ] Check with your friends that they can also check your favourite videos -- [ ] Check that you and your friends can all see the titles of your videos, and if they click on them they get redirected to YouTube to watch those videos - -## Next Level - -Congratulations! You have finished your MVP! Feel free to look at [Level 199](./199.md) for some optional extras that will make your project stand out, or continue with the [Week 2 requirements](./200.md). diff --git a/requirements/199.md b/requirements/199.md deleted file mode 100644 index e64991a52b..0000000000 --- a/requirements/199.md +++ /dev/null @@ -1,114 +0,0 @@ -# Level 199 - Week 1 - Code quality improvements (Optional) - -While the following work items are completely optional, they will help you to make fewer mistakes as you continue with future requirements. It is generally a good idea to have them when working on projects of any size. - -## 1) Proper error handling - -You should make your system to be designed with error handling in mind. For example if the database cannot be accessed when you call `GET /api/videos`, then your backend endpoint should return a properly formatted error message with a HTTP `500` error code. - -Here is an example response: - -```json -{ "success": false, "error": "Could not connect to the database" } -``` - -**Note:** You can design how you return error messages differently than the above example. You could also try and merge the error and non-error response styles into one. For example the standard `200` response on the same endpoint could be something like the following: - -```json -{"success":true,"videos":[(...)]} -``` - -Once you do this on the backend you should also change your frontend, to make sure it handles errors that are received. For example if your frontend receives an error like above it might show a message like `"Could not connect to the database, please reload the page at a later time"`. - -**Note:** Once you add this feature, make sure you keep handling errors properly during the week 2 and week 3 requirements as well. - -### Example - -Please check https://lvl199--cyf-fsa-solution.netlify.app and https://lvl199--cyf-fsa-solution.netlify.app/api/videos for an example solution of this level - -## 2) Prettying and linting - -It is also usually a good idea to make sure that your code is formatted based on a single standard throughout, and also passes basic sanity checks. There are two projects that can usually help you with that: - -- `prettier` is a formatter that makes sure that your code is formatted the same way throughout. For example all files use `tab` characters for indenting. -- `eslint` is a linter that checks the code for common coding mistakes and warns you if it encounters any of them. It can also automatically fix some mistakes. - -Let's set up both of them! - -### `prettier` - -First install prettier into your `package.json` file: - -```sh -npm install prettier --save-dev -``` - -Next you will need a `.prettierrc` file in the root directory. We have already provided one for your convenience. - -You can now run prettier to check your files: - -```sh -npm exec prettier -- --check . -``` - -And also to automatically fix them: - -```sh -npm exec prettier -- --write . -``` - -If you don't want to type out these commands you can add them as `scripts` into your `package.json` file. For example you can add a line like: - -```json - "prettier": "prettier --write ." -``` - -to the scripts section, and then you'll be able to automatically pretty your files by typing: - -```sh -npm run prettier -``` - -### `eslint` - -Installing `eslint` is similar, but to get the most out of it you will need to install multiple projects: - -```sh -npm install eslint eslint-config-prettier eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-refresh eslint-plugin-react-hooks eslint-plugin-n eslint-plugin-jest eslint-plugin-jest-dom eslint-plugin-vitest eslint-plugin-testing-library @codeyourfuture/eslint-config-standard --save-dev -``` - -This will install `eslint`, and a couple plugins that help you with validating tests, JSX code and React components, like proper `useEffect` usage. - -You will also need to have multiple `.eslintrc.json` files, one for each project, tailored to that project's needs. These have also all been provided already. - -Once you have everything in place you can run the linter to check for common code mistakes: - -```sh -npm exec eslint . -``` - -You can also ask it to fix any issues it can automatically fix: - -```sh -npm exec eslint -- --fix . -``` - -Same as for `prettier`, you might want to add these commands to your `package.json` for easier access. - -### Checks during PRs - -It is a good idea to enforce running both the linter and prettier during PRs. One way to do that is to make sure GitHub runs these checks for every PR, blocking the PR in case the code doesn't pass these checks. We have already prepared the `.github/workflows/enforce-linting.yml` file that you can use to run checks on GitHub manually. If you also uncomment the `pull_request` line, you will enable GitHub to run these checks automatically on every PR. - -To confirm, the top of the file should look like this: - -```yaml -on: - workflow_dispatch: - pull_request: -``` - -**Note:** Make sure to have a full read of this file and try to figure out what it does. - -## Next Level - -Once finished you can go to [Level 200](./200.md) diff --git a/requirements/200.md b/requirements/200.md deleted file mode 100644 index 4e6c69f1d4..0000000000 --- a/requirements/200.md +++ /dev/null @@ -1,54 +0,0 @@ -# Level 200 - Week 2 - UX Improvements - -**Overview** - -Following feedback on the MVP, this iteration focuses on enhancing user experience through embedded videos, improved design, and accessibility considerations. - -## New Requirements - -### 1. Embedded Videos - -#### Acceptance Criteria - -- Users can view YouTube videos directly within the website, without external redirects. -- Videos are embedded using HTML ` - -``` - -Here to get from the title to the video container you need to go two levels up. First from `` to `

`, then from this `

` to `
`. If your website is structured differently you will need to update this in the tests. - -### Enable PR tests - -Tests are useful to run every time you create a PR to make sure you don't accidentally add or change code that breaks existing functionality. You can go to `.github/workflows/run-e2e.yml` and remove the comment from the line that says `pull_request:`. This will run the `npm run test:e2e` call every time you create a new PR blocking merging in case tests fail. - -### Add new test cases - -You might want to add tests to cover some additional scenarios. For example if you have opted into doing the ordering feature you might want to add a test that checks that sorting by ascending and descending really updates the page to sort accordingly. - -## Next Level - -Once finished please check if you have missed any optional features before, and finish them. If you have done all of them, then congratulations, you have finished this exercise 100%! - -Feel free to use this project as part of your portfolio. You might also use it as a base project to start with testing out new ideas, frameworks or deployment services. diff --git a/requirements/about-githubrepo.png b/requirements/about-githubrepo.png deleted file mode 100644 index b2e80d0e34..0000000000 Binary files a/requirements/about-githubrepo.png and /dev/null differ diff --git a/requirements/image.png b/requirements/image.png deleted file mode 100644 index b2e80d0e34..0000000000 Binary files a/requirements/image.png and /dev/null differ