Skip to content

SnakeAid Release: The Snake Catching and Rescue Pairing - #46

Merged
the-khiem7 merged 46 commits into
mainfrom
dev
Feb 11, 2026
Merged

SnakeAid Release: The Snake Catching and Rescue Pairing#46
the-khiem7 merged 46 commits into
mainfrom
dev

Conversation

@the-khiem7

Copy link
Copy Markdown
Member

This pull request introduces several new API controllers for mission management in the SnakeAid system, enhances development tooling configuration, and adds a new package dependency. The most significant changes are the addition of controllers for managing rescue missions, snake catching missions, catching mission details, and system monitoring. Additionally, there are updates to Visual Studio Code configuration files for improved development experience and a new package version is included for Doppler configuration.

New API Controllers:

  • Added RescueMissionController to handle rescue mission status updates, including transitions such as start, arrival, completion, abort, and cancel, with appropriate status transitions and incident updates.
  • Added SnakeCatchingMissionController to manage snake catching missions, supporting start, arrival, and completion transitions, with validation for evidence media and automatic request status updates.
  • Added CatchingMissionDetailController to create and record details of snakes caught during a mission, including species and quantity.
  • Added MonitoringController to provide endpoints for monitoring session timeout service status and health checks.

Development Tooling & Configuration:

  • Updated .vscode/launch.json to improve server ready detection patterns and adjust default ports for development, enhancing debugging experience. [1] [2] [3] [4]
  • Enhanced .vscode/settings.json with a new default solution, and added/excluded common directories and file types for file explorer, search, and file watching, streamlining the developer workflow.

Dependencies:

  • Added Doppler.Extensions.Configuration version 1.0.1 to centralized package management, enabling Doppler secrets/configuration integration.

DuongNManh and others added 30 commits February 6, 2026 00:13
- Remove unused ServiceImplement class.
- Introduce SessionTimeoutBackgroundService for managing session timeouts with in-memory scheduling.
- Update SnakebiteIncidentService to integrate session management and rescue request handling.
- Add new interfaces for rescue mission and notification services.
- Enhance ISnakebiteIncidentService with methods for triggering and starting rescues.
- Remove obsolete ServiceInterface.
…ntralize

Devops/ops002 doppler config centralize
…capabilities; add demo data seeder for testing

- Improved logging in SessionTimeoutBackgroundService for better traceability of session management.
- Added GetMonitoringInfo method to ISessionTimeoutService for detailed session tracking.
- Implemented DemoDataSeeder to populate the database with demo users and rescuers for testing purposes.
- Included cleanup methods to remove demo data from the database.
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
- Updated RescueMissionService to allow multiple active missions per incident for retry scenarios.
- Enhanced RescuerAbortMissionAsync to ensure proper transaction handling and incident status updates.
- Modified RescueRequestSessionService to exclude rescuers who previously aborted missions for the same incident.
- Improved SnakeAIService to handle first aid guideline content more robustly.
- Fixed response type naming in SnakebiteIncidentService and ISnakebiteIncidentService for consistency.
NeoNgyn and others added 15 commits February 11, 2026 20:41
…ller endpoint to retrieve all snake catching requests
…ller endpoint to retrieve all snake catching requests
Copilot AI review requested due to automatic review settings February 11, 2026 18:35
@coderabbitai

coderabbitai Bot commented Feb 11, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Comment @coderabbitai help to get the list of available commands and usage tips.

@the-khiem7 the-khiem7 changed the title SnakeAid Release: The Snake Catching, Rescue Pairing SnakeAid Release: The Snake Catching and Rescue Pairing Feb 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds mission-management APIs and supporting infrastructure for SnakeAid, including the rescue-session workflow (broadcast/timeout/mission lifecycle), snake catching requests/missions, and monitoring endpoints, plus EF schema updates and dev tooling tweaks.

Changes:

  • Introduces new services/controllers for rescue sessions & missions, snake catching requests/missions, and monitoring/diagnostics.
  • Adds background session-timeout scheduling and SignalR-based rescuer notifications.
  • Updates EF model (incident↔mission 1:N), mapping/DTO shapes, seed data, and dev launch configuration/ports.

Reviewed changes

Copilot reviewed 78 out of 79 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docker-compose.yml Removes container env flag no longer used by Kestrel binding logic.
SnakeAid.Service/Interfaces/ServiceInterface.cs Deletes unused placeholder interface.
SnakeAid.Service/Interfaces/ISnakebiteIncidentService.cs Fixes response type typo and adds rescue trigger/start/accept service methods.
SnakeAid.Service/Interfaces/ISnakeCatchingRequestService.cs Adds snake catching request service contract.
SnakeAid.Service/Interfaces/ISnakeCatchingMissionService.cs Adds snake catching mission status transition contract.
SnakeAid.Service/Interfaces/ISessionTimeoutService.cs Adds timeout scheduling/monitoring interface and DTO for monitoring output.
SnakeAid.Service/Interfaces/IRescueRequestSessionService.cs Expands rescue session service API for broadcast/timeout/accept/expand flows.
SnakeAid.Service/Interfaces/IRescueNotificationService.cs Adds abstraction for rescuer push notifications (SignalR in API layer).
SnakeAid.Service/Interfaces/IRescueMissionService.cs Adds rescue mission lifecycle service contract.
SnakeAid.Service/Interfaces/ICatchingMissionDetailService.cs Adds service contract to record caught-snake mission details.
SnakeAid.Service/Implements/SnakebiteIncidentService.cs Implements rescue start/trigger/accept helpers and updates session-range logic.
SnakeAid.Service/Implements/SnakeCatchingRequestService.cs Implements snake catching request create/accept/detail/list flows.
SnakeAid.Service/Implements/SnakeCatchingMissionService.cs Implements snake catching mission start/arrive/complete transitions.
SnakeAid.Service/Implements/SnakeAIService.cs Updates first-aid override mapping from Steps to structured Content.
SnakeAid.Service/Implements/SessionTimeoutBackgroundService.cs Adds in-memory scheduled timeout background service implementing ISessionTimeoutService.
SnakeAid.Service/Implements/ServiceImplement.cs Deletes unused placeholder implementation.
SnakeAid.Service/Implements/RescueRequestSessionService.cs Implements session creation/broadcast/accept/timeout/expand logic with SignalR notifications.
SnakeAid.Service/Implements/RescueMissionService.cs Adds mission lifecycle logic including abort→new session behavior.
SnakeAid.Service/Implements/FirstAidGuidelineService.cs Applies append/replace override logic for first-aid content on guideline responses.
SnakeAid.Service/Implements/CatchingMissionDetailService.cs Implements creation of catching mission detail records.
SnakeAid.Repository/Seeds/DataSeeder.cs Updates seeded first-aid overrides to structured FirstAidContent/FirstAidStep.
SnakeAid.Repository/Migrations/SnakeAidDbContextModelSnapshot.cs Updates model snapshot for mission relationship change and index uniqueness removal.
SnakeAid.Repository/Migrations/20260210164830_UpdateSchemaV1.cs Adds migration to drop unique index on RescueMissions.IncidentId.
SnakeAid.Repository/Interfaces/IUnitOfWork.cs Adds ClearChangeTracker() for EF tracking cleanup scenarios.
SnakeAid.Repository/Implements/UnitOfWork.cs Implements ClearChangeTracker().
SnakeAid.Repository/Implements/GenericRepository.cs Improves Update() to avoid duplicate tracked entities with same key.
SnakeAid.Repository/Data/Configurations/SnakebiteIncidentConfiguration.cs Changes incident→mission relationship from 1:1 to 1:N.
SnakeAid.Repository/Data/Configurations/RescueMissionConfiguration.cs Removes uniqueness constraint on incident mission index.
SnakeAid.Repository/Data/Configurations/CatchingRequestDetailConfiguration.cs Adds navigation-based relationship for request details.
SnakeAid.Repository/Data/Configurations/CatchingMissionDetailConfiguration.cs Adds navigation-based relationship for mission details.
SnakeAid.Docs Updates docs submodule pointer.
SnakeAid.Core/Validators/NotInPastAttribute.cs Adds DateTime “not too far in past” validation attribute.
SnakeAid.Core/Validators/CoordinateAttribute.cs Adds coordinate validation attribute for lat/lng string inputs.
SnakeAid.Core/Responses/SnakebiteIncident/TriggerRescueResponse.cs Adds response DTO for initiating rescue sessions.
SnakeAid.Core/Responses/SnakebiteIncident/RejectRescueResponse.cs Adds response DTO for rejecting rescue requests (even if flow is disabled).
SnakeAid.Core/Responses/SnakebiteIncident/DetailSnakebiteIncidentReposne.cs Renames detail response type to DetailSnakebiteIncidentResponse.
SnakeAid.Core/Responses/SnakebiteIncident/CreateIncidentResponse.cs Changes location response shape and adds session summary fields.
SnakeAid.Core/Responses/SnakebiteIncident/AcceptRescueResponse.cs Adds response DTO for rescuer request accept.
SnakeAid.Core/Responses/SnakeCatchingRequest/ListSnakeCatchingRequestResponse.cs Adds list response DTO for snake catching requests.
SnakeAid.Core/Responses/SnakeCatchingRequest/CreateSnakeCatchingRequestResponse.cs Adds create/detail response DTO for snake catching requests.
SnakeAid.Core/Responses/SnakeCatchingRequest/CatchingRequestDetailResponse.cs Adds request-detail response DTO with species names.
SnakeAid.Core/Responses/SnakeCatchingMission/SnakeCatchingMissionDetailResponse.cs Adds mission detail response DTO including caught snake details.
SnakeAid.Core/Responses/SnakeCatchingMission/CreateSnakeCatchingMissionResponse.cs Adds mission create response DTO.
SnakeAid.Core/Responses/SnakeCatchingMission/CatchingMissionDetailResponse.cs Adds response DTO for per-species caught counts.
SnakeAid.Core/Responses/RescueMission/RescueMissionStatusResponse.cs Adds mission status response DTO.
SnakeAid.Core/Responses/ListRescueRequestResponse.cs Moves rescue request response into Responses.RescueMission namespace.
SnakeAid.Core/Responses/CreateRescueMissionResponse.cs Moves rescue mission response into Responses.RescueMission namespace.
SnakeAid.Core/Requests/SnakeCatchingRequest/SnakeSpeciesRequestItem.cs Adds request DTO for identified species + quantity.
SnakeAid.Core/Requests/SnakeCatchingRequest/CreateSnakeCatchingRequestRequest.cs Adds snake catching request DTO with coords, time, estimate, media/species lists.
SnakeAid.Core/Requests/SnakeCatchingMission/UpdateMissionStatusRequest.cs Adds mission status update request DTO (notes).
SnakeAid.Core/Requests/SnakeCatchingMission/CreateCatchingMissionDetailRequest.cs Adds create detail request DTO for caught snakes.
SnakeAid.Core/Requests/RescueMission/UpdateRescueMissionStatusRequest.cs Adds rescue mission status update request DTO.
SnakeAid.Core/Middlewares/ApiExceptionHandlerMiddleware.cs Avoids writing JSON if the response has already started.
SnakeAid.Core/Mappings/SnakebiteIncidentMapper.cs Maps Point→GeoPointResponse and maps latest mission onto incident detail response.
SnakeAid.Core/Mappings/SnakeCatchingRequestMapper.cs Adds Mapster mappings and circular reference handling for snake catching request responses.
SnakeAid.Core/Mappings/MapsterConfig.cs Adds global PreserveReference/MaxDepth to mitigate circular mapping recursion.
SnakeAid.Core/Mappings/CatchingRequestDetailMapper.cs Maps request details to include species common/scientific names.
SnakeAid.Core/Domains/SnakebiteIncident.cs Changes incident mission navigation to collection and adjusts radius range validation.
SnakeAid.Core/Domains/SnakeSpecies.cs Changes first-aid override from list of strings to structured content.
SnakeAid.Core/Domains/SnakeCatchingRequest.cs Adds Details collection navigation.
SnakeAid.Core/Domains/SnakeCatchingMission.cs Adds MissionDetails collection navigation.
SnakeAid.Core/Domains/RescueRequestSession.cs Updates comment to match max 3 sessions.
SnakeAid.Api/Services/SignalRRescueNotificationService.cs Implements notification interface via SignalR and tracks rescuer connections.
SnakeAid.Api/Services/DemoDataSeeder.cs Adds demo seeding/cleanup to test rescue flow end-to-end.
SnakeAid.Api/Properties/launchSettings.json Standardizes app URLs to 8080/8081 for local run profiles.
SnakeAid.Api/Program.cs Registers background timeout service, adds hub endpoint, tweaks SignalR keepalive, adds diagnostics endpoints, and standardizes ports.
SnakeAid.Api/Pages/Demo/RescueDemo.cshtml.cs Adds page model for UI demo page.
SnakeAid.Api/Hubs/RescuerHub.cs Adds rescuer SignalR hub for joining/accepting requests and connection tracking.
SnakeAid.Api/DI/DependencyInjection.cs Registers demo data seeder in DI.
SnakeAid.Api/Controllers/SnakebiteIncidentController.cs Starts rescue session immediately after incident creation and adds cancel endpoint.
SnakeAid.Api/Controllers/SnakeCatchingRequestController.cs Adds CRUD-ish endpoints for snake catching requests (create, list, accept, detail).
SnakeAid.Api/Controllers/SnakeCatchingMissionController.cs Adds endpoints for mission start/arrived/complete transitions.
SnakeAid.Api/Controllers/RescueMissionController.cs Adds endpoints for rescue mission status transitions and abort/cancel flows.
SnakeAid.Api/Controllers/RescueDemoController.cs Adds extensive demo endpoints to seed/drive/monitor rescue flows.
SnakeAid.Api/Controllers/MonitoringController.cs Adds monitoring endpoints for session timeout service health/status.
SnakeAid.Api/Controllers/CatchingMissionDetailController.cs Adds endpoint to add caught-snake mission detail records.
.vscode/launch.json Updates serverReadyAction patterns for new local ports.
Comments suppressed due to low confidence (15)

SnakeAid.Service/Implements/SnakeCatchingRequestService.cs:1

  • CatchingRequestDetail rows are inserted before the parent SnakeCatchingRequest is inserted/committed. With an FK from CatchingRequestDetail.SnakeCatchingRequestId → SnakeCatchingRequest.Id, this will fail at runtime. Insert/attach the parent request first (or add details via navigation and let EF insert in the right order) before inserting the details.
    SnakeAid.Service/Implements/SnakeCatchingRequestService.cs:1
  • CatchingRequestDetail rows are inserted before the parent SnakeCatchingRequest is inserted/committed. With an FK from CatchingRequestDetail.SnakeCatchingRequestId → SnakeCatchingRequest.Id, this will fail at runtime. Insert/attach the parent request first (or add details via navigation and let EF insert in the right order) before inserting the details.
    SnakeAid.Service/Implements/SessionTimeoutBackgroundService.cs:1
  • ProcessExpiredSessions() removes each expired session from _sessionTimeouts (lines 187-191) before later checking whether it was rescheduled (lines 217-224). That reschedule guard can never be true, so rescheduled sessions may be processed incorrectly. Keep entries until after processing, or check reschedule status before removing from _sessionTimeouts.
    SnakeAid.Service/Implements/SessionTimeoutBackgroundService.cs:1
  • ProcessExpiredSessions() removes each expired session from _sessionTimeouts (lines 187-191) before later checking whether it was rescheduled (lines 217-224). That reschedule guard can never be true, so rescheduled sessions may be processed incorrectly. Keep entries until after processing, or check reschedule status before removing from _sessionTimeouts.
    SnakeAid.Service/Implements/RescueRequestSessionService.cs:1
  • TryExpandAndCreateNewSessionAsync() is not wrapped in ExecuteInTransactionAsync, but it calls CreateSessionInternalAsync() and BroadcastRequestsInternalAsync() which write multiple tables and schedule timeouts. The comment says it's already in a transaction, but it isn't here—this can lead to partial updates if anything fails mid-flow. Wrap the whole expand+create+broadcast sequence in a single UnitOfWork transaction.
    SnakeAid.Service/Implements/RescueRequestSessionService.cs:1
  • TryExpandAndCreateNewSessionAsync() is not wrapped in ExecuteInTransactionAsync, but it calls CreateSessionInternalAsync() and BroadcastRequestsInternalAsync() which write multiple tables and schedule timeouts. The comment says it's already in a transaction, but it isn't here—this can lead to partial updates if anything fails mid-flow. Wrap the whole expand+create+broadcast sequence in a single UnitOfWork transaction.
    SnakeAid.Service/Implements/RescueRequestSessionService.cs:1
  • The timeout is scheduled before the DB transaction is known to be committed. If the surrounding transaction rolls back, the background service may later attempt to process a sessionId that doesn't exist. Consider scheduling the timeout only after commit (or via an outbox/after-commit hook), or ensure HandleSessionTimeoutAsync treats missing sessions as a normal no-op.
    SnakeAid.Service/Implements/RescueRequestSessionService.cs:1
  • SignalR notifications are being sent as part of the broadcast workflow that is executed inside a DB transaction (via BroadcastRequestsAsync → ExecuteInTransactionAsync). External I/O in a DB transaction can significantly increase lock duration and amplify failure modes (e.g., transient network errors aborting the transaction). Prefer committing DB changes first, then dispatch notifications (e.g., outbox pattern or after-commit step).
    SnakeAid.Service/Implements/SnakeCatchingMissionService.cs:1
  • mission.EstimatedCost is nullable, but mission.Price is calculated using mission.EstimatedCost.Value. If EstimatedCost is null for older rows or edge cases, this will throw at runtime. Use a null-safe default (e.g., EstimatedCost ?? 0m) or validate it is present before using .Value.
    SnakeAid.Service/Implements/SnakeCatchingMissionService.cs:1
  • The controller documentation states that completing a snake catching mission requires evidence media, but the service-side validation is commented out. Either re-enable this validation (so behavior matches the API contract) or update the endpoint documentation to reflect the actual rules.
    SnakeAid.Api/Controllers/RescueDemoController.cs:1
  • RescueDemoController provides powerful endpoints (seed/cleanup/demo flow) and seeds accounts with a known password ("Demo@123"). If deployed beyond local/dev, this is a serious security risk. Consider compiling/mapping this controller only in Development, and/or enforce strict authorization + environment checks.
using Microsoft.AspNetCore.Mvc;

SnakeAid.Api/Hubs/RescuerHub.cs:1

  • Hub methods accept caller-supplied identities (userId/rescuerId), which allows a client to impersonate another rescuer by passing a different GUID. Prefer deriving rescuerId from Context.User / claims (e.g., Context.UserIdentifier) and ignore client-provided IDs for authorization-related decisions.
using System;

SnakeAid.Service/Implements/SnakebiteIncidentService.cs:1

  • This log message is in RaiseSessionRangeAsync() but says it's retrieving incident details, which is misleading for troubleshooting. Update the message to reflect the actual operation (raising/expanding session range).
    SnakeAid.Service/Implements/SnakeCatchingRequestService.cs:1
  • Path.GetExtension(url) will return incorrect results for URLs with query strings/fragments (e.g., ".jpg?token=..."), causing the content type to fall back to octet-stream. Parse the URL as a Uri and take Path.GetExtension(uri.AbsolutePath) instead.
    SnakeAid.Repository/Migrations/SnakeAidDbContextModelSnapshot.cs:1
  • The snapshot ProductVersion changed from 8.0.23 to 8.0.11. This often happens when migrations are generated with a different EF Core tooling/runtime version and can cause noisy diffs. Consider regenerating the migration/snapshot using the repo’s standard EF tooling version to keep this consistent.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

{
[Route("api/monitoring")]
[ApiController]
// [Authorize] // Only authenticated users can access monitoring

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Monitoring endpoints are exposed without authorization. This leaks operational state (timeouts, queue sizes, health) and can aid attackers. Re-enable [Authorize] (and ideally restrict to an admin role/policy) or gate these endpoints to Development environments only.

Suggested change
// [Authorize] // Only authenticated users can access monitoring
[Authorize] // Only authenticated users can access monitoring

Copilot uses AI. Check for mistakes.
Comment thread SnakeAid.Api/Program.cs
Comment on lines +326 to +353
// Test database connection endpoint
app.MapGet("/api/test/db", async (SnakeAidDbContext dbContext) =>
{
try
{
var canConnect = await dbContext.Database.CanConnectAsync();
if (canConnect)
{
var accountCount = await dbContext.MemberProfiles.CountAsync();
return Results.Ok(new
{
status = "Connected",
message = "Database connection successful",
accountCount,
timestamp = DateTime.UtcNow
});
}
return Results.Problem("Cannot connect to database");
}
catch (Exception ex)
{
return Results.Problem(
detail: ex.Message,
title: "Database Connection Failed",
statusCode: 500
);
}
}).WithTags("Diagnostics");

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This diagnostics endpoint is publicly accessible and exposes database connectivity and entity counts. It should be protected (auth/admin policy) or only mapped in Development, otherwise it increases the application's attack surface and leaks sensitive operational metadata.

Suggested change
// Test database connection endpoint
app.MapGet("/api/test/db", async (SnakeAidDbContext dbContext) =>
{
try
{
var canConnect = await dbContext.Database.CanConnectAsync();
if (canConnect)
{
var accountCount = await dbContext.MemberProfiles.CountAsync();
return Results.Ok(new
{
status = "Connected",
message = "Database connection successful",
accountCount,
timestamp = DateTime.UtcNow
});
}
return Results.Problem("Cannot connect to database");
}
catch (Exception ex)
{
return Results.Problem(
detail: ex.Message,
title: "Database Connection Failed",
statusCode: 500
);
}
}).WithTags("Diagnostics");
// Test database connection endpoint (only available in Development)
if (app.Environment.IsDevelopment())
{
app.MapGet("/api/test/db", async (SnakeAidDbContext dbContext) =>
{
try
{
var canConnect = await dbContext.Database.CanConnectAsync();
if (canConnect)
{
var accountCount = await dbContext.MemberProfiles.CountAsync();
return Results.Ok(new
{
status = "Connected",
message = "Database connection successful",
accountCount,
timestamp = DateTime.UtcNow
});
}
return Results.Problem("Cannot connect to database");
}
catch (Exception ex)
{
return Results.Problem(
detail: ex.Message,
title: "Database Connection Failed",
statusCode: 500
);
}
}).WithTags("Diagnostics");
}

Copilot uses AI. Check for mistakes.
@the-khiem7
the-khiem7 merged commit 028ab64 into main Feb 11, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants