towerops/lib/towerops/devices/firmware_release.ex
Graham McIntire 004189aaf9
Add firmware tracking database schema
- Create firmware_releases table to store latest available firmware versions
- Create device_firmware_history table to track version changes over time
- Add FirmwareRelease and DeviceFirmwareHistory Ecto schemas with validations
- Add comprehensive tests for both schemas (23 tests, 100% coverage)

firmware_releases stores one record per vendor/product_line with latest version.
device_firmware_history is append-only audit log of device firmware changes.

Part of firmware version tracking system for MikroTik (extensible to other vendors).
2026-02-01 10:13:16 -06:00

64 lines
1.9 KiB
Elixir

defmodule Towerops.Devices.FirmwareRelease do
@moduledoc """
Schema for tracking the latest available firmware releases from vendors.
This table stores the CURRENT LATEST version for each vendor/product_line combination.
Records are updated in place when new versions are detected (not a history table).
The `device_firmware_history` table tracks when individual devices change versions.
"""
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "firmware_releases" do
field :vendor, :string
field :product_line, :string
field :version, :string
field :release_date, :date
field :download_url, :string
field :changelog_url, :string
field :metadata, :map, default: %{}
field :fetched_at, :utc_datetime
timestamps(type: :utc_datetime)
end
@doc """
Changeset for creating or updating a firmware release record.
Required fields:
- `vendor` - Vendor name (e.g., "mikrotik", "cisco", "ubiquiti")
- `version` - Version string (e.g., "7.14.1", "17.9.4a")
- `fetched_at` - When this record was last fetched from the vendor source
Optional fields:
- `product_line` - Product line for multi-product vendors (e.g., "ios-xe", "unifi")
- `release_date` - Official release date from vendor
- `download_url` - Link to download page
- `changelog_url` - Link to release notes
- `metadata` - Additional data from RSS/API (JSON)
"""
def changeset(firmware_release, attrs) do
firmware_release
|> cast(attrs, [
:vendor,
:product_line,
:version,
:release_date,
:download_url,
:changelog_url,
:metadata,
:fetched_at
])
|> validate_required([:vendor, :version, :fetched_at])
|> unique_constraint([:vendor, :product_line],
name: :firmware_releases_vendor_product_line_index,
message: "has already been taken"
)
end
end