ck 2

quietlight
May 11, 2026, 4:02 AM
GE3VNRXLBCRRCW3R5CFGYKCAZE2WCQNTKTUW4BKV5GEN3NZKWXTAC

Dependencies

  • [2] JZRF7OBJ refactor to get db omports out of utils, but still have failing tests, may need updating
  • [3] 2P27XV3D fixed cyclo over 30
  • [4] KZKLAINJ run out of space on nest, cleaned out
  • [5] JAT3DXOL cyclo over 15
  • [6] IFLKNMMP ck 1

Change contents

  • edit in tools/calls_from_preds.go at line 67
    [3.485788][3.485788:486294](),[3.486294][3.19740:19741]()
    // AviaNZMeta is the metadata element in a .data file
    type AviaNZMeta struct {
    Operator string `json:"Operator"`
    Reviewer *string `json:"Reviewer,omitempty"`
    Duration float64 `json:"Duration"`
    }
    // AviaNZLabel represents a species label in a segment
    type AviaNZLabel struct {
    Species string `json:"species"`
    Certainty int `json:"certainty"`
    Filter string `json:"filter"`
    }
    // AviaNZSegment represents a detection segment [start, end, freq_low, freq_high, labels]
    type AviaNZSegment [5]any
  • file addition: avianz_types.go (----------)
    [3.248737]
    package tools
    // AviaNZMeta is the metadata element in a .data file
    type AviaNZMeta struct {
    Operator string `json:"Operator"`
    Reviewer *string `json:"Reviewer,omitempty"`
    Duration float64 `json:"Duration"`
    }
    // AviaNZLabel represents a species label in a segment
    type AviaNZLabel struct {
    Species string `json:"species"`
    Certainty int `json:"certainty"`
    Filter string `json:"filter"`
    }
    // AviaNZSegment represents a detection segment [start, end, freq_low, freq_high, labels]
    type AviaNZSegment [5]any
  • edit in db/types.go at line 10
    [3.790987]
    [3.790987]
    // JSONTime wraps time.Time and marshals as RFC3339 string.
    // Used as an embedded field in marshal-only structs to avoid
    // duplicating MarshalJSON for every DB type that has timestamps.
    type JSONTime time.Time
    // MarshalJSON implements json.Marshaler for JSONTime.
    func (t JSONTime) MarshalJSON() ([]byte, error) {
    return json.Marshal(time.Time(t).Format(time.RFC3339))
    }
    // jt converts a time.Time to JSONTime.
    func jt(t time.Time) JSONTime { return JSONTime(t) }
  • edit in db/types.go at line 46
    [3.791786][3.791786:791819]()
    // Formats timestamps as RFC3339
  • replacement in db/types.go at line 47
    [3.791868][3.791868:791899]()
    return json.Marshal(&struct {
    [3.791868]
    [3.791899]
    return json.Marshal(struct {
  • replacement in db/types.go at line 51
    [3.792027][3.792027:792124]()
    CreatedAt string `json:"created_at"`
    LastModified string `json:"last_modified"`
    [3.792027]
    [3.792124]
    CreatedAt JSONTime `json:"created_at"`
    LastModified JSONTime `json:"last_modified"`
  • replacement in db/types.go at line 59
    [3.792289][3.792289:792392]()
    CreatedAt: d.CreatedAt.Format(time.RFC3339),
    LastModified: d.LastModified.Format(time.RFC3339),
    [3.792289]
    [3.792392]
    CreatedAt: jt(d.CreatedAt),
    LastModified: jt(d.LastModified),
  • edit in db/types.go at line 81
    [3.793026][3.793026:793059]()
    // Formats timestamps as RFC3339
  • replacement in db/types.go at line 82
    [3.793109][3.793109:793554]()
    return json.Marshal(&struct {
    ID string `json:"id"`
    DatasetID string `json:"dataset_id"`
    Name string `json:"name"`
    Latitude float64 `json:"latitude"`
    Longitude float64 `json:"longitude"`
    Description *string `json:"description"`
    CreatedAt string `json:"created_at"`
    LastModified string `json:"last_modified"`
    Active bool `json:"active"`
    TimezoneID string `json:"timezone_id"`
    [3.793109]
    [3.793554]
    return json.Marshal(struct {
    ID string `json:"id"`
    DatasetID string `json:"dataset_id"`
    Name string `json:"name"`
    Latitude float64 `json:"latitude"`
    Longitude float64 `json:"longitude"`
    Description *string `json:"description"`
    CreatedAt JSONTime `json:"created_at"`
    LastModified JSONTime `json:"last_modified"`
    Active bool `json:"active"`
    TimezoneID string `json:"timezone_id"`
  • replacement in db/types.go at line 100
    [3.793721][3.793721:793824]()
    CreatedAt: l.CreatedAt.Format(time.RFC3339),
    LastModified: l.LastModified.Format(time.RFC3339),
    [3.793721]
    [3.793824]
    CreatedAt: jt(l.CreatedAt),
    LastModified: jt(l.LastModified),
  • edit in db/types.go at line 122
    [3.794613][3.794613:794646]()
    // Formats timestamps as RFC3339
  • replacement in db/types.go at line 123
    [3.794695][3.794695:795281]()
    return json.Marshal(&struct {
    ID string `json:"id"`
    DatasetID string `json:"dataset_id"`
    LocationID string `json:"location_id"`
    Name string `json:"name"`
    Description *string `json:"description"`
    CreatedAt string `json:"created_at"`
    LastModified string `json:"last_modified"`
    Active bool `json:"active"`
    CyclicRecordingPatternID *string `json:"cyclic_recording_pattern_id"`
    SampleRate int `json:"sample_rate"`
    [3.794695]
    [3.795281]
    return json.Marshal(struct {
    ID string `json:"id"`
    DatasetID string `json:"dataset_id"`
    LocationID string `json:"location_id"`
    Name string `json:"name"`
    Description *string `json:"description"`
    CreatedAt JSONTime `json:"created_at"`
    LastModified JSONTime `json:"last_modified"`
    Active bool `json:"active"`
    CyclicRecordingPatternID *string `json:"cyclic_recording_pattern_id"`
    SampleRate int `json:"sample_rate"`
  • replacement in db/types.go at line 140
    [3.795481][3.795481:795608]()
    CreatedAt: c.CreatedAt.Format(time.RFC3339),
    LastModified: c.LastModified.Format(time.RFC3339),
    [3.795481]
    [3.795608]
    CreatedAt: jt(c.CreatedAt),
    LastModified: jt(c.LastModified),
  • edit in db/types.go at line 179
    [3.797108][3.797108:797141]()
    // Formats timestamps as RFC3339
  • replacement in db/types.go at line 180
    [3.797205][3.797205:797474]()
    return json.Marshal(&struct {
    ID string `json:"id"`
    RecordS int `json:"record_s"`
    SleepS int `json:"sleep_s"`
    CreatedAt string `json:"created_at"`
    LastModified string `json:"last_modified"`
    Active bool `json:"active"`
    [3.797205]
    [3.797474]
    return json.Marshal(struct {
    ID string `json:"id"`
    RecordS int `json:"record_s"`
    SleepS int `json:"sleep_s"`
    CreatedAt JSONTime `json:"created_at"`
    LastModified JSONTime `json:"last_modified"`
    Active bool `json:"active"`
  • replacement in db/types.go at line 191
    [3.797553][3.797553:797656]()
    CreatedAt: p.CreatedAt.Format(time.RFC3339),
    LastModified: p.LastModified.Format(time.RFC3339),
    [3.797553]
    [3.797656]
    CreatedAt: jt(p.CreatedAt),
    LastModified: jt(p.LastModified),
  • replacement in cmd/pattern.go at line 49
    [3.1055461][3.1055461:1055792]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *record == 0 {
    missing = append(missing, "--record")
    }
    if *sleep == 0 {
    missing = append(missing, "--sleep")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1055461]
    [3.1055792]
    requireFlags(fs, "--db", *dbPath)
    requireNonZeroFlags(fs,
    struct {
    Name string
    Value int
    }{"--record", *record},
    struct {
    Name string
    Value int
    }{"--sleep", *sleep},
    )
  • replacement in cmd/pattern.go at line 104
    [3.1057095][3.1057095:1057359]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *id == "" {
    missing = append(missing, "--id")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1057095]
    [3.1057359]
    requireFlags(fs, "--db", *dbPath, "--id", *id)
  • replacement in cmd/location.go at line 56
    [3.1062610][3.1062610:1063120]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *datasetID == "" {
    missing = append(missing, "--dataset")
    }
    if *name == "" {
    missing = append(missing, "--name")
    }
    if *lat == "" {
    missing = append(missing, "--lat")
    }
    if *lon == "" {
    missing = append(missing, "--lon")
    }
    if *tz == "" {
    missing = append(missing, "--timezone")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1062610]
    [3.1063120]
    requireFlags(fs, "--db", *dbPath, "--dataset", *datasetID, "--name", *name, "--lat", *lat, "--lon", *lon, "--timezone", *tz)
  • replacement in cmd/location.go at line 120
    [3.1064987][3.1064987:1065251]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *id == "" {
    missing = append(missing, "--id")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1064987]
    [3.1065251]
    requireFlags(fs, "--db", *dbPath, "--id", *id)
  • replacement in cmd/import.go at line 90
    [3.1073641][3.1073641:1074039]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *datasetID == "" {
    missing = append(missing, "--dataset")
    }
    if *csvPath == "" {
    missing = append(missing, "--csv")
    }
    if *logPath == "" {
    missing = append(missing, "--log")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1073641]
    [3.1074039]
    requireFlags(fs, "--db", *dbPath, "--dataset", *datasetID, "--csv", *csvPath, "--log", *logPath)
  • replacement in cmd/import.go at line 162
    [3.1076537][3.1076537:1077012]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *datasetID == "" {
    missing = append(missing, "--dataset")
    }
    if *locationID == "" {
    missing = append(missing, "--location")
    }
    if *clusterID == "" {
    missing = append(missing, "--cluster")
    }
    if *filePath == "" {
    missing = append(missing, "--file")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1076537]
    [3.1077012]
    requireFlags(fs, "--db", *dbPath, "--dataset", *datasetID, "--location", *locationID, "--cluster", *clusterID, "--file", *filePath)
  • replacement in cmd/import.go at line 229
    [3.1079292][3.1079292:1079771]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *datasetID == "" {
    missing = append(missing, "--dataset")
    }
    if *locationID == "" {
    missing = append(missing, "--location")
    }
    if *clusterID == "" {
    missing = append(missing, "--cluster")
    }
    if *folderPath == "" {
    missing = append(missing, "--folder")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1079292]
    [3.1079771]
    requireFlags(fs, "--db", *dbPath, "--dataset", *datasetID, "--location", *locationID, "--cluster", *clusterID, "--folder", *folderPath)
  • replacement in cmd/import.go at line 334
    [3.1083926][3.1083926:1084474]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *datasetID == "" {
    missing = append(missing, "--dataset")
    }
    if *locationID == "" {
    missing = append(missing, "--location")
    }
    if *clusterID == "" {
    missing = append(missing, "--cluster")
    }
    if *folderPath == "" {
    missing = append(missing, "--folder")
    }
    if *mappingPath == "" {
    missing = append(missing, "--mapping")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1083926]
    [3.1084474]
    requireFlags(fs, "--db", *dbPath, "--dataset", *datasetID, "--location", *locationID, "--cluster", *clusterID, "--folder", *folderPath, "--mapping", *mappingPath)
  • replacement in cmd/import.go at line 419
    [3.1087767][3.1087767:1088110]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *datasetID == "" {
    missing = append(missing, "--dataset")
    }
    if *folderPath == "" {
    missing = append(missing, "--folder")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1087767]
    [3.1088110]
    requireFlags(fs, "--db", *dbPath, "--dataset", *datasetID, "--folder", *folderPath)
  • replacement in cmd/export.go at line 75
    [3.1091658][3.1091658:1091992]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *datasetID == "" {
    missing = append(missing, "--id")
    }
    if *output == "" {
    missing = append(missing, "--output")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1091658]
    [3.1091992]
    requireFlags(fs, "--db", *dbPath, "--id", *datasetID, "--output", *output)
  • replacement in cmd/dataset.go at line 50
    [3.1094232][3.1094232:1094500]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *name == "" {
    missing = append(missing, "--name")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1094232]
    [3.1094500]
    requireFlags(fs, "--db", *dbPath, "--name", *name)
  • replacement in cmd/dataset.go at line 98
    [3.1095969][3.1095969:1096233]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *id == "" {
    missing = append(missing, "--id")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1095969]
    [3.1096233]
    requireFlags(fs, "--db", *dbPath, "--id", *id)
  • edit in cmd/common.go at line 4
    [3.1098342]
    [3.1098342]
    "flag"
  • edit in cmd/common.go at line 24
    [3.1098810]
    // requireFlags checks that the given flag values are non-empty strings.
    // If any are empty, prints an error and exits with usage.
    // Each pair is (flagName, flagValue) — e.g. requireFlags(fs, "--db", *dbPath, "--id", *id)
    func requireFlags(fs *flag.FlagSet, pairs ...string) {
    var missing []string
    for i := 0; i < len(pairs); i += 2 {
    if pairs[i+1] == "" {
    missing = append(missing, pairs[i])
    }
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    }
    // requireNonZeroFlags checks that the given int flag values are non-zero.
    // Each pair is (flagName, flagValue) — e.g. requireNonZeroFlags(fs, "--record", *record)
    func requireNonZeroFlags(fs *flag.FlagSet, pairs ...struct {
    Name string
    Value int
    }) {
    var missing []string
    for _, p := range pairs {
    if p.Value == 0 {
    missing = append(missing, p.Name)
    }
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    }
  • replacement in cmd/cluster.go at line 55
    [3.1100901][3.1100901:1101377]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *datasetID == "" {
    missing = append(missing, "--dataset")
    }
    if *locationID == "" {
    missing = append(missing, "--location")
    }
    if *name == "" {
    missing = append(missing, "--name")
    }
    if *sampleRate == "" {
    missing = append(missing, "--sample-rate")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1100901]
    [3.1101377]
    requireFlags(fs, "--db", *dbPath, "--dataset", *datasetID, "--location", *locationID, "--name", *name, "--sample-rate", *sampleRate)
  • replacement in cmd/cluster.go at line 111
    [3.1102961][3.1102961:1103225]()
    missing := []string{}
    if *dbPath == "" {
    missing = append(missing, "--db")
    }
    if *id == "" {
    missing = append(missing, "--id")
    }
    if len(missing) > 0 {
    fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
    fs.Usage()
    os.Exit(1)
    }
    [3.1102961]
    [3.1103225]
    requireFlags(fs, "--db", *dbPath, "--id", *id)
  • edit in CHANGELOG.md at line 4
    [3.1198010]
    [2.7567]
    ## [2026-05-11] Validation consolidation, DBPath migration, cmd helpers, type dedup
    ### Validation consolidation (Stream 2)
    Moved duplicated verify/validate functions from `tools/` to `db/validation.go`,
    using the `db.Querier` interface consistently. This eliminates signature drift
    (`*sql.DB` vs `db.Querier` vs anonymous interface) and provides a single source
    of truth for entity-exists-and-active checks.
    **New functions in `db/validation.go`:**
    - `ClusterExistsAndActive(Querier, string)` — cluster exists and is active
    - `PatternExistsAndActive(Querier, string)` — cyclic recording pattern exists and is active
    - `LocationExistsAndActive(Querier, string)` — location exists and is active
    - `ValidateDatasetTypeForExport(Querier, string)` — dataset exists, active, and structured (for export)
    **Removed from `tools/`:**
    - `verifyPatternExists` (cluster.go) → `db.PatternExistsAndActive`
    - `validateClusterActive` (cluster.go) → `db.ClusterExistsAndActive`
    - `validateCyclicPattern` (cluster.go) → `db.PatternExistsAndActive`
    - `verifyDatasetActive` (dataset.go) → `db.DatasetExistsAndActive`
    - `verifyExportDataset` (export.go) → `db.ValidateDatasetTypeForExport`
    - `verifyDatasetExistsAndActive` (location.go) → `db.DatasetExistsAndActive`
    - `verifyLocationExistsAndActive` (location.go) → `db.LocationExistsAndActive`
    - `verifyPatternExistsAndActive` (pattern.go) → `db.PatternExistsAndActive`
    ### DBPath migration (Stream 3a)
    Added `DBPath` field to all Input structs that access the database. The tools
    package now uses `resolveDBPath(input.DBPath)` which prefers the explicit
    field and falls back to the package-level `var dbPath` (set by `SetDBPath`).
    This is an incremental migration — `SetDBPath` still works, but all `cmd/`
    functions now also pass `DBPath: *dbPath` in their Input structs.
  • edit in CHANGELOG.md at line 38
    [2.7568]
    [2.7568]
    **Input structs with new `DBPath` field:**
    `BulkFileImportInput`, `ClusterInput`, `DatasetInput`, `ExecuteSQLInput`,
    `ExportDatasetInput`, `ImportAudioFilesInput`, `ImportFileInput`,
    `ImportSegmentsInput`, `ImportUnstructuredInput`, `LocationInput`,
    `PatternInput`
    **New helper:** `resolveDBPath(inputPath string) string` in `tools/sql.go`
    **Updated sub-functions to accept `dbPath` parameter:**
    - `bulkValidateLocations` now takes `dbPath string` parameter
    - `copyDataToOutput` now takes `sourceDBPath string` parameter
    ### cmd/ boilerplate reduction (Stream 3b)
    Added `requireFlags()` and `requireNonZeroFlags()` helpers in `cmd/common.go`.
    Replaced 16 instances of the `missing := []string{}` + append + error pattern
    across cmd/cluster.go, cmd/dataset.go, cmd/export.go, cmd/import.go,
    cmd/location.go, and cmd/pattern.go.
    ### AviaNZ types extraction (Stream 4a)
    Moved `AviaNZMeta`, `AviaNZLabel`, `AviaNZSegment` type definitions from
    `tools/calls_from_preds.go` to `tools/avianz_types.go`. These types are shared
    by `calls_from_birda.go` and `calls_from_raven.go` and should live in their
    own file.
    ### MarshalJSON dedup (Stream 4b)
    Introduced `JSONTime` type in `db/types.go` that marshals as RFC3339 string.
    Replaced four near-identical `MarshalJSON` implementations (Dataset, Location,
    Cluster, CyclicRecordingPattern) with `JSONTime`-based versions, eliminating
    ~80 lines of boilerplate.