Files
SafelyYouCodingChallenge/dotnet/SafelyYou/Program.cs
T

86 lines
2.4 KiB
C#
Raw Normal View History

2026-08-06 12:58:54 -05:00
using Microsoft.AspNetCore.Http.HttpResults;
using SafelyYou;
using SafelyYou.Api;
using SafelyYou.Config;
2026-08-06 11:33:04 -05:00
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
2026-08-06 12:58:54 -05:00
builder.Services.AddSingleton<KnownDevices>(_ =>
{
var deviceIds = File.ReadAllLines("/devices.csv").Skip(1).Select(id => new DeviceId(id)).ToHashSet();
return new KnownDevices(deviceIds);
});
builder.Services.AddSingleton<HeartBeatHistoryConfig>(_ =>
{
var millis = builder.Configuration.GetSection("HeartBeatHistory").GetValue<int>("WindowMillis");
return new HeartBeatHistoryConfig() { Window = TimeSpan.FromMilliseconds(millis) };
});
builder.Services.AddSingleton<HeartBeatHistories>();
2026-08-06 11:33:04 -05:00
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.UseHttpsRedirection();
2026-08-06 12:58:54 -05:00
// heartbeat history
// upload stats
app.MapPost("/devices/{deviceId}/heartbeat", (string deviceId, HeartbeatRequest request,
KnownDevices knownDevices, HeartBeatHistories histories) =>
{
var device = new DeviceId(deviceId);
if (!knownDevices.Contains(device))
{
return Results.NotFound(new NotFoundResponse($"Device ID {deviceId} not found"));
}
var addResult = histories.Add(device, request.SentAt);
return addResult switch
{
DeviceHeartBeatHistory.AddResult.Added => Results.Ok(),
DeviceHeartBeatHistory.AddResult.OutOfSequence => Results.InternalServerError(
new ErrorResponse("Attempted to add a timestamp that was out of sequence or invalid.")),
_ => throw new ArgumentOutOfRangeException()
};
});
2026-08-06 11:33:04 -05:00
var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast");
app.Run();
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}