From 40b256b8706bd0eb799385202cae469ae33f39c9 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 20 Mar 2026 01:10:22 +0100 Subject: [PATCH] fix: add ProducesResponseType to controllers, regenerate openapi.json --- .../Controllers/AuthController.cs | 2 + .../Controllers/DashboardController.cs | 5 + .../Controllers/TransactionsController.cs | 4 + src/AccountTracking.Api/openapi.json | 249 ++++++++++++++++-- 4 files changed, 236 insertions(+), 24 deletions(-) diff --git a/src/AccountTracking.Api/Controllers/AuthController.cs b/src/AccountTracking.Api/Controllers/AuthController.cs index 4d24bcc..a199070 100644 --- a/src/AccountTracking.Api/Controllers/AuthController.cs +++ b/src/AccountTracking.Api/Controllers/AuthController.cs @@ -16,6 +16,8 @@ public class AuthController : ControllerBase => _credentials = credentials; [HttpPost("login")] + [ProducesResponseType(typeof(LoginResponse), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] public IActionResult Login([FromBody] LoginRequest request) { if (request.Username != _credentials.Username diff --git a/src/AccountTracking.Api/Controllers/DashboardController.cs b/src/AccountTracking.Api/Controllers/DashboardController.cs index 814e160..e955795 100644 --- a/src/AccountTracking.Api/Controllers/DashboardController.cs +++ b/src/AccountTracking.Api/Controllers/DashboardController.cs @@ -1,3 +1,4 @@ +using AccountTracking.Api.Models.Dtos; using AccountTracking.Api.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -13,18 +14,22 @@ public class DashboardController : ControllerBase public DashboardController(DashboardService svc) => _svc = svc; [HttpGet("summary")] + [ProducesResponseType(typeof(SummaryDto), StatusCodes.Status200OK)] public async Task Summary([FromQuery] int year, [FromQuery] int? month) => Ok(await _svc.GetSummaryAsync(year, month)); [HttpGet("spending-by-category")] + [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] public async Task SpendingByCategory([FromQuery] int year, [FromQuery] int? month) => Ok(await _svc.GetSpendingByCategoryAsync(year, month)); [HttpGet("monthly-balances")] + [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] public async Task MonthlyBalances([FromQuery] int year) => Ok(await _svc.GetMonthlyBalancesAsync(year)); [HttpGet("cumulative-spending")] + [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] public async Task CumulativeSpending([FromQuery] int year, [FromQuery] int month) => Ok(await _svc.GetCumulativeSpendingAsync(year, month)); } diff --git a/src/AccountTracking.Api/Controllers/TransactionsController.cs b/src/AccountTracking.Api/Controllers/TransactionsController.cs index f2506ad..bd222c2 100644 --- a/src/AccountTracking.Api/Controllers/TransactionsController.cs +++ b/src/AccountTracking.Api/Controllers/TransactionsController.cs @@ -22,6 +22,8 @@ public class TransactionsController : ControllerBase } [HttpPost("import")] + [ProducesResponseType(typeof(ImportResult), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ErrorResult), StatusCodes.Status400BadRequest)] public async Task Import(IFormFile file) { if (file == null || file.Length == 0) @@ -40,6 +42,7 @@ public class TransactionsController : ControllerBase } [HttpGet] + [ProducesResponseType(typeof(TransactionListResponse), StatusCodes.Status200OK)] public async Task List( [FromQuery] int year, [FromQuery] int? month, @@ -78,6 +81,7 @@ public class TransactionsController : ControllerBase } [HttpGet("categories")] + [ProducesResponseType(typeof(string[]), StatusCodes.Status200OK)] public async Task Categories() { var cats = await _db.Transactions diff --git a/src/AccountTracking.Api/openapi.json b/src/AccountTracking.Api/openapi.json index cf2aa3d..61a9cad 100644 --- a/src/AccountTracking.Api/openapi.json +++ b/src/AccountTracking.Api/openapi.json @@ -33,10 +33,19 @@ "200": { "description": "", "content": { - "application/octet-stream": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "$ref": "#/components/schemas/LoginResponse" + } + } + } + }, + "401": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" } } } @@ -75,10 +84,9 @@ "200": { "description": "", "content": { - "application/octet-stream": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "$ref": "#/components/schemas/SummaryDto" } } } @@ -117,10 +125,12 @@ "200": { "description": "", "content": { - "application/octet-stream": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "type": "array", + "items": { + "$ref": "#/components/schemas/CategorySpendingDto" + } } } } @@ -149,10 +159,12 @@ "200": { "description": "", "content": { - "application/octet-stream": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "type": "array", + "items": { + "$ref": "#/components/schemas/MonthlyBalanceDto" + } } } } @@ -190,10 +202,12 @@ "200": { "description": "", "content": { - "application/octet-stream": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "type": "array", + "items": { + "$ref": "#/components/schemas/CumulativeSpendingDto" + } } } } @@ -227,10 +241,19 @@ "200": { "description": "", "content": { - "application/octet-stream": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "$ref": "#/components/schemas/ImportResult" + } + } + } + }, + "400": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResult" } } } @@ -307,10 +330,9 @@ "200": { "description": "", "content": { - "application/octet-stream": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "$ref": "#/components/schemas/TransactionListResponse" } } } @@ -328,10 +350,12 @@ "200": { "description": "", "content": { - "application/octet-stream": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "type": "array", + "items": { + "type": "string" + } } } } @@ -342,6 +366,47 @@ }, "components": { "schemas": { + "LoginResponse": { + "type": "object", + "additionalProperties": false, + "properties": { + "token": { + "type": "string" + }, + "expiresAt": { + "type": "string" + } + } + }, + "ProblemDetails": { + "type": "object", + "additionalProperties": { + "nullable": true + }, + "properties": { + "type": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "status": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "instance": { + "type": "string", + "nullable": true + } + } + }, "LoginRequest": { "type": "object", "additionalProperties": false, @@ -353,6 +418,142 @@ "type": "string" } } + }, + "SummaryDto": { + "type": "object", + "additionalProperties": false, + "properties": { + "totalSpent": { + "type": "number", + "format": "decimal" + }, + "totalIncome": { + "type": "number", + "format": "decimal" + } + } + }, + "CategorySpendingDto": { + "type": "object", + "additionalProperties": false, + "properties": { + "category": { + "type": "string" + }, + "total": { + "type": "number", + "format": "decimal" + } + } + }, + "MonthlyBalanceDto": { + "type": "object", + "additionalProperties": false, + "properties": { + "month": { + "type": "integer", + "format": "int32" + }, + "closingBalance": { + "type": "number", + "format": "decimal" + } + } + }, + "CumulativeSpendingDto": { + "type": "object", + "additionalProperties": false, + "properties": { + "day": { + "type": "integer", + "format": "int32" + }, + "cumulativeSpent": { + "type": "number", + "format": "decimal" + } + } + }, + "ImportResult": { + "type": "object", + "additionalProperties": false, + "properties": { + "recordsImported": { + "type": "integer", + "format": "int32" + }, + "recordsSkipped": { + "type": "integer", + "format": "int32" + } + } + }, + "ErrorResult": { + "type": "object", + "additionalProperties": false, + "properties": { + "error": { + "type": "string" + } + } + }, + "TransactionListResponse": { + "type": "object", + "additionalProperties": false, + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TransactionDto" + } + }, + "totalCount": { + "type": "integer", + "format": "int32" + }, + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + } + } + }, + "TransactionDto": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "bookingDate": { + "type": "string", + "format": "date" + }, + "counterPartyName": { + "type": "string", + "nullable": true + }, + "category": { + "type": "string", + "nullable": true + }, + "amount": { + "type": "number", + "format": "decimal" + }, + "balance": { + "type": "number", + "format": "decimal" + }, + "message": { + "type": "string", + "nullable": true + } + } } }, "securitySchemes": {