Refactor code structure for improved readability and maintainability

This commit is contained in:
2026-05-06 14:47:16 +02:00
parent 55b4405c28
commit 806138def6
19 changed files with 3756 additions and 129 deletions
+19
View File
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.14">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.14" />
<PackageReference Include="NSwag.AspNetCore" Version="14.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>
</Project>
@@ -0,0 +1,48 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Api.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20260506065055_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.14");
modelBuilder.Entity("Workout", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<DateTime>("Date")
.HasColumnType("TEXT");
b.Property<int>("DurationMinutes")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Notes")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Workouts");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,37 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Api.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Workouts",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: false),
Date = table.Column<DateTime>(type: "TEXT", nullable: false),
DurationMinutes = table.Column<int>(type: "INTEGER", nullable: false),
Notes = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Workouts", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Workouts");
}
}
}
@@ -0,0 +1,45 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Api.Migrations
{
[DbContext(typeof(AppDbContext))]
partial class AppDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.14");
modelBuilder.Entity("Workout", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<DateTime>("Date")
.HasColumnType("TEXT");
b.Property<int>("DurationMinutes")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Notes")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Workouts");
});
#pragma warning restore 612, 618
}
}
}
+75
View File
@@ -0,0 +1,75 @@
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlite("Data Source=fitness.db"));
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddOpenApiDocument();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseOpenApi();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
// ===================================================================
// CRUD ENDPUNKTE (minimal, ohne Auth)
// ===================================================================
// CREATE
app.MapPost("/api/workouts", async (Workout workout, AppDbContext db) =>
{
workout.Id = Guid.NewGuid();
db.Workouts.Add(workout);
await db.SaveChangesAsync();
return Results.Created($"/api/workouts/{workout.Id}", workout);
});
// READ ALL
app.MapGet("/api/workouts", async (AppDbContext db) =>
await db.Workouts.OrderByDescending(w => w.Date).ToListAsync());
// READ BY ID
app.MapGet("/api/workouts/{id:guid}", async (Guid id, AppDbContext db) =>
await db.Workouts.FindAsync(id) is Workout w ? Results.Ok(w) : Results.NotFound());
// UPDATE
app.MapPut("/api/workouts/{id:guid}", async (Guid id, Workout input, AppDbContext db) =>
{
var workout = await db.Workouts.FindAsync(id);
if (workout is null) return Results.NotFound();
workout.Name = input.Name;
workout.Date = input.Date;
workout.DurationMinutes = input.DurationMinutes;
workout.Notes = input.Notes;
await db.SaveChangesAsync();
return Results.Ok(workout);
});
// DELETE
app.MapDelete("/api/workouts/{id:guid}", async (Guid id, AppDbContext db) =>
{
var workout = await db.Workouts.FindAsync(id);
if (workout is null) return Results.NotFound();
db.Workouts.Remove(workout);
await db.SaveChangesAsync();
return Results.NoContent();
});
app.MapGet("/", () => "🏋️ Fitness API läuft!");
app.Run();
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
public DbSet<Workout> Workouts => Set<Workout>();
}
+38
View File
@@ -0,0 +1,38 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:16915",
"sslPort": 44327
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5107",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7079;http://localhost:5107",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
public class Workout
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public DateTime Date { get; set; }
public int DurationMinutes { get; set; }
public string? Notes { get; set; }
}
+8
View File
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
+9
View File
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Binary file not shown.
Binary file not shown.