diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 4501fdf66bc70fe63cd767152d57724b9e28bf44..d1da7959558ac4be0af32a2eb8910b89e547c67a 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -3,26 +3,26 @@ import { Component, ViewChild, OnInit } from '@angular/core';
 import { MatSidenav } from '@angular/material';
 
 @Component({
-	selector: 'cse-root',
-	templateUrl: './app.component.html',
-	styleUrls: ['./app.component.scss']
+  selector: 'cse-root',
+  templateUrl: './app.component.html',
+  styleUrls: ['./app.component.scss'],
 })
 export class AppComponent implements OnInit {
-	@ViewChild('rightAddCourse') public rightAddCourse: MatSidenav;
-	constructor(private sidenavService: SidenavService) { }
+  @ViewChild('rightAddCourse') public rightAddCourse: MatSidenav;
+  constructor(private sidenavService: SidenavService) {}
 
-	ngOnInit() {
-		this.sidenavService.setSidenav(this.rightAddCourse);
-	}
+  ngOnInit() {
+    this.sidenavService.setSidenav(this.rightAddCourse);
+  }
 }
 
 document.addEventListener('WebComponentsReady', function() {
-	const customEvent = new CustomEvent('myuw-login', {
-		detail: {
-			person: {
-				// 'firstName': 'Bucky'
-			}
-		}
-	});
-	document.dispatchEvent(customEvent);
+  const customEvent = new CustomEvent('myuw-login', {
+    detail: {
+      person: {
+        // 'firstName': 'Bucky'
+      },
+    },
+  });
+  document.dispatchEvent(customEvent);
 });
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 75bdd82109c5dce49f8b8ac600c75ba2d70239e6..83f523b88a51128a4426c1c92afabaea61418bdd 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -12,32 +12,29 @@ import { CoreModule } from '@app/core/core.module';
 import { SharedModule } from '@app/shared/shared.module';
 import { HeaderComponent } from './core/header/header.component';
 import { SidenavService } from './core/service/sidenav.service';
-import { degreePlannerReducer } from '@app/degree-planner/reducer';
-import { DegreePlanEffects } from '@app/degree-planner/effects/plan.effects';
-import { NoteEffects } from '@app/degree-planner/effects/note.effects';
+import { degreePlannerReducer } from '@app/degree-planner/store/reducer';
+import { DegreePlanEffects } from '@app/degree-planner/store/effects/plan.effects';
+import { NoteEffects } from '@app/degree-planner/store/effects/note.effects';
 
 @NgModule({
-	imports: [
-		StoreModule.forRoot({
-			degreePlanner: degreePlannerReducer
-		}),
-		EffectsModule.forRoot([DegreePlanEffects, NoteEffects]),
-		BrowserModule,
-		BrowserAnimationsModule,
-		HttpClientModule,
-		CoreModule,
-		SharedModule,
-		AppRoutingModule,
-		StoreDevtoolsModule.instrument({
-			maxAge: 5
-		}),
-	],
-	declarations: [
-		AppComponent,
-		HeaderComponent
-	],
-	providers: [ SidenavService ],
-	bootstrap: [ AppComponent ],
-	schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
+  imports: [
+    StoreModule.forRoot({
+      degreePlanner: degreePlannerReducer,
+    }),
+    EffectsModule.forRoot([DegreePlanEffects, NoteEffects]),
+    BrowserModule,
+    BrowserAnimationsModule,
+    HttpClientModule,
+    CoreModule,
+    SharedModule,
+    AppRoutingModule,
+    StoreDevtoolsModule.instrument({
+      maxAge: 5,
+    }),
+  ],
+  declarations: [AppComponent, HeaderComponent],
+  providers: [SidenavService],
+  bootstrap: [AppComponent],
+  schemas: [CUSTOM_ELEMENTS_SCHEMA],
 })
-export class AppModule { }
+export class AppModule {}
diff --git a/src/app/app.routing.module.ts b/src/app/app.routing.module.ts
index c4fc6c324731215b8e9af4bcd81a32bdea30490a..585d241f00794e89e229f17e5c2127acb077c139 100644
--- a/src/app/app.routing.module.ts
+++ b/src/app/app.routing.module.ts
@@ -1,17 +1,15 @@
 import { NgModule } from '@angular/core';
 import { Routes, RouterModule } from '@angular/router';
 
-import { AppComponent } from './app.component';
-
 const routes: Routes = [
-	{
-		path: '',
-		loadChildren: './degree-planner/degree-planner.module#DegreePlannerModule'
-	}
+  {
+    path: '',
+    loadChildren: './degree-planner/degree-planner.module#DegreePlannerModule',
+  },
 ];
 
 @NgModule({
-	imports: [RouterModule.forRoot(routes)],
-	exports: [RouterModule]
+  imports: [RouterModule.forRoot(routes)],
+  exports: [RouterModule],
 })
-export class AppRoutingModule { }
+export class AppRoutingModule {}
diff --git a/src/app/core/state.ts b/src/app/core/state.ts
index 51a17639c2f13161ce526b8b3b69661ad5a53a30..a4d7e03c8d375ca1f3d6ec0fff176904974eef04 100644
--- a/src/app/core/state.ts
+++ b/src/app/core/state.ts
@@ -1,5 +1,5 @@
-import { DegreePlannerState } from '@app/degree-planner/state';
+import { DegreePlannerState } from '@app/degree-planner/store/state';
 
 export interface GlobalState {
-	degreePlanner: DegreePlannerState;
+  degreePlanner: DegreePlannerState;
 }
diff --git a/src/app/degree-planner/actions/note.actions.ts b/src/app/degree-planner/actions/note.actions.ts
deleted file mode 100644
index 8397c027ecdf2ba5e70e64707219f2e7383f5db9..0000000000000000000000000000000000000000
--- a/src/app/degree-planner/actions/note.actions.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { Action } from '@ngrx/store';
-import { Note } from '@app/core/models/note';
-
-export enum NoteActionTypes {
-	WriteNoteRequest = '[Note] Write Request',
-	WriteNoteResponse = '[Note] Write Response',
-	DeleteNoteRequest = '[Note] Delete Request',
-	DeleteNoteResponse = '[Note] Delete Response'
-}
-
-export class WriteNoteRequest implements Action {
-	public readonly type = NoteActionTypes.WriteNoteRequest;
-	constructor(public payload: { termCode: string; noteText: string }) {}
-}
-
-export class WriteNoteResponse implements Action {
-	public readonly type = NoteActionTypes.WriteNoteResponse;
-	constructor(public payload: { updatedNote: Note }) {}
-}
-
-export class DeleteNoteRequest implements Action {
-	public readonly type = NoteActionTypes.DeleteNoteRequest;
-	constructor(public payload: { termCode: string }) {}
-}
-
-export class DeleteNoteResponse implements Action {
-	public readonly type = NoteActionTypes.DeleteNoteResponse;
-	constructor(public payload: { termCode: string }) {}
-}
diff --git a/src/app/degree-planner/degree-planner.component.ts b/src/app/degree-planner/degree-planner.component.ts
index 58d2f4d8c3712c7e2e9b29a42850a03f5de2876b..444465958f2f3a0b0021977b46f65e99200aa924 100644
--- a/src/app/degree-planner/degree-planner.component.ts
+++ b/src/app/degree-planner/degree-planner.component.ts
@@ -18,10 +18,10 @@ import {
   getVisibleRoadmapId,
   firstActiveTermCode,
   getAllVisibleTermsByYear,
-} from '@app/degree-planner/selectors';
+} from '@app/degree-planner/store/selectors';
 
 // Actions
-import { ChangeVisiblePlanRequest } from '@app/degree-planner/actions/plan.actions';
+import { ChangeVisiblePlanRequest } from '@app/degree-planner/store/actions/plan.actions';
 
 @Component({
   selector: 'cse-degree-planner',
diff --git a/src/app/degree-planner/degree-planner.module.ts b/src/app/degree-planner/degree-planner.module.ts
index 5600c87d3fd5764b8eb6c4e82cf25aab49cfa99e..cd9a4a46a533f8f11de32cf1d94473ea7ad9f9ed 100644
--- a/src/app/degree-planner/degree-planner.module.ts
+++ b/src/app/degree-planner/degree-planner.module.ts
@@ -13,22 +13,22 @@ import { DragDropModule } from '@angular/cdk/drag-drop';
 import { RemoveCourseConfirmDialogComponent } from './dialogs/remove-course-confirm-dialog/remove-course-confirm-dialog.component';
 
 @NgModule({
-	imports: [SharedModule, DragDropModule, DegreePlannerRoutingModule],
-	exports: [DragDropModule],
-	declarations: [
-		DegreePlannerComponent,
-		TermContainerComponent,
-		CourseItemComponent,
-		SidenavMenuItemComponent,
-		SavedForLaterContainerComponent,
-		CourseDetailsDialogComponent,
-		NotesDialogComponent,
-		RemoveCourseConfirmDialogComponent
-	],
-	entryComponents: [
-		CourseDetailsDialogComponent,
-		NotesDialogComponent,
-		RemoveCourseConfirmDialogComponent
-	]
+  imports: [SharedModule, DragDropModule, DegreePlannerRoutingModule],
+  exports: [DragDropModule],
+  declarations: [
+    DegreePlannerComponent,
+    TermContainerComponent,
+    CourseItemComponent,
+    SidenavMenuItemComponent,
+    SavedForLaterContainerComponent,
+    CourseDetailsDialogComponent,
+    NotesDialogComponent,
+    RemoveCourseConfirmDialogComponent,
+  ],
+  entryComponents: [
+    CourseDetailsDialogComponent,
+    NotesDialogComponent,
+    RemoveCourseConfirmDialogComponent,
+  ],
 })
 export class DegreePlannerModule {}
diff --git a/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.html b/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.html
deleted file mode 100644
index 35b902da77b74d0a7cb4c55c9323ed7233e7d7ae..0000000000000000000000000000000000000000
--- a/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<mat-toolbar color="primary" class="dialog-toolbar">
-	<span class="dialog-toolbar-title">Course Details</span>
-	<button mat-button mat-dialog-close class="close-btn"><i class="material-icons">clear</i></button>
-</mat-toolbar>
-
-<mat-dialog-content class="mat-typography dialog-with-toolbar">
-	<cse-course-details></cse-course-details>
-</mat-dialog-content>
\ No newline at end of file
diff --git a/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.scss b/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.scss
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.spec.ts b/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.spec.ts
deleted file mode 100644
index 6a866893a532e50e90de66e204b56d2d78a26aa5..0000000000000000000000000000000000000000
--- a/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.spec.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
-// import { SharedModule } from '@app/shared/shared.module';
-// import { CoreModule } from '@app/core/core.module';
-// import { DataService } from '@app/core/data.service';
-// import { HttpClient } from '@angular/common/http';
-// import { HttpHandler } from '@angular/common/http';
-// import { CourseDetailsDialogComponent } from './course-details-dialog.component';
-// import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
-
-// describe('CourseDetailsDialogComponent', () => {
-// 	let component: CourseDetailsDialogComponent;
-// 	let fixture: ComponentFixture<CourseDetailsDialogComponent>;
-
-// 	beforeEach(async(() => {
-// 		TestBed.configureTestingModule({
-// 			imports: [CoreModule, SharedModule],
-// 			declarations: [ CourseDetailsDialogComponent ],
-// 			providers: [DataService, HttpClient, HttpHandler, { provide: MatDialogRef, useValue: {} }, { provide: MAT_DIALOG_DATA, useValue: {} }]
-// 		})
-// 		.compileComponents();
-// 	}));
-
-// 	beforeEach(() => {
-// 		fixture = TestBed.createComponent(CourseDetailsDialogComponent);
-// 		component = fixture.componentInstance;
-// 		fixture.detectChanges();
-// 	});
-
-// 	it('should create', () => {
-// 		expect(component).toBeTruthy();
-// 	});
-// });
diff --git a/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.ts b/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.ts
index 782169c17e32626a762d5d248895fcabb3044181..8d3701f4de013149192205840d03c0026dbe944e 100644
--- a/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.ts
+++ b/src/app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component.ts
@@ -1,15 +1,22 @@
-import { CourseDetails } from './../../../core/models/course-details';
-import { Component, OnInit, Inject } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
 
 @Component({
-	selector: 'cse-course-details-dialog',
-	templateUrl: './course-details-dialog.component.html',
-	styleUrls: ['./course-details-dialog.component.scss']
-})
+  selector: 'cse-course-details-dialog',
+  template: `
+    <mat-toolbar color="primary" class="dialog-toolbar">
+      <span class="dialog-toolbar-title">Course Details</span>
+      <button mat-button mat-dialog-close class="close-btn">
+        <i class="material-icons">clear</i>
+      </button>
+    </mat-toolbar>
 
+    <mat-dialog-content class="mat-typography dialog-with-toolbar">
+      <cse-course-details></cse-course-details>
+    </mat-dialog-content>
+  `,
+})
 export class CourseDetailsDialogComponent implements OnInit {
-	constructor() {}
+  constructor() {}
 
-	ngOnInit() {
-	}
+  ngOnInit() {}
 }
diff --git a/src/app/degree-planner/dialogs/notes-dialog/notes-dialog.component.ts b/src/app/degree-planner/dialogs/notes-dialog/notes-dialog.component.ts
index 0896ccee413f4886cff5c14fddc033ab3d2e3609..e3927428861dd8bbacf8038ee308202dac501a66 100644
--- a/src/app/degree-planner/dialogs/notes-dialog/notes-dialog.component.ts
+++ b/src/app/degree-planner/dialogs/notes-dialog/notes-dialog.component.ts
@@ -7,51 +7,51 @@ import { Store } from '@ngrx/store';
 // State management
 import { GlobalState } from '@app/core/state';
 import {
-	WriteNoteRequest,
-	DeleteNoteRequest
-} from '@app/degree-planner/actions/note.actions';
+  WriteNoteRequest,
+  DeleteNoteRequest,
+} from '@app/degree-planner/store/actions/note.actions';
 
 export type NotesDialogData =
-	| { termCode: string; hasExistingNote: true; initialText: string }
-	| { termCode: string; hasExistingNote: false; initialText?: never };
+  | { termCode: string; hasExistingNote: true; initialText: string }
+  | { termCode: string; hasExistingNote: false; initialText?: never };
 
 @Component({
-	selector: 'cse-notes-dialog',
-	templateUrl: './notes-dialog.component.html',
-	styleUrls: ['./notes-dialog.component.scss']
+  selector: 'cse-notes-dialog',
+  templateUrl: './notes-dialog.component.html',
+  styleUrls: ['./notes-dialog.component.scss'],
 })
 export class NotesDialogComponent implements OnInit {
-	public form: FormGroup;
-	public MAX_LENGTH = 512;
+  public form: FormGroup;
+  public MAX_LENGTH = 512;
 
-	constructor(
-		private store: Store<GlobalState>,
-		private dialogRef: MatDialogRef<NotesDialogComponent>,
-		@Inject(MAT_DIALOG_DATA) public data: NotesDialogData
-	) {}
+  constructor(
+    private store: Store<GlobalState>,
+    private dialogRef: MatDialogRef<NotesDialogComponent>,
+    @Inject(MAT_DIALOG_DATA) public data: NotesDialogData,
+  ) {}
 
-	public ngOnInit() {
-		this.form = new FormGroup({
-			textarea: new FormControl(this.data.initialText || '', [
-				Validators.maxLength(this.MAX_LENGTH),
-				Validators.required
-			])
-		});
-	}
+  public ngOnInit() {
+    this.form = new FormGroup({
+      textarea: new FormControl(this.data.initialText || '', [
+        Validators.maxLength(this.MAX_LENGTH),
+        Validators.required,
+      ]),
+    });
+  }
 
-	public writeNote() {
-		const termCode = this.data.termCode;
-		const noteText =
-			typeof this.form.value.textarea === 'string'
-				? this.form.value.textarea
-				: '';
-		this.store.dispatch(new WriteNoteRequest({ termCode, noteText }));
-		this.dialogRef.close({ event: 'save' });
-	}
+  public writeNote() {
+    const termCode = this.data.termCode;
+    const noteText =
+      typeof this.form.value.textarea === 'string'
+        ? this.form.value.textarea
+        : '';
+    this.store.dispatch(new WriteNoteRequest({ termCode, noteText }));
+    this.dialogRef.close({ event: 'save' });
+  }
 
-	public deleteNote() {
-		const termCode = this.data.termCode;
-		this.store.dispatch(new DeleteNoteRequest({ termCode }));
-		this.dialogRef.close({ event: 'remove' });
-	}
+  public deleteNote() {
+    const termCode = this.data.termCode;
+    this.store.dispatch(new DeleteNoteRequest({ termCode }));
+    this.dialogRef.close({ event: 'remove' });
+  }
 }
diff --git a/src/app/degree-planner/dialogs/remove-course-confirm-dialog/remove-course-confirm-dialog.component.ts b/src/app/degree-planner/dialogs/remove-course-confirm-dialog/remove-course-confirm-dialog.component.ts
index 1381509c1ffcbbda32595b35e7bfdaba389d3583..d44598736a17cff3b249a6c1741c22aeead62541 100644
--- a/src/app/degree-planner/dialogs/remove-course-confirm-dialog/remove-course-confirm-dialog.component.ts
+++ b/src/app/degree-planner/dialogs/remove-course-confirm-dialog/remove-course-confirm-dialog.component.ts
@@ -4,10 +4,10 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
 import { Course } from '@app/core/models/course';
 import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
 
-import { DegreePlannerState } from '@app/degree-planner/state';
+import { DegreePlannerState } from '@app/degree-planner/store/state';
 import { Store } from '@ngrx/store';
 
-import { RemoveCourseRequest } from '@app/degree-planner/actions/plan.actions';
+import { RemoveCourseRequest } from '@app/degree-planner/store/actions/plan.actions';
 
 @Component({
   selector: 'cse-remove-course-confirm-dialog',
diff --git a/src/app/degree-planner/effects/note.effects.ts b/src/app/degree-planner/effects/note.effects.ts
deleted file mode 100644
index 5dd812a7215bcd6b27dc461346ce15a0535551cf..0000000000000000000000000000000000000000
--- a/src/app/degree-planner/effects/note.effects.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-// Libraries
-import { Injectable } from '@angular/core';
-import { Store } from '@ngrx/store';
-import { Actions, Effect, ofType } from '@ngrx/effects';
-import { Observable, of } from 'rxjs';
-import { mergeMap, withLatestFrom, map, filter } from 'rxjs/operators';
-
-// Models
-import { Note } from '@app/core/models/note';
-
-// Services
-import { DegreePlannerApiService } from '@app/degree-planner/services/api.service';
-
-// State management
-import {
-	NoteActionTypes,
-	WriteNoteRequest,
-	WriteNoteResponse,
-	DeleteNoteRequest,
-	DeleteNoteResponse
-} from '@app/degree-planner/actions/note.actions';
-import { getDegreePlannerState } from '@app/degree-planner/selectors';
-import { GlobalState } from '@app/core/state';
-import { DegreePlannerState } from '@app/degree-planner/state';
-
-@Injectable()
-export class NoteEffects {
-	constructor(
-		private actions$: Actions,
-		private store$: Store<GlobalState>,
-		private api: DegreePlannerApiService
-	) {}
-
-	@Effect()
-	writeNote$: Observable<WriteNoteResponse> = this.actions$.pipe(
-		ofType<WriteNoteRequest>(NoteActionTypes.WriteNoteRequest),
-
-		// Get the most recent Degree Planner state object from the store. This is
-		// used to decide to fire either the `updateNote` API or `createNote` API.
-		withLatestFrom(this.store$.select(getDegreePlannerState)),
-
-		// Only handle WriteNote actions when a current plan ID is set.
-		filter(([_, state]) => typeof state.visibleRoadmapId === 'number'),
-
-		// Using the action and State objects, determine whether to fire the
-		// `updateNote` or `createNote` API. Both of these API calls return
-		// an observable wrapper around the modified/created Note object.
-		mergeMap(([action, state]) => {
-			const planId = state.visibleRoadmapId as number;
-			const termCode = action.payload.termCode;
-			const noteText = action.payload.noteText;
-			const existingNote = getExistingNote(state, termCode);
-			if (existingNote !== undefined) {
-				// Since the term DOES have a note, update the existing note
-				const noteId = existingNote.id;
-				return this.api.updateNote(planId, termCode, noteText, noteId);
-			} else {
-				// Since the term DOES NOT have a note, create a new note
-				return this.api.createNote(planId, termCode, noteText);
-			}
-		}),
-
-		// Dispatch an `WriteNoteSuccess` action so that the State
-		// object can be updated with the new Note data.
-		map(updatedNote => new WriteNoteResponse({ updatedNote }))
-	);
-
-	@Effect()
-	deleteNote$: Observable<DeleteNoteResponse> = this.actions$.pipe(
-		ofType<DeleteNoteRequest>(NoteActionTypes.DeleteNoteRequest),
-
-		// Get the most recent Degree Planner state object.
-		// This is used to lookup the Note ID.
-		withLatestFrom(this.store$.select(getDegreePlannerState)),
-
-		// Only handle DeleteNote actions when a current plan ID is set.
-		filter(([_, state]) => typeof state.visibleRoadmapId === 'number'),
-
-		// Using the action and State objects, fire the `deleteNote` API.
-		mergeMap(([action, state]) => {
-			const planId = state.visibleRoadmapId as number;
-			const termCode = action.payload.termCode;
-			const existingNote = getExistingNote(state, termCode);
-			if (existingNote !== undefined) {
-				// Since the term DOES have a note, delete it
-				const noteId = existingNote.id;
-				return this.api.deleteNote(planId, noteId).pipe(map(() => termCode));
-			} else {
-				// Since the term DID NOT already have a note, return an action that
-				// makes no changes to the current state
-				return of(termCode);
-			}
-		}),
-
-		// Dispatch an `DeleteNoteSuccess` action so that the
-		// State object can be updated with the note removed.
-		map(termCode => new DeleteNoteResponse({ termCode }))
-	);
-}
-
-const getExistingNote = (state: DegreePlannerState, termCode: string) => {
-	for (const term of state.visibleTerms || []) {
-		if (term.termCode === termCode) {
-			return term.note;
-		}
-	}
-	return undefined;
-};
diff --git a/src/app/degree-planner/favorites-container/favorites-container.component.ts b/src/app/degree-planner/favorites-container/favorites-container.component.ts
index 3e82e551bf84298813ea6299a99f1ad799a5f06d..a0a4e5b5f0cc4b7c638a11471aabdba1484b2c19 100644
--- a/src/app/degree-planner/favorites-container/favorites-container.component.ts
+++ b/src/app/degree-planner/favorites-container/favorites-container.component.ts
@@ -3,49 +3,49 @@ import { Observable } from 'rxjs';
 import { Store, select } from '@ngrx/store';
 import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
 import { GlobalState } from '@app/core/state';
-import { getSavedForLaterCourses } from '@app/degree-planner/selectors';
+import { getSavedForLaterCourses } from '@app/degree-planner/store/selectors';
 
 // rsjx / ngrx
-import { DegreePlannerState } from '@app/degree-planner/state';
+import { DegreePlannerState } from '@app/degree-planner/store/state';
 import {
-	AddSavedForLaterRequest, RemoveCourseRequest
-} from '@app/degree-planner/actions/plan.actions';
+  AddSavedForLaterRequest,
+  RemoveCourseRequest,
+} from '@app/degree-planner/store/actions/plan.actions';
 
 // Selectors
-import {
-	getDropZones
-} from '@app/degree-planner/selectors';
+import { getDropZones } from '@app/degree-planner/store/selectors';
 
 @Component({
-	selector: 'cse-favorites-container',
-	templateUrl: './favorites-container.component.html',
-	styleUrls: ['./favorites-container.component.scss']
+  selector: 'cse-favorites-container',
+  templateUrl: './favorites-container.component.html',
+  styleUrls: ['./favorites-container.component.scss'],
 })
 export class SavedForLaterContainerComponent implements OnInit {
-	public courses$: Observable<SavedForLaterCourse[]>;
-	public dropZones$: Observable<String[]>;
-
-	constructor(private store: Store<{ degreePlanner: DegreePlannerState }>) {}
-
-	public ngOnInit() {
-		this.dropZones$ = this.store.pipe(select(getDropZones));
-		this.courses$ = this.store.pipe(select(getSavedForLaterCourses));
-	}
-
-	drop(event) {
-		const newContainer = event.container.id;
-		const previousContainer = event.previousContainer.id;
-
-		if (newContainer === previousContainer) {
-			// If the user dropped a course into the same container do nothing
-			return;
-
-		} else if (previousContainer.indexOf('term-') === 0) {
-			// If moving from term to to saved for later
-
-			const {subjectCode, courseId, id} = event.item.data;
-			this.store.dispatch(new AddSavedForLaterRequest({subjectCode, courseId}));
-			this.store.dispatch(new RemoveCourseRequest({id}));
-		}
-	}
+  public courses$: Observable<SavedForLaterCourse[]>;
+  public dropZones$: Observable<String[]>;
+
+  constructor(private store: Store<{ degreePlanner: DegreePlannerState }>) {}
+
+  public ngOnInit() {
+    this.dropZones$ = this.store.pipe(select(getDropZones));
+    this.courses$ = this.store.pipe(select(getSavedForLaterCourses));
+  }
+
+  drop(event) {
+    const newContainer = event.container.id;
+    const previousContainer = event.previousContainer.id;
+
+    if (newContainer === previousContainer) {
+      // If the user dropped a course into the same container do nothing
+      return;
+    } else if (previousContainer.indexOf('term-') === 0) {
+      // If moving from term to to saved for later
+
+      const { subjectCode, courseId, id } = event.item.data;
+      this.store.dispatch(
+        new AddSavedForLaterRequest({ subjectCode, courseId }),
+      );
+      this.store.dispatch(new RemoveCourseRequest({ id }));
+    }
+  }
 }
diff --git a/src/app/degree-planner/services/api.service.ts b/src/app/degree-planner/services/api.service.ts
index af4f561d3d52220baa7667f5b37ef03815b11741..d1fbfde8fcde6b9112bdaaccb747e60981f4a076 100644
--- a/src/app/degree-planner/services/api.service.ts
+++ b/src/app/degree-planner/services/api.service.ts
@@ -1,3 +1,4 @@
+import { CourseDetails } from './../../core/models/course-details';
 // Libraries
 import { Injectable } from '@angular/core';
 import { HttpClient, HttpHeaders } from '@angular/common/http';
@@ -51,6 +52,16 @@ export class DegreePlannerApiService {
     return this.http.get<Note[]>(this.degreePlanEndpoint(roadmapId, 'notes'));
   }
 
+  getCourseDetails(
+    subjectCode: string,
+    courseId: string,
+  ): Observable<CourseDetails[]> {
+    return this.http.get<CourseDetails[]>(
+      this.config.apiSearchUrl + '/course/0000/' + subjectCode + '/' + courseId,
+      HTTP_OPTIONS,
+    );
+  }
+
   public getAllTermCourses(
     roadmapId: number,
   ): Observable<{ termCode: string; courses: Course[] }[]> {
diff --git a/src/app/degree-planner/shared/course-item/course-item.component.ts b/src/app/degree-planner/shared/course-item/course-item.component.ts
index cb84c36a3e3ff9c1f4c68a1c5a8e910c80896981..9c19e2d8b2ea7e32de5330a61a74cb8844e4d5d4 100644
--- a/src/app/degree-planner/shared/course-item/course-item.component.ts
+++ b/src/app/degree-planner/shared/course-item/course-item.component.ts
@@ -3,6 +3,7 @@ import { MatDialog } from '@angular/material';
 
 import { Course } from '@app/core/models/course';
 
+import { DegreePlannerApiService } from '@app/degree-planner/services/api.service';
 // tslint:disable-next-line:max-line-length
 import { CourseDetailsDialogComponent } from '@app/degree-planner/dialogs/course-details-dialog/course-details-dialog.component';
 // tslint:disable-next-line:max-line-length
@@ -14,19 +15,18 @@ import { RemoveCourseConfirmDialogComponent } from '@app/degree-planner/dialogs/
   styleUrls: ['./course-item.component.scss'],
 })
 export class CourseItemComponent implements OnInit {
-  dataService; // TODO refactor to use api service
   status; // TODO make this work k thx plz!?
   @Input() course: Course;
   @Input() disabled: string;
   @Input() type: 'saved' | 'course' | 'search';
 
-  constructor(public dialog: MatDialog) {}
+  constructor(private api: DegreePlannerApiService, public dialog: MatDialog) {}
 
   ngOnInit() {}
 
   openCourseDetailsDialog(course) {
-    this.dataService
-      .getCourseDetails(course.termCode, course.subjectCode, course.courseId)
+    this.api
+      .getCourseDetails(course.subjectCode, course.courseId)
       .subscribe(courseDetails => {
         const dialogRef = this.dialog.open(CourseDetailsDialogComponent, {
           data: { courseDetails: courseDetails },
diff --git a/src/app/degree-planner/sidenav-menu-item/sidenav-menu-item.component.ts b/src/app/degree-planner/sidenav-menu-item/sidenav-menu-item.component.ts
index 2aa55f20a3fa0bb1cf66889e269df4cd5edfd495..32afc442de96078b5c80ea8a5bc0e685374a2445 100644
--- a/src/app/degree-planner/sidenav-menu-item/sidenav-menu-item.component.ts
+++ b/src/app/degree-planner/sidenav-menu-item/sidenav-menu-item.component.ts
@@ -1,19 +1,12 @@
-import { Component, OnInit, Input } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
 
 @Component({
-	selector: 'cse-sidenav-menu-item',
-	templateUrl: './sidenav-menu-item.component.html',
-	styleUrls: ['./sidenav-menu-item.component.scss']
+  selector: 'cse-sidenav-menu-item',
+  templateUrl: './sidenav-menu-item.component.html',
+  styleUrls: ['./sidenav-menu-item.component.scss'],
 })
 export class SidenavMenuItemComponent implements OnInit {
-	events: string[] = [];
-	opened: boolean;
-	@Input() favoriteDropZone: [];
-	// @Input() termsByAcademicYear: Object;
-	// @Input() favoriteCourses;
+  constructor() {}
 
-	constructor() { }
-
-	ngOnInit() {
-	}
+  ngOnInit() {}
 }
diff --git a/src/app/degree-planner/store/actions/note.actions.ts b/src/app/degree-planner/store/actions/note.actions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9c3bba9be7e8f1b86fde6fdc272e6fd1fe546f40
--- /dev/null
+++ b/src/app/degree-planner/store/actions/note.actions.ts
@@ -0,0 +1,29 @@
+import { Action } from '@ngrx/store';
+import { Note } from '@app/core/models/note';
+
+export enum NoteActionTypes {
+  WriteNoteRequest = '[Note] Write Request',
+  WriteNoteResponse = '[Note] Write Response',
+  DeleteNoteRequest = '[Note] Delete Request',
+  DeleteNoteResponse = '[Note] Delete Response',
+}
+
+export class WriteNoteRequest implements Action {
+  public readonly type = NoteActionTypes.WriteNoteRequest;
+  constructor(public payload: { termCode: string; noteText: string }) {}
+}
+
+export class WriteNoteResponse implements Action {
+  public readonly type = NoteActionTypes.WriteNoteResponse;
+  constructor(public payload: { updatedNote: Note }) {}
+}
+
+export class DeleteNoteRequest implements Action {
+  public readonly type = NoteActionTypes.DeleteNoteRequest;
+  constructor(public payload: { termCode: string }) {}
+}
+
+export class DeleteNoteResponse implements Action {
+  public readonly type = NoteActionTypes.DeleteNoteResponse;
+  constructor(public payload: { termCode: string }) {}
+}
diff --git a/src/app/degree-planner/actions/plan.actions.ts b/src/app/degree-planner/store/actions/plan.actions.ts
similarity index 98%
rename from src/app/degree-planner/actions/plan.actions.ts
rename to src/app/degree-planner/store/actions/plan.actions.ts
index c919236b6068ce904088169377995dd760b6cf52..7095e93cb7cc832bf6aacfc30065f7b74905a99e 100644
--- a/src/app/degree-planner/actions/plan.actions.ts
+++ b/src/app/degree-planner/store/actions/plan.actions.ts
@@ -1,7 +1,7 @@
 import { Action } from '@ngrx/store';
 
 import { PlannedTerm } from '@app/core/models/planned-term';
-import { DegreePlannerState } from '@app/degree-planner/state';
+import { DegreePlannerState } from '@app/degree-planner/store/state';
 import { Course } from '@app/core/models/course';
 
 export enum PlanActionTypes {
diff --git a/src/app/degree-planner/store/effects/note.effects.ts b/src/app/degree-planner/store/effects/note.effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..eb7a0ff58e7e88cc0d585c13bc572cef64ede3b1
--- /dev/null
+++ b/src/app/degree-planner/store/effects/note.effects.ts
@@ -0,0 +1,108 @@
+// Libraries
+import { Injectable } from '@angular/core';
+import { Store } from '@ngrx/store';
+import { Actions, Effect, ofType } from '@ngrx/effects';
+import { Observable, of } from 'rxjs';
+import { mergeMap, withLatestFrom, map, filter } from 'rxjs/operators';
+
+// Models
+import { Note } from '@app/core/models/note';
+
+// Services
+import { DegreePlannerApiService } from '@app/degree-planner/services/api.service';
+
+// State management
+import {
+  NoteActionTypes,
+  WriteNoteRequest,
+  WriteNoteResponse,
+  DeleteNoteRequest,
+  DeleteNoteResponse,
+} from '@app/degree-planner/store/actions/note.actions';
+import { getDegreePlannerState } from '@app/degree-planner/store/selectors';
+import { GlobalState } from '@app/core/state';
+import { DegreePlannerState } from '@app/degree-planner/store/state';
+
+@Injectable()
+export class NoteEffects {
+  constructor(
+    private actions$: Actions,
+    private store$: Store<GlobalState>,
+    private api: DegreePlannerApiService,
+  ) {}
+
+  @Effect()
+  writeNote$: Observable<WriteNoteResponse> = this.actions$.pipe(
+    ofType<WriteNoteRequest>(NoteActionTypes.WriteNoteRequest),
+
+    // Get the most recent Degree Planner state object from the store. This is
+    // used to decide to fire either the `updateNote` API or `createNote` API.
+    withLatestFrom(this.store$.select(getDegreePlannerState)),
+
+    // Only handle WriteNote actions when a current plan ID is set.
+    filter(([_, state]) => typeof state.visibleRoadmapId === 'number'),
+
+    // Using the action and State objects, determine whether to fire the
+    // `updateNote` or `createNote` API. Both of these API calls return
+    // an observable wrapper around the modified/created Note object.
+    mergeMap(([action, state]) => {
+      const planId = state.visibleRoadmapId as number;
+      const termCode = action.payload.termCode;
+      const noteText = action.payload.noteText;
+      const existingNote = getExistingNote(state, termCode);
+      if (existingNote !== undefined) {
+        // Since the term DOES have a note, update the existing note
+        const noteId = existingNote.id;
+        return this.api.updateNote(planId, termCode, noteText, noteId);
+      } else {
+        // Since the term DOES NOT have a note, create a new note
+        return this.api.createNote(planId, termCode, noteText);
+      }
+    }),
+
+    // Dispatch an `WriteNoteSuccess` action so that the State
+    // object can be updated with the new Note data.
+    map(updatedNote => new WriteNoteResponse({ updatedNote })),
+  );
+
+  @Effect()
+  deleteNote$: Observable<DeleteNoteResponse> = this.actions$.pipe(
+    ofType<DeleteNoteRequest>(NoteActionTypes.DeleteNoteRequest),
+
+    // Get the most recent Degree Planner state object.
+    // This is used to lookup the Note ID.
+    withLatestFrom(this.store$.select(getDegreePlannerState)),
+
+    // Only handle DeleteNote actions when a current plan ID is set.
+    filter(([_, state]) => typeof state.visibleRoadmapId === 'number'),
+
+    // Using the action and State objects, fire the `deleteNote` API.
+    mergeMap(([action, state]) => {
+      const planId = state.visibleRoadmapId as number;
+      const termCode = action.payload.termCode;
+      const existingNote = getExistingNote(state, termCode);
+      if (existingNote !== undefined) {
+        // Since the term DOES have a note, delete it
+        const noteId = existingNote.id;
+        return this.api.deleteNote(planId, noteId).pipe(map(() => termCode));
+      } else {
+        // Since the term DID NOT already have a note, return an action that
+        // makes no changes to the current state
+        return of(termCode);
+      }
+    }),
+
+    // Dispatch an `DeleteNoteSuccess` action so that the
+    // State object can be updated with the note removed.
+    map(termCode => new DeleteNoteResponse({ termCode })),
+  );
+}
+
+const getExistingNote = (state: DegreePlannerState, termCode: string) => {
+  for (const term of state.visibleTerms || []) {
+    if (term.termCode === termCode) {
+      return term.note;
+    }
+  }
+  return undefined;
+};
diff --git a/src/app/degree-planner/effects/plan.effects.ts b/src/app/degree-planner/store/effects/plan.effects.ts
similarity index 98%
rename from src/app/degree-planner/effects/plan.effects.ts
rename to src/app/degree-planner/store/effects/plan.effects.ts
index 0c68883d9532c35e65e325cb357c7d431e9a55ae..7f92568e1a50490638d11e45ff3d19434a16a3ce 100644
--- a/src/app/degree-planner/effects/plan.effects.ts
+++ b/src/app/degree-planner/store/effects/plan.effects.ts
@@ -8,7 +8,7 @@ import { Store } from '@ngrx/store';
 
 // Services
 import { DegreePlannerApiService } from '@app/degree-planner/services/api.service';
-import { getDegreePlannerState } from '@app/degree-planner/selectors';
+import { getDegreePlannerState } from '@app/degree-planner/store/selectors';
 
 // Actions
 import {
@@ -21,7 +21,7 @@ import {
   RemoveCourseResponse,
   RemoveSavedForLaterResponse,
   AddSavedForLaterResponse,
-} from '@app/degree-planner/actions/plan.actions';
+} from '@app/degree-planner/store/actions/plan.actions';
 
 // Models
 import { PlannedTerm } from '@app/core/models/planned-term';
diff --git a/src/app/degree-planner/reducer.ts b/src/app/degree-planner/store/reducer.ts
similarity index 97%
rename from src/app/degree-planner/reducer.ts
rename to src/app/degree-planner/store/reducer.ts
index 2ab6474ed37a0a7d479ff2c2172a79f8362477f9..7b99521660a9e2ecaf115e30a5e2fb4a8f6887e2 100644
--- a/src/app/degree-planner/reducer.ts
+++ b/src/app/degree-planner/store/reducer.ts
@@ -1,7 +1,7 @@
 import {
   DegreePlannerState,
   INITIAL_DEGREE_PLANNER_STATE,
-} from '@app/degree-planner/state';
+} from '@app/degree-planner/store/state';
 import {
   PlanActionTypes,
   InitialPlanLoadResponse,
@@ -11,12 +11,12 @@ import {
   AddCourseResponse,
   RemoveSavedForLaterResponse,
   AddSavedForLaterResponse,
-} from '@app/degree-planner/actions/plan.actions';
+} from '@app/degree-planner/store/actions/plan.actions';
 import {
   NoteActionTypes,
   WriteNoteResponse,
   DeleteNoteResponse,
-} from '@app/degree-planner/actions/note.actions';
+} from '@app/degree-planner/store/actions/note.actions';
 
 type SupportedActions =
   | InitialPlanLoadResponse
diff --git a/src/app/degree-planner/selectors.ts b/src/app/degree-planner/store/selectors.ts
similarity index 100%
rename from src/app/degree-planner/selectors.ts
rename to src/app/degree-planner/store/selectors.ts
diff --git a/src/app/degree-planner/state.ts b/src/app/degree-planner/store/state.ts
similarity index 100%
rename from src/app/degree-planner/state.ts
rename to src/app/degree-planner/store/state.ts
diff --git a/src/app/degree-planner/term-container/term-container.component.ts b/src/app/degree-planner/term-container/term-container.component.ts
index c7ae8e37abb40e3b414bab8330f6453a9c7ef479..fcb2eea2cbfc6bdf1f0a454c12c2678393bc013c 100644
--- a/src/app/degree-planner/term-container/term-container.component.ts
+++ b/src/app/degree-planner/term-container/term-container.component.ts
@@ -11,15 +11,18 @@ import { MatDialog } from '@angular/material';
 // rsjx / ngrx
 import { Observable } from 'rxjs';
 import { Store, select } from '@ngrx/store';
-import { DegreePlannerState } from '@app/degree-planner/state';
+import { DegreePlannerState } from '@app/degree-planner/store/state';
 import {
   ChangeCourseTermRequest,
   AddCourseRequest,
   RemoveSavedForLaterRequest,
-} from '@app/degree-planner/actions/plan.actions';
+} from '@app/degree-planner/store/actions/plan.actions';
 
 // Selectors
-import { getDropZones, isActiveTerm } from '@app/degree-planner/selectors';
+import {
+  getDropZones,
+  isActiveTerm,
+} from '@app/degree-planner/store/selectors';
 
 // Services
 import { SidenavService } from './../../core/service/sidenav.service';
diff --git a/src/app/shared/components/course-details/course-details.component.ts b/src/app/shared/components/course-details/course-details.component.ts
index 998b88886a8ca283dee981565b554dbeef5c4ad9..bec3f7b0c10dc0b73b69fee84ad48b47e52c3d56 100644
--- a/src/app/shared/components/course-details/course-details.component.ts
+++ b/src/app/shared/components/course-details/course-details.component.ts
@@ -3,19 +3,16 @@ import { CourseDetails } from '../../../core/models/course-details';
 import { MAT_DIALOG_DATA } from '@angular/material';
 
 @Component({
-	selector: 'cse-course-details',
-	templateUrl: './course-details.component.html',
-	styleUrls: ['./course-details.component.scss']
+  selector: 'cse-course-details',
+  templateUrl: './course-details.component.html',
+  styleUrls: ['./course-details.component.scss'],
 })
-
 export class CourseDetailsComponent implements OnInit {
-	courseDetails: CourseDetails;
-
-	constructor(@Inject(MAT_DIALOG_DATA) public data: any) {
-		this.courseDetails = data.courseDetails;
-	}
+  courseDetails: CourseDetails;
 
-	ngOnInit() {
-	}
+  constructor(@Inject(MAT_DIALOG_DATA) public data: any) {
+    this.courseDetails = data.courseDetails;
+  }
 
+  ngOnInit() {}
 }