# Be-Kind Re-Mind

---
#### Planning
- First we listed out the user stories for our project on our project board
- We categorised each of the user stories into big issues where we split the task of into front-end and back-end
- We also had smaller issues for researching new technologies and smaller tasks
---

---
- We planned to create the front-end first so we had a visual understanding of where data will be retrieved and sent to and later on it will help with what we would also add to the database that we wouldn't have intially known if we hadn't created the front-end
---
- we created all of the core pages such as the homepage and medication page, later on added the add medication form
- Since we had the front end set up we decided to then go on to work onto user authentication/ creating db queries add/delete medication
---
#### DB Schema :elephant:
- Hosted on elephant SQL
- 4 tables to store users, sessions, user record and medications
---

---
#### Add Medication :heavy_plus_sign:
- Medication page in next which includes a component which submits a form containing the users information about their medication.
- The forms submits to an api end point "update-medlist".
- This performs a SQL query in the model file which adds the information into the elephant SQL DB and re-directs to the medication page.
---
- Then we use server side props on the medication page to do another SQL query to get all medications from the DB and pass these down as props to insert the information into the components via a map to create `li`.
- Learning: Keeping the form on one page to keep track of information, unsure about issue with crashing? :exploding_head:
---
#### Delete Medication :negative_squared_cross_mark:
- Inside of the mapped `li` we created a form
```
<form method="POST" action="/api/delete-med">
<input
type="hidden"
id="deleteInput"
name="id"
value={medication.id}
/>
<button type="submit">Delete Medication</button>
```
---
#### Continued...
- send information to api end point.
- calls SQL query in the model file to delete medication from the table and the page will re-render going through the same process as before with the removed medication.
Issues: `error: update or delete on table "medications" violates foreign key constraint "record_med_id_fkey" on table "record"`
---
#### Fix :sparkles:

---
#### ON DELETE SET NULL
* NO ACTION is assigned by default, PostgreSQL issues a constraint violation because the referencing rows of the customer id 1 still exist in the contacts table.
* The `SET NULL` automatically sets NULL to the foreign key columns in the referencing rows of the child table when the referenced rows in the parent table are deleted.This is actioned on the `ON DELETE` clause:
---
### Auth 🔐
---
### Goals 🎯
+ Sign up - Add user to user table, hash password and issue sid cookie
+ Log in - issue sid cookie
+ Log out - delete session from db
+ Middleware - verify users and check for unauthenticated users
+ getUserInfo = use the cookie sid to look up the user_id and identify user
+ handling sign up and login errors
---
#### Issues 🚨
+ comparing hashed passwords directly in postgres 🙈 (bcrypt.compare() is the tool for the job!)
+ duplication of sid cookies occurred on failure to logout properly
+
---
#### Code example: cookies 🍪
We had cookie setting problems:
```js
res.setHeader("set-cookie", `sid=${sid}; ${cookie_options}`);
```
Workaround was to use 'cookies' npm package:
```
npm install cookies
import Cookies from "cookies";
const cookies = new Cookies(req, res);
cookies.set("sid", ${sid}, {
httpOnly: true, // true by default
maxAge: cookie_options.maxAge,});
```
---
#### Todo
+ Client side validation on form on login and sign-in inputs
---
#### Heatmap plans :fire:
- Record table will store a history of when meds were or weren't taken: `taken: true`
- Shift from calendar :calendar: to heatmap :fire:
- Clickable tiles :crossed_fingers:
- Research spike planned as part of next sprint for node modules :thinking_face:
---
#### In-app Notification and unfinished business...
- Aim: render notification which lists that day's medication not yet taken
- Set up db query to return records and converted SQL date into JS date
```
cleanRecord[
{ id: 2, date: "Wed Mar 02", user_id: 1, med_id: 2, taken: false },
{ id: 3, date: "Wed Mar 02", user_id: 1, med_id: 3, taken: false },
{ id: 4, date: "Wed Mar 02", user_id: 1, med_id: 1, taken: false }
];
```
---
- Once users record is returned need to use the `med_id` of each record to access the full medication details and render info on page
- Initial approach promises and maps :dizzy_face:
- Tried to map over array of cleanRecord and run db query for each `med_id`
---
- Does not work as map is a synchronous, higher order function so does not wait for the db query to return, instead returns an empty array
``` javascript
//cleanRecord is the array of records with the date cleaned
const fullMedDetails = cleanRecord.map((record) => {
const fullMedDetailsArray = [];
//uses medication id to query db and return the full details for that med
retrieveMedDetails(record.med_id).then((result) => {
let medDetails = result;
fullMedDetailsArray.push(medDetails);
//51 logs the array with all the details successfully pushed
console.log("51 full med details array", fullMedDetailsArray);
});
//line 53 console log returning BEFORE line 51
console.log("53 full med details array", fullMedDetailsArray);
return fullMedDetailsArray;
});
```
---
- Not yet resolved :thumbsdown:
- refactoring and trying a new approach next week :thinking_face:
- Possible approaches:
- exploring async await with map
- nested SQL queries
*__To be continued....__*
---
#### Group learnings :seedling:
* Using elephant SQL, important to let your team know if your re-populating.
* Never under-estimate authentication, and sometimes having a break of this is not a bad idea!
---
* expected 18
* actual 18
---
### DEMO
https://be-kind-re-mind-ten.vercel.app/