feat(feedback): Fehler-melden-Dialog + ID-kopieren (Stammbaum/Akte/Wurf)
Rechtsklick auf eine Maus im Stammbaum öffnet ein Kontextmenü mit „ID kopieren" (Clipboard + Toast) und „Fehler melden". Zusätzlich „Fehler melden"-Buttons in der Rennmausakte und der Wurf-Ansicht. Der Dialog erfasst eine Beschreibung und sendet sie samt Debug-Kontext (Ansicht, Tier-/Wurf-ID + Name, URL, Zeitstempel, User-Agent) an POST /feedback; gespeichert in einer neuen Feedback-Tabelle. Backend: Feedback-Entity (lose nullable GerbilId/LitterId ohne FK), Endpoints POST/GET /feedback, EF-Migration AddFeedback. Die Tabelle wird vom Import-Ingest NICHT geleert — Feedback überlebt Re-Ingests (Test deckt das ab). Tests: FeedbackEndpointTests (persistiert, 400 bei leer, übersteht Ingest-Wipe); e2e feedback.spec.ts. tsc/eslint/vitest(129)/playwright(6)/dotnet(212) grün. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
44
GerbilManagerWebAPI/Models/Feedback.cs
Normal file
44
GerbilManagerWebAPI/Models/Feedback.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace GerbilManagerWebAPI.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// FEEDBACK: a user-submitted "Fehler melden" report. Decoupled from the rest of the
|
||||
/// model on purpose — GerbilId/LitterId are plain nullable Guid columns (NOT enforced
|
||||
/// foreign keys), so the import re-ingest wipe (IngestResolvedService) can delete
|
||||
/// gerbils/litters without deleting or breaking feedback rows. The captured EntityName
|
||||
/// keeps the report human-readable even after the referenced animal is gone.
|
||||
/// </summary>
|
||||
public class Feedback
|
||||
{
|
||||
[Key]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>The user's free-text description of the problem.</summary>
|
||||
public required string Message { get; set; }
|
||||
|
||||
/// <summary>Which view the report came from: stammbaum | gerbil-detail | litter-detail.</summary>
|
||||
public required string Context { get; set; }
|
||||
|
||||
/// <summary>Loose reference (no FK) to the gerbil the report is about, if any.</summary>
|
||||
public Guid? GerbilId { get; set; }
|
||||
|
||||
/// <summary>Loose reference (no FK) to the litter the report is about, if any.</summary>
|
||||
public Guid? LitterId { get; set; }
|
||||
|
||||
/// <summary>Captured name of the referenced animal/litter (survives an ingest wipe).</summary>
|
||||
public string? EntityName { get; set; }
|
||||
|
||||
/// <summary>The client URL/route the report was filed from.</summary>
|
||||
public string? Url { get; set; }
|
||||
|
||||
/// <summary>Client-supplied timestamp (when the user submitted, in their browser).</summary>
|
||||
public DateTimeOffset? ClientTimestamp { get; set; }
|
||||
|
||||
/// <summary>Optional browser user-agent for diagnostics.</summary>
|
||||
public string? UserAgent { get; set; }
|
||||
|
||||
/// <summary>Server-side creation time.</summary>
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user