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 identifierUserId: Owner of the sessionName: Optional session name (e.g., "Morning Trip - Lake Michigan")StartTime,EndTime: Session time rangeStartLatitude,StartLongitude: Starting locationLocationName: Human-readable locationGearSetupId: Gear setup used for this sessionFishingMethod: Primary fishing methodIsQuickLogSession: True if using quick-log buttonConnectedDeviceId: Bluetooth device IDDataSharingConsent: Consent level for this sessionAllowDnrAccess: 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
WeatherConditionssummary for quick reference - Future: Add
TotalCatchesdenormalized count - Future: Add
TotalSpeciescount - Future: Add
Notesfield for session notes - Future: Add
EndReason(TimeUp, Weather, LimitReached, etc.) - Future: Add
DistanceTraveledKmcalculated from telemetry - Future: Add
FuelUsedLitersfor 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 identifierUserId: Owner of the log entryFishingSessionId: Optional session this catch belongs toDate,Time,CaughtAt: Catch timestampLatitude,Longitude: Precise catch locationAccuracyMeters: GPS accuracyAltitudeM: ElevationFishingMethod: Method usedVisibility: Privacy level (Public, Private, Circle, Friends)IsQuickLogged: True if logged via quick-log buttonHasAutoCapturedData: True if data auto-captured from devicesIncludeInMigrationAnalysis: Opt-in for migration pattern researchIncludeInHotspotAnalysis: Opt-in for hotspot analysisDataSharingConsent: Per-entry consent overrideAllowDnrAccess: 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
CatchNumberfor session catch order - Future: Add
IsPersonalBestflag - Future: Add
IsRecordflag 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 identifierFishSpeciesId: Reference to FishSpecies entitySpecies: Fallback string if species not in databaseLengthCm,WeightKg,GirthCm: MeasurementsCondition: Alive, Dead, Injured, UnknownDisposition: Released, Kept, Donated, UnknownPhotoUrl,LurePhotoUrl: Photo URLsAiAnalyzedLengthCm,AiAnalyzedLureName,AiAnalyzedSpecies: AI analysis resultsNeedsReview: True if quick-logged and needs user verificationIsVerified: 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
EstimatedAgebased 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
HookTypeandHookSize - 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 identifierFishingLogEntryId: Associated log entryDepthM: Water depth in metersGpsSpeedKph: GPS speed in km/hWaterTempC: Water temperature in CelsiusHeadingDeg: Heading in degreesWaveHeightM: Wave height in metersSource: 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
CurrentSpeedKtsandCurrentDirectionDeg - Future: Add
Salinityfor saltwater - Future: Add
DissolvedOxygenfor water quality - Future: Add
pHfor 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 identifierFishingSessionId: Associated sessionRecordedAt: Timestamp for this data pointLatitude,Longitude: GPS locationDepthM,GpsSpeedKph,WaterTempC,HeadingDeg,WaveHeightM: Telemetry dataAirTempC,BarometricPressureHpa,WindSpeedKph,WindDirectionDeg: Additional sensor dataSource: 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
BatteryLevelof device - Future: Add
SignalStrengthfor device connection quality - Future: Add
DataQualityscore (GPS accuracy, sensor calibration) - Future: Consider data compression for high-frequency sampling
- Future: Add
IsAnchoredflag (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 identifierFishingLogEntryId: Associated log entryTemperatureC: Air temperatureWindSpeedKph,WindDirectionDeg: Wind dataPressureHpa: Barometric pressureHumidityPercent: HumidityCloudCoveragePercent: Cloud coverMoonPhase: Moon phaseSunrise,Sunset: Sun timesSource: 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
PrecipitationMmandPrecipitationType - Future: Add
UVIndex - Future: Add
DewPointC - Future: Add
HeatIndexCorWindChillC - 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 identifierFishingLogEntryId: Associated log entryDate: Date for this current data (allows historical data)SurfaceTempC: Surface water temperatureCurrentSpeedKts: Current speed in knotsCurrentDirectionDeg: Current direction in degreesTideHeightM: Tide height in metersSource: 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
Upwellingflag (cold water upwelling) - Future: Add
Chlorophylllevels (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 identifierFishingLogEntryId: Verified catchVerificationType: Photo, Witness, Scale, Video, etc.Status: Pending, Approved, RejectedVerifiedByUserId: Verifier userVerifiedAt: Verification timestampVerificationNotes: 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 identifierCatchVerificationId: Associated verificationEvidenceType: Photo, Video, ScaleReading, etc.EvidenceUrl: Evidence URLDescription: Evidence description
Relationships:
- Many-to-one: CatchVerification
CatchVerificationWitness
Purpose: Witnesses for catch verification.
Key Fields:
Id(int): Unique identifierCatchVerificationId: Associated verificationWitnessUserId: Witness userWitnessName: Witness name (if not user)WitnessEmail: Witness emailWitnessStatement: Witness statement
Relationships:
- Many-to-one: CatchVerification, User (optional)
AiVerificationRequest
Purpose: AI-powered catch verification requests.
Key Fields:
Id(int): Unique identifierFishingLogEntryId: Catch to verifyPhotoUrl: Photo for AI analysisRequestedAt: Request timestampStatus: Pending, Processing, Completed, FailedAiAnalysisResult: 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 identifierUserId: Agreement userAgreementType: Research, DNR, CommercialConsentLevel: Full, Partial, MinimalStartDate,EndDate: Agreement periodIsActive: Whether agreement is activeAgreementText: Agreement textAcceptedAt: Acceptance timestamp
Relationships:
- Many-to-one: User
DnrAccessLog
Purpose: Logs all DNR access to user data for compliance.
Key Fields:
Id(int): Unique identifierUserId: Data ownerDnrUserId: DNR user accessing dataAccessType: Read, Export, etc.DataAccessed: Data types accessed (JSON)AccessReason: Access reasonConsentLevel: Consent level usedAccessedAt: Access timestamp
Relationships:
- Many-to-one: User (data owner and DNR user)
Related Documentation
- Quick Logging & DNR Access - Quick logging workflow and DNR access
- Personal Best - PB tracking with verification
- Regulations - Master Angler submissions
- Weather & Environmental - Comprehensive weather tracking