diff --git a/.gitignore b/.gitignore
index 05d5560..8b5f11a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,5 +11,6 @@ tmp
 perf-logs
 v8.log
 *.js
+*.js.map
 
 
diff --git a/app/.editorconfig b/app/.editorconfig
new file mode 100644
index 0000000..f352616
--- /dev/null
+++ b/app/.editorconfig
@@ -0,0 +1,14 @@
+# Editor configuration, see http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+max_line_length = 0
+trim_trailing_whitespace = false
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..fccc4d9
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1,33 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+
+# compiled output
+/dist
+/tmp
+
+# dependencies
+/node_modules
+/bower_components
+
+# IDEs and editors
+/.idea
+.project
+.classpath
+*.launch
+.settings/
+
+# misc
+/.sass-cache
+/connect.lock
+/coverage/*
+/libpeerconnection.log
+npm-debug.log
+testem.log
+/typings
+
+# e2e
+/e2e/*.js
+/e2e/*.map
+
+#System Files
+.DS_Store
+Thumbs.db
diff --git a/app/angular-cli.json b/app/angular-cli.json
new file mode 100644
index 0000000..a648678
--- /dev/null
+++ b/app/angular-cli.json
@@ -0,0 +1,44 @@
+{
+  "project": {
+    "version": "1.0.0-beta.16",
+    "name": "frontend"
+  },
+  "apps": [
+    {
+      "root": "src",
+      "outDir": "dist",
+      "assets": "assets",
+      "index": "index.html",
+      "main": "main.ts",
+      "test": "test.ts",
+      "tsconfig": "tsconfig.json",
+      "prefix": "app",
+      "mobile": false,
+      "styles": [
+        "styles.css"
+      ],
+      "scripts": [],
+      "environments": {
+        "source": "environments/environment.ts",
+        "dev": "environments/environment.ts",
+        "prod": "environments/environment.prod.ts"
+      }
+    }
+  ],
+  "addons": [],
+  "packages": [],
+  "e2e": {
+    "protractor": {
+      "config": "./protractor.conf.js"
+    }
+  },
+  "test": {
+    "karma": {
+      "config": "./karma.conf.js"
+    }
+  },
+  "defaults": {
+    "styleExt": "css",
+    "prefixInterfaces": false
+  }
+}
diff --git a/app/e2e/app.e2e-spec.ts b/app/e2e/app.e2e-spec.ts
new file mode 100644
index 0000000..68ef1b0
--- /dev/null
+++ b/app/e2e/app.e2e-spec.ts
@@ -0,0 +1,14 @@
+import { FrontendPage } from './app.po';
+
+describe('frontend App', function() {
+  let page: FrontendPage;
+
+  beforeEach(() => {
+    page = new FrontendPage();
+  });
+
+  it('should display message saying app works', () => {
+    page.navigateTo();
+    expect(page.getParagraphText()).toEqual('app works!');
+  });
+});
diff --git a/app/e2e/app.po.ts b/app/e2e/app.po.ts
new file mode 100644
index 0000000..6991fd4
--- /dev/null
+++ b/app/e2e/app.po.ts
@@ -0,0 +1,11 @@
+import { browser, element, by } from 'protractor';
+
+export class FrontendPage {
+  navigateTo() {
+    return browser.get('/');
+  }
+
+  getParagraphText() {
+    return element(by.css('app-root h1')).getText();
+  }
+}
diff --git a/app/e2e/tsconfig.json b/app/e2e/tsconfig.json
new file mode 100644
index 0000000..656bdb1
--- /dev/null
+++ b/app/e2e/tsconfig.json
@@ -0,0 +1,16 @@
+{
+  "compileOnSave": false,
+  "compilerOptions": {
+    "declaration": false,
+    "emitDecoratorMetadata": true,
+    "experimentalDecorators": true,
+    "module": "commonjs",
+    "moduleResolution": "node",
+    "outDir": "../dist/out-tsc-e2e",
+    "sourceMap": true,
+    "target": "es5",
+    "typeRoots": [
+      "../node_modules/@types"
+    ]
+  }
+}
diff --git a/app/package.json b/app/package.json
new file mode 100644
index 0000000..9f80622
--- /dev/null
+++ b/app/package.json
@@ -0,0 +1,45 @@
+{
+  "name": "frontend",
+  "version": "0.0.0",
+  "license": "MIT",
+  "angular-cli": {},
+  "scripts": {
+    "start": "ng serve",
+    "lint": "tslint \"src/**/*.ts\"",
+    "test": "ng test",
+    "pree2e": "webdriver-manager update",
+    "e2e": "protractor"
+  },
+  "private": true,
+  "dependencies": {
+    "@angular/common": "2.0.0",
+    "@angular/compiler": "2.0.0",
+    "@angular/core": "2.0.0",
+    "@angular/forms": "2.0.0",
+    "@angular/http": "2.0.0",
+    "@angular/platform-browser": "2.0.0",
+    "@angular/platform-browser-dynamic": "2.0.0",
+    "@angular/router": "3.0.0",
+    "core-js": "^2.4.1",
+    "rxjs": "5.0.0-beta.12",
+    "ts-helpers": "^1.1.1",
+    "zone.js": "^0.6.23",
+    "ctc-shared": "^1.0.0"
+  },
+  "devDependencies": {
+    "@types/jasmine": "^2.2.30",
+    "angular-cli": "1.0.0-beta.16",
+    "codelyzer": "~0.0.26",
+    "jasmine-core": "2.4.1",
+    "jasmine-spec-reporter": "2.5.0",
+    "karma": "1.2.0",
+    "karma-chrome-launcher": "^2.0.0",
+    "karma-cli": "^1.0.1",
+    "karma-jasmine": "^1.0.2",
+    "karma-remap-istanbul": "^0.2.1",
+    "protractor": "4.0.9",
+    "ts-node": "1.2.1",
+    "tslint": "3.13.0",
+    "typescript": "2.0.2"
+  }
+}
diff --git a/app/proxy.conf.json b/app/proxy.conf.json
new file mode 100644
index 0000000..52cde71
--- /dev/null
+++ b/app/proxy.conf.json
@@ -0,0 +1,6 @@
+{
+  "/api": {
+    "target": "http://localhost:8090",
+    "secure": false
+  }
+}
\ No newline at end of file
diff --git a/app/src/app/app-routing.module.ts b/app/src/app/app-routing.module.ts
new file mode 100644
index 0000000..daa7621
--- /dev/null
+++ b/app/src/app/app-routing.module.ts
@@ -0,0 +1,11 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+const routes: Routes = [];
+
+@NgModule({
+  imports: [RouterModule.forRoot(routes)],
+  exports: [RouterModule],
+  providers: []
+})
+export class FrontendRoutingModule { }
diff --git a/app/src/app/app.component.css b/app/src/app/app.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/app/src/app/app.component.html b/app/src/app/app.component.html
new file mode 100644
index 0000000..90441ff
--- /dev/null
+++ b/app/src/app/app.component.html
@@ -0,0 +1,15 @@
+
+<main class="l-main l-sample-app">
+
+    <div>
+
+        <div class="main-container">
+            <div class="list">
+                <course [course]="course$ | async"></course>
+            </div>
+        </div>
+
+    </div>
+
+</main>
+
diff --git a/app/src/app/app.component.spec.ts b/app/src/app/app.component.spec.ts
new file mode 100644
index 0000000..54a5538
--- /dev/null
+++ b/app/src/app/app.component.spec.ts
@@ -0,0 +1,33 @@
+/* tslint:disable:no-unused-variable */
+
+import { TestBed, async } from '@angular/core/testing';
+import { AppComponent } from './app.component';
+
+describe('App: Frontend', () => {
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      declarations: [
+        AppComponent
+      ],
+    });
+  });
+
+  it('should create the app', async(() => {
+    let fixture = TestBed.createComponent(AppComponent);
+    let app = fixture.debugElement.componentInstance;
+    expect(app).toBeTruthy();
+  }));
+
+  it(`should have as title 'app works!'`, async(() => {
+    let fixture = TestBed.createComponent(AppComponent);
+    let app = fixture.debugElement.componentInstance;
+    expect(app.title).toEqual('app works!');
+  }));
+
+  it('should render title in a h1 tag', async(() => {
+    let fixture = TestBed.createComponent(AppComponent);
+    fixture.detectChanges();
+    let compiled = fixture.debugElement.nativeElement;
+    expect(compiled.querySelector('h1').textContent).toContain('app works!');
+  }));
+});
diff --git a/app/src/app/app.component.ts b/app/src/app/app.component.ts
new file mode 100644
index 0000000..1213590
--- /dev/null
+++ b/app/src/app/app.component.ts
@@ -0,0 +1,30 @@
+import { Component,OnInit } from '@angular/core';
+import {CourseService} from "./shared/services/course.service";
+import {Observable} from "rxjs/Rx";
+import {Course} from "ctc-shared/model/course";
+
+import 'rxjs/add/operator/map';
+
+
+@Component({
+  selector: 'app-root',
+  templateUrl: './app.component.html',
+  styleUrls: ['./app.component.css']
+})
+export class AppComponent implements OnInit {
+
+    course$: Observable<Course>;
+
+
+    constructor(private courseService: CourseService) {
+
+    }
+
+    ngOnInit():void {
+
+        this.course$ = this.courseService.findCourseById(1);
+
+    }
+
+
+}
diff --git a/app/src/app/app.module.ts b/app/src/app/app.module.ts
new file mode 100644
index 0000000..a1573a4
--- /dev/null
+++ b/app/src/app/app.module.ts
@@ -0,0 +1,23 @@
+import { BrowserModule } from '@angular/platform-browser';
+import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { HttpModule } from '@angular/http';
+
+import { AppComponent } from './app.component';
+import { CourseComponent } from './course/course.component';
+import {CourseService} from "./shared/services/course.service";
+
+@NgModule({
+  declarations: [
+    AppComponent,
+    CourseComponent
+  ],
+  imports: [
+    BrowserModule,
+    FormsModule,
+    HttpModule
+  ],
+  providers: [CourseService],
+  bootstrap: [AppComponent]
+})
+export class AppModule { }
diff --git a/app/src/app/course/course.component.css b/app/src/app/course/course.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/app/src/app/course/course.component.html b/app/src/app/course/course.component.html
new file mode 100644
index 0000000..130534a
--- /dev/null
+++ b/app/src/app/course/course.component.html
@@ -0,0 +1,18 @@
+<h2>{{ course?.description }}</h2>
+
+
+<div class="lessons-list-container v-h-center-block-parent">
+
+    <table class="table lessons-list card card-strong">
+        <tbody>
+        <tr *ngFor="let lesson of course?.lessons">
+            <td class="lesson-title"> {{lesson.description}}</td>
+            <td class="duration">
+                <i class="md-icon duration-icon">access_time</i>
+                <span>{{lesson.duration}}</span>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+
+</div>
\ No newline at end of file
diff --git a/app/src/app/course/course.component.spec.ts b/app/src/app/course/course.component.spec.ts
new file mode 100644
index 0000000..16d695e
--- /dev/null
+++ b/app/src/app/course/course.component.spec.ts
@@ -0,0 +1,11 @@
+/* tslint:disable:no-unused-variable */
+
+import { TestBed, async } from '@angular/core/testing';
+import { CourseComponent } from './course.component';
+
+describe('Component: Course', () => {
+  it('should create an instance', () => {
+    let component = new CourseComponent();
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/app/src/app/course/course.component.ts b/app/src/app/course/course.component.ts
new file mode 100644
index 0000000..7a39bc1
--- /dev/null
+++ b/app/src/app/course/course.component.ts
@@ -0,0 +1,24 @@
+import { Component, OnInit, Input } from '@angular/core';
+import {Course} from "ctc-shared/model/course";
+
+
+
+
+
+
+@Component({
+  selector: 'course',
+  templateUrl: './course.component.html',
+  styleUrls: ['./course.component.css']
+})
+export class CourseComponent implements OnInit {
+
+  @Input()
+  course: Course;
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}
diff --git a/app/src/app/index.ts b/app/src/app/index.ts
new file mode 100644
index 0000000..875bdb2
--- /dev/null
+++ b/app/src/app/index.ts
@@ -0,0 +1,2 @@
+export * from './app.component';
+export * from './app.module';
diff --git a/app/src/app/shared/index.ts b/app/src/app/shared/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/app/src/app/shared/services/course.service.spec.ts b/app/src/app/shared/services/course.service.spec.ts
new file mode 100644
index 0000000..f29100c
--- /dev/null
+++ b/app/src/app/shared/services/course.service.spec.ts
@@ -0,0 +1,16 @@
+/* tslint:disable:no-unused-variable */
+
+import { TestBed, async, inject } from '@angular/core/testing';
+import { CourseService } from './course.service';
+
+describe('Service: Course', () => {
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      providers: [CourseService]
+    });
+  });
+
+  it('should ...', inject([CourseService], (service: CourseService) => {
+    expect(service).toBeTruthy();
+  }));
+});
diff --git a/app/src/app/shared/services/course.service.ts b/app/src/app/shared/services/course.service.ts
new file mode 100644
index 0000000..98b09ac
--- /dev/null
+++ b/app/src/app/shared/services/course.service.ts
@@ -0,0 +1,22 @@
+import { Injectable } from '@angular/core';
+import {Http} from "@angular/http";
+import {Observable} from "rxjs/Rx";
+import {Course} from "ctc-shared/model/course";
+
+
+
+@Injectable()
+export class CourseService {
+
+
+  constructor(private http: Http) {
+
+  }
+
+
+    findCourseById(id:number): Observable<Course> {
+        return this.http.get(`/api/courses/${id}`).map(res => res.json());
+    }
+
+
+}
diff --git a/app/src/assets/.gitkeep b/app/src/assets/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/app/src/assets/.npmignore b/app/src/assets/.npmignore
new file mode 100644
index 0000000..e69de29
diff --git a/app/src/assets/app.css b/app/src/assets/app.css
new file mode 100644
index 0000000..150839d
--- /dev/null
+++ b/app/src/assets/app.css
@@ -0,0 +1,297 @@
+
+.lesson {
+    margin: 25px auto 0 auto;
+    max-width: 350px;
+}
+
+.lessons-list {
+    padding: 10px 10px 0 10px;
+    display: table-cell;
+    margin-bottom: 15px;
+}
+
+.lessons-list tr {
+    border-bottom: 1px solid darkgray;
+    cursor: pointer;
+}
+
+.lessons-list td {
+    padding-bottom: 5px;
+}
+
+.lesson-logo {
+    height: 20px;
+    margin-right: 10px;
+}
+
+.add-lesson {
+    width: 350px;
+    margin-bottom: 15px;
+}
+
+.md-icon {
+    font-family: 'Material Icons';
+    text-rendering: optimizeLegibility;
+    font-feature-settings: "liga" 1;
+    font-style: normal;
+    text-transform: none;
+    line-height: 1;
+    width: 24px;
+    height: 24px;
+    display: inline-block;
+    overflow: hidden;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+}
+
+.collapsible-indicator {
+    font-size: 30px;
+    line-height:30px;
+}
+
+
+.collapsible-section {
+    padding: 0 20px 20px 20px;
+}
+
+.collapsed .collapsible-section {
+    display: none;
+}
+
+
+.disable-text-selection {
+    -webkit-touch-callout: none;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+}
+
+
+.course-logo {
+    height: 75px;
+    margin: 0 auto;
+    background-color: #FAFAFA;
+    background-image: url(https://angular-academy.s3.amazonaws.com/main-logo/main-page-logo-small-hat.png);
+    background-repeat: no-repeat;
+    background-position-x: center;
+    background-size: 65px;
+    background-position-y: center;
+}
+
+form label {
+    width: 100px;
+    display: inline-block;
+    text-align: right;
+    vertical-align: top;
+    margin-right: 5px;
+}
+
+.field-error-message {
+    text-align: right;
+    padding-right: 68px;
+    font-size: 16px;
+    color: #a10000;
+}
+
+form fieldset {
+    margin-bottom: 20px;
+}
+
+form textarea {
+    width: 170px;
+}
+
+form input[type='radio'] {
+    box-shadow: none;
+    width: 20px;
+    vertical-align: bottom;
+    margin-left: 10px;
+}
+
+form button[type='submit'] {
+    float: right;
+    margin-right: 75px;
+}
+
+.debug {
+    clear: both;
+    font-size: 14px;
+}
+
+.debug h3 {
+    margin-top: 20px;
+    margin-bottom: 5px;
+}
+
+.form-field {
+    margin-bottom: 15px;
+}
+
+.lesson-button {
+    background: #1976d2;
+    color: white;
+    font-weight: bold;
+}
+
+.lesson-button[disabled] {
+    background: grey;
+    color: white;
+    cursor: not-allowed;
+}
+
+button[disabled] {
+    cursor: not-allowed;
+    opacity: 0.5;
+}
+
+
+.top-menu {
+    margin-bottom: 30px;
+}
+
+
+
+
+.ng-dirty.ng-invalid {
+    border: 2px solid #ff2118;
+}
+
+.ng-touched.ng-invalid {
+    border: 1px solid #cccccc !important;
+}
+
+
+form.ng-dirty.ng-invalid {
+    border:none;
+}
+
+form.ng-touched.ng-invalid {
+    border:none !important;
+}
+
+.l-header img {
+    cursor: pointer;
+}
+
+.youtube-logo {
+    max-height: 100px;
+    border-radius: 4px;
+}
+
+.lessons-list {
+    text-align: left;
+}
+
+.home-screen {
+    margin-top: 50px;
+}
+
+.courses-list {
+    padding: 5px 10px;
+    text-align: left;
+}
+
+
+table.courses-list tr {
+    border-bottom: 1px solid darkgray;
+}
+
+table.courses-list tr td {
+    padding: 5px 0;
+}
+
+table.courses-list tr td.description {
+    padding-right: 15px;
+}
+
+table.courses-list tr td:first-child {
+    padding-left: 15px;
+}
+
+table.courses-list tr td:last-child {
+    padding-right: 15px;
+}
+
+ul.top-menu > li > a.menu-active {
+    color: #ee1c1b;
+    font-weight: bold;
+    text-decoration: underline;
+}
+
+.nav-button {
+    margin-bottom: 20px;
+}
+
+.playlist {
+    float: right;
+}
+
+.main-container .list {
+    display: inline-block;
+    max-width: 270px;
+    vertical-align: top;
+    margin-right: 50px;
+}
+
+
+.nav-fields {
+    margin-bottom: 40px;
+}
+
+.course-summary {
+    cursor: pointer;
+}
+
+.chat {
+
+}
+
+img.dashboard-section  {
+    display: block;
+    max-height: 300px;
+    margin: 0 auto 50px auto;
+
+}
+
+.toggle-buttons {
+    margin-bottom: 15px;
+}
+
+.graph-toggle {
+    width: 30px;
+    box-shadow: none;
+    vertical-align: bottom;
+}
+
+
+
+.l-header {
+    height: 58px;
+}
+
+.top-menu {
+    margin-left: 50px;
+}
+
+.top-menu li {
+    box-shadow: none !important;
+}
+
+.l-sample-app {
+    text-align: center;
+}
+
+.tools-bar {
+    text-align: right;
+    margin-top: 30px;
+}
+
+.login-form {
+    width: 350px;
+}
+
+.search-bar {
+    margin-bottom: 30px;
+    width: 250px;
+}
diff --git a/app/src/environments/environment.prod.ts b/app/src/environments/environment.prod.ts
new file mode 100644
index 0000000..3612073
--- /dev/null
+++ b/app/src/environments/environment.prod.ts
@@ -0,0 +1,3 @@
+export const environment = {
+  production: true
+};
diff --git a/app/src/environments/environment.ts b/app/src/environments/environment.ts
new file mode 100644
index 0000000..00313f1
--- /dev/null
+++ b/app/src/environments/environment.ts
@@ -0,0 +1,8 @@
+// The file contents for the current environment will overwrite these during build.
+// The build system defaults to the dev environment which uses `environment.ts`, but if you do
+// `ng build --env=prod` then `environment.prod.ts` will be used instead.
+// The list of which env maps to which file can be found in `angular-cli.json`.
+
+export const environment = {
+  production: false
+};
diff --git a/app/src/favicon.ico b/app/src/favicon.ico
new file mode 100644
index 0000000..8081c7c
Binary files /dev/null and b/app/src/favicon.ico differ
diff --git a/app/src/index.html b/app/src/index.html
new file mode 100644
index 0000000..fbc9008
--- /dev/null
+++ b/app/src/index.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Frontend</title>
+  <base href="/">
+
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+
+  <link rel="icon" type="image/x-icon" href="favicon.ico">
+
+    <link rel="stylesheet" href="assets/app.css">
+    <link rel="stylesheet" href="https://angular-academy.s3.amazonaws.com/bundles/bundle.20160714172956.min.css">
+    <link rel="stylesheet"
+          href="https://angular-academy.s3-us-west-1.amazonaws.com/styles/angular-academy-lessons-theme-v1.css">
+    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
+
+</head>
+<body>
+  <app-root>Loading...</app-root>
+</body>
+</html>
diff --git a/app/src/main.ts b/app/src/main.ts
new file mode 100644
index 0000000..5c3c520
--- /dev/null
+++ b/app/src/main.ts
@@ -0,0 +1,12 @@
+import './polyfills.ts';
+
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+import { enableProdMode } from '@angular/core';
+import { environment } from './environments/environment';
+import { AppModule } from './app/';
+
+if (environment.production) {
+  enableProdMode();
+}
+
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/app/src/polyfills.ts b/app/src/polyfills.ts
new file mode 100644
index 0000000..3b4c55b
--- /dev/null
+++ b/app/src/polyfills.ts
@@ -0,0 +1,19 @@
+// This file includes polyfills needed by Angular 2 and is loaded before
+// the app. You can add your own extra polyfills to this file.
+import 'core-js/es6/symbol';
+import 'core-js/es6/object';
+import 'core-js/es6/function';
+import 'core-js/es6/parse-int';
+import 'core-js/es6/parse-float';
+import 'core-js/es6/number';
+import 'core-js/es6/math';
+import 'core-js/es6/string';
+import 'core-js/es6/date';
+import 'core-js/es6/array';
+import 'core-js/es6/regexp';
+import 'core-js/es6/map';
+import 'core-js/es6/set';
+import 'core-js/es6/reflect';
+
+import 'core-js/es7/reflect';
+import 'zone.js/dist/zone';
diff --git a/app/src/styles.css b/app/src/styles.css
new file mode 100644
index 0000000..e50a47e
--- /dev/null
+++ b/app/src/styles.css
@@ -0,0 +1 @@
+/* You can add global styles to this file, and also import other style files */
\ No newline at end of file
diff --git a/app/src/test.ts b/app/src/test.ts
new file mode 100644
index 0000000..7727c8e
--- /dev/null
+++ b/app/src/test.ts
@@ -0,0 +1,34 @@
+import './polyfills.ts';
+
+import 'zone.js/dist/long-stack-trace-zone';
+import 'zone.js/dist/proxy.js';
+import 'zone.js/dist/sync-test';
+import 'zone.js/dist/jasmine-patch';
+import 'zone.js/dist/async-test';
+import 'zone.js/dist/fake-async-test';
+
+// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
+declare var __karma__: any;
+declare var require: any;
+
+// Prevent Karma from running prematurely.
+__karma__.loaded = function () {};
+
+
+Promise.all([
+  System.import('@angular/core/testing'),
+  System.import('@angular/platform-browser-dynamic/testing')
+])
+  // First, initialize the Angular testing environment.
+  .then(([testing, testingBrowser]) => {
+    testing.getTestBed().initTestEnvironment(
+      testingBrowser.BrowserDynamicTestingModule,
+      testingBrowser.platformBrowserDynamicTesting()
+    );
+  })
+  // Then we find all the tests.
+  .then(() => require.context('./', true, /\.spec\.ts/))
+  // And load the modules.
+  .then(context => context.keys().map(context))
+  // Finally, start Karma to run the tests.
+  .then(__karma__.start, __karma__.error);
diff --git a/app/src/tsconfig.json b/app/src/tsconfig.json
new file mode 100644
index 0000000..9b4c84c
--- /dev/null
+++ b/app/src/tsconfig.json
@@ -0,0 +1,17 @@
+{
+  "compilerOptions": {
+    "declaration": false,
+    "emitDecoratorMetadata": true,
+    "experimentalDecorators": true,
+    "lib": ["es6", "dom"],
+    "mapRoot": "./",
+    "module": "es6",
+    "moduleResolution": "node",
+    "outDir": "../dist/out-tsc",
+    "sourceMap": true,
+    "target": "es5",
+    "typeRoots": [
+      "../node_modules/@types"
+    ]
+  }
+}
diff --git a/app/src/typings.d.ts b/app/src/typings.d.ts
new file mode 100644
index 0000000..a73f586
--- /dev/null
+++ b/app/src/typings.d.ts
@@ -0,0 +1,5 @@
+// Typings reference file, see links for more information
+// https://github.com/typings/typings
+// https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html
+
+declare var System: any;
diff --git a/app/tslint.json b/app/tslint.json
new file mode 100644
index 0000000..29f24ee
--- /dev/null
+++ b/app/tslint.json
@@ -0,0 +1,112 @@
+{
+  "rulesDirectory": [
+    "node_modules/codelyzer"
+  ],
+  "rules": {
+    "class-name": true,
+    "comment-format": [
+      true,
+      "check-space"
+    ],
+    "curly": true,
+    "eofline": true,
+    "forin": true,
+    "indent": [
+      true,
+      "spaces"
+    ],
+    "label-position": true,
+    "label-undefined": true,
+    "max-line-length": [
+      true,
+      140
+    ],
+    "member-access": false,
+    "member-ordering": [
+      true,
+      "static-before-instance",
+      "variables-before-functions"
+    ],
+    "no-arg": true,
+    "no-bitwise": true,
+    "no-console": [
+      true,
+      "debug",
+      "info",
+      "time",
+      "timeEnd",
+      "trace"
+    ],
+    "no-construct": true,
+    "no-debugger": true,
+    "no-duplicate-key": true,
+    "no-duplicate-variable": true,
+    "no-empty": false,
+    "no-eval": true,
+    "no-inferrable-types": true,
+    "no-shadowed-variable": true,
+    "no-string-literal": false,
+    "no-switch-case-fall-through": true,
+    "no-trailing-whitespace": true,
+    "no-unused-expression": true,
+    "no-unused-variable": true,
+    "no-unreachable": true,
+    "no-use-before-declare": true,
+    "no-var-keyword": true,
+    "object-literal-sort-keys": false,
+    "one-line": [
+      true,
+      "check-open-brace",
+      "check-catch",
+      "check-else",
+      "check-whitespace"
+    ],
+    "quotemark": [
+      true,
+      "single"
+    ],
+    "radix": true,
+    "semicolon": [
+      "always"
+    ],
+    "triple-equals": [
+      true,
+      "allow-null-check"
+    ],
+    "typedef-whitespace": [
+      true,
+      {
+        "call-signature": "nospace",
+        "index-signature": "nospace",
+        "parameter": "nospace",
+        "property-declaration": "nospace",
+        "variable-declaration": "nospace"
+      }
+    ],
+    "variable-name": false,
+    "whitespace": [
+      true,
+      "check-branch",
+      "check-decl",
+      "check-operator",
+      "check-separator",
+      "check-type"
+    ],
+
+    "directive-selector-prefix": [true, "app"],
+    "component-selector-prefix": [true, "app"],
+    "directive-selector-name": [true, "camelCase"],
+    "component-selector-name": [true, "kebab-case"],
+    "directive-selector-type": [true, "attribute"],
+    "component-selector-type": [true, "element"],
+    "use-input-property-decorator": true,
+    "use-output-property-decorator": true,
+    "use-host-property-decorator": true,
+    "no-input-rename": true,
+    "no-output-rename": true,
+    "use-life-cycle-interface": true,
+    "use-pipe-transform-interface": true,
+    "component-class-suffix": true,
+    "directive-class-suffix": true
+  }
+}
diff --git a/db-schema-create-and-populate.sql b/db-schema-create-and-populate.sql
new file mode 100644
index 0000000..dbea32c
--- /dev/null
+++ b/db-schema-create-and-populate.sql
@@ -0,0 +1,234 @@
+
+-- Database: "complete-typescript-course"
+
+
+-- DROP TABLE "Courses";
+
+CREATE TABLE "Courses"
+(
+  id serial NOT NULL,
+  url character varying(255),
+  description character varying(255) NOT NULL,
+  "longDescription" text NOT NULL,
+  "seqNo" integer NOT NULL,
+  "iconUrl" character varying(255) NOT NULL,
+  "comingSoon" boolean NOT NULL DEFAULT false,
+  "isNew" boolean NOT NULL DEFAULT false,
+  "isOngoing" boolean NOT NULL DEFAULT false,
+  "visibleFrom" timestamp with time zone NOT NULL DEFAULT '1970-02-01 00:00:00+01'::timestamp with time zone,
+  "createdAt" timestamp with time zone NOT NULL,
+  "updatedAt" timestamp with time zone NOT NULL,
+  "courseListIcon" character varying(255),
+  CONSTRAINT "Courses_pkey" PRIMARY KEY (id)
+);
+
+
+-- Table: "Lessons"
+
+CREATE TABLE "Lessons"
+(
+  id serial NOT NULL,
+  url character varying(255),
+  description character varying(255) NOT NULL,
+  duration character varying(255) NOT NULL,
+  "seqNo" integer NOT NULL,
+  "courseId" integer,
+  pro boolean DEFAULT false,
+  "gitHubUrl" character varying(255) NOT NULL,
+  tags character varying(255) DEFAULT ''::character varying,
+  "createdAt" timestamp with time zone NOT NULL,
+  "updatedAt" timestamp with time zone NOT NULL,
+  CONSTRAINT "Lessons_pkey" PRIMARY KEY (id),
+  CONSTRAINT "Lessons_courseId_fkey" FOREIGN KEY ("courseId")
+      REFERENCES "Courses" (id) MATCH SIMPLE
+      ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+
+-- Index: "sortByUrl"
+
+-- DROP INDEX "sortByUrl";
+
+CREATE UNIQUE INDEX "sortByUrl"
+  ON "Lessons"
+  USING btree
+  (url COLLATE pg_catalog."default");
+
+
+
+
+
+
+
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (3, 'angular2-pipes', 'Angular 2 Pipes', '<p class=''course-description''>Learn how to leverage Pipes in Angular 2, both stateless and stateful.</p>', 3, 'https://angular-academy.s3.amazonaws.com/course-logos/pipes.jpg', true, false, true, '2016-05-30 17:19:09.507+02', '2016-06-10 21:54:55.142+02', NULL);
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (2, 'angular2-components-and-directives', 'Angular 2 Components and Directives', '<p class=''course-description''>Learn Components and maybe the most useful feature of Angular 2: Directives.</p>', 2, 'https://angular-academy.s3.amazonaws.com/course-logos/components-and-directives.svg', true, false, true, '2016-05-30 17:19:09.507+02', '2016-06-10 21:54:55.16+02', NULL);
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (5, 'build-an-application-with-angular2', 'Build a Web App with Angular 2 and Firebase', '<p class=''course-description''>Put all the concepts together to build a fully running Angular 2 application using Firebase as the database.</p>', 4, 'https://angular-academy.s3.amazonaws.com/thumbnails/angular_app-firebase-small.jpg', false, false, false, '2016-05-30 17:19:09.507+02', '2016-10-07 21:16:20.671+02', 'https://angular-academy.s3.amazonaws.com/thumbnails/firebase-logo.jpg');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (10, 'angular2-rxjs-observable-data-services', 'RxJs Observable Data Services', '<p class=''course-description''>Use RxJs to build service layers using the Observable Data Service Pattern.</p>', 8, 'https://angular-academy.s3.amazonaws.com/thumbnails/observable-data-services.jpg', true, false, true, '2016-05-30 17:19:09.507+02', '2016-10-07 21:16:20.697+02', 'https://angular-academy.s3.amazonaws.com/course-logos/observables_rxjs.png');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (7, 'angular2-routing', 'Angular 2 Router', '<p class=''course-description''>Build Single Page Applications with Angular 2 and its powerful Router.</p>', 3, 'https://angular-academy.s3.amazonaws.com/thumbnails/angular2-routing-small.png', false, false, false, '2016-05-30 17:19:09.507+02', '2016-10-07 21:16:20.698+02', '/src/images/router-icon.png');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (8, 'module-loaders-and-systemjs', 'Module Loaders and Webpack 2', '<p class=''course-description''>Learn how Module Loaders Work - Learn Webpack 2 and its Plugin Ecosystem.</p>', 7, 'https://angular-academy.s3.amazonaws.com/thumbnails/webpack-small.jpg', true, false, true, '2016-05-30 17:19:09.507+02', '2016-10-07 21:16:20.699+02', 'https://angular-academy.s3.amazonaws.com/course-logos/observables_rxjs.png');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (11, 'angular2-ngrx', 'NgRx Angular 2 Reactive Extensions', '<p class=''course-description''>Learn some of the most useful libraries in the Angular 2 Ecosystem.</p>', 9, 'https://angular-academy.s3.amazonaws.com/thumbnails/ngrx.jpg', true, false, true, '2016-05-30 17:19:09.507+02', '2016-10-07 21:16:20.715+02', 'https://angular-academy.s3.amazonaws.com/course-logos/observables_rxjs.png');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (12, 'angular2-universal', 'Angular 2 Universal', '<p class=''course-description''>Learn maybe the biggest game changing technology in the Angular 2 Ecosystem.</p>', 10, 'https://angular-academy.s3.amazonaws.com/thumbnails/angular_universal.jpg', true, false, true, '2016-05-30 17:19:09.507+02', '2016-10-07 21:16:20.736+02', 'https://angular-academy.s3.amazonaws.com/course-logos/observables_rxjs.png');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (4, 'angular2-forms', 'Angular 2 Forms', '<p class=''course-description''>Learn how to build validatable and user-friendly data Forms effectively.</p>', 3, 'https://angular-academy.s3.amazonaws.com/thumbnails/angular-forms-small.png', false, false, false, '2016-05-30 17:19:09.507+02', '2016-10-07 21:16:20.611+02', 'https://angular-academy.s3.amazonaws.com/course-logos/lesson-icons/forms.jpg');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (9, 'angular2-http', 'Angular 2 HTTP and Services', '<p class=''course-description''>Build Services using Observables, learn to use the HTTP module effectively.</p>', 1, 'https://angular-academy.s3.amazonaws.com/thumbnails/angular-http.png', false, false, false, '2016-05-30 17:19:09.507+02', '2016-10-07 21:16:20.632+02', 'https://angular-academy.s3.amazonaws.com/course-logos/observables_rxjs.png');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (13, 'angular2-progressive-web-applications', 'Angular 2 Progressive Web Apps', '<p class=''course-description''>Learn the Future of Mobile development: Progressive Web Applications.</p>', 11, 'https://angular-academy.s3.amazonaws.com/thumbnails/pwa.jpg', true, false, true, '2016-05-30 17:19:09.507+02', '2016-10-07 21:16:20.75+02', 'https://angular-academy.s3.amazonaws.com/course-logos/observables_rxjs.png');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (6, 'angular2-advanced-components', 'Angular 2 Advanced Components', '<p class=''course-description''>A deep dive on Components, focusing on commonly needed advanced use cases.</p>', 5, 'https://angular-academy.s3.amazonaws.com/thumbnails/advanced-components.jpg', true, false, true, '2016-05-30 17:19:09.507+02', '2016-10-07 21:16:20.63+02', 'https://angular-academy.s3.amazonaws.com/course-logos/observables_rxjs.png');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (1, 'getting-started-with-angular2', 'Angular 2 Tutorial For Beginners', '<p class=''course-description''>Establish a solid layer of fundamentals, learn what''s under the hood of Angular 2</p>', 0, 'https://angular-academy.s3.amazonaws.com/thumbnails/angular2-for-beginners-small.png', false, false, false, '2016-05-30 17:19:09.507+02', '2016-10-07 21:16:20.606+02', 'https://angular-academy.s3.amazonaws.com/main-logo/main-page-logo-small-hat.png');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (14, 'angular2-architecture', 'Angular 2 Architecture', '<p class=''course-description''>Learn how to build next-generation (Post-REST ?) user interfaces in Angular 2.</p>', 12, 'https://angular-academy.s3.amazonaws.com/thumbnails/architecture.jpg', true, false, true, '2016-08-16 15:55:24.236181+02', '2016-10-07 21:16:20.75+02', 'https://angular-academy.s3.amazonaws.com/course-logos/observables_rxjs.png');
+INSERT INTO "Courses" (id, url, description, "longDescription", "seqNo", "iconUrl", "comingSoon", "isNew", "isOngoing", "createdAt", "updatedAt", "courseListIcon") VALUES (15, 'angular2-security', 'Angular 2 Security', '<p class=''course-description''>Learn how to build secure Angular 2 Applications Using JSON Web Tokens.</p>', 13, 'https://angular-academy.s3.amazonaws.com/thumbnails/angular2-security.jpg', true, false, true, '2016-08-16 15:59:06.727615+02', '2016-10-07 21:16:20.751+02', 'https://angular-academy.s3.amazonaws.com/course-logos/observables_rxjs.png');
+
+
+
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (17, 'angular2-component-events', 'Angular 2 Event Handling', '4:44', 3, 1, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:29.967+02', '2016-10-07 21:16:21.458+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (74, 'angular2-template-driven-forms-ngmodel', 'Angular 2 Template Driven Forms   - NgModel is Not Only For Two-Way Data Binding', '4:59', 0, 4, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:17:36.888+02', '2016-10-07 21:16:24.725+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (182, 'angular2-firebase-logout', 'Setup the Logout Functionality', '1:42', 51, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:35.385+02', '2016-10-07 21:16:33.618+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (92, 'angular2-router-initial-setup', 'Angular 2 Router Setup - Avoid A Pitfall Right From The Start, Setup Router Debugging', '5:33', 1, 7, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:06.18+02', '2016-10-07 21:16:34.147+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (19, 'angular2-components-styling-component-isolation', 'Styling Angular 2 Components - Learn About Component Style Isolation', '3:27', 5, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:30.014+02', '2016-10-07 21:16:21.463+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (101, 'angular2-router-avoid-memory-leaks', 'Exiting an Angular 2 Route - How To Prevent Memory Leaks', '4:48', 9, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:07.305+02', '2016-10-07 21:16:35.13+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (105, 'angular2-router-auxiliary-route-parameters', 'Angular 2 Auxiliary Routes - How To Pass Router Parameters', '2:55', 13, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:07.858+02', '2016-10-07 21:16:35.504+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (168, 'angular2-firebase-choose-ide', 'Choosing an IDE', '1:50', -1, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:29.569+02', '2016-10-06 17:06:57.988+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (108, 'angular2-router-exercise-build-a-dashboard', 'Exercise - Implement a Widget Dashboard With Multiple Auxiliary Routes', '2:50', 18, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:08.387+02', '2016-10-07 21:16:36.018+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (20, 'angular2-components-component-interaction', 'Angular 2 Component Interaction - Extended Components Example', '9:22', 6, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:30.015+02', '2016-10-07 21:16:21.463+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (116, 'angular2-firebase-cli-hello-world', 'Angular 2 Final Application Scaffolding using the Angular CLI', '2:58', 0, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-23 20:16:17.567+02', '2016-10-07 21:16:28.407+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (119, 'angular2-firebase-references-and-snapshots', 'Firebase Fundamentals  - References,  Snapshots and Keys', '3:24', 3, 5, false, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-23 20:16:17.569+02', '2016-10-07 21:16:28.813+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (112, 'angular2-lazy-loading-shared-modules', 'Angular 2 Router Lazy Loading and Shared Modules - How to Lazy-Load a Module', '8:43', 16, 7, false, 'https://github.com/angular-university/courses', 'ADVANCED', '2016-09-02 16:31:04.247+02', '2016-10-07 21:16:35.722+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (12, 'angular2-setting-up-a-project-using-typescript-systemjs', 'Angular 2 Development Environment - Start Development Using a Beginner Friendly Playground', '10:56', 23, 1, false, 'https://github.com/angular-university/courses/tree/master/01-getting-started-with-angular2/', 'BEGINNER', '2016-05-30 17:19:09.547+02', '2016-07-25 20:55:31.536+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (13, 'introduction-to-angular2-running-the-lessons', 'Running the the Lessons Code', '3:00', -2, 1, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:09.547+02', '2016-10-07 21:16:20.889+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (172, 'angular2-firebase-create-form-component', 'Creating the Lesson Form Component - Used both for Edit and for Creation', '6:37', 41, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:34.333+02', '2016-10-07 21:16:32.567+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (177, 'angular2-firebase-edit-lesson-show-data-in-edit-form', 'Edit Lesson - Passing the Retrieved Data to the Lesson Form', '3:25', 46, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:34.856+02', '2016-10-07 21:16:33.09+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (16, 'angular2-hello-world-write-first-application', 'Angular 2 Tutorial For Beginners - Build Your First App - Hello World Step By Step', '2:49', 0, 1, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:29.945+02', '2016-10-07 21:16:20.898+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (15, 'angular2-build-your-first-component', 'Building Your First Angular 2 Component - Component Composition', '2:07', 1, 1, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:29.967+02', '2016-10-07 21:16:20.899+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (18, 'angular2-component-templates-internal-vs-external', 'Angular 2 Component Templates - Inline Vs External', '2:55', 4, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:29.988+02', '2016-10-07 21:16:21.464+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (11, 'angular2-debugging-with-augury-or-console', 'How To Debug An Angular 2 Application - Debugging via Augury or the Console', '2:59', 22, 1, true, 'https://github.com/angular-university/courses', 'INTERMEDIATE', '2016-05-30 17:19:09.547+02', '2016-10-07 21:16:23.112+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (187, 'angular2-firebase-rounding-up', 'Rounding Up the Course', '01:01', 56, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:35.911+02', '2016-10-06 17:27:09.056+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (50, 'angular2-introduction-to-typescript-the-arrow-operator', 'Introduction To Typescript - The Arrow (=>) Operator', '4:52', 34, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-10 14:47:27.989+02', '2016-10-07 21:16:24.189+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (167, 'angular2-firebase-starter-kit', 'Installing the Starter Kit', '2:14', 1, 5, false, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:29.571+02', '2016-10-07 21:16:28.427+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (6, 'angular2-core-directives-ngfor', 'Angular 2 Core Directives  - ngFor', '3:46', 11, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:09.547+02', '2016-10-07 21:16:22.008+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (76, 'angular2-ngmodel-bidirectional-binding', 'NgModel - Why Would You Want To Turn Off Two-Way Data Binding ?', '3:44', 1, 4, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:14.349+02', '2016-10-07 21:16:24.724+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (24, 'angular2-write-first-injectable-service', 'Angular 2 Services Tutorial - Writing Your First Service - Learn @Injectable', '3:46', 25, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-01 22:25:57.621+02', '2016-10-07 21:16:23.632+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (46, 'angular2-introduction-to-directives-write-a-custom-directive', 'Angular 2 Directives Tutorial - Write Your First Custom Directive', '4:31', 9, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-10 14:05:54.065+02', '2016-10-07 21:16:22.009+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (48, 'angular2-directives-exercise-improve-collapsible-directive', 'Introduction to Angular 2 Directives - Exercise - Improve the Collapsible Directive', '1:30', 15, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-10 14:05:55.14+02', '2016-10-07 21:16:22.553+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (3, 'angular2-template-syntax-interpolation', 'Angular 2 Template Syntax - Interpolation', '2:41', 18, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:09.547+02', '2016-10-07 21:16:23.103+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (42, 'angular2-http-error-handling', 'Angular 2 Services - HTTP Error Handling', '2:21', 28, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-03 10:25:37.253+02', '2016-10-07 21:16:23.653+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (41, 'angular2-http-how-to-do-an-http-post-call', 'Angular 2 Services - Using the HTTP service to do an HTTP POST ', '5:32', 27, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-03 10:25:36.712+02', '2016-10-07 21:16:23.641+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (75, 'angular2-form-state-classes', 'Angular 2 Form CSS State Classes with NgModel - How to Mark a Field As Mandatory ?', '4:02', 2, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:14.362+02', '2016-10-07 21:16:24.724+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (81, 'angular2-ngmodelgroup', 'Control Groups with ngModelGroup - Validation And Binding', '3:03', 6, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:15.077+02', '2016-10-07 21:16:25.256+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (4, 'angular2-template-syntax-events', 'Template Syntax - Introduction To Zones - How does the Angular 2 event handling mechanism work?', '5:14', 19, 1, true, 'https://github.com/angular-university/courses', 'ADVANCED', '2016-05-30 17:19:09.547+02', '2016-10-07 21:16:23.103+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (23, 'anhular-http-do-a-get-call-to-express-server', 'Angular 2 Services - Introduction to the HTTP Service - Do a GET HTTP Server Call', '3:43', 26, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-01 22:25:57.642+02', '2016-10-07 21:16:23.642+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (43, 'angular2-introduction-to-services-exercise', 'Angular 2 Services  - Exercise - Do an HTTP DELETE', '0:54', 31, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-03 10:25:37.254+02', '2016-10-07 21:16:24.183+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (10, 'angular2-guided-tour-pipes', 'Angular 2 Pipes - Learn Why Standard Pipes Might Not Work, Create a Custom Pipe', '5:01', 21, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:09.547+02', '2016-10-07 21:16:23.104+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (87, 'angular2-formcontrol-directive', 'Angular 2 Model Driven Forms - The formControl Directive', '1:57', 12, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:15.629+02', '2016-10-07 21:16:25.789+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (88, 'angular2-custom-validator-form-driven', 'Angular 2 Template Driven Form Custom Validator', '5:44', 14, 4, true, 'https://github.com/angular-university/courses', 'ADVANCED', '2016-07-14 10:56:15.634+02', '2016-10-07 21:16:26.228+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (173, 'angular2-firebase-save-new-lesson', 'Lessons Service - Add Save New Lesson Functionality', '12:58', 42, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:34.335+02', '2016-10-07 21:16:32.572+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (178, 'angular2-firebase-edit-lesson-implement-lessons-service', 'Edit Lesson - Implement the Save Lesson Service', '3:02', 47, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:34.863+02', '2016-10-07 21:16:33.095+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (183, 'angular2-firebase-redirect-to-login-router-guard', 'Redirect User To Login Page Using a Router Guard', '5:33', 52, 5, false, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:35.391+02', '2016-10-07 21:16:33.621+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (5, 'angular2-guided-tour-components', 'Guided Tour to Angular 2 Components', '5:57', 20, 1, true, 'https://github.com/angular-university/courses/tree/master/01-getting-started-with-angular2/', 'BEGINNER', '2016-05-30 17:19:09.547+02', '2016-07-25 20:55:31.53+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (100, 'angular2-router-child-routes', 'Child Routes - How To Setup a Master Detail Route - What Are Componentless Routes ?', '4:09', 5, 7, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:07.271+02', '2016-10-07 21:16:34.668+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (103, 'angular2-router-auxiliary-routes', 'Configure Auxiliary Routes in the Angular 2 Router - What is the Difference Towards a Primary Route?', '5:16', 12, 7, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:07.838+02', '2016-10-07 21:16:35.194+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (77, 'angular2-standard-validators', 'Angular 2 Standard Form Validators How do Template Driven Forms Work Under The Hood ?', '3:32', 3, 4, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:14.379+02', '2016-10-07 21:16:24.729+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (80, 'angular2-model-driven-reactive-forms', 'Angular 2 Reactive or Model Driven Forms - formGroup and formControlName', '4:07', 7, 4, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:15.068+02', '2016-10-07 21:16:25.257+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (169, 'angular2-firebase-router-navigate-detail-to-lesson', 'Navigating From Lesson To Lesson - Part 1', '5:17', 37, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:33.863+02', '2016-10-07 21:16:32.052+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (85, 'angular2-model-driven-forms-errors', 'Angular 2 Model Driven Forms - Mark Fields in Error', '2:08', 11, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:15.62+02', '2016-10-07 21:16:25.79+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (58, 'angular2-what-is-an-observable', 'What is an Observable ? Introduction to Streams and RxJs Observables', '5:41', 0, 9, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-16 17:25:37.294+02', '2016-10-07 21:16:26.747+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (7, 'angular2-core-directives-ngclass-ngstyle', 'Angular 2 Core Directives - ngClass and ngStyle', '3:15', 12, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:09.547+02', '2016-10-07 21:16:22.545+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (69, 'angular2-how-to-setup-an-http-request-sequence-using-the-rxjs-switchmap-operator', 'How to setup an HTTP request sequence using the RxJs switchMap Operator', '4:33', 10, 9, true, 'https://github.com/angular-university/courses', 'INTERMEDIATE', '2016-06-17 12:46:13.787+02', '2016-10-07 21:16:27.783+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (60, 'angular2-observables-error-handling-and-completion-network-calls-as-observables', 'Observables Error Handling and Completion - How do Observables handle Errors?', '5:28', 1, 9, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-17 11:22:44.281+02', '2016-10-07 21:16:26.846+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (70, 'angular2-retry-http-requests-in-error-using-the-retry-and-retrywhen-rxjs-operators', 'Retry HTTP requests in Error using the retry and retryWhen RxJs Operators', '3:42', 11, 9, true, 'https://github.com/angular-university/courses', 'INTERMEDIATE', '2016-06-17 12:46:13.875+02', '2016-10-07 21:16:27.884+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (71, 'angular2-how-to-cancel-an-http-request-using-an-rxjs-subscription', 'How to Cancel an HTTP Request using an RxJs Subscription', '2:56', 12, 9, true, 'https://github.com/angular-university/courses', 'INTERMEDIATE', '2016-06-17 12:46:13.878+02', '2016-10-07 21:16:27.893+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (49, 'angular2-directives-exercise-solution-improve-collapsible-directive', 'Introduction to Angular 2 Directives - Exercise Solution', '2:40', 16, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-10 14:05:55.146+02', '2016-10-07 21:16:22.553+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (174, 'angular2-firebase-custom-url-validator', 'Add New Lesson - Add a Custom Url Field Validator', '3:05', 43, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:34.407+02', '2016-10-07 21:16:32.575+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (179, 'angular2-firebase-authentication-login-page', 'Setup Firebase Authentication, Create a Login Page', '8:52', 48, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:34.929+02', '2016-10-07 21:16:33.094+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (184, 'angular2-firebase-rest', 'REST and Firebase - Using the Firebase REST API', '8:25', 53, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:35.452+02', '2016-10-07 21:16:33.621+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (68, 'angular2-how-to-do-two-http-requests-in-parallel-using-the-rxjs-combinelatest-operator', 'How to do two HTTP Requests in Parallel using the RxJs combineLatest Operator', '3:58', 9, 9, true, 'https://github.com/angular-university/courses', 'INTERMEDIATE', '2016-06-17 12:46:13.362+02', '2016-10-07 21:16:27.393+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (99, 'angular2-router-optional-route-parameters', 'Optional Route Query Parameters - The queryParams Directive and the Query Parameters Observable', '2:38', 8, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:07.27+02', '2016-10-07 21:16:34.99+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (72, 'angular2-exercise-improve-a-search-service-and-build-a-typeahead', 'Exercise - Improve a Search Service and Build a Typeahead', '3:15', 13, 9, true, 'https://github.com/angular-university/courses', 'INTERMEDIATE', '2016-06-17 12:46:13.878+02', '2016-10-07 21:16:27.908+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (106, 'angular2-router-redirects-path-matching', 'Angular 2 Router Redirects and Path Matching - Avoid Common Routing Pitfall', '2:59', 14, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:07.866+02', '2016-10-07 21:16:35.643+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (59, 'angular2-', 'When To Use Template Driven Vs Model Driven Forms ? It Might Surprise You', '6:10', 15, 9, false, 'https://github.com/angular-university/courses/tree/master/01-getting-started-with-angular2/', 'BEGINNER', '2016-06-17 11:02:05.708+02', '2016-07-14 10:51:02.929+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (45, 'angular2-introduction-to-services-exercise-solution', 'Angular 2 Services - Exercise Solution - Do an HTTP DELETE', '3:55', 32, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-03 10:25:37.259+02', '2016-10-07 21:16:24.188+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (51, 'angular2-introduction-to-typescript-high-level-overview', 'Introduction to Typescript - High-level Overview', '7:00', 32, 1, true, 'https://github.com/angular-university/courses/tree/master/01-getting-started-with-angular2/', 'BEGINNER', '2016-06-10 14:47:27.988+02', '2016-07-25 20:55:32.629+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (93, 'angular2-router-styling-active-routes', 'Styling Active Routes With The routerLinkActive And routerLinkActiveOptions Directives', '2:00', 4, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:06.205+02', '2016-10-07 21:16:34.611+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (90, 'angular2-signup-form', 'Angular 2 Forms Section Exercise - Build a Signup Form', '1:34', 17, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:16.158+02', '2016-10-07 21:16:26.334+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (175, 'angular2-firebase-edit-lesson-initial-setup', 'Edit Lesson - Initial Screen Setup', '2:35', 44, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:34.567+02', '2016-10-07 21:16:32.937+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (91, 'angular2-signup-form-example', 'Exercise - Build an Angular 2 Signup Form - Lets do a little Functional Programming', '6:10', 18, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:16.172+02', '2016-10-07 21:16:26.335+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (62, 'angular2-observable-map-operator-how-to-create-an-observable-from-another', 'The RxJs Map Operator - How to create an Observable from another Observable', '3:04', 5, 9, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-17 12:32:57.146+02', '2016-10-07 21:16:27.267+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (83, 'angular2-formbuilder', 'Building Reactive or Model Driven Forms using the FormBuilder', '2:13', 9, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:15.076+02', '2016-10-07 21:16:25.718+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (22, 'angular2-components-exercise-solution', 'Angular 2 Components Tutorial For Beginners - Components Exercise Solution Inside', '2:08', 8, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:30.033+02', '2016-10-07 21:16:22.002+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (180, 'angular2-firebase-authentication-observable-data-service', 'Building an Authentication Observable Data Service', '7:06', 49, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:35.094+02', '2016-10-07 21:16:33.45+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (118, 'angular2-firebase-typescript', 'Use Firebase SDK with Typescript - Preparing to Run a Firebase Database Population Script', '3:18', 4, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-23 20:16:17.593+02', '2016-10-07 21:16:28.922+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (185, 'angular2-firebase-security-rules', 'Protect Write Access Using Security Rules', '1:34', 54, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:35.63+02', '2016-10-07 21:16:33.964+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (157, 'angular2-firebase-join-3', 'Joins in Firebase - Performance Considerations', '7:39', 28, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:32:19.844+02', '2016-10-07 21:16:31.393+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (154, 'angular2-setup-dev-environment-1', 'Setting Up an Angular 2 Development Environment', '8:47', -3, 1, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-09-30 10:32:13.193+02', '2016-10-07 21:16:20.888+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (144, 'angular2-firebase-home-screen', 'Starting the Application From the Beginning - Build the Home Screen', '3:33', 16, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:14.926+02', '2016-10-07 21:16:29.98+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (47, 'angular2-directives-inputs-outputs-event-emitters', 'Angular 2 Directives - Inputs, Output Event Emitters and How To Export Template References', '4:01', 10, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-10 14:05:54.592+02', '2016-10-07 21:16:22.009+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (137, 'angular2-angular-cli', 'Getting Started with Angular 2 - Off the Ground Running with the Angular CLI', '8:47', -1, 1, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-09-25 20:47:01.476+02', '2016-10-07 21:16:20.898+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (162, 'angular2-firebase-pagination-3', 'Firebase Pagination Concluded - Loading the Previous Page', '2:11', 33, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:32:20.364+02', '2016-10-07 21:16:31.905+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (96, 'angular2-router-home-route-fallback-route', 'Configuring a Home Route and Fallback Route - Learn An Essential Routing Concept', '2:55', 3, 7, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:06.199+02', '2016-10-07 21:16:34.477+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (86, 'angular2-custom-validator-model-driven', 'Angular 2 Model Driven Form Custom Validator', '3:05', 13, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:15.629+02', '2016-10-07 21:16:25.789+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (170, 'angular2-firebase-detail-navigation-route-params-observable', 'Navigating From Lesson To Lesson - The Route Params Observable', '4:48', 39, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:34.031+02', '2016-10-07 21:16:32.423+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (102, 'angular2-router-can-activate-guard', 'CanActivate Route Guard - An Example of An Asynchronous Route Guard', '3:31', 11, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:07.838+02', '2016-10-07 21:16:35.195+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (67, 'angular2-how-to-do-multiple-http-requests-using-the-rxjs-concat-operator', 'How to do multiple HTTP requests using the RxJs Concat Operator', '4:19', 8, 9, true, 'https://github.com/angular-university/courses', 'INTERMEDIATE', '2016-06-17 12:46:13.319+02', '2016-10-07 21:16:27.391+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (133, 'angular2-firebase-arrays', 'Firebase Arrays - Does Firebase Support Arrays ? ', '5:34', 9, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-23 20:22:37.174+02', '2016-10-07 21:16:29.445+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (150, 'angular2-firebase-router-config', 'Setting Up the Router Configuration of our Application', '4:47', 21, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:15.458+02', '2016-10-07 21:16:30.498+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (107, 'angular2-router-hash-location-strategy', 'Angular 2 Router Hash Location Strategy vs HTML5 Location Strategy', '3:04', 15, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:08.384+02', '2016-10-07 21:16:35.719+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (97, 'angular2-router-manual-navigation', 'Programmatic Router Navigation via the Router API - Relative And Absolute Router Navigation', '3:59', 6, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:07.269+02', '2016-10-07 21:16:34.671+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (53, 'angular2-introduction-to-typescript-array-spread-operator-object-destructuring', 'Introduction To Typescript - The Array Spread Operator, Object Destructuring and more', '4:54', 35, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-10 14:47:27.99+02', '2016-10-07 21:16:24.196+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (54, 'angular2-introduction-to-typescript-imports-and-exports', 'Introduction To Typescript - Imports and Exports - One of the main missing features of ES5 ?', '4:32', 36, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-10 14:47:28.017+02', '2016-10-07 21:16:24.691+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (113, 'angular2-shared-modules-service-configuration', 'Shared Modules And Lazy Loading - How to Setup Shared Services', '6:39', 17, 7, true, 'https://github.com/angular-university/courses', 'ADVANCED', '2016-09-02 16:31:04.607+02', '2016-10-07 21:16:35.721+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (8, 'angular2-core-directives-ngIf', 'Angular 2 Core Directives - ngIf', '3:56', 13, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:09.547+02', '2016-10-07 21:16:22.547+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (84, 'angular2-reactive-forms-rxjs', 'Reactive Forms with RxJs - Learn Why They Are more Powerful than Template Driven', '6:23', 10, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:15.417+02', '2016-10-07 21:16:25.784+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (61, 'angular2-observable-composition-combine-latests', 'Observable Composition - combine multiple Observables Using combineLatest', '5:59', 6, 9, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-17 12:32:57.158+02', '2016-10-07 21:16:27.363+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (110, 'angular2-ngmodule', 'Angular 2 Modularity - @NgModule and Feature Modules - Learn why a Component Might Not Be Visible', '4:48', 30, 1, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-09-02 15:52:42.033+02', '2016-10-07 21:16:24.162+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (171, 'angular2-firebase-create-new-lesson', 'The Create New Lesson Form', '5:21', 40, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:34.035+02', '2016-10-07 21:16:32.552+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (186, 'angular2-firebase-node-queue', 'Build a Custom Node Backend Using Firebase Queue', '11:46', 55, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:35.635+02', '2016-10-07 21:16:34.09+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (176, 'angular2-firebase-edit-lesson-router-resolve', 'Edit Lesson - Retrieve Lesson using the Router Resolve Functionality', '7:54', 45, 5, false, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:34.569+02', '2016-10-07 21:16:33.065+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (79, 'angular2-form-field-errors', 'How to display Form Field Validation Error Messages with NgModel', '3:28', 5, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:14.895+02', '2016-10-07 21:16:25.252+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (145, 'angular2-firebase-service-layer-example', 'Building our First Firebase Service - The Lessons Service', '7:24', 17, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:14.93+02', '2016-10-07 21:16:29.984+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (2, 'angular2-template-syntax-properties', 'Angular 2 Template Syntax - Properties', '5:12', 17, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:09.547+02', '2016-10-07 21:16:23.094+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (146, 'angular2-firebase-smart-vs-presentation-components', 'Angular 2 Smart Components vs Presentation Components: What''s the Difference and When to Use Each ?', '4:36', 18, 5, false, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:14.969+02', '2016-10-07 21:16:30.364+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (52, 'angular2-introduction-to-typescript-classes-and-interfaces', 'Introduction To Typescript - Classes and Interfaces', '3:47', 33, 1, true, 'https://github.com/angular-university/courses/tree/master/01-getting-started-with-angular2/', 'BEGINNER', '2016-06-10 14:47:27.989+02', '2016-09-25 21:35:33.363+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (66, 'angular2-how-to--aAvoid-duplicate-http-requests-rxjs-cache-operator', 'Avoid the Biggest Pitfall of Angular 2 HTTP - Learn the RxJs Cache Operator', '5:10', 7, 9, true, 'https://github.com/angular-university/courses', 'INTERMEDIATE', '2016-06-17 12:46:13.312+02', '2016-10-07 21:16:27.378+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (73, 'angular2-exercise-solution-learn-how-to-build-a-typeahead-that-cancels-obsolete-search-requests', 'Exercise Solution - Learn How to build a Typeahead that cancels obsolete search requests', '5:07', 14, 9, true, 'https://github.com/angular-university/courses', 'INTERMEDIATE', '2016-06-17 12:46:13.903+02', '2016-10-07 21:16:27.911+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (114, 'what-is-a-single-page-application', 'What is a Single Page Application ? Learn Why They Might Become More Frequent In The Future', '4:00', 0, 7, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-09-20 13:16:05.526+02', '2016-10-07 21:16:34.144+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (89, 'angular2-template-driven-vs-model-driven-forms', 'When To Use Angular 2 Template Driven Vs Model Driven Forms, and Why ? ', '5:04', 16, 4, false, 'https://github.com/angular-university/courses', 'ADVANCED', '2016-07-14 10:56:15.937+02', '2016-10-07 21:16:26.331+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (98, 'angular2-router-navigation-parameters', 'Master Detail Navigation And Route Parameters  - The Route Parameters Observable', '6:03', 7, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:07.27+02', '2016-10-07 21:16:34.674+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (104, 'angular2-router-can-deactivate-guard', 'CanDeactivate Route Guard - How To Confirm If The User Wants To Exit A Route', '4:42', 10, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:07.839+02', '2016-10-07 21:16:35.191+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (44, 'angular2-rest-api-http-server-development', 'How to Setup a Development REST API HTTP Server with Express and ts-node', '2:46', 29, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-03 10:25:37.254+02', '2016-10-07 21:16:23.653+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (109, 'angular2-router-exercise-solution-build-a-dashboard', 'Exercise Solution - Implement a Widget Dashboard With Multiple Auxiliary Routes', '4:41', 19, 7, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:08.387+02', '2016-10-07 21:16:36.157+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (147, 'angular2-firebase-typescript-pitfall', 'Pitfall of Using Typescript Classes when Querying Data From a Backend', '6:21', 19, 5, false, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:14.972+02', '2016-10-07 21:16:30.477+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (149, 'angular2-firebase-navigation-menu', 'Building a Navigation Menu Using The Angular 2 Router', '5:53', 22, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:15.456+02', '2016-10-07 21:16:30.501+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (181, 'angular2-firebase-user-registration-page', 'Build a User Registration Page', '3:50', 50, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-10-06 17:01:35.106+02', '2016-10-07 21:16:33.579+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (151, 'angular2-firebase-master-detail', 'Setting Up the Master Screen of the Master Detail Pattern', '6:46', 23, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:15.486+02', '2016-10-07 21:16:30.879+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (94, 'angular2-router-navigation', 'Navigate Between Angular 2 Routes - Several Ways Of Using the routerLink Directive', '3:18', 2, 7, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-22 13:11:06.198+02', '2016-10-07 21:16:34.15+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (134, 'angular2-firebase-data-modelling', 'Firebase Data Modeling 101 - How To Model Data In Firebase ?', '4:11', 7, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-23 20:22:37.173+02', '2016-10-07 21:16:28.946+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (140, 'angular2-firebase-list-push', 'How to Write Data to the Database using AngularFire 2 ? Adding Elements to a List', '3:52', 12, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 16:44:44.433+02', '2016-10-07 21:16:29.468+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (142, 'angular2-firebase-list-remove', 'How To Remove an Element from a List using AngularFire 2 ?', '3:08', 13, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:14.406+02', '2016-10-07 21:16:29.847+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (95, 'angular2-router-introduction', 'Angular 2 Router Demo - Why Build Single Applications ?', '4:00', 0, 7, false, 'https://github.com/angular-university/courses/tree/master/01-getting-started-with-angular2/', 'BEGINNER', '2016-07-22 13:11:06.17+02', '2016-07-22 19:39:03.616+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (148, 'angular2-firebase-client-side-search', 'How To Implement Client-Side Search in Angular 2 ?', '4:00', 20, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:15.348+02', '2016-10-07 21:16:30.485+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (141, 'angular2-firebase-list-update', 'How To Update an Element in a Firebase List using AngularFire 2 ?', '1:11', 14, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:14.406+02', '2016-10-07 21:16:29.961+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (166, 'angular2-firebase-install-node-and-demo-app', 'Installing Node and the Angular 2 and Firebase Demo Application', '4:45', -2, 5, false, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:50:35.241+02', '2016-10-07 21:16:28.403+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (115, 'angular2-firebase-sdk-hello-world', 'Firebase Real-Time Database Hello World - First Query - Debug Websockets !', '8:15', 2, 5, false, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-23 20:16:17.568+02', '2016-10-07 21:16:28.43+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (123, 'angular2-populate-firebase-db-ts-node', 'Populate a Firebase Database with a Node Program - Use Typescript with Node using ts-node', '4:24', 5, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-23 20:16:18.338+02', '2016-10-07 21:16:28.927+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (136, 'angular2-firebase-db-script-explained', 'Populate a Firebase Database -Initialization Script Explained Step By Step', '3:53', 6, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-23 20:22:37.165+02', '2016-10-07 21:16:28.943+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (152, 'angular2-firebase-master-detail-navigation', 'Configuring the Angular 2 Router for Master To Detail Navigation', '3:23', 24, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:15.499+02', '2016-10-07 21:16:30.993+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (135, 'angular2-firebase-database-ekeys', 'Firebase Key Generation - How to use the Firebase Push Keys, Should We Use Them and Why ?', '3:09', 8, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-23 20:22:37.174+02', '2016-10-07 21:16:29.327+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (82, 'angular2-model-driven-forms-validation', 'Angular 2 Form  Validation in Model Driven Forms - Configuring a Form Validator', '2:29', 8, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:15.077+02', '2016-10-07 21:16:25.256+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (111, 'angular2-set-form-value-reset-form', 'Angular 2 Model Driven Forms - How to Set a Form Value and Reset a Form', '4:48', 15, 4, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-09-02 16:24:08.915+02', '2016-10-07 21:16:26.32+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (14, 'angular2-passing-data-to-component-using-input', 'Component @Input - How To Pass Input Data To an Angular 2 Component', '2:33', 2, 1, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:29.966+02', '2016-10-07 21:16:21.457+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (63, 'how-does-angular2-use-observables-http-response-object', 'How does Angular 2 HTTP use Observables ? The HTTP Response object', '4:32', 2, 9, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-17 12:46:12.757+02', '2016-10-07 21:16:26.858+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (64, 'angular2-how-to-use-observables-and-http-to-build-a-servicelayer', 'How to use Observables and HTTP to build a Service Layer', '4:32', 3, 9, false, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-17 12:46:13.26+02', '2016-10-07 21:16:26.87+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (21, 'angular2-components-exercise', 'Angular 2 Components Tutorial For Beginners - Components Exercise !', '1:26', 7, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:30.024+02', '2016-10-07 21:16:22.001+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (65, 'angular2-how-to-use-the-async-pipe-to-pass-observables-into-a-template', 'Introduction to Functional Reactive Programming - Using the Async Pipe - Pitfalls to Avoid', '4:36', 4, 9, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-06-17 12:46:13.311+02', '2016-10-07 21:16:26.872+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (9, 'angular2-guided-tour-directives', 'Directives Guided Tour - Learn Why Directives Might be a Better Choice Than Components', '7:58', 14, 1, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-05-30 17:19:09.547+02', '2016-10-07 21:16:22.545+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (117, 'angular2-firebase-demo-course-intro', 'Build an Application with Angular 2 and Firebase - Application Demo and Course Objectives', '6:51', -3, 5, false, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-23 20:16:17.566+02', '2016-10-07 21:16:28.297+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (153, 'angular2-firebase-master-detail-detail-screen', 'Setting Up the Detail Screen of a Master Detail Setup', '5:03', 25, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:15.866+02', '2016-10-07 21:16:31.001+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (143, 'angular2-firebase-object-set-update', 'How to Modify an Object in Firebase using AngularFire 2, what is the Difference Between Set and Update?', '3:31', 15, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 17:53:14.83+02', '2016-10-07 21:16:29.97+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (78, 'angular2-form-exports', 'Understanding Angular 2 Form Exports -  Disable a Form Button Until the Form is Valid', '3:15', 4, 4, true, 'https://github.com/angular-university/courses', 'BEGINNER', '2016-07-14 10:56:14.379+02', '2016-10-07 21:16:25.202+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (138, 'angular2-firebase-list-observable', 'AngularFire 2 Hello World - How To Write your First Query using AngularFire 2 List Observables ?', '7:43', 10, 5, false, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 16:44:44.347+02', '2016-10-07 21:16:29.457+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (139, 'angular2-firebase-object-observable', 'AngularFire 2 Object Observables - How to Read Objects from a Firebase Database?', '2:19', 11, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-28 16:44:44.429+02', '2016-10-07 21:16:29.466+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (156, 'angular2-firebase-join-1', 'How To Make a Join in Firebase Using AngularFire 2 ? Reading a Course based on its url', '9:30', 26, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:32:19.502+02', '2016-10-07 21:16:31.014+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (155, 'angular2-firebase-join-2', 'Joins in Firebase Continued - Querying the List Of Lesson Keys Of Lessons that Belong to a Course', '2:51', 27, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:32:19.504+02', '2016-10-07 21:16:31.016+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (158, 'angular2-rxjs-clean-code', 'How to Write Maintainable RxJs Code ? Some Tips and Tricks on How to Write Clean Reactive Code', '4:53', 29, 5, false, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:32:19.898+02', '2016-10-07 21:16:31.512+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (159, 'angular2-firebase-pagination-display-course-lessons', 'Displaying the Lessons Per Course in the Course Detail Page', '3:50', 30, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:32:19.934+02', '2016-10-07 21:16:31.514+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (160, 'angular2-firebase-pagination', 'How To Do Pagination in Firebase ? Loading the First Page of a Paginated Table', '7:52', 31, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:32:20.063+02', '2016-10-07 21:16:31.53+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (161, 'angular2-firebase-pagination-2', 'Firebase Pagination Continued - Loading the Next Page', '4:12', 32, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:32:20.08+02', '2016-10-07 21:16:31.533+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (163, 'angular2-firebase-navigate-from-course-to-lesson', 'Navigate From Course Detail to Lesson', '5:17', 34, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:32:20.435+02', '2016-10-07 21:16:32.036+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (164, 'angular2-firebase-lesson-detail', 'Building a Lesson Detail Component', '4:17', 35, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:32:20.476+02', '2016-10-07 21:16:32.046+02');
+INSERT INTO "Lessons" (id, url, description, duration, "seqNo", "courseId", pro, "gitHubUrl", tags, "createdAt", "updatedAt") VALUES (165, 'angular2-firebase-security-iframe', 'Angular 2 Security - Adding an iframe to an Angular 2 Template', '4:14', 36, 5, true, 'https://github.com/angular-university/angular-firebase-app', 'BEGINNER', '2016-09-30 10:32:20.585+02', '2016-10-07 21:16:32.053+02');
diff --git a/db-schema-drop.sql b/db-schema-drop.sql
new file mode 100644
index 0000000..1c57978
--- /dev/null
+++ b/db-schema-drop.sql
@@ -0,0 +1,6 @@
+
+DROP TABLE "Lessons";
+
+DROP TABLE "Courses";
+
+DROP DATABASE "complete-typescript-course";
\ No newline at end of file
diff --git a/hello-world.ts b/hello-world.ts
index f172064..6a16023 100644
--- a/hello-world.ts
+++ b/hello-world.ts
@@ -1,6 +1,4 @@
 
-var message = 'Hello World';
 
 
-console.log(message);
-
+console.log('Hello World !');
\ No newline at end of file
diff --git a/package.json b/package.json
index 277d3a8..83dc738 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,11 @@
   "description": "",
   "main": "index.js",
   "scripts": {
-    "hello": "./node_modules/.bin/ts-node ./hello-world.ts"
+    "hello": "./node_modules/.bin/ts-node ./hello-world.ts",
+    "sql": "./node_modules/.bin/ts-node ./sql-examples.ts",
+    "start": "./node_modules/.bin/ts-node ./server/server.ts",
+    "watch": "./node_modules/.bin/nodemon -w . --ext \".ts\" --exec \"npm run start\"",
+    "debug": "node --inspect --debug-brk   ./src/server.js"
   },
   "repository": {
     "type": "git",
@@ -17,8 +21,21 @@
   },
   "homepage": "https://github.com/angular-university/complete-typescript-course#readme",
   "devDependencies": {
+    "@types/es6-promise": "0.0.32",
+    "@types/express": "^4.0.33",
+    "@types/lodash": "^4.14.37",
+    "@types/node": "^6.0.45",
+    "@types/sequelize": "^4.0.38",
     "http-server": "^0.9.0",
+    "nodemon": "^1.11.0",
     "ts-node": "^1.6.0",
     "typescript": "^2.0.3"
+  },
+  "dependencies": {
+    "body-parser": "^1.15.2",
+    "express": "^4.14.0",
+    "lodash": "^4.16.4",
+    "pg": "^6.1.0",
+    "sequelize": "^3.24.4"
   }
 }
diff --git a/server/api/api.ts b/server/api/api.ts
new file mode 100644
index 0000000..3b5f825
--- /dev/null
+++ b/server/api/api.ts
@@ -0,0 +1,22 @@
+
+
+import {apiGetAllCourses} from "./apiGetAllCourses";
+import {Application} from "express";
+import {apiGetCourseDetail} from "./apiGetCourseDetail";
+import {apiPatchLesson} from "./apiPatchLesson";
+import {apiDeleteLesson} from "./apiDeleteLesson";
+import {apiCreateLesson} from "./apiCreateLesson";
+
+
+export function initApi(app: Application) {
+
+    app.route('/api/courses').get(apiGetAllCourses);
+    app.route('/api/courses/:id').get(apiGetCourseDetail);
+
+
+    app.route('/api/lesson/:id').patch(apiPatchLesson);
+    app.route('/api/lesson/:id').delete(apiDeleteLesson);
+    app.route('/api/lesson/:id').post(apiCreateLesson);
+
+
+}
\ No newline at end of file
diff --git a/server/api/apiCreateLesson.ts b/server/api/apiCreateLesson.ts
new file mode 100644
index 0000000..f379639
--- /dev/null
+++ b/server/api/apiCreateLesson.ts
@@ -0,0 +1,16 @@
+
+import {Request, Response} from 'express';
+import {createLesson} from "../queries/createLesson";
+import {onSuccess} from "./onSuccess";
+import {onError} from "./onError";
+import * as _ from 'lodash';
+
+export function apiCreateLesson(req:Request, res:Response) {
+
+    const lessonId = req.params.id;
+
+    createLesson(lessonId, req.body)
+        .then(_.partial(onSuccess, res))
+        .catch( _.partial(onError, res, `Could not create lesson ${lessonId}`) );
+
+}
\ No newline at end of file
diff --git a/server/api/apiDeleteLesson.ts b/server/api/apiDeleteLesson.ts
new file mode 100644
index 0000000..38bd660
--- /dev/null
+++ b/server/api/apiDeleteLesson.ts
@@ -0,0 +1,16 @@
+
+import {Request, Response} from 'express';
+import {onError} from "./onError";
+import {onSuccess} from "./onSuccess";
+import {deleteLesson} from "../queries/deleteLesson";
+import * as _ from 'lodash';
+
+export function apiDeleteLesson(req:Request, res:Response) {
+
+    const lessonId = req.params.id;
+
+    deleteLesson(lessonId)
+        .then(_.partial(onSuccess, res))
+        .catch( _.partial(onError, res, `Could not delete lesson ${lessonId}`) );
+
+}
\ No newline at end of file
diff --git a/server/api/apiErrorHandler.ts b/server/api/apiErrorHandler.ts
new file mode 100644
index 0000000..5b7281d
--- /dev/null
+++ b/server/api/apiErrorHandler.ts
@@ -0,0 +1,22 @@
+
+import {Request, Response, RequestHandler, ErrorRequestHandler, NextFunction} from 'express';
+
+
+
+
+
+export const apiErrorHandler: ErrorRequestHandler =  (err: any, req: Request, res: Response, next: NextFunction) => {
+
+    console.log('error handler triggered');
+
+    if (req.xhr) {
+        res.status(500).send({ error: 'Something failed!' });
+    } else {
+        console.log('not an ajax request, continuing....');
+        next(err);
+    }
+
+
+};
+
+
diff --git a/server/api/apiGetAllCourses.ts b/server/api/apiGetAllCourses.ts
new file mode 100644
index 0000000..db23595
--- /dev/null
+++ b/server/api/apiGetAllCourses.ts
@@ -0,0 +1,17 @@
+
+import {Request, Response} from 'express';
+import {findAllCourses} from "../queries/findAllCourses";
+import * as _ from 'lodash';
+import {onSuccess} from "./onSuccess";
+import {onError} from "./onError";
+
+
+
+
+
+
+export function apiGetAllCourses(req:Request, res:Response) {
+        findAllCourses()
+            .then(_.partial(onSuccess, res))
+            .catch( _.partial(onError, res, "Could not find all courses") );
+}
diff --git a/server/api/apiGetCourseDetail.ts b/server/api/apiGetCourseDetail.ts
new file mode 100644
index 0000000..300a8ac
--- /dev/null
+++ b/server/api/apiGetCourseDetail.ts
@@ -0,0 +1,20 @@
+
+import {Request, Response} from 'express';
+import {findCourseDetail} from "../queries/findCourseDetail";
+import {onSuccess} from "./onSuccess";
+import {onError} from "./onError";
+import * as _ from 'lodash';
+
+
+export function apiGetCourseDetail(req:Request, res:Response) {
+
+    const courseId = parseInt(req.params.id);
+
+    findCourseDetail(courseId)
+        .then(_.partial(onSuccess, res))
+        .catch( _.partial(onError, res, `Could not find course detail for id ${courseId}`) );
+
+}
+
+
+
diff --git a/server/api/apiPatchLesson.ts b/server/api/apiPatchLesson.ts
new file mode 100644
index 0000000..d19d210
--- /dev/null
+++ b/server/api/apiPatchLesson.ts
@@ -0,0 +1,23 @@
+
+import {Request, Response} from 'express';
+import {onSuccess} from "./onSuccess";
+import {onError} from "./onError";
+import {updateLesson} from "../queries/updateLesson";
+import * as _ from 'lodash';
+
+
+
+
+
+
+export function apiPatchLesson(req:Request, res:Response) {
+
+    const lessonId = req.params.id;
+
+    updateLesson(lessonId, req.body)
+        .then(_.partial(onSuccess, res))
+        .catch( _.partial(onError, res, "Could not update lesson") );
+}
+
+
+
diff --git a/server/api/fallbackErrorHandler.ts b/server/api/fallbackErrorHandler.ts
new file mode 100644
index 0000000..1a82718
--- /dev/null
+++ b/server/api/fallbackErrorHandler.ts
@@ -0,0 +1,17 @@
+
+
+import {ErrorRequestHandler} from 'express';
+import {NextFunction} from "express-serve-static-core";
+import {Response} from "express-serve-static-core";
+import {Request} from "express-serve-static-core";
+
+
+
+
+export function fallbackErrorHandler(err: any, req: Request, res: Response, next: NextFunction) {
+
+    res.status(500).send("Error Occurred.");
+
+}
+
+
diff --git a/server/api/onError.ts b/server/api/onError.ts
new file mode 100644
index 0000000..79f8fdc
--- /dev/null
+++ b/server/api/onError.ts
@@ -0,0 +1,12 @@
+
+import {Request, Response} from 'express';
+
+
+export function onError(res:Response, message: string, err:any) {
+
+    console.log('onError', err);
+
+    console.error(message, err);
+    res.status(500).send();
+
+}
diff --git a/server/api/onSuccess.ts b/server/api/onSuccess.ts
new file mode 100644
index 0000000..d26d548
--- /dev/null
+++ b/server/api/onSuccess.ts
@@ -0,0 +1,6 @@
+
+import {Request, Response} from 'express';
+
+export function onSuccess(res: Response, data:any) {
+    res.status(200).json(data);
+}
diff --git a/server/model/index.ts b/server/model/index.ts
new file mode 100644
index 0000000..8d2b329
--- /dev/null
+++ b/server/model/index.ts
@@ -0,0 +1,22 @@
+
+import Sequelize = require("Sequelize");
+import {LoggingOptions} from 'sequelize';
+import {initCourseModel} from "./initCourseModel";
+import {initLessonModel} from "./initLessonModel";
+
+
+const loggingConfig: LoggingOptions = {benchmark:true, logging:console.log};
+
+const dbUrl = 'postgres://postgres:postgres@localhost:5432/complete-typescript-course';
+
+const sequelize = new Sequelize(dbUrl, loggingConfig);
+
+
+export const CourseModel = initCourseModel(sequelize);
+
+export const LessonModel = initLessonModel(sequelize);
+
+
+CourseModel.hasMany(LessonModel, {foreignKey: 'courseId'});
+
+LessonModel.belongsTo(CourseModel, {foreignKey: 'courseId'});
\ No newline at end of file
diff --git a/server/model/initCourseModel.ts b/server/model/initCourseModel.ts
new file mode 100644
index 0000000..5f6bbd2
--- /dev/null
+++ b/server/model/initCourseModel.ts
@@ -0,0 +1,21 @@
+
+
+import * as ORM from "Sequelize";
+import {Sequelize} from 'Sequelize';
+
+
+
+
+export function initCourseModel(sequelize:Sequelize) {
+    return sequelize.define('Course', {
+        description: ORM.STRING,
+        url:  ORM.STRING,
+        longDescription: ORM.TEXT,
+        iconUrl: ORM.STRING,
+        courseListIcon: ORM.STRING,
+        seqNo: ORM.INTEGER,
+        comingSoon: ORM.BOOLEAN,
+        isNew: ORM.BOOLEAN,
+        isOngoing: ORM.BOOLEAN
+    });
+}
\ No newline at end of file
diff --git a/server/model/initLessonModel.ts b/server/model/initLessonModel.ts
new file mode 100644
index 0000000..581f29a
--- /dev/null
+++ b/server/model/initLessonModel.ts
@@ -0,0 +1,19 @@
+
+
+import ORM = require("Sequelize");
+import {Sequelize} from 'Sequelize';
+
+
+
+export function initLessonModel(sequelize:Sequelize) {
+    return sequelize.define('Lesson', {
+        url: ORM.STRING,
+        description: ORM.STRING,
+        duration: ORM.STRING,
+        seqNo: ORM.INTEGER,
+        courseId: ORM.INTEGER,
+        pro: ORM.BOOLEAN,
+        tags: ORM.STRING,
+        gitHubUrl: ORM.STRING
+    });
+}
\ No newline at end of file
diff --git a/server/queries/createLesson.ts b/server/queries/createLesson.ts
new file mode 100644
index 0000000..b66486c
--- /dev/null
+++ b/server/queries/createLesson.ts
@@ -0,0 +1,16 @@
+
+
+
+
+
+import {LessonModel} from "../model";
+
+export function createLesson(id:string, props: any) {
+    return LessonModel.findOrCreate({
+        where: {id},
+        defaults: props
+    });
+}
+
+
+
diff --git a/server/queries/deleteLesson.ts b/server/queries/deleteLesson.ts
new file mode 100644
index 0000000..0c9974e
--- /dev/null
+++ b/server/queries/deleteLesson.ts
@@ -0,0 +1,11 @@
+
+
+
+import {LessonModel} from "../model";
+
+export function deleteLesson(id:string) {
+    return LessonModel.destroy({
+        where: {id}
+    });
+}
+
diff --git a/server/queries/findAllCourses.ts b/server/queries/findAllCourses.ts
new file mode 100644
index 0000000..c2e4900
--- /dev/null
+++ b/server/queries/findAllCourses.ts
@@ -0,0 +1,11 @@
+
+import {CourseModel} from "../model";
+
+
+export function findAllCourses() {
+    return CourseModel.findAll({
+        order: ['seqNo']
+    })
+}
+
+
diff --git a/server/queries/findCourseDetail.ts b/server/queries/findCourseDetail.ts
new file mode 100644
index 0000000..e72062f
--- /dev/null
+++ b/server/queries/findCourseDetail.ts
@@ -0,0 +1,35 @@
+
+
+import {CourseModel, LessonModel} from "../model";
+import Bluebird = require("bluebird");
+import * as _ from 'lodash';
+import {mapCourseAndLessons} from "../../shared/model/course-utils";
+
+
+
+
+
+export function findCourseDetail(courseId:number): Bluebird<Course | null> {
+    return CourseModel.findById(courseId, {
+        include: [
+            {
+                model: LessonModel
+            }
+        ],
+        order: [
+            [ LessonModel, 'seqNo' , 'ASC']
+        ]
+    })
+    .then(onCourseModelFound);
+
+}
+
+
+
+function onCourseModelFound(result:any) {
+    return Promise.resolve(mapCourseAndLessons(result));
+}
+
+
+
+
diff --git a/server/queries/updateLesson.ts b/server/queries/updateLesson.ts
new file mode 100644
index 0000000..0b194fc
--- /dev/null
+++ b/server/queries/updateLesson.ts
@@ -0,0 +1,10 @@
+
+
+
+
+import {LessonModel} from "../model";
+
+
+export function updateLesson(id:string, updatedProperties: any) {
+    return LessonModel.update(updatedProperties, {where: {id}});
+}
\ No newline at end of file
diff --git a/server/server.ts b/server/server.ts
new file mode 100644
index 0000000..a1a250c
--- /dev/null
+++ b/server/server.ts
@@ -0,0 +1,48 @@
+
+import * as express from 'express';
+
+import * as path from 'path';
+import {initApi} from "./api/api";
+import {apiErrorHandler} from "./api/apiErrorHandler";
+import {fallbackErrorHandler} from "./api/fallbackErrorHandler";
+
+var bodyParser = require('body-parser');
+
+
+
+
+
+const port = 8090;
+
+const app = express();
+
+
+let root = path.join(path.resolve(__dirname, '..'));
+
+
+app.use(bodyParser.json());
+
+app.use(express.static(root));
+
+
+
+initApi(app);
+
+
+app.use(apiErrorHandler);
+app.use(fallbackErrorHandler);
+
+
+
+
+
+
+app.listen(port, () => {
+    console.log('Listen on port:' + port + ' at ' + new Date());
+});
+
+
+
+
+
+
diff --git a/shared/model/course-utils.ts b/shared/model/course-utils.ts
new file mode 100644
index 0000000..ed470b8
--- /dev/null
+++ b/shared/model/course-utils.ts
@@ -0,0 +1,21 @@
+
+import {mapLesson} from "./lesson-utils";
+import {Course} from "./course";
+
+export function mapCourseAndLessons({description, url, longDescription, iconUrl, courseListIcon, seqNo, comingSoon, isNew, isOngoing, Lessons}:any): Course {
+    return {
+        description,
+        url,
+        longDescription,
+        iconUrl,
+        courseListIcon,
+        seqNo,
+        comingSoon,
+        isNew,
+        isOngoing,
+        lessons: Lessons.map((lesson:any) => mapLesson(lesson) )
+    };
+}
+
+
+
diff --git a/shared/model/course.ts b/shared/model/course.ts
new file mode 100644
index 0000000..8a0b692
--- /dev/null
+++ b/shared/model/course.ts
@@ -0,0 +1,16 @@
+
+import {Lesson} from "./lesson";
+
+export interface Course {
+
+    readonly description: string,
+    readonly url:  string,
+    readonly longDescription: string,
+    readonly iconUrl: string,
+    readonly courseListIcon: string,
+    readonly seqNo: number,
+    readonly comingSoon: boolean,
+    readonly isNew: boolean,
+    readonly isOngoing: boolean,
+    readonly lessons: Lesson[];
+}
\ No newline at end of file
diff --git a/shared/model/lesson-utils.ts b/shared/model/lesson-utils.ts
new file mode 100644
index 0000000..06d6ce2
--- /dev/null
+++ b/shared/model/lesson-utils.ts
@@ -0,0 +1,16 @@
+
+
+export function mapLesson({url, description, duration, seqNo,courseId, pro, tags}:any): Lesson {
+    return {
+        url,
+        description,
+        duration,
+        seqNo,
+        courseId,
+        pro,
+        tags
+    }
+}
+
+
+
diff --git a/shared/model/lesson.ts b/shared/model/lesson.ts
new file mode 100644
index 0000000..2897faf
--- /dev/null
+++ b/shared/model/lesson.ts
@@ -0,0 +1,16 @@
+
+
+
+export interface Lesson  {
+
+    readonly url:string;
+    readonly description: string;
+    readonly duration: string;
+    readonly seqNo: number;
+    readonly courseId:string;
+    readonly pro: boolean;
+    readonly tags: string;
+
+}
+
+
diff --git a/shared/package.json b/shared/package.json
new file mode 100644
index 0000000..209398c
--- /dev/null
+++ b/shared/package.json
@@ -0,0 +1,11 @@
+{
+  "name": "ctc-shared",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "JhadesDev <jhades.dev@gmail.com> (http://blog.jhades.org/)",
+  "license": "MIT"
+}
diff --git a/sql-examples.ts b/sql-examples.ts
new file mode 100644
index 0000000..b70dc93
--- /dev/null
+++ b/sql-examples.ts
@@ -0,0 +1,17 @@
+
+
+import {findAllCourses} from "./src/queries/findAllCourses";
+
+
+let courses = findAllCourses();
+
+
+courses
+    .then((data:any) => {
+
+        console.log(data[0].dataValues);
+
+    })
+    .catch(console.error);
+
+
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..a6cdafe
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,12 @@
+{
+    "compilerOptions": {
+        "emitDecoratorMetadata": true,
+        "experimentalDecorators": true,
+        "module": "commonjs",
+        "target": "es5",
+        "noImplicitAny": true,
+        "skipLibCheck":true,
+        "strictNullChecks": true,
+        "sourceMap": true
+    }
+}
\ No newline at end of file
