Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
f25ca6c
updates readme
luishrd Jul 23, 2018
2e3ab3f
updates instructions
luishrd Aug 3, 2018
bbbe503
updates instructions
luishrd Aug 3, 2018
1c7060f
fixes typos
luishrd Sep 7, 2018
c3e26ec
updates instructions
luishrd Sep 7, 2018
cfe144d
updates instructions
luishrd Oct 12, 2018
60ebf2f
clarifies instructions
luishrd Oct 12, 2018
f3562b0
clarify instructions
luishrd Oct 12, 2018
10047c5
reformats readme to fit standard
ryan-hamblin Dec 28, 2018
6869240
clarifies instructions
ryan-hamblin Dec 28, 2018
3bb382d
formats bullets to checkboxes
ryan-hamblin Dec 28, 2018
8d0dc08
Update README.md
ryan-hamblin Jan 18, 2019
2661ddf
fixes typo
luishrd Jan 26, 2019
47504b8
updates instructions
luishrd Jan 26, 2019
653a675
updates .gitignore
luishrd Feb 22, 2019
aeb1269
fixes typos
luishrd Feb 22, 2019
040d482
updates instructions
luishrd Feb 22, 2019
52cd34c
First Commit
Kseniyapl Mar 23, 2019
8c6e549
Add Answers.md File
Kseniyapl Mar 23, 2019
560ab16
Add file structures and dependencies
Kseniyapl Mar 23, 2019
56689d9
Modified Knexfile.js
Kseniyapl Mar 23, 2019
1b64e02
Create Migrations And Seeds
Kseniyapl Mar 23, 2019
ff57bdb
Add Migrations and Seeds For Testing
Kseniyapl Mar 23, 2019
d62b783
Add dbHelpers.js
Kseniyapl Mar 23, 2019
4b4f98c
Add addProject And Endpoint Post The Unique Project
Kseniyapl Mar 23, 2019
d10d602
Add GET All Actions and POST An Action With Endpoints
Kseniyapl Mar 23, 2019
8072a25
Add Get Projects And Actions
Kseniyapl Mar 23, 2019
ec6ba0e
Merge pull request #404 from Kseniyapl/kseniya-platonava
henron1 Mar 28, 2019
d0e6d95
Revert "Merge pull request #404 from Kseniyapl/kseniya-platonava"
luishrd Mar 29, 2019
6c28f48
updates instructions
luishrd Jul 17, 2019
6e26482
updates instructions
luishrd Aug 16, 2019
15edd1a
updates instructions
luishrd Aug 16, 2019
95089f9
Adds dependencies, sets up server
Prouty89 Sep 13, 2019
87d9044
creates knexfile and migrations
Prouty89 Sep 13, 2019
e1012b7
tables created with test data to meet requirements, db-config, questi…
Prouty89 Sep 13, 2019
d2365a8
builds all endpoints, MVP but would like to replace test data
Prouty89 Sep 13, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 80 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,80 @@
/node_modules
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/
Empty file removed Answers.md
Empty file.
204 changes: 144 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,96 +1,180 @@
# Sprint Challenge for RDBMS and SQL
# Sprint Challenge: Node DB Sprint

The purpose of this exercise is to get you used to being quizzed on _Interview
Questions_ commonly asked about Relational Database Management Systems and SQL.
## Description

Answers to your written questions will be recorded in _Answers.md_
In this challenge, you design and build a Data Model and a RESTful API that stores data into a Relational Database.

Please work on this challenge alone, but feel free to use outside resources. You can _reference_ any old code you may have, however, please refrain from copying and pasting any of your answers. Try and understand the question and put your responses in your own words. Be as thorough as possible when explaining something.
## Instructions

**Just a friendly Reminder**: Don't fret or get anxious, this is a no-pressure assessment that is only going to help guide you in the near future. This is NOT a pass/fail situation.
**Read these instructions carefully. Understand exactly what is expected _before_ starting this Sprint Challenge.**

**Start by forking and cloning this repository.**
This is an individual assessment, please work on it alone. It is an opportunity to demonstrate proficiency in the concepts and objectives introduced and practiced in preceding days.

## Questions - Self Study
You can exercise your Google-Fu for this and any other _Sprint Challenge_ in the future.
If the instructions are not clear, please seek support from your TL and Instructor on Slack.

1. Explain the difference between `RDBMS` and `SQL`.
1. Why do tables need a `primary key`?
1. What is the name given to a table column that references the primary key
on another table.
1. What do we need in order to have a _many to many_ relationship between two
tables.
1. What SQL statement is used to retrieve data from a table?
1. What SQL clause is used to filter the results of a query?
1. What are `views`? Provide one example use case for them.
The Minimum Viable Product must be completed in three hours.

## Project description
Follow these steps to set up and work on your project:

**This is just a backend. Testing your application will require the use
of Postman or something simliar.**
- [ ] Create a forked copy of this project.
- [ ] Add your _Team Lead_ as collaborator on Github.
- [ ] Clone your forked version of the Repository.
- [ ] Create a new Branch on the clone: git checkout -b `firstName-lastName`.
- [ ] Implement the project on this Branch, committing changes regularly.
- [ ] Push commits: git push origin `firstName-lastName`.

For this Project we'll use _Node.js_, _Express.js_ and _Knex_ to build a RESTful
API for a `Project Tracker` application that persists data to either _SQLite_ or
_MySQL_.
Follow these steps for completing your project.

## General Requirements
- [ ] Submit a Pull-Request to merge `firstName-lastName` Branch into master on **your fork, don't make Pull Requests against Lambda's repository**.
- [ ] Please don't merge your own pull request.
- [ ] Add your _Team Lead_ as a Reviewer on the Pull-request
- [ ] Your _Team Lead_ will count the challenge as done by merging the branch into _master_.

The application let the users track `Projects`, `Actions` and `Contexts` in the
spirit of the _Getting Things Done (GTD)_ methodology.
## Commits

* A project can contain many actions and can be assigned to different contexts.
A project has:
* a unique Id.
* a name.
* a description.
* a flag that indicates if the project is complete or not.
* An action belongs to only one project and can be assigned to different contexts. An action has:
* a unique id.
* a description of what needs to be done.
* a notes column to add additional information.
* a flag that indicates if the action has been completed.
* A context can appear in multiple actions or projects. A context has:
* a unique id.
* a context column ('home', 'office', 'at computer').
Commit your code regularly and use descriptive messages. This helps both you (in case you ever need to return to old code) and your Team Lead.

Feel free to name the tables and fields anyway you want. Add constraints and
relationships as you see fit.
## Self-Study/Essay Questions

## Assignment
Demonstrate your understanding of this week's concepts by answering the following free-form questions. Edit this document to include your answers after each question. Make sure to leave a blank line above and below your answer so it is clear and easy to read by your project manager.

* Build the database and tables.
* Build the API to perform CRUD operations on all the resources (projects,
actions, contexts).
* Build an endpoint to retrieve a `project` by its `id` that returns an object
with the following structure:
- [X] Explain the difference between `Relational Databases` and `SQL`.

Relational Databases store data in table form containing columns and rows. SQL is the standard language used when working with Relational DB's allowing us to preform data interations (CRUD)

- [X] Why do tables need a `primary key`?

Unique idendifier attached to each row in a database table.

- [X] What is the name given to a table column that references the primary key on another table.

A Foreign Key

- [X] What do we need in order to have a _many to many_ relationship between two tables.

A Composite Key

## Minimum Viable Product

Take the steps necessary to complete the project from scratch. Start by initializing your project with a `package.json` and go from there.

Complete the following tasks:

- [ ] Design the data model and use _knex migrations_ to create the database and tables.
- [ ] Build an API with endpoints for:
- [ ] adding resources.
- [ ] retrieving a list of resources.
- [ ] adding projects.
- [ ] retrieving a list of projects.
- [ ] adding tasks.
- [ ] retrieving a list of tasks. **The list of tasks should include the project name and project description**.
- [ ] When returning `project` or `task` information, the `completed` property should be `true` or `false`.

For example, instead of returning a `task` that looks like this:

```js
{
id: 1,
name: 'convert to boolean',
completed: 1 // the database stores a 1 to represent true values on a boolean field
}
```

The API should return:

```js
{
id: 1,
name: 'convert to boolean',
completed: true // write code to convert the 1 to true and 0 to false
}
```

### Business Rules

- a `project` can have multiple `tasks`.
- a `task` belongs to only one `project`.
- a `project` can use multiple `resources`.
- the same `resource` can be used in multiple `projects`.
- when adding `projects` the client must provide a name, the description is optional.
- when adding `resources` the client must provide a name, the description is optional.
- when adding a `task` the client must provide a description, the notes are optional.
- when adding a `task` the client must provide the `id` of an existing project.
- for `projects` and `tasks` if no value is provided for the `completed` property, the API should provide a default value of `false`.

### Entities

A `project` is what needs to be done. We want to store the following data about a `project`:

- [X] a unique Id.
- [X] a name. This column is required.
- [X] a description.
- [X] a boolean that indicates if the project has been completed. This column cannot be NULL, the default value should be `false`.

A `resource` is anything needed to complete a project, some examples are: a person, a tool, a meeting room or a software license. We want to store the following data about a `resource`:

- [X] a unique Id.
- [X] a name. This column is required.
- [X] a description.

The database should not allow resources with duplicate names.

An `task` one of the steps needed to complete the project. We want to store the following data about an `task`.

- [X] a unique id.
- [X] a description of what needs to be done. This column is required.
- [X] a notes column to add additional information.
- [X] a boolean that indicates if the task has been completed. This column cannot be NULL, the default value should be `false`.

## Stretch Problem

This section is **optional** and not counted towards MVP. Start working on it after you're done with the main assignment.

Add an endpoint for retrieving a `project` by its `id` that returns an object with the following structure:

```js
{
id: 1,
name: 'project name here',
desctiption: 'the project description',
completed: false, // or true
actions: [
description: 'the project description',
completed: false, // or true, the database will return 1 for true and 0 for false
tasks: [
{
id: 1,
description: 'action description',
notes: 'the action notes',
description: 'task description',
notes: 'the task notes',
completed: false // or true
},
{
id: 7,
description: 'another action description',
notes: 'the action notes',
description: 'another task description',
notes: 'the task notes',
completed: false // or true
}
],
contexts: [
{ id: 1, context: 'the context' }
{ id: 5, context: 'another context' }
resources: [
{
id: 1,
name: 'Lambda Student',
description: 'a soon to be hired developer'
},
{
id: 2,
name: 'MacBook Pro #1'
description: 'an overly expensive laptop computer'
}
]
}
```

Remember to run `npm init -y` to generate a _package.json_ before adding your dependencies.
Add the remaining CRUD operations for projects and tasks.

Use `knex` to add _data seeding_ scripts for projects and tasks.

Add support for the concept of `contexts`. A context is something like _at home_, _at work_ or _at computer_. The idea is that some tasks require one or more `contexts` in order to be worked on. For example, the task of _file income taxes_ may require that you are _at home_, _at computer_ and _online_ so if you are _at work_ and look at the list of pending tasks you could do in your current context, filing your taxes will not be one of them.

A `context` can be applied to more than one `task`. An task can be tied to more than one context, like in the example above.

When retrieving an `task` by _id_, add a property that lists all the `contexts` related to that task.

_Good luck and have fun!_
5 changes: 5 additions & 0 deletions data/db-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const knex = require('knex');

const config = require('../knexfile.js');

module.exports = knex(config.development);
Binary file added data/db.db3
Binary file not shown.
61 changes: 61 additions & 0 deletions data/migrations/20190913115215_projects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@

exports.up = function(knex) {
return knex.schema
.createTable('projects', tbl => {
tbl.increments();
tbl.string('name', 255)
.notNullable()
.unique();
tbl.string('project_description', 500);
tbl.boolean('completed')
.defaultTo(false);
})
.createTable('resources', tbl => {
tbl.increments();
tbl.string('name', 255)
.notNullable()
.unique()
tbl.string('resource_description', 500);
})
.createTable('project_resources', tbl => {
tbl.increments();
tbl.integer('project_id')
.notNullable()
.unsigned()
.references('id')
.inTable('projects')
.onDelete('RESTRICT')
.onUpdate('CASCADE');
tbl.integer('resource_id')
.notNullable()
.unsigned()
.references('id')
.inTable('resources')
.onDelete('RESTRICT')
.onUpdate('CASCADE');
})
.createTable('tasks', tbl => {
tbl.increments();
tbl.string('description', 500)
.notNullable()
.unique();
tbl.string('notes', 500);
tbl.boolean('completed')
.defaultTo(false);
tbl.integer('project_id')
.notNullable()
.unsigned()
.references('id')
.inTable('projects')
.onDelete('RESTRICT')
.onUpdate('CASCADE');
})
};

exports.down = function(knex) {
return knex.schema
.dropTableIfExists('tasks')
.dropTableIfExists('project_resources')
.dropTableIfExists('projects')
.dropTableIfExists('resources')
};
Loading