Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Shifts Logger WebAPI

## Overview

A WebAPI + Console application pair that uses http request to access WebAPI data
and display that data to the user

## Requirements

- WebAPI should record a worker's shifts
- Should create two applications: a WebAPI and Console UI
- Validation should occur in UI App
- API controller should be lean
- Should use Code-First Approach
- Shift duration should be calculated based off start and end of shift

## Technologies

- C#
- Sqlite
- Spectre.Console
- EF Core

## Looking back

- Felt pretty similar to previous projects. The exposure to WebAPIs in previous projects before creating my own really helped understand what was going on
- UI was fairly simple this time around as I had gotten used to planning it in previous projects. I was able to plan it quicker this time
- Got stuck with Http requests as I didn't know there were different methods that were needed for POST, PUT, and DELETE. Was pretty simple after finding that out
- Testing with Postman and swagger really helped with understanding how http requests work
- Feel like i need to study more on the builder methods in the WebAPI program.cs file. Still a little confused on what and why each method is called

59 changes: 59 additions & 0 deletions ShiftsLogger.WebAPI.davetn657/Controllers/ShiftsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Microsoft.AspNetCore.Mvc;
using ShiftsLogger.WebAPI.davetn657.Data;
using ShiftsLogger.WebAPI.davetn657.Services;

namespace ShiftsLogger.WebAPI.davetn657.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class ShiftsController : ControllerBase
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Lean API Controller

⭐ The controller follows best practices - it's thin and delegates to the service layer. Well done!

{
private readonly ILoggingService _loggingService;
public ShiftsController(ILoggingService loggingService)
{
_loggingService = loggingService;
}

[HttpGet]
public ActionResult<List<Shift>> GetAllShifts()
{
return Ok(_loggingService.GetAllShifts());
}

[HttpGet("{id}")]
public ActionResult<Shift> GetShiftById(int id)
{
var result = _loggingService.GetShiftById(id);

if (result == null) return NotFound();

return Ok(result);
}

[HttpPost]
public ActionResult<Shift> CreateShift(Shift shift)
{
return Ok(_loggingService.CreateShift(shift));
}

[HttpPut("{id}")]
public ActionResult<Shift> UpdateShift(int id, Shift updatedShift)
{
var result = _loggingService.UpdateShift(id, updatedShift);

if (result == null) return NotFound();

return Ok(result);
}

[HttpDelete("{id}")]
public ActionResult<string> DeleteShift(int id)
{
var result = _loggingService.DeleteShift(id);

if (result == null) return NotFound();

return Ok(result);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace ShiftsLogger.WebAPI.davetn657.Data.Migrations
{
/// <inheritdoc />
public partial class InitalCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Shifts",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
LoggerName = table.Column<string>(type: "TEXT", nullable: false),
ShiftStart = table.Column<DateTime>(type: "TEXT", nullable: false),
ShiftEnd = table.Column<DateTime>(type: "TEXT", nullable: false),
Duration = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Shifts", x => x.Id);
});
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Shifts");
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace ShiftsLogger.WebAPI.davetn657.Data.Migrations
{
/// <inheritdoc />
public partial class DurationToTimeSpan : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<DateTime>(
name: "ShiftStart",
table: "Shifts",
type: "TEXT",
nullable: true,
oldClrType: typeof(DateTime),
oldType: "TEXT");

migrationBuilder.AlterColumn<DateTime>(
name: "ShiftEnd",
table: "Shifts",
type: "TEXT",
nullable: true,
oldClrType: typeof(DateTime),
oldType: "TEXT");
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<DateTime>(
name: "ShiftStart",
table: "Shifts",
type: "TEXT",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
oldClrType: typeof(DateTime),
oldType: "TEXT",
oldNullable: true);

migrationBuilder.AlterColumn<DateTime>(
name: "ShiftEnd",
table: "Shifts",
type: "TEXT",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
oldClrType: typeof(DateTime),
oldType: "TEXT",
oldNullable: true);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace ShiftsLogger.WebAPI.davetn657.Data.Migrations
{
/// <inheritdoc />
public partial class TimespanNullable : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<TimeSpan>(
name: "Duration",
table: "Shifts",
type: "TEXT",
nullable: true,
oldClrType: typeof(TimeSpan),
oldType: "TEXT");
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<TimeSpan>(
name: "Duration",
table: "Shifts",
type: "TEXT",
nullable: false,
defaultValue: new TimeSpan(0, 0, 0, 0, 0),
oldClrType: typeof(TimeSpan),
oldType: "TEXT",
oldNullable: true);
}
}
}
Loading