diff --git a/AirAware/Controllers/ReadingController.cs b/AirAware/Controllers/ReadingController.cs new file mode 100644 index 0000000..cd3b2ec --- /dev/null +++ b/AirAware/Controllers/ReadingController.cs @@ -0,0 +1,77 @@ +using AirAware.Data; +using AirAware.Models; +using AirAware.ViewModels; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace AirAware.Controllers; + +[ApiController] +[Route("api/v1")] +public class ReadingController: ControllerBase +{ + [HttpGet] + [Route("readings")] + public async Task GetAsync([FromServices] AppDbContext context) + { + var readings = await context + .Readings + .AsNoTracking() + .ToListAsync(); + return Ok(readings); + } + + [HttpGet] + [Route("readings/{id}")] + public async Task GetByIdAsync( + [FromServices] AppDbContext context, + [FromRoute] Guid id + ) + { + var reading = await context + .Readings + .AsNoTracking() + .FirstOrDefaultAsync(r => r.Id == id); + + return reading == null + ? NotFound() + : Ok(reading); + } + + [HttpPost("readings")] + public async Task PostAsync( + [FromServices] AppDbContext context, + [FromBody] CreateReadingViewModel model + ) + { + if (!ModelState.IsValid) + return BadRequest("Invalid data provided."); + + var station = await context + .Stations + .AsNoTracking() + .FirstOrDefaultAsync(s => s.Id == model.StationId); + + if (station == null) + return BadRequest("Station with the provided ID does not exist."); + + var reading = new Reading + { + StationId = model.StationId, + Pm2_5 = model.Pm2_5, + Pm10 = model.Pm10, + RawPayload = model.RawPayload + }; + + try + { + await context.Readings.AddAsync(reading); + await context.SaveChangesAsync(); + return Created($"api/v1/readings/{reading.Id}", reading); + } + catch (Exception) + { + return StatusCode(StatusCodes.Status500InternalServerError); + } + } +} \ No newline at end of file diff --git a/AirAware/Controllers/StationController.cs b/AirAware/Controllers/StationController.cs index 9705e5d..1128703 100644 --- a/AirAware/Controllers/StationController.cs +++ b/AirAware/Controllers/StationController.cs @@ -60,7 +60,7 @@ [FromBody] CreateStationViewModel model { await context.Stations.AddAsync(station); await context.SaveChangesAsync(); - return Created($"v1/stations/{station.Id}", station); + return Created($"api/v1/stations/{station.Id}", station); } catch (Exception) { diff --git a/AirAware/Data/AppDbContext.cs b/AirAware/Data/AppDbContext.cs index c8741f8..b10af74 100644 --- a/AirAware/Data/AppDbContext.cs +++ b/AirAware/Data/AppDbContext.cs @@ -6,6 +6,7 @@ namespace AirAware.Data; public class AppDbContext: DbContext { public DbSet Stations { get; set; } + public DbSet Readings { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseSqlite("DataSource=app.db;Cache=Shared"); diff --git a/AirAware/Models/Reading.cs b/AirAware/Models/Reading.cs new file mode 100644 index 0000000..df903fd --- /dev/null +++ b/AirAware/Models/Reading.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace AirAware.Models; + +public class Reading +{ + public Guid Id { get; set; } = Guid.NewGuid(); + public Guid StationId { get; set; } + [JsonIgnore] + public Station Station { get; set; } = null!; + public double Pm2_5 { get; set; } + public double Pm10 { get; set; } + public string? RawPayload { get; set; } + public DateTime CreatedAt { get; set; } = DateTime.Now; +} \ No newline at end of file diff --git a/AirAware/ViewModels/CreateReadingViewModel.cs b/AirAware/ViewModels/CreateReadingViewModel.cs new file mode 100644 index 0000000..c6e33a1 --- /dev/null +++ b/AirAware/ViewModels/CreateReadingViewModel.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; + +namespace AirAware.ViewModels; + +public class CreateReadingViewModel +{ + [Required] + public Guid StationId { get; set; } + [Required] + public double Pm2_5 { get; set; } + [Required] + public double Pm10 { get; set; } + public string? RawPayload { get; set; } +} \ No newline at end of file