diff options
| author | Claude <noreply@anthropic.com> | 2026-04-22 05:35:49 +0000 |
|---|---|---|
| committer | Claude <noreply@anthropic.com> | 2026-04-22 05:35:49 +0000 |
| commit | eeafe2f0f3a3718bd52e9c333894e1abbc0611ab (patch) | |
| tree | 68ba329f0cadd64333fb5d72587f684fc38a500a /test-runner/src/main | |
| parent | 3cddcd3b0a8719da5e828734a1d3054cef803235 (diff) | |
feat: vessel registry, crew management, and thermal alarm
- Vessel/CrewMember data classes with full profile fields
(MMSI, callsign, flag, home port, hull type, dimensions, roles)
- VesselRepository: in-memory CRUD for own vessel, fleet, and crew;
getOwnVessel(), getSkipper(), getCrewByRole() helpers
- VesselRegistryFragment: own-vessel card + crew list + known-vessels
list; AlertDialog editors for add/edit; long-press to delete
- ic_vessel.xml sailboat icon; 5th bottom-nav tab "Vessel"
- ThermalMonitor: thermalFlow() using Intent.ACTION_BATTERY_CHANGED
(battery °C) + PowerManager.OnThermalStatusChangedListener (API 29+);
ThermalState OK/WARM/HOT/CRITICAL with distinct-until-changed filter
- MainActivity: startThermalMonitoring() sounds mob_alarm + Toast on
HOT (≥45°C) and CRITICAL (≥50°C); auto-silences on OK/WARM
- MainViewModel: thermalState and thermalReading StateFlows
- 18 VesselRepositoryTest cases — all GREEN (test-runner)
- design.md: updated competitive matrix + feature implementation status
https://claude.ai/code/session_011h2dXbgXg3PesQMmQUNTCW
Diffstat (limited to 'test-runner/src/main')
3 files changed, 92 insertions, 0 deletions
diff --git a/test-runner/src/main/kotlin/org/terst/nav/vessel/CrewMember.kt b/test-runner/src/main/kotlin/org/terst/nav/vessel/CrewMember.kt new file mode 100644 index 0000000..0df8cb9 --- /dev/null +++ b/test-runner/src/main/kotlin/org/terst/nav/vessel/CrewMember.kt @@ -0,0 +1,15 @@ +package org.terst.nav.vessel + +data class CrewMember( + val id: String, + val name: String, + val role: CrewRole = CrewRole.CREW, + val emergencyContact: String = "", + val emergencyPhone: String = "", + val certifications: List<String> = emptyList(), + val notes: String = "" +) + +enum class CrewRole { + SKIPPER, FIRST_MATE, WATCH_CAPTAIN, CREW, GUEST +} diff --git a/test-runner/src/main/kotlin/org/terst/nav/vessel/Vessel.kt b/test-runner/src/main/kotlin/org/terst/nav/vessel/Vessel.kt new file mode 100644 index 0000000..b7c0eaf --- /dev/null +++ b/test-runner/src/main/kotlin/org/terst/nav/vessel/Vessel.kt @@ -0,0 +1,22 @@ +package org.terst.nav.vessel + +data class Vessel( + val id: String, + val name: String, + val mmsi: String = "", + val callsign: String = "", + val flag: String = "", + val homePort: String = "", + val hullType: HullType = HullType.MONOHULL, + val loaMeters: Double = 0.0, + val beamMeters: Double = 0.0, + val draftMeters: Double = 0.0, + val displacementKg: Double = 0.0, + val engineHp: Int = 0, + val notes: String = "", + val isOwnVessel: Boolean = false +) + +enum class HullType { + MONOHULL, CATAMARAN, TRIMARAN, POWERBOAT, OTHER +} diff --git a/test-runner/src/main/kotlin/org/terst/nav/vessel/VesselRepository.kt b/test-runner/src/main/kotlin/org/terst/nav/vessel/VesselRepository.kt new file mode 100644 index 0000000..fe4c44d --- /dev/null +++ b/test-runner/src/main/kotlin/org/terst/nav/vessel/VesselRepository.kt @@ -0,0 +1,55 @@ +package org.terst.nav.vessel + +import java.util.UUID + +class VesselRepository { + + private val vessels = mutableListOf<Vessel>() + private val crew = mutableListOf<CrewMember>() + + fun addVessel(vessel: Vessel): Vessel { + val v = if (vessel.id.isBlank()) vessel.copy(id = UUID.randomUUID().toString()) else vessel + vessels.removeAll { it.id == v.id } + vessels.add(v) + return v + } + + fun updateVessel(vessel: Vessel): Boolean { + val idx = vessels.indexOfFirst { it.id == vessel.id } + if (idx < 0) return false + vessels[idx] = vessel + return true + } + + fun removeVessel(id: String): Boolean = vessels.removeAll { it.id == id } + + fun getVessel(id: String): Vessel? = vessels.find { it.id == id } + + fun getVessels(): List<Vessel> = vessels.toList() + + fun getOwnVessel(): Vessel? = vessels.find { it.isOwnVessel } + + fun addCrewMember(member: CrewMember): CrewMember { + val m = if (member.id.isBlank()) member.copy(id = UUID.randomUUID().toString()) else member + crew.removeAll { it.id == m.id } + crew.add(m) + return m + } + + fun updateCrewMember(member: CrewMember): Boolean { + val idx = crew.indexOfFirst { it.id == member.id } + if (idx < 0) return false + crew[idx] = member + return true + } + + fun removeCrewMember(id: String): Boolean = crew.removeAll { it.id == id } + + fun getCrewMember(id: String): CrewMember? = crew.find { it.id == id } + + fun getCrew(): List<CrewMember> = crew.toList() + + fun getCrewByRole(role: CrewRole): List<CrewMember> = crew.filter { it.role == role } + + fun getSkipper(): CrewMember? = crew.find { it.role == CrewRole.SKIPPER } +} |
