diff --git a/.gitignore b/.gitignore
index 686d413..0e5c9aa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,6 +69,7 @@ nunit-*.xml
node_modules/
dist/
dist-ssr/
+API/wwwroot/
.vite/
.npm/
.pnpm-store/
diff --git a/API/API.csproj b/API/API.csproj
index 6e13ddb..a3a34b6 100644
--- a/API/API.csproj
+++ b/API/API.csproj
@@ -6,8 +6,4 @@
enable
-
-
-
-
diff --git a/API/Controllers/HealthController.cs b/API/Controllers/HealthController.cs
new file mode 100644
index 0000000..007bb6d
--- /dev/null
+++ b/API/Controllers/HealthController.cs
@@ -0,0 +1,14 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace API.Controllers;
+
+[ApiController]
+[Route("api/health")]
+public class HealthController : ControllerBase
+{
+ [HttpGet]
+ public IActionResult Get()
+ {
+ return Ok();
+ }
+}
diff --git a/API/Controllers/WeatherForecastController.cs b/API/Controllers/WeatherForecastController.cs
deleted file mode 100644
index a6e5178..0000000
--- a/API/Controllers/WeatherForecastController.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-
-namespace API.Controllers
-{
- [ApiController]
- [Route("[controller]")]
- public class WeatherForecastController : ControllerBase
- {
- private static readonly string[] Summaries =
- [
- "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
- ];
-
- [HttpGet(Name = "GetWeatherForecast")]
- public IEnumerable Get()
- {
- return Enumerable.Range(1, 5).Select(index => new WeatherForecast
- {
- Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
- TemperatureC = Random.Shared.Next(-20, 55),
- Summary = Summaries[Random.Shared.Next(Summaries.Length)]
- })
- .ToArray();
- }
- }
-}
diff --git a/API/Program.cs b/API/Program.cs
index 666a9c5..c6e5257 100644
--- a/API/Program.cs
+++ b/API/Program.cs
@@ -1,23 +1,31 @@
var builder = WebApplication.CreateBuilder(args);
-// Add services to the container.
-
builder.Services.AddControllers();
-// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
-builder.Services.AddOpenApi();
var app = builder.Build();
+var webRootPath = app.Environment.WebRootPath ?? Path.Combine(app.Environment.ContentRootPath, "wwwroot");
+var indexFilePath = Path.Combine(webRootPath, "index.html");
-// Configure the HTTP request pipeline.
-if (app.Environment.IsDevelopment())
-{
- app.MapOpenApi();
-}
-
-app.UseHttpsRedirection();
-
-app.UseAuthorization();
+app.UseDefaultFiles();
+app.UseStaticFiles();
app.MapControllers();
+app.MapFallback(async context =>
+{
+ if (context.Request.Path.StartsWithSegments("/api"))
+ {
+ context.Response.StatusCode = StatusCodes.Status404NotFound;
+ return;
+ }
+
+ if (!File.Exists(indexFilePath))
+ {
+ context.Response.StatusCode = StatusCodes.Status404NotFound;
+ return;
+ }
+
+ context.Response.ContentType = "text/html; charset=utf-8";
+ await context.Response.SendFileAsync(indexFilePath);
+});
app.Run();
diff --git a/API/WeatherForecast.cs b/API/WeatherForecast.cs
deleted file mode 100644
index 10c41a8..0000000
--- a/API/WeatherForecast.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace API
-{
- public class WeatherForecast
- {
- public DateOnly Date { get; set; }
-
- public int TemperatureC { get; set; }
-
- public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
-
- public string? Summary { get; set; }
- }
-}
diff --git a/GUI/vite.config.ts b/GUI/vite.config.ts
index 4217010..56fc17d 100644
--- a/GUI/vite.config.ts
+++ b/GUI/vite.config.ts
@@ -10,6 +10,10 @@ export default defineConfig({
vue(),
vueDevTools(),
],
+ build: {
+ outDir: fileURLToPath(new URL('../API/wwwroot', import.meta.url)),
+ emptyOutDir: true,
+ },
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
diff --git a/codexInfo.md b/codexInfo.md
index f8fbc9c..91d3444 100644
--- a/codexInfo.md
+++ b/codexInfo.md
@@ -87,6 +87,8 @@ Ich baue alleine neben meiner Ausbildung eine einfache self-hosted Web-App für
- Sidebar-Sichtbarkeit unterstützt `Visibility.Route` mit optionalem `visibilityRoute` in `GUI/src/plugins/routesLayout.ts`.
- Mobile-Touch-Optimierung ist für alle aktuellen öffentlichen Oberflächen aktiv (Shell, Home, Login, Impressum, 404), inklusive Safe-Area-Unterstützung.
- Desktop-Ansicht bleibt unverändert, da alle neuen Anpassungen ausschließlich in mobilen Breakpoints (`<= 960px`, Feinschliff `<= 600px`) umgesetzt sind.
+- Backend-API ist auf ein Minimal-Setup reduziert und stellt aktuell den Test-Endpunkt `GET /api/health` bereit.
+- Frontend-Build (`npm run build` im `GUI`-Projekt) schreibt direkt nach `API/wwwroot`; das Backend liefert die SPA und statische Assets aus.
## Änderungen durch Codex
- Grundlegender UI-Neuaufbau der App-Shell (`GUI/src/Layout.vue`) inklusive Navigation, Footer und Seitenkontext.
@@ -102,3 +104,8 @@ Ich baue alleine neben meiner Ausbildung eine einfache self-hosted Web-App für
- Mobile-spezifische Detailoptimierungen in `Home.vue`, `Login.vue`, `Impressum.vue` und `404NotFound.vue` ergänzt (Actions, Card-/Form-Spacing, CTA-Stacking), ohne Desktop-Basislayout zu verändern.
- `GUI/style.md` um einen verbindlichen Abschnitt „Umsetzungsstandard Responsivität“ ergänzt (Breakpoints, Touch-Zielgrößen, Safe-Area, globale Pattern-Nutzung, QA-Checkliste), damit Folgeaufgaben denselben Stil beibehalten.
- Topbar-Kontext in `GUI/src/Layout.vue` für schmalere Breiten beruhigt: auf Mobile wird der Seitenkontext komplett ausgeblendet, auf mittleren Breiten bleibt nur der Seitentitel (ohne Unterzeile), damit das Header-Layout sauber und nicht gequetscht wirkt.
+- Backend-Template-Code bereinigt: `WeatherForecastController` und `WeatherForecast` entfernt, OpenAPI-Templatepaket aus `API/API.csproj` entfernt.
+- Neuen Test-Controller `API/Controllers/HealthController.cs` angelegt (`GET /api/health`), der `200 OK` zurückgibt.
+- `GUI/vite.config.ts` Build-Ausgabe auf `API/wwwroot` umgestellt (`outDir`) und Bereinigung des Zielordners beim Build aktiviert (`emptyOutDir: true`).
+- `API/Program.cs` erweitert, damit statische Dateien aus `wwwroot` inkl. SPA-Fallback (`index.html`) ausgeliefert werden.
+- SPA-Fallback im Backend aufgeteilt: Frontend-Routen liefern `index.html`, unbekannte `/api/*`-Routen bleiben korrekt `404` statt auf die SPA zu fallen.