Skip to main content

Fishing Log Entities

Entities for fishing sessions, catch logging, and related data.

Core Session & Catch Entities

FishingSession

Purpose: Represents a fishing trip/session that can contain multiple catches. Supports quick logging workflow.

Key Fields:

  • Id (Guid): Unique identifier
  • UserId: Owner of the session
  • Name: Optional session name (e.g., "Morning Trip - Lake Michigan")
  • StartTime, EndTime: Session time range
  • StartLatitude, StartLongitude: Starting location
  • LocationName: Human-readable location
  • GearSetupId: Gear setup used for this session
  • FishingMethod: Primary fishing method
  • IsQuickLogSession: True if using quick-log button
  • ConnectedDeviceId: Bluetooth device ID
  • DataSharingConsent: Consent level for this session
  • AllowDnrAccess: Explicit DNR access permission

Relationships:

  • Many-to-one: User (owner)
  • Many-to-one: GearSetup (optional)
  • One-to-many: FishingLogEntry (catches in this session)
  • One-to-many: SessionTelemetry (continuous telemetry data)

Usage Patterns:

// Start a fishing session
var session = new FishingSession
{{
UserId = userId,
StartTime = DateTime.UtcNow,
StartLatitude = currentLat,
StartLongitude = currentLon,
IsQuickLogSession = true,
ConnectedDeviceId = bluetoothDeviceId
}};

// Get session with all catches
var session = context.FishingSessions
.Include(s => s.LogEntries)
.ThenInclude(e => e.CatchDetails)
.Include(s => s.TelemetryData)
.FirstOrDefault(s => s.Id == sessionId);

Considerations:

  • Future: Add WeatherConditions summary for quick reference
  • Future: Add TotalCatches denormalized count
  • Future: Add TotalSpecies count
  • Future: Add Notes field for session notes
  • Future: Add EndReason (TimeUp, Weather, LimitReached, etc.)
  • Future: Add DistanceTraveledKm calculated from telemetry
  • Future: Add FuelUsedLiters for boat trips
  • Index: Indexed on UserId, StartTime, IsQuickLogSession

FishingLogEntry

Purpose: Individual catch log entry - can be standalone or part of a fishing session.

Key Fields:

  • Id (Guid): Unique identifier
  • UserId: Owner of the log entry
  • FishingSessionId: Optional session this catch belongs to
  • Date, Time, CaughtAt: Catch timestamp
  • Latitude, Longitude: Precise catch location
  • AccuracyMeters: GPS accuracy
  • AltitudeM: Elevation
  • FishingMethod: Method used
  • Visibility: Privacy level (Public, Private, Circle, Friends)
  • IsQuickLogged: True if logged via quick-log button
  • HasAutoCapturedData: True if data auto-captured from devices
  • IncludeInMigrationAnalysis: Opt-in for migration pattern research
  • IncludeInHotspotAnalysis: Opt-in for hotspot analysis
  • DataSharingConsent: Per-entry consent override
  • AllowDnrAccess: Per-entry DNR access

Relationships:

  • Many-to-one: User (owner)
  • Many-to-one: FishingSession (optional)
  • Many-to-one: GearSetup (optional)
  • One-to-one: CatchDetail (required)
  • One-to-one: Telemetry (optional)
  • One-to-one: Weather (optional)
  • One-to-many: Current (can have multiple historical current records)

Usage Patterns:

// Create log entry
var logEntry = new FishingLogEntry
{{
UserId = userId,
Date = DateOnly.FromDateTime(DateTime.UtcNow),
Time = TimeOnly.FromDateTime(DateTime.UtcNow),
CaughtAt = DateTime.UtcNow,
Latitude = gpsLat,
Longitude = gpsLon,
FishingMethod = FishingMethod.Trolling,
Visibility = LogVisibility.Private
}};

// Get logs for migration analysis
var migrationData = context.FishingLogEntries
.Where(e => e.IncludeInMigrationAnalysis && e.FishSpeciesId == speciesId)
.Include(e => e.Telemetry)
.Include(e => e.Weather)
.ToList();

Considerations:

  • Future: Add WaterBody (Lake, River, Ocean) for categorization
  • Future: Add DepthZone (Shallow, Medium, Deep) calculated from telemetry
  • Future: Add CatchNumber for session catch order
  • Future: Add IsPersonalBest flag
  • Future: Add IsRecord flag for state/regional records
  • Future: Add VerifiedBy (user who verified the catch)
  • Future: Add VerificationMethod (Photo, Witness, Scale, etc.)
  • Index: Indexed on UserId, Date, (Latitude, Longitude), IncludeInMigrationAnalysis, IncludeInHotspotAnalysis

CatchDetail

Purpose: Detailed catch information - one per fishing log entry.

Key Fields:

  • Id (int): Unique identifier
  • FishSpeciesId: Reference to FishSpecies entity
  • Species: Fallback string if species not in database
  • LengthCm, WeightKg, GirthCm: Measurements
  • Condition: Alive, Dead, Injured, Unknown
  • Disposition: Released, Kept, Donated, Unknown
  • PhotoUrl, LurePhotoUrl: Photo URLs
  • AiAnalyzedLengthCm, AiAnalyzedLureName, AiAnalyzedSpecies: AI analysis results
  • NeedsReview: True if quick-logged and needs user verification
  • IsVerified: User has reviewed/edited the catch

Relationships:

  • Many-to-one: FishingLogEntry (required, one-to-one)
  • Many-to-one: FishSpecies (optional)
  • Many-to-one: Lure (optional)

Usage Patterns:

// Create catch detail
var catchDetail = new CatchDetail
{{
FishingLogEntryId = logEntryId,
FishSpeciesId = speciesId,
LengthCm = measuredLength,
WeightKg = measuredWeight,
Condition = CatchCondition.Alive,
Disposition = CatchDisposition.Released,
NeedsReview = false,
IsVerified = true
}};

// Get catches needing review
var needsReview = context.CatchDetails
.Where(cd => cd.NeedsReview && cd.FishingLogEntry.UserId == userId)
.Include(cd => cd.FishingLogEntry)
.Include(cd => cd.FishSpecies)
.ToList();

Considerations:

  • Future: Add EstimatedAge based on size
  • Future: Add Sex (Male, Female, Unknown) if identifiable
  • Future: Add SpawningCondition (Pre-spawn, Spawning, Post-spawn)
  • Future: Add HealthScore (1-10) for catch-and-release quality
  • Future: Add ReleaseMethod (Gentle, Standard, Rough)
  • Future: Add BaitUsed (if different from lure)
  • Future: Add HookType and HookSize
  • Future: Add FightDuration (time to land fish)
  • Index: Indexed on FishSpeciesId for species queries

Telemetry

Purpose: Telemetry data captured at the time of catch (depth, speed, water temp, etc.).

Key Fields:

  • Id (int): Unique identifier
  • FishingLogEntryId: Associated log entry
  • DepthM: Water depth in meters
  • GpsSpeedKph: GPS speed in km/h
  • WaterTempC: Water temperature in Celsius
  • HeadingDeg: Heading in degrees
  • WaveHeightM: Wave height in meters
  • Source: Garmin, FishHawk, Manual

Relationships:

  • Many-to-one: FishingLogEntry (required, one-to-one)

Usage Patterns:

// Create telemetry
var telemetry = new Telemetry
{{
FishingLogEntryId = logEntryId,
DepthM = fishHawkDevice.Depth,
WaterTempC = fishHawkDevice.WaterTemp,
GpsSpeedKph = gpsDevice.Speed,
Source = TelemetrySource.FishHawk
}};

Considerations:

  • Future: Add SurfaceTempC (if different from water temp)
  • Future: Add ThermoclineDepthM (if detected)
  • Future: Add CurrentSpeedKts and CurrentDirectionDeg
  • Future: Add Salinity for saltwater
  • Future: Add DissolvedOxygen for water quality
  • Future: Add pH for water quality
  • Future: Add Turbidity (water clarity)
  • Index: Indexed on FishingLogEntryId (unique)

SessionTelemetry

Purpose: Continuous telemetry data captured during a fishing session from Bluetooth devices.

Key Fields:

  • Id (int): Unique identifier
  • FishingSessionId: Associated session
  • RecordedAt: Timestamp for this data point
  • Latitude, Longitude: GPS location
  • DepthM, GpsSpeedKph, WaterTempC, HeadingDeg, WaveHeightM: Telemetry data
  • AirTempC, BarometricPressureHpa, WindSpeedKph, WindDirectionDeg: Additional sensor data
  • Source: Device source

Relationships:

  • Many-to-one: FishingSession (required)

Usage Patterns:

// Capture telemetry point
var telemetry = new SessionTelemetry
{{
FishingSessionId = sessionId,
RecordedAt = DateTime.UtcNow,
Latitude = currentLat,
Longitude = currentLon,
DepthM = device.Depth,
WaterTempC = device.WaterTemp,
Source = TelemetrySource.FishHawk
}};

// Get session path
var path = context.SessionTelemetry
.Where(st => st.FishingSessionId == sessionId)
.OrderBy(st => st.RecordedAt)
.Select(st => new {{ st.Latitude, st.Longitude }})
.ToList();

Considerations:

  • Future: Add BatteryLevel of device
  • Future: Add SignalStrength for device connection quality
  • Future: Add DataQuality score (GPS accuracy, sensor calibration)
  • Future: Consider data compression for high-frequency sampling
  • Future: Add IsAnchored flag (speed = 0 for extended period)
  • Index: Indexed on (FishingSessionId, RecordedAt) and (Latitude, Longitude)

Weather

Purpose: Weather conditions at the time of catch.

Key Fields:

  • Id (int): Unique identifier
  • FishingLogEntryId: Associated log entry
  • TemperatureC: Air temperature
  • WindSpeedKph, WindDirectionDeg: Wind data
  • PressureHpa: Barometric pressure
  • HumidityPercent: Humidity
  • CloudCoveragePercent: Cloud cover
  • MoonPhase: Moon phase
  • Sunrise, Sunset: Sun times
  • Source: Windy, OpenWeather, Manual

Relationships:

  • Many-to-one: FishingLogEntry (required, one-to-one)

Usage Patterns:

// Create weather entry
var weather = new Weather
{{
FishingLogEntryId = logEntryId,
TemperatureC = windyApi.Temperature,
WindSpeedKph = windyApi.WindSpeed,
WindDirectionDeg = windyApi.WindDirection,
PressureHpa = windyApi.Pressure,
Source = WeatherSource.Windy
}};

Considerations:

  • Future: Add PressureTrend (Rising, Falling, Stable)
  • Future: Add VisibilityKm (fog, haze)
  • Future: Add PrecipitationMm and PrecipitationType
  • Future: Add UVIndex
  • Future: Add DewPointC
  • Future: Add HeatIndexC or WindChillC
  • Future: Add WeatherCondition (Clear, PartlyCloudy, Overcast, Rain, etc.)
  • Index: Indexed on FishingLogEntryId (unique)

Current

Purpose: Water current/conditions data. Can store both current conditions and historical data (prevCurrents).

Key Fields:

  • Id (int): Unique identifier
  • FishingLogEntryId: Associated log entry
  • Date: Date for this current data (allows historical data)
  • SurfaceTempC: Surface water temperature
  • CurrentSpeedKts: Current speed in knots
  • CurrentDirectionDeg: Current direction in degrees
  • TideHeightM: Tide height in meters
  • Source: Seagull, Manual

Relationships:

  • Many-to-one: FishingLogEntry (required, one-to-many - can have multiple historical records)

Usage Patterns:

// Create current entry
var current = new Current
{{
FishingLogEntryId = logEntryId,
Date = DateOnly.FromDateTime(DateTime.UtcNow),
SurfaceTempC = seagullApi.SurfaceTemp,
CurrentSpeedKts = seagullApi.CurrentSpeed,
CurrentDirectionDeg = seagullApi.CurrentDirection,
TideHeightM = seagullApi.TideHeight,
Source = CurrentSource.Seagull
}};

// Get historical current data (prevCurrents)
var historical = context.Currents
.Where(c => c.FishingLogEntryId == logEntryId && c.Date < logEntry.Date)
.OrderByDescending(c => c.Date)
.Take(5) // Last 5 days
.ToList();

Considerations:

  • Future: Add TideType (High, Low, Rising, Falling)
  • Future: Add TideTime (time of high/low tide)
  • Future: Add CurrentType (Tidal, River, Wind-driven)
  • Future: Add Upwelling flag (cold water upwelling)
  • Future: Add Chlorophyll levels (for fishing productivity)
  • Future: Add WaterClarityM (visibility depth)
  • Index: Indexed on (FishingLogEntryId, Date) for historical queries

Additional Fishing Log Entities

CatchVerification

Purpose: Catch verification system for record claims and PB verification.

Key Fields:

  • Id (int): Unique identifier
  • FishingLogEntryId: Verified catch
  • VerificationType: Photo, Witness, Scale, Video, etc.
  • Status: Pending, Approved, Rejected
  • VerifiedByUserId: Verifier user
  • VerifiedAt: Verification timestamp
  • VerificationNotes: Verification notes

Relationships:

  • Many-to-one: FishingLogEntry, User (verifier)
  • One-to-many: CatchVerificationEvidence, CatchVerificationWitness

CatchVerificationEvidence

Purpose: Evidence for catch verification (photos, videos, etc.).

Key Fields:

  • Id (int): Unique identifier
  • CatchVerificationId: Associated verification
  • EvidenceType: Photo, Video, ScaleReading, etc.
  • EvidenceUrl: Evidence URL
  • Description: Evidence description

Relationships:

  • Many-to-one: CatchVerification

CatchVerificationWitness

Purpose: Witnesses for catch verification.

Key Fields:

  • Id (int): Unique identifier
  • CatchVerificationId: Associated verification
  • WitnessUserId: Witness user
  • WitnessName: Witness name (if not user)
  • WitnessEmail: Witness email
  • WitnessStatement: Witness statement

Relationships:

  • Many-to-one: CatchVerification, User (optional)

AiVerificationRequest

Purpose: AI-powered catch verification requests.

Key Fields:

  • Id (int): Unique identifier
  • FishingLogEntryId: Catch to verify
  • PhotoUrl: Photo for AI analysis
  • RequestedAt: Request timestamp
  • Status: Pending, Processing, Completed, Failed
  • AiAnalysisResult: AI analysis result (JSON)
  • ConfidenceScore: Analysis confidence score

Relationships:

  • Many-to-one: FishingLogEntry

DataSharingAgreement

Purpose: Data sharing agreements for research and DNR access.

Key Fields:

  • Id (int): Unique identifier
  • UserId: Agreement user
  • AgreementType: Research, DNR, Commercial
  • ConsentLevel: Full, Partial, Minimal
  • StartDate, EndDate: Agreement period
  • IsActive: Whether agreement is active
  • AgreementText: Agreement text
  • AcceptedAt: Acceptance timestamp

Relationships:

  • Many-to-one: User

DnrAccessLog

Purpose: Logs all DNR access to user data for compliance.

Key Fields:

  • Id (int): Unique identifier
  • UserId: Data owner
  • DnrUserId: DNR user accessing data
  • AccessType: Read, Export, etc.
  • DataAccessed: Data types accessed (JSON)
  • AccessReason: Access reason
  • ConsentLevel: Consent level used
  • AccessedAt: Access timestamp

Relationships:

  • Many-to-one: User (data owner and DNR user)