QVIGQOQZIEXLFMMAA7RTL7MQWI4MC3CH22R6YO6J7LGLHWLCSD4AC // ApplyTimezoneOffset applies a fixed timezone offset to timestamps// Uses the EARLIEST (chronologically) timestamp to determine the offset, then applies it to all// This matches AudioMoth behavior (no DST adjustment during deployment)// ApplyTimezoneOffset converts local timestamps to location timezone with DST handling
// ApplyTimezoneOffset converts local timestamps to a location timezone with DST handling.// Uses the EARLIEST (chronologically) timestamp to determine the offset, then applies it to all.// This matches AudioMoth behavior (no DST adjustment during deployment).
// FileImportError records errors encountered during file processingtype FileImportError struct {FileName string `json:"file_name"`Error string `json:"error"`Stage string `json:"stage"` // "scan", "hash", "parse", "validate", "insert"}
// IsAudioMoth checks if the comment or artist field indicates an AudioMoth recording// IsAudioMoth detects if WAV file is from AudioMoth recorder
// IsAudioMoth detects if a WAV file is from an AudioMoth recorder by checking comment and artist fields
// ParseAudioMothComment parses structured AudioMoth comment field// Returns parsed data or error if parsing fails// ParseAudioMothComment extracts timestamp, gain, battery, and temperature from AudioMoth comment
// ParseAudioMothComment extracts timestamp, gain, battery, and temperature from an AudioMoth comment.
Here is a brief report based on a comprehensive review of the utils directory.### 1. Duplicated Functionality- Audio Processing (Float64 to 16-bit PCM): wav_writer.go and audio_player.go contain identical,duplicated logic for converting float64 arrays into int16 LittleEndian bytes (including the [-1.0,1.0] bounds clamping and * 32767 scaling).- Timestamp Resolution Strategy: cluster_import.go (batchProcessFiles) manually reimplements theentire fallback chain for timestamp resolution (AudioMoth → Filename → File Modification Time). Thisexact logic is already neatly abstracted in file_import.go as ResolveTimestamp().- Directory Scanning: cluster_import.go implements its own scanClusterFiles to find .wav files, whiledata_file.go implements FindDataFiles to find .data files. These could be consolidated into ageneric, reusable directory walker.
Overall statement coverage for utils is at 46.5%. The following areas are completely untested (0%coverage):- Files with 0% coverage:- audio_player.go (Audio playback and context management)- config.go (JSON config file loading/parsing)- cluster_import.go (The core batch import logic and database transactions)- spectrogram.go (FFT operations, windowing, and image rendering)- wav_writer.go (WAV encoding logic)- Untested Critical Functions in otherwise tested files:- file_import.go: ProcessSingleFile, CheckDuplicateHash- mapping.go: ValidateMappingAgainstDB, Classify, ValidateCoversSpecies, Classes, Placeholders- validation.go: GetDatasetType, ValidateDatasetTypeForImport, ValidateDatasetTypeUnstructured,ValidateLocationBelongsToDataset