-
Notifications
You must be signed in to change notification settings - Fork 273
Expand file tree
/
Copy pathProductionPlanController.cs
More file actions
executable file
·94 lines (87 loc) · 3.19 KB
/
ProductionPlanController.cs
File metadata and controls
executable file
·94 lines (87 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
using Microsoft.AspNetCore.Mvc;
using PowerplantCodingChallenge.Application.DTOs;
using PowerplantCodingChallenge.Application.Interfaces;
namespace PowerplantCodingChallenge.API.Controllers;
/// <summary>
/// Controller for calculating the powerplant production plan
/// </summary>
[ApiController]
[Route("productionplan")]
[Produces("application/json")]
public class ProductionPlanController : ControllerBase
{
private readonly IProductionPlanService _productionPlanService;
private readonly ILogger<ProductionPlanController> _logger;
public ProductionPlanController(
IProductionPlanService productionPlanService,
ILogger<ProductionPlanController> logger)
{
_productionPlanService = productionPlanService;
_logger = logger;
}
/// <summary>
/// Calculates the optimal production plan to satisfy the requested load
/// </summary>
/// <param name="request">Market data and powerplant configuration (load, fuel prices, available powerplants)</param>
/// <returns>Production plan indicating the power (in MW) to be generated by each powerplant</returns>
/// <remarks>
/// Request example:
///
/// POST /productionplan
/// {
/// "load": 910,
/// "fuels": {
/// "gas(euro/MWh)": 13.4,
/// "kerosine(euro/MWh)": 50.8,
/// "co2(euro/ton)": 20,
/// "wind(%)": 60
/// },
/// "powerplants": [
/// {
/// "name": "gasfiredbig1",
/// "type": "gasfired",
/// "efficiency": 0.53,
/// "pmin": 100,
/// "pmax": 460
/// }
/// ]
/// }
///
/// Expected response:
///
/// [
/// {
/// "name": "gasfiredbig1",
/// "p": 460.0
/// }
/// ]
///
/// </remarks>
/// <response code="200">Production plan calculated successfully</response>
/// <response code="400">Invalid data or load cannot be satisfied</response>
/// <response code="500">Internal server error</response>
[HttpPost]
[ProducesResponseType(typeof(List<ProductionPlanResponse>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
public ActionResult<List<ProductionPlanResponse>> Post([FromBody] ProductionPlanRequest request)
{
_logger.LogInformation("Received production plan request for load: {Load} MWh", request.Load);
try
{
var result = _productionPlanService.CalculateProductionPlan(request);
_logger.LogInformation("Production plan calculated successfully. Total plants: {Count}", result.Count);
return Ok(result);
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Cannot satisfy load requirement");
return BadRequest(new { error = ex.Message });
}
catch (ArgumentException ex)
{
_logger.LogWarning(ex, "Invalid argument in request");
return BadRequest(new { error = ex.Message });
}
}
}