Minimal API slice /api/tasks (idempotent create with client ids, versioned updates, state-based status changes, checklist, parent approval/rejection, points overview and audited adjustments, recurring next instance), per-user SignalR broadcasts that respect private tasks, /api/push subscription endpoints, a dependency-free Web Push sender (RFC 8291/8292) and a minimal reminder service. VAPID keys via Aspire parameters and deploy/.env (tools/generate-vapid-keys.cs); integration test login limit raised. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
58 lines
2.5 KiB
C#
58 lines
2.5 KiB
C#
var builder = DistributedApplication.CreateBuilder(args);
|
||
|
||
// `aspire publish` erzeugt daraus eine docker-compose.yaml (siehe docs/ARCHITECTURE.md §9).
|
||
builder.AddDockerComposeEnvironment("compose");
|
||
|
||
// Integrationstests setzen FamilyPlanner:EphemeralDatabase=true, damit die Entwicklungsdaten unberührt bleiben.
|
||
var ephemeralDatabase = bool.TryParse(builder.Configuration["FamilyPlanner:EphemeralDatabase"], out var ephemeral) && ephemeral;
|
||
|
||
var sql = builder.AddSqlServer("sql");
|
||
if (!ephemeralDatabase)
|
||
{
|
||
sql.WithDataVolume("familyplanner-sql-data")
|
||
.WithLifetime(ContainerLifetime.Persistent);
|
||
}
|
||
|
||
var database = sql.AddDatabase("familyplannerdb");
|
||
|
||
// Initial-Admin (nur beim allerersten Start relevant, Passwortwechsel wird erzwungen).
|
||
var adminUserName = builder.AddParameter("seed-admin-username", value: "admin", publishValueAsDefault: true);
|
||
var adminPassword = builder.AddParameter("seed-admin-password", secret: true);
|
||
var adminEmail = builder.AddParameter("seed-admin-email", value: "", publishValueAsDefault: true);
|
||
|
||
var migrations = builder.AddProject<Projects.FamilyPlanner_MigrationService>("migrations")
|
||
.WithReference(database)
|
||
.WaitFor(database)
|
||
.WithEnvironment("Seed__AdminUserName", adminUserName)
|
||
.WithEnvironment("Seed__AdminPassword", adminPassword)
|
||
.WithEnvironment("Seed__AdminEmail", adminEmail);
|
||
|
||
var api = builder.AddProject<Projects.FamilyPlanner_Api>("api")
|
||
.WithReference(database)
|
||
.WaitFor(database)
|
||
.WaitForCompletion(migrations)
|
||
.WithHttpHealthCheck("/health");
|
||
|
||
// Web-Push-Erinnerungen (ADR-0014): VAPID-Schlüssel per User Secrets/Parameter setzen (`dotnet run tools/generate-vapid-keys.cs`).
|
||
// Leer = Benachrichtigungen deaktiviert.
|
||
var vapidPublicKey = builder.AddParameter("vapid-public-key", value: "", publishValueAsDefault: true);
|
||
var vapidPrivateKey = builder.AddParameter("vapid-private-key", value: "", secret: true);
|
||
var vapidSubject = builder.AddParameter("vapid-subject", value: "mailto:admin@localhost", publishValueAsDefault: true);
|
||
api.WithEnvironment("WebPush__PublicKey", vapidPublicKey)
|
||
.WithEnvironment("WebPush__PrivateKey", vapidPrivateKey)
|
||
.WithEnvironment("WebPush__Subject", vapidSubject);
|
||
|
||
if (ephemeralDatabase)
|
||
{
|
||
// Tests melden sich mehrfach an – Rate Limit großzügiger.
|
||
api.WithEnvironment("RateLimiting__LoginPermitLimit", "1000");
|
||
}
|
||
|
||
builder.AddProject<Projects.FamilyPlanner_Web>("web")
|
||
.WithExternalHttpEndpoints()
|
||
.WithReference(api)
|
||
.WaitFor(api)
|
||
.WithHttpHealthCheck("/health");
|
||
|
||
builder.Build().Run();
|