Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Git
.git
.gitignore
.gitattributes
.gitmodules

# Visual Studio / VS Code
.vs
.vscode
**/*.user
**/*.suo
**/*.launch
*.sln.docstates

# Build results
**/bin/
**/obj/
**/TestResults/

# Docker
Dockerfile
docker-compose*
.dockerignore

# Automation
Jenkinsfile

# Documentation
SnakeAid.Docs/
*.md

# Settings (Local overrides)
appsettings.*.json
!appsettings.json
!appsettings.Development.json

# Temporary files
**/*.swp
**/*.tmp
14 changes: 7 additions & 7 deletions SnakeAid.Api/Controllers/AuthController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ [FromBody] RegisterRequest request
)
{
var result = await _authService.RegisterAsync(request, role);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Registration successful."));
}

/// <summary>
Expand All @@ -56,7 +56,7 @@ [FromBody] RegisterRequest request
public async Task<IActionResult> Login([FromBody] LoginRequest request)
{
var result = await _authService.LoginAsync(request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Login successful."));
}

/// <summary>
Expand All @@ -70,7 +70,7 @@ public async Task<IActionResult> Login([FromBody] LoginRequest request)
public async Task<IActionResult> RefreshToken([FromBody] RefreshTokenRequest request)
{
var result = await _authService.RefreshTokenAsync(request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Token refreshed successfully."));
}

/// <summary>
Expand All @@ -85,7 +85,7 @@ public async Task<IActionResult> RefreshToken([FromBody] RefreshTokenRequest req
public async Task<IActionResult> GoogleLogin([FromBody] GoogleLoginRequest request)
{
var result = await _authService.GoogleLoginAsync(request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Google login successful."));
}

/// <summary>
Expand All @@ -100,8 +100,8 @@ public async Task<IActionResult> GoogleLogin([FromBody] GoogleLoginRequest reque
public async Task<IActionResult> Logout()
{
var userId = GetCurrentUserId();
var result = await _authService.LogoutAsync(userId);
return StatusCode(result.StatusCode, result);
await _authService.LogoutAsync(userId);
return Ok(ApiResponseBuilder.BuildSuccessResponse("Logged out successfully."));
}

/// <summary>
Expand All @@ -116,7 +116,7 @@ public async Task<IActionResult> Logout()
public async Task<IActionResult> VerifyAccount([FromBody] VerifyAccountRequest request)
{
var result = await _authService.VerifyAccountAsync(request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, result.Message));
}

/// <summary>
Expand Down
16 changes: 8 additions & 8 deletions SnakeAid.Api/Controllers/FirstAidGuidelineController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public FirstAidGuidelineController(
public async Task<IActionResult> CreateFirstAidGuideline([FromBody] CreateFirstAidGuidelineRequest request)
{
var result = await _guidelineService.CreateFirstAidGuidelineAsync(request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "First aid guideline created successfully!"));
}

/// <summary>
Expand All @@ -52,7 +52,7 @@ public async Task<IActionResult> CreateFirstAidGuideline([FromBody] CreateFirstA
public async Task<IActionResult> GetFirstAidGuidelineById(int id)
{
var result = await _guidelineService.GetFirstAidGuidelineByIdAsync(id);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result));
}

/// <summary>
Expand All @@ -64,7 +64,7 @@ public async Task<IActionResult> GetFirstAidGuidelineById(int id)
public async Task<IActionResult> FilterFirstAidGuidelines([FromQuery] GetFirstAidGuidelineRequest request)
{
var result = await _guidelineService.FilterFirstAidGuidelinesAsync(request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result));
}

/// <summary>
Expand All @@ -76,7 +76,7 @@ public async Task<IActionResult> FilterFirstAidGuidelines([FromQuery] GetFirstAi
public async Task<IActionResult> GetAllFirstAidGuideline()
{
var result = await _guidelineService.GetAllFirstAidGuidelineAsync();
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result));
}

/// <summary>
Expand All @@ -89,7 +89,7 @@ public async Task<IActionResult> GetAllFirstAidGuideline()
public async Task<IActionResult> GetFirstAidGuidelinesBySnakeSpecies(int snakeSpeciesId)
{
var result = await _guidelineService.GetFirstAidGuidelinesBySnakeSpeciesIdAsync(snakeSpeciesId);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result));
}

/// <summary>
Expand All @@ -106,7 +106,7 @@ public async Task<IActionResult> GetFirstAidGuidelinesBySnakeSpecies(int snakeSp
public async Task<IActionResult> UpdateFirstAidGuideline(int id, [FromBody] UpdateFirstAidGuidelineRequest request)
{
var result = await _guidelineService.UpdateFirstAidGuidelineAsync(id, request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "First aid guideline updated successfully!"));
}

/// <summary>
Expand All @@ -120,8 +120,8 @@ public async Task<IActionResult> UpdateFirstAidGuideline(int id, [FromBody] Upda
[SwaggerResponse(404, "Guideline not found")]
public async Task<IActionResult> DeleteFirstAidGuideline(int id)
{
var result = await _guidelineService.DeleteFirstAidGuidelineAsync(id);
return StatusCode(result.StatusCode, result);
await _guidelineService.DeleteFirstAidGuidelineAsync(id);
return Ok(ApiResponseBuilder.BuildSuccessResponse("First aid guideline deleted successfully!"));
}
}
}
2 changes: 1 addition & 1 deletion SnakeAid.Api/Controllers/MediaController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,6 @@ public async Task<IActionResult> UploadReportMedia(
CancellationToken ct = default)
{
var result = await _mediaService.UploadReportMediaAsync(request, type, purpose, User, ct);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Report media uploaded successfully."));
}
}
6 changes: 3 additions & 3 deletions SnakeAid.Api/Controllers/SnakeDetectionController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public SnakeDetectionController(
/// <summary>
/// Detect snake species from uploaded ReportMedia
/// </summary>
/// <param name="request">Detection request with ReportMediaId</param>
/// <param name="reportMediaId">ID of the ReportMedia entity</param>
/// <param name="ct">Cancellation token</param>
/// <returns>Detection result with species info and confidence</returns>
[HttpPost("detect/{reportMediaId:guid}")]
Expand All @@ -45,7 +45,7 @@ public SnakeDetectionController(
public async Task<IActionResult> Detect([FromRoute] Guid reportMediaId, CancellationToken ct = default)
{
var result = await _snakeAIService.DetectFromReportMediaAsync(reportMediaId, ct);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Snake detection completed successfully."));
}

/// <summary>
Expand All @@ -63,6 +63,6 @@ public async Task<IActionResult> Detect([FromRoute] Guid reportMediaId, Cancella
public async Task<IActionResult> GetDetectionResult(Guid id, CancellationToken ct = default)
{
var result = await _snakeAIService.GetRecognitionResultAsync(id, ct);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Recognition result retrieved successfully."));
}
}
21 changes: 16 additions & 5 deletions SnakeAid.Api/Controllers/SnakebiteIncidentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
using SnakeAid.Core.Requests;
using SnakeAid.Core.Requests.RescueRequestSession;
using SnakeAid.Core.Requests.SnakebiteIncident;
using SnakeAid.Core.Responses.Auth;
using SnakeAid.Core.Responses.SnakebiteIncident;
using SnakeAid.Service.Implements;
using SnakeAid.Service.Interfaces;
using Swashbuckle.AspNetCore.Annotations;

Expand Down Expand Up @@ -45,7 +43,7 @@ public async Task<IActionResult> CreateSnakebiteIncident([FromBody] CreateIncide

// Create incident and first rescue request session
var result = await _incidentService.CreateIncidentAsync(request, userId);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Snakebite Incident created successfully!"));
}

/// <summary>
Expand All @@ -60,7 +58,20 @@ public async Task<IActionResult> RaiseSessionRange(Guid incidentId)
{
var request = new RaiseSessionRangeRequest { IncidentId = incidentId };
var result = await _incidentService.RaiseSessionRangeAsync(request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, $"Session range expanded successfully. New radius: {result.CurrentRadiusKm}km"));
}

/// <summary>
/// Get detailed information about a specific snakebite incident
/// </summary>
[HttpGet("{incidentId}")]
[SwaggerOperation(Summary = "Get Incident Detail", Description = "Retrieve detailed information about a snakebite incident including user, rescuer, sessions, and media")]
[SwaggerResponse(200, "Incident details retrieved successfully", typeof(ApiResponse<DetailSnakebiteIncidentReposne>))]
[SwaggerResponse(404, "Incident not found")]
public async Task<IActionResult> GetIncidentDetail(Guid incidentId)
{
var result = await _incidentService.GetDetailIncidentAsync(incidentId);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Incident details retrieved successfully!"));
}

/// <summary>
Expand All @@ -74,7 +85,7 @@ public async Task<IActionResult> RaiseSessionRange(Guid incidentId)
public async Task<IActionResult> UpdateSymptomReport(Guid incidentId, [FromBody] UpdateSymptomReportRequest request)
{
var result = await _incidentService.UpdateSymptomReportAsync(incidentId, request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Symptom report updated successfully!"));
}
}
}
16 changes: 8 additions & 8 deletions SnakeAid.Api/Controllers/SymptomConfigController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public SymptomConfigController(
public async Task<IActionResult> CreateSymptomConfig([FromBody] CreateSymptomConfigRequest request)
{
var result = await _symptomConfigService.CreateSymptomConfigAsync(request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Symptom configuration created successfully!"));
}

/// <summary>
Expand All @@ -53,7 +53,7 @@ public async Task<IActionResult> CreateSymptomConfig([FromBody] CreateSymptomCon
public async Task<IActionResult> GetSymptomConfigById(int id)
{
var result = await _symptomConfigService.GetSymptomConfigByIdAsync(id);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result));
}

/// <summary>
Expand All @@ -65,7 +65,7 @@ public async Task<IActionResult> GetSymptomConfigById(int id)
public async Task<IActionResult> FilterSymptomConfigs([FromQuery] GetSymptomConfigRequest request)
{
var result = await _symptomConfigService.FilterSymptomConfigsAsync(request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result));
}

/// <summary>
Expand All @@ -77,7 +77,7 @@ public async Task<IActionResult> FilterSymptomConfigs([FromQuery] GetSymptomConf
public async Task<IActionResult> GetAllSymptomConfig()
{
var result = await _symptomConfigService.GetAllSymptomConfigAsync();
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result));
}

/// <summary>
Expand All @@ -89,7 +89,7 @@ public async Task<IActionResult> GetAllSymptomConfig()
public async Task<IActionResult> GetSymptomConfigsGrouped()
{
var result = await _symptomConfigService.GetSymptomConfigsGroupedByKeyAsync();
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result));
}

/// <summary>
Expand All @@ -106,7 +106,7 @@ public async Task<IActionResult> GetSymptomConfigsGrouped()
public async Task<IActionResult> UpdateSymptomConfig(int id, [FromBody] UpdateSymptomConfigRequest request)
{
var result = await _symptomConfigService.UpdateSymptomConfigAsync(id, request);
return StatusCode(result.StatusCode, result);
return Ok(ApiResponseBuilder.BuildSuccessResponse(result, "Symptom configuration updated successfully!"));
}

/// <summary>
Expand All @@ -120,8 +120,8 @@ public async Task<IActionResult> UpdateSymptomConfig(int id, [FromBody] UpdateSy
[SwaggerResponse(404, "Configuration not found")]
public async Task<IActionResult> DeleteSymptomConfig(int id)
{
var result = await _symptomConfigService.DeleteSymptomConfigAsync(id);
return StatusCode(result.StatusCode, result);
await _symptomConfigService.DeleteSymptomConfigAsync(id);
return Ok(ApiResponseBuilder.BuildSuccessResponse("Symptom configuration deleted successfully!"));
}
}
}
48 changes: 48 additions & 0 deletions SnakeAid.Core/Responses/CreateRescueMissionResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using SnakeAid.Core.Domains;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SnakeAid.Core.Responses
{
public class CreateRescueMissionResponse
{
public Guid Id { get; set; }


public Guid IncidentId { get; set; } // FK to SnakebiteIncident (1-1)


public Guid RescuerId { get; set; } // FK to RescuerProfile

public RescueMissionStatus Status { get; set; } = RescueMissionStatus.Preparing;

[Column(TypeName = "numeric(18,2)")]
[Range(0, double.MaxValue)]
public decimal Price { get; set; }

public DateTime? StartedAt { get; set; }

public DateTime? ArrivedAt { get; set; }

public DateTime? CompletedAt { get; set; }

[MaxLength(2000)]
public string? Notes { get; set; }

[MaxLength(500)]
public string? CancellationReason { get; set; }

[Column(TypeName = "numeric(18,2)")]
[Range(0, double.MaxValue)]
public decimal? EstimatedCost { get; set; }

[Column(TypeName = "numeric(18,2)")]
[Range(0, double.MaxValue)]
public decimal? ActualCost { get; set; }
}
}
33 changes: 33 additions & 0 deletions SnakeAid.Core/Responses/ListRescueRequestResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using SnakeAid.Core.Domains;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SnakeAid.Core.Responses
{
public class ListRescueRequestResponse
{
public Guid Id { get; set; }


public Guid SessionId { get; set; } // FK to RescueRequestSession (quan trọng!)


public Guid IncidentId { get; set; } // FK to SnakebiteIncident


public Guid RescuerId { get; set; } // FK to RescuerProfile

public RescueRequestStatus Status { get; set; } = RescueRequestStatus.Pending;

public DateTime RequestSentAt { get; set; } = DateTime.UtcNow;

public DateTime? ResponseAt { get; set; } // Khi rescuer accept/reject

public DateTime ExpiredAt { get; set; } // Auto-expire after X minutes
}
}
Loading