minor refactor and more tests for utils/

quietlight
Apr 30, 2026, 8:42 PM
LBWQJEDHCNUNMEJWXILGBGYZUKQI7CDAMH2BD44HULM77SVH5UYQC

Dependencies

  • [2] LQLC7S3A trying gemini: Inconsistent Standards in @utils/ refactoring
  • [3] KZKLAINJ run out of space on nest, cleaned out

Change contents

  • file addition: wav_writer_test.go (----------)
    [3.1]
    package utils
    import (
    "os"
    "path/filepath"
    "testing"
    )
    func TestWriteWAVFile(t *testing.T) {
    t.Run("writes valid samples", func(t *testing.T) {
    path := filepath.Join(t.TempDir(), "test.wav")
    samples := []float64{0.5, -0.5, 1.5, -1.5} // includes out of bounds for clamping
    err := WriteWAVFile(path, samples, 8000)
    if err != nil {
    t.Fatalf("unexpected error: %v", err)
    }
    info, err := os.Stat(path)
    if err != nil || info.Size() == 0 {
    t.Error("expected file to be written with data")
    }
    })
    t.Run("fails on empty samples", func(t *testing.T) {
    path := filepath.Join(t.TempDir(), "empty.wav")
    err := WriteWAVFile(path, []float64{}, 8000)
    if err == nil {
    t.Error("expected error for empty samples")
    }
    })
    }
  • replacement in utils/wav_writer.go at line 57
    [3.6306][3.6306:6563]()
    buf := make([]byte, dataSize)
    for i, sample := range samples {
    // Clamp to [-1, 1]
    if sample > 1.0 {
    sample = 1.0
    } else if sample < -1.0 {
    sample = -1.0
    }
    binary.LittleEndian.PutUint16(buf[i*2:], uint16(int16(sample*32767)))
    }
    [3.6306]
    [3.6563]
    buf := Float64ToPCM16(samples)
  • file addition: spectrogram_test.go (----------)
    [3.1]
    package utils
    import (
    "testing"
    )
    func TestExtractSegmentSamples(t *testing.T) {
    samples := []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    sampleRate := 2 // 2 samples per sec
    // sec 1.0 to 3.0 => indices 2 to 6 => [2, 3, 4, 5]
    seg := ExtractSegmentSamples(samples, sampleRate, 1.0, 3.0)
    if len(seg) != 4 || seg[0] != 2 || seg[len(seg)-1] != 5 {
    t.Errorf("unexpected segment extraction: %v", seg)
    }
    // out of bounds
    empty := ExtractSegmentSamples(samples, sampleRate, 5.0, 6.0)
    if len(empty) != 0 {
    t.Error("expected empty segment")
    }
    }
    func TestGenerateSpectrogram_Basic(t *testing.T) {
    samples := make([]float64, 1000) // Silent buffer
    cfg := DefaultSpectrogramConfig(16000)
    res := GenerateSpectrogram(samples, cfg)
    if len(res) == 0 {
    t.Error("expected spectrogram generation to succeed")
    }
    shortSamples := []float64{0.0, 0.1}
    resShort := GenerateSpectrogram(shortSamples, cfg)
    if resShort != nil {
    t.Error("expected nil for samples smaller than window size")
    }
    }
    func TestGetCachedHannWindow(t *testing.T) {
    w1 := getCachedHannWindow(256)
    w2 := getCachedHannWindow(256)
    if len(w1) != 256 {
    t.Errorf("expected length 256, got %d", len(w1))
    }
    // Ensure memory address is the same (cached)
    if &w1[0] != &w2[0] {
    t.Error("expected cached slice to have the same memory address")
    }
    }
  • edit in utils/mapping_test.go at line 226
    [3.89513]
    func TestMappingClassify(t *testing.T) {
    m := MappingFile{
    "noise": {Species: MappingNegative},
    "ignore": {Species: MappingIgnore},
    "kiwi": {Species: "Kiwi"},
    }
    c, k, ok := m.Classify("noise")
    if !ok || k != MappingNeg || c != "" {
    t.Error("failed classify negative")
    }
    c, k, ok = m.Classify("ignore")
    if !ok || k != MappingIgn || c != "" {
    t.Error("failed classify ignore")
    }
    c, k, ok = m.Classify("kiwi")
    if !ok || k != MappingReal || c != "Kiwi" {
    t.Error("failed classify real")
    }
    _, _, ok = m.Classify("missing")
    if ok {
    t.Error("expected missing to be not ok")
    }
    }
    func TestMappingValidateCoversSpecies(t *testing.T) {
    m := MappingFile{"kiwi": {Species: "Kiwi"}}
    missing := m.ValidateCoversSpecies(map[string]bool{"kiwi": true, "tui": true})
    if len(missing) != 1 || missing[0] != "tui" {
    t.Errorf("expected [tui], got %v", missing)
    }
    }
    func TestMappingClasses(t *testing.T) {
    m := MappingFile{
    "noise": {Species: MappingNegative},
    "kiwi": {Species: "Kiwi"},
    "tui": {Species: "Tui"},
    "duplicate": {Species: "Kiwi"},
    }
    classes := m.Classes()
    if len(classes) != 2 || classes[0] != "Kiwi" || classes[1] != "Tui" {
    t.Errorf("expected [Kiwi, Tui], got %v", classes)
    }
    }
  • file addition: fs_test.go (----------)
    [3.1]
    package utils
    import (
    "os"
    "path/filepath"
    "testing"
    )
    func TestFindFiles(t *testing.T) {
    dir := t.TempDir()
    // Write dummy files
    os.WriteFile(filepath.Join(dir, "1.wav"), []byte("data"), 0644)
    os.WriteFile(filepath.Join(dir, "2.WAV"), []byte("data"), 0644)
    os.WriteFile(filepath.Join(dir, ".hidden.wav"), []byte("data"), 0644)
    os.WriteFile(filepath.Join(dir, "1.txt"), []byte("data"), 0644)
    subDir := filepath.Join(dir, "sub")
    os.Mkdir(subDir, 0755)
    os.WriteFile(filepath.Join(subDir, "3.wav"), []byte("data"), 0644)
    clipsDir := filepath.Join(dir, "Clips_1")
    os.Mkdir(clipsDir, 0755)
    os.WriteFile(filepath.Join(clipsDir, "4.wav"), []byte("data"), 0644)
    opts := FindFilesOptions{
    Extension: ".wav",
    Recursive: true,
    SkipHidden: true,
    SkipPrefixes: []string{"Clips_"},
    MinSize: 1,
    }
    files, err := FindFiles(dir, opts)
    if err != nil {
    t.Fatal(err)
    }
    if len(files) != 3 { // Should find 1.wav, 2.WAV, sub/3.wav
    t.Errorf("expected 3 files, got %d", len(files))
    }
    }
  • file addition: fs.go (----------)
    [3.1]
    package utils
    import (
    "os"
    "path/filepath"
    "sort"
    "strings"
    )
    // FindFilesOptions configures directory scanning
    type FindFilesOptions struct {
    Extension string // e.g. ".wav" or ".data"
    Recursive bool // whether to walk subdirectories
    SkipPrefixes []string // directory prefixes to skip (e.g. "Clips_")
    SkipHidden bool // skip files/folders starting with "."
    MinSize int64 // minimum file size in bytes
    }
    // FindFiles scans a directory for files matching the given options
    func FindFiles(rootPath string, opts FindFilesOptions) ([]string, error) {
    var results []string
    extTarget := strings.ToLower(opts.Extension)
    if opts.Recursive {
    err := filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {
    if err != nil {
    return err
    }
    name := info.Name()
    // Skip hidden files/directories
    if opts.SkipHidden && strings.HasPrefix(name, ".") && path != rootPath {
    if info.IsDir() {
    return filepath.SkipDir
    }
    return nil
    }
    // Check directory skip prefixes
    if info.IsDir() && path != rootPath {
    for _, prefix := range opts.SkipPrefixes {
    if strings.HasPrefix(name, prefix) {
    return filepath.SkipDir
    }
    }
    return nil
    }
    // Check file
    if !info.IsDir() {
    if strings.ToLower(filepath.Ext(name)) == extTarget && info.Size() >= opts.MinSize {
    results = append(results, path)
    }
    }
    return nil
    })
    if err != nil {
    return nil, err
    }
    } else {
    entries, err := os.ReadDir(rootPath)
    if err != nil {
    return nil, err
    }
    for _, entry := range entries {
    if entry.IsDir() {
    continue
    }
    name := entry.Name()
    if opts.SkipHidden && strings.HasPrefix(name, ".") {
    continue
    }
    if strings.ToLower(filepath.Ext(name)) == extTarget {
    path := filepath.Join(rootPath, name)
    if info, err := os.Stat(path); err == nil && info.Size() >= opts.MinSize {
    results = append(results, path)
    }
    }
    }
    }
    sort.Strings(results)
    return results, nil
    }
  • edit in utils/file_import_test.go at line 4
    [3.130936]
    [3.130936]
    "path/filepath"
  • replacement in utils/file_import_test.go at line 54
    [3.132261][3.132261:132351]()
    result, err := ResolveTimestamp(meta, "20250224_210000.wav", "Pacific/Auckland", false)
    [3.132261]
    [3.132351]
    result, err := ResolveTimestamp(meta, "20250224_210000.wav", "Pacific/Auckland", false, nil)
  • replacement in utils/file_import_test.go at line 76
    [3.132952][3.132952:133042]()
    result, err := ResolveTimestamp(meta, "20250224_210000.wav", "Pacific/Auckland", false)
    [3.132952]
    [3.133042]
    result, err := ResolveTimestamp(meta, "20250224_210000.wav", "Pacific/Auckland", false, nil)
  • replacement in utils/file_import_test.go at line 95
    [3.133491][3.133491:133574]()
    result, err := ResolveTimestamp(meta, "nopattern.wav", "Pacific/Auckland", true)
    [3.133491]
    [3.133574]
    result, err := ResolveTimestamp(meta, "nopattern.wav", "Pacific/Auckland", true, nil)
  • replacement in utils/file_import_test.go at line 109
    [3.133911][3.133911:133990]()
    _, err := ResolveTimestamp(meta, "nopattern.wav", "Pacific/Auckland", false)
    [3.133911]
    [3.133990]
    _, err := ResolveTimestamp(meta, "nopattern.wav", "Pacific/Auckland", false, nil)
  • replacement in utils/file_import_test.go at line 120
    [3.134221][3.134221:134299]()
    _, err := ResolveTimestamp(meta, "nopattern.wav", "Pacific/Auckland", true)
    [3.134221]
    [3.134299]
    _, err := ResolveTimestamp(meta, "nopattern.wav", "Pacific/Auckland", true, nil)
  • replacement in utils/file_import_test.go at line 131
    [3.134554][3.134554:134644]()
    result, err := ResolveTimestamp(meta, "20250224_210000.wav", "Pacific/Auckland", false)
    [3.134554]
    [3.134644]
    result, err := ResolveTimestamp(meta, "20250224_210000.wav", "Pacific/Auckland", false, nil)
  • edit in utils/file_import_test.go at line 145
    [3.135019]
    [3.135019]
    }
    func TestReadWAVSegmentSamples(t *testing.T) {
    tmpPath := filepath.Join(t.TempDir(), "segment_test.wav")
    // Create a simple WAV file with 4 samples
    err := WriteWAVFile(tmpPath, []float64{0.1, 0.2, 0.3, 0.4}, 8000)
    if err != nil {
    t.Fatalf("failed to create temp wav: %v", err)
    }
    // Test 1: Read specific segment (0.25s = 2 samples at 8000Hz)
    // Actually, 1 sample is 1/8000s. Let's just read the whole thing for the test to keep it simple and test the binary chunk reading logic
    samples, rate, err := ReadWAVSegmentSamples(tmpPath, 0, 0)
    if err != nil {
    t.Fatalf("unexpected error: %v", err)
    }
    if rate != 8000 {
    t.Errorf("expected sample rate 8000, got %d", rate)
    }
    if len(samples) != 4 {
    t.Errorf("expected 4 samples, got %d", len(samples))
    }
    // Test 2: Helper ReadWAVSamples wrapper
    samples2, _, err := ReadWAVSamples(tmpPath)
    if err != nil {
    t.Fatalf("unexpected error: %v", err)
    }
    if len(samples2) != 4 {
    t.Errorf("expected 4 samples, got %d", len(samples2))
    }
    }
    func TestProcessSingleFile(t *testing.T) {
    tmpPath := filepath.Join(t.TempDir(), "20240101_120000.wav")
    err := WriteWAVFile(tmpPath, []float64{0.0, 0.0}, 8000)
    if err != nil {
    t.Fatalf("failed to create temp wav: %v", err)
    }
    res, err := ProcessSingleFile(tmpPath, -41.0, 174.0, "Pacific/Auckland", false)
    if err != nil {
    t.Fatalf("unexpected error: %v", err)
    }
    if res.SampleRate != 8000 {
    t.Errorf("expected sample rate 8000, got %d", res.SampleRate)
    }
    if res.Hash == "" {
    t.Error("expected non-empty hash")
    }
  • edit in utils/file_import_test.go at line 198
    [3.135021]
    func TestParseWAVHeaderWithHash(t *testing.T) {
    tmpPath := filepath.Join(t.TempDir(), "hash_test.wav")
    err := WriteWAVFile(tmpPath, []float64{0.0, 0.0}, 8000)
    if err != nil {
    t.Fatalf("failed to create temp wav: %v", err)
    }
    meta, hash, err := ParseWAVHeaderWithHash(tmpPath)
    if err != nil {
    t.Fatalf("unexpected error: %v", err)
    }
    if meta.SampleRate != 8000 {
    t.Errorf("expected 8000, got %d", meta.SampleRate)
    }
    if hash == "" {
    t.Error("expected non-empty hash")
    }
    }
  • replacement in utils/file_import.go at line 23
    [3.135606][3.135606:135735]()
    func ResolveTimestamp(wavMeta *WAVMetadata, filePath string, timezoneID string, useFileModTime bool) (*TimestampResult, error) {
    [3.135606]
    [3.135735]
    func ResolveTimestamp(wavMeta *WAVMetadata, filePath string, timezoneID string, useFileModTime bool, preParsedFilenameTime *time.Time) (*TimestampResult, error) {
  • replacement in utils/file_import.go at line 39
    [3.136163][3.136163:136200]()
    if HasTimestampFilename(filePath) {
    [3.136163]
    [3.136200]
    if preParsedFilenameTime != nil && !preParsedFilenameTime.IsZero() {
    result.Timestamp = *preParsedFilenameTime
    return result, nil
    } else if HasTimestampFilename(filePath) {
  • replacement in utils/file_import.go at line 92
    [3.137835][3.137835:137918]()
    tsResult, err := ResolveTimestamp(metadata, filePath, timezoneID, useFileModTime)
    [3.137835]
    [3.137918]
    tsResult, err := ResolveTimestamp(metadata, filePath, timezoneID, useFileModTime, nil)
  • edit in utils/data_file.go at line 8
    [3.157989][2.5304:5321]()
    "path/filepath"
  • replacement in utils/data_file.go at line 331
    [3.165404][3.165404:165691](),[3.165691][2.5322:5376](),[2.5376][3.165733:165760](),[3.165733][3.165733:165760]()
    var files []string
    entries, err := os.ReadDir(folder)
    if err != nil {
    return nil, err
    }
    for _, entry := range entries {
    name := entry.Name()
    // Skip hidden files (starting with ".")
    if strings.HasPrefix(name, ".") {
    continue
    }
    if strings.HasSuffix(name, ".data") {
    files = append(files, filepath.Join(folder, name))
    }
    }
    return files, nil
    [3.165404]
    [3.165760]
    return FindFiles(folder, FindFilesOptions{
    Extension: ".data",
    Recursive: false,
    SkipHidden: true,
    })
  • file addition: config_test.go (----------)
    [3.1]
    package utils
    import (
    "os"
    "path/filepath"
    "testing"
    )
    func TestLoadConfig(t *testing.T) {
    homeDir := t.TempDir()
    t.Setenv("HOME", homeDir)
    configDir := filepath.Join(homeDir, ".skraak")
    err := os.MkdirAll(configDir, 0755)
    if err != nil {
    t.Fatalf("failed to create config dir: %v", err)
    }
    jsonContent := `{
    "classify": {
    "reviewer": "Test Reviewer",
    "color": true
    }
    }`
    err = os.WriteFile(filepath.Join(configDir, "config.json"), []byte(jsonContent), 0644)
    if err != nil {
    t.Fatalf("failed to write config: %v", err)
    }
    cfg, path, err := LoadConfig()
    if err != nil {
    t.Fatalf("unexpected error: %v", err)
    }
    if cfg.Classify.Reviewer != "Test Reviewer" {
    t.Errorf("expected Test Reviewer, got %s", cfg.Classify.Reviewer)
    }
    if !cfg.Classify.Color {
    t.Error("expected color to be true")
    }
    if path == "" {
    t.Error("expected path to be returned")
    }
    }
  • edit in utils/cluster_import.go at line 9
    [3.171595][3.171595:171614]()
    "sort"
    "strings"
  • replacement in utils/cluster_import.go at line 109
    [3.174589][3.174589:174659]()
    wavFiles, err := scanClusterFiles(input.FolderPath, input.Recursive)
    [3.174589]
    [3.174659]
    wavFiles, err := FindFiles(input.FolderPath, FindFilesOptions{
    Extension: ".wav",
    Recursive: input.Recursive,
    SkipPrefixes: []string{"Clips_"},
    SkipHidden: true, // Standard to ignore hidden
    MinSize: 1, // Must have size > 0
    })
  • edit in utils/cluster_import.go at line 212
    [3.177178][3.177178:178444]()
    }
    // scanClusterFiles recursively scans a folder for WAV files, excluding Clips_* subfolders
    func scanClusterFiles(rootPath string, recursive bool) ([]string, error) {
    var wavFiles []string
    if recursive {
    err := filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {
    if err != nil {
    return err
    }
    // Skip "Clips_*" directories
    if info.IsDir() && strings.HasPrefix(info.Name(), "Clips_") {
    return filepath.SkipDir
    }
    // Check for WAV files
    if !info.IsDir() {
    ext := strings.ToLower(filepath.Ext(path))
    if ext == ".wav" && info.Size() > 0 {
    wavFiles = append(wavFiles, path)
    }
    }
    return nil
    })
    if err != nil {
    return nil, err
    }
    } else {
    // Non-recursive: scan only top level
    entries, err := os.ReadDir(rootPath)
    if err != nil {
    return nil, err
    }
    for _, entry := range entries {
    if !entry.IsDir() {
    name := entry.Name()
    ext := strings.ToLower(filepath.Ext(name))
    if ext == ".wav" {
    path := filepath.Join(rootPath, name)
    if info, err := os.Stat(path); err == nil && info.Size() > 0 {
    wavFiles = append(wavFiles, path)
    }
    }
    }
    }
    }
    // Sort for consistent processing order
    sort.Strings(wavFiles)
    return wavFiles, nil
  • edit in utils/cluster_import.go at line 292
    [3.180873][3.180873:181700]()
    }
    // Determine timestamp
    var timestampLocal time.Time
    var isAudioMoth bool
    var mothData *AudioMothData
    // Try AudioMoth comment first
    if IsAudioMoth(info.metadata.Comment, info.metadata.Artist) {
    isAudioMoth = true
    var parseErr error
    mothData, parseErr = ParseAudioMothComment(info.metadata.Comment)
    if parseErr == nil {
    timestampLocal = mothData.Timestamp
    } else {
    // AudioMoth detected but parsing failed - try filename
    errors = append(errors, FileImportError{
    FileName: filepath.Base(info.path),
    Error: fmt.Sprintf("AudioMoth comment parsing failed: %v", parseErr),
    Stage: "parse",
    })
    }
    }
    // If no AudioMoth timestamp, use filename timestamp
    if timestampLocal.IsZero() {
    if ts, ok := filenameTimestampMap[i]; ok {
    timestampLocal = ts
    }
  • replacement in utils/cluster_import.go at line 294
    [3.181705][3.181705:182012]()
    // If still no timestamp, use file modification time as fallback
    if timestampLocal.IsZero() {
    if !info.metadata.FileModTime.IsZero() {
    // Assume FileModTime is already in location timezone
    // (recorder was at the location when it recorded)
    timestampLocal = info.metadata.FileModTime
    }
    [3.181705]
    [3.182012]
    var preParsedTime *time.Time
    if ts, ok := filenameTimestampMap[i]; ok {
    preParsedTime = &ts
  • replacement in utils/cluster_import.go at line 299
    [3.182017][3.182017:182086]()
    // If still no timestamp, skip file
    if timestampLocal.IsZero() {
    [3.182017]
    [3.182086]
    // Resolve timestamp using common function
    tsResult, err := ResolveTimestamp(info.metadata, info.path, location.TimezoneID, true, preParsedTime)
    if err != nil {
  • replacement in utils/cluster_import.go at line 304
    [3.182170][3.182170:182277]()
    Error: "no timestamp available (not AudioMoth, filename not parseable, and file mod time missing)",
    [3.182170]
    [3.182277]
    Error: err.Error(),
  • replacement in utils/cluster_import.go at line 312
    [3.182398][3.182398:182423]()
    timestampLocal.UTC(),
    [3.182398]
    [3.182423]
    tsResult.Timestamp.UTC(),
  • replacement in utils/cluster_import.go at line 324
    [3.182726][3.182726:182822]()
    TimestampLocal: timestampLocal,
    IsAudioMoth: isAudioMoth,
    MothData: mothData,
    [3.182726]
    [3.182822]
    TimestampLocal: tsResult.Timestamp,
    IsAudioMoth: tsResult.IsAudioMoth,
    MothData: tsResult.MothData,
  • edit in utils/audio_player.go at line 5
    [3.213919][3.213919:213946]()
    "encoding/binary"
    "math"
  • replacement in utils/audio_player.go at line 61
    [3.215513][3.215513:215765]()
    buf := make([]byte, len(samples)*2)
    for i, s := range samples {
    // Clamp to [-1.0, 1.0]
    if s > 1.0 {
    s = 1.0
    } else if s < -1.0 {
    s = -1.0
    }
    v := int16(math.Round(s * 32767.0))
    binary.LittleEndian.PutUint16(buf[i*2:], uint16(v))
    }
    [3.215513]
    [3.215765]
    buf := Float64ToPCM16(samples)
  • file addition: audio_convert_test.go (----------)
    [3.1]
    package utils
    import "testing"
    func TestFloat64ToPCM16(t *testing.T) {
    samples := []float64{0.0, 1.0, -1.0, 1.5, -1.5}
    bytes := Float64ToPCM16(samples)
    if len(bytes) != len(samples)*2 {
    t.Fatalf("expected length %d, got %d", len(samples)*2, len(bytes))
    }
    }
  • file addition: audio_convert.go (----------)
    [3.1]
    package utils
    import "encoding/binary"
    // Float64ToPCM16 converts float64 samples [-1.0, 1.0] to signed 16-bit PCM (LittleEndian) bytes.
    func Float64ToPCM16(samples []float64) []byte {
    buf := make([]byte, len(samples)*2)
    for i, sample := range samples {
    // Clamp to [-1.0, 1.0]
    if sample > 1.0 {
    sample = 1.0
    } else if sample < -1.0 {
    sample = -1.0
    }
    // Convert to 16-bit PCM
    binary.LittleEndian.PutUint16(buf[i*2:], uint16(int16(sample*32767)))
    }
    return buf
    }
  • replacement in tools/isnight.go at line 57
    [3.301119][3.301119:301208]()
    tsResult, err := utils.ResolveTimestamp(metadata, input.FilePath, input.Timezone, true)
    [3.301119]
    [3.301208]
    tsResult, err := utils.ResolveTimestamp(metadata, input.FilePath, input.Timezone, true, nil)
  • edit in me.txt at line 592
    [2.7741][2.7741:7773]()
    ### 3. Inconsistent Standards
  • edit in me.txt at line 593
    [2.7774][2.7774:8939]()
    - Memory Inefficiency in Spectrograms: In spectrogram.go, GenerateSegmentSpectrogram loads the entire
    WAV file into memory using ReadWAVSamples(wavPath) before calling ExtractSegmentSamples. If a user
    requests a 3-second segment from a 500MB continuous recording, the process will unnecessarily
    allocate the whole file.
    - Path Construction: In data_file.go (FindDataFiles), paths are constructed using string
    concatenation (folder+"/"+name) instead of standard library utilities (filepath.Join), which is
    handled correctly elsewhere in the codebase.
    - Separation of Concerns (DB vs Utils): Pure utility files are tightly coupled with the database. For
    example, validation.go mixes pure string/numeric assertions (ValidateShortID) with stateful database
    queries (e.g. ValidateLocationBelongsToDataset). Similarly, mapping.go contains
    ValidateMappingAgainstDB. These queries belong in a db package or should rely on injected interfaces
    rather than hardcoding *sql.DB dependencies into utils/.
    - Misplaced Helpers: The SQL utility function Placeholders(n int) is randomly declared inside
    mapping.go instead of a dedicated database or query utility file.