Deployment: - custom-app.compose.yaml: self-contained Compose fuer TrueNAS "Custom App" (absolute Host-Bind-Pfade, postgres:18, pull_policy always, Port 8090) - scripts/truenas-deploy.sh: Host-Skript create/redeploy via midclt (App bleibt unter Apps sichtbar) inkl. Image-Pull + Health-Check - ci.yml Deploy-Job: laeuft auf ubuntu-latest-Runner, kopiert Deploy-Dateien per SSH auf den NAS-Host und triggert truenas-deploy.sh (statt runs-on goldeye) - compose.yaml/.env.example: postgres:18 (Locale-Match zur Quell-DB), Port 8090 - .gitignore: .agents/, tools/rag/, deploy/truenas/.env (Secrets/Scratch) Aufgelaufene Feature-Arbeit (verified/Freeze, Migrationen, Import-Triage): - GerbilOverride/VerifiedGerbil-Endpoints + GerbilSnapshotService + Tests - EF-Migrationen (ShowInChronicle, Stillborn, BirthOrder, ManualFlag, DSGVO) - Frontend VerifizierteTierePage + verified-API + e2e-Spec - diverse Import-/Triage-Skripte und -Tests Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
63 lines
3.4 KiB
C#
63 lines
3.4 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
|
|
namespace GerbilManagerWebAPI.Models
|
|
{
|
|
/// <summary>
|
|
/// VERIFIED/PROTECTED OVERRIDE: authoritative, hand-curated per-gerbil field values. Decoupled
|
|
/// from the rest of the model on purpose — <see cref="GerbilId"/> is a plain Guid column (NOT an
|
|
/// enforced foreign key, no navigation property), so the import re-ingest wipe
|
|
/// (<c>IngestResolvedService</c>) can delete and reload gerbils without deleting or breaking
|
|
/// override rows. After every ingest the override is re-applied on top of the fresh import (the
|
|
/// "freeze"), so the breeder's curated values are never lost. Matched to the (deterministic)
|
|
/// gerbil id. Same ingest-surviving pattern as <see cref="Feedback"/>.
|
|
///
|
|
/// Two flavours, both stored here:
|
|
/// - <see cref="IsVerified"/> = true → "vollständig korrekt": the whole own-field freeze set is
|
|
/// pinned, and a full Akte snapshot (<see cref="SnapshotJson"/>) is kept for the drift report,
|
|
/// export and regression test.
|
|
/// - <see cref="IsVerified"/> = false → "geschützt": created by a manual edit; only the changed
|
|
/// fields are pinned (per-field) so untouched fields keep receiving import improvements.
|
|
/// </summary>
|
|
public class GerbilOverride
|
|
{
|
|
[Key]
|
|
public Guid Id { get; set; }
|
|
|
|
/// <summary>Loose reference (no FK) to the gerbil this override curates.</summary>
|
|
public Guid GerbilId { get; set; }
|
|
|
|
/// <summary>Captured gerbil name — keeps the row human-readable and survives an ingest wipe.</summary>
|
|
public string? EntityName { get; set; }
|
|
|
|
/// <summary>true = "vollständig korrekt" (full freeze + certified); false = "geschützt" (per-field edit).</summary>
|
|
public bool IsVerified { get; set; }
|
|
|
|
/// <summary>Frozen own-field values as a JSON object (field name → value). Verified rows carry
|
|
/// the full freeze set; protected rows carry only the manually-changed fields. Re-applied on
|
|
/// top of the fresh import after every ingest.</summary>
|
|
public required string OverrideJson { get; set; }
|
|
|
|
/// <summary>Full human-readable Akte snapshot (self + parents + own litters/children) captured
|
|
/// at verify time — feeds the drift report, export and regression test. null for protected-only rows.</summary>
|
|
public string? SnapshotJson { get; set; }
|
|
|
|
/// <summary>Raw-import Akte snapshot captured during the LAST ingest, BEFORE the freeze was
|
|
/// applied — lets the UI show where the raw import disagrees with the golden state. null until
|
|
/// the first ingest after verifying.</summary>
|
|
public string? LastImportSnapshotJson { get; set; }
|
|
|
|
/// <summary>Cached diff (golden ↔ last raw import) as a JSON array, computed at ingest time.
|
|
/// null/empty = no drift / not yet computed.</summary>
|
|
public string? LastImportDiffJson { get; set; }
|
|
|
|
/// <summary>Optional free-text note the breeder attached when verifying.</summary>
|
|
public string? Note { get; set; }
|
|
|
|
/// <summary>When the row was marked "vollständig korrekt"; null for protected-only rows.</summary>
|
|
public DateTimeOffset? VerifiedAt { get; set; }
|
|
|
|
/// <summary>When the override was last created/updated.</summary>
|
|
public DateTimeOffset UpdatedAt { get; set; }
|
|
}
|
|
}
|