do_backup <- function(all_obs_data, transects, raw_track_points) {
  console_log("backup.r", "do_backup() start")
  timestamp <- format(now(), "%Y%m%d%H%M%S")
  if (!dir.exists("backups")) {
    dir.create("backups")
  }
  backup <- all_obs_data %>%
    filter(is.na(delete) | delete == "") %>%
    ungroup() %>%
    bind_rows(raw_track_points) %>%
    mutate(
      Type = if_else(!is.na(Species), "USER", "GPS"),
      `On/OffTx` = ONOFFTX
    )

  # Columns that might or might not exist
  all_columns <- tibble(
    Vessel = as.character(NA),
    PortObs = as.character(NA),
    StarboardObs = as.character(NA),
    PortCondition = as.integer(NA),
    StarboardCondition = as.integer(NA),
    Beaufort = as.integer(NA),
    Weather = as.character(NA),
    CloudCover = as.integer(NA),
    FogConc = as.integer(NA),
    IceType = as.character(NA),
    IceConc = as.integer(NA),
    ObsSideIO = as.character(NA),
    ObsSidePS = as.character(NA),
    SecondaryBehavior = as.character(NA),
    Age = as.character(NA),
    Sex = as.character(NA),
    Plumage = as.character(NA),
    Distance = as.integer(NA),
    Angle = as.integer(NA),
    Bin = as.character(NA),
    UserSelect1 = as.character(NA),
    UserSelect2 = as.character(NA),
    UserText = as.character(NA),
    UserNumeric = as.numeric(NA),
    Comments = as.character(NA),
    bogus = "TRUE"
  )

  backup <- bind_rows(backup, all_columns) |>
    filter(is.na(bogus))

  backup <- backup |>
    left_join(
      transects,
      join_by(Vessel, TripID, Transect)
    ) |>
    mutate(TxWidth = coalesce(TxWidth.y, TxWidth.x)) |>
    select(
      Vessel, TxWidth, TripID, Transect, Record, PortObs, StarboardObs,
      PortCondition, StarboardCondition, Beaufort, Weather, CloudCover,
      FogConc, IceType, IceConc, `On/OffTx`, Type, ObsSideIO, ObsSidePS,
      Species, Count, PrimaryBehavior, SecondaryBehavior, Age, Sex,
      Plumage, Distance, Angle, Bin,
      UserSelect1, UserSelect2, UserText, UserNumeric,
      Latitude, Longitude, Date, Time,
      GPSTime, Comments
    ) |>
    arrange(Date, Time)

  write_csv(backup, glue("backups/raw_data_{timestamp}.csv"), na = "null")

  all_files <- list.files("backups", pattern = "raw_data_2", full.names = TRUE)
  if (length(all_files) > MAX_BACKUP_FILES) {
    to_remove <- all_files[seq(1, length(all_files) - MAX_BACKUP_FILES)]
    file.remove(to_remove)
  }
  console_log("backup.r", "do_backup() end")
}
