2026-06-06 23:51:30 -04:00
|
|
|
-- +goose Up
|
|
|
|
|
-- +goose StatementBegin
|
2026-06-05 22:19:38 -04:00
|
|
|
-- Autoscan: connections-based scan-source model. The host pulls changed paths
|
|
|
|
|
-- from installed scan_source.v1 plugins (Sonarr/Radarr, etc.) on a timer,
|
|
|
|
|
-- applies per-source path rewrites, and enqueues targeted library rescans.
|
|
|
|
|
--
|
|
|
|
|
-- Three tables:
|
|
|
|
|
-- * autoscan_settings - singleton global config (enable, poll cadence, debounce)
|
|
|
|
|
-- * autoscan_connections - reachable upstreams: own credentials, OR a live link
|
|
|
|
|
-- to a Requests integration (reused arr server)
|
|
|
|
|
-- * autoscan_sources - operator-created rows, each binding one installed
|
|
|
|
|
-- scan_source capability to a connection + rewrites +
|
|
|
|
|
-- cadence (many sources may share one capability)
|
|
|
|
|
|
|
|
|
|
CREATE TABLE public.autoscan_settings (
|
|
|
|
|
id boolean PRIMARY KEY DEFAULT true,
|
|
|
|
|
enabled boolean NOT NULL DEFAULT false,
|
|
|
|
|
default_poll_interval_seconds integer NOT NULL DEFAULT 600,
|
|
|
|
|
debounce_seconds integer NOT NULL DEFAULT 60,
|
|
|
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
|
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
|
|
|
CONSTRAINT autoscan_settings_singleton CHECK (id),
|
|
|
|
|
CONSTRAINT autoscan_settings_interval_pos CHECK (default_poll_interval_seconds > 0),
|
|
|
|
|
CONSTRAINT autoscan_settings_debounce_nonneg CHECK (debounce_seconds >= 0)
|
|
|
|
|
);
|
|
|
|
|
INSERT INTO public.autoscan_settings (id) VALUES (true) ON CONFLICT (id) DO NOTHING;
|
|
|
|
|
|
|
|
|
|
CREATE TABLE public.autoscan_connections (
|
|
|
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
|
name text NOT NULL,
|
|
|
|
|
kind text NOT NULL,
|
|
|
|
|
base_url text,
|
|
|
|
|
api_key_ref text,
|
|
|
|
|
request_integration_id text REFERENCES public.request_integrations(id) ON DELETE SET NULL,
|
|
|
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
|
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
|
|
|
-- Creation-time validity (own creds OR a link) is enforced at the application
|
|
|
|
|
-- layer. A linked connection may become orphaned (both null) when its Requests
|
|
|
|
|
-- integration is deleted (ON DELETE SET NULL), surfacing as "needs attention".
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CREATE TABLE public.autoscan_sources (
|
|
|
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
|
installation_id integer NOT NULL,
|
|
|
|
|
capability_id text NOT NULL,
|
|
|
|
|
-- Nullable: a freshly-discovered source has no connection until the operator
|
|
|
|
|
-- binds one. The engine skips an enabled source with no connection.
|
|
|
|
|
connection_id uuid REFERENCES public.autoscan_connections(id) ON DELETE RESTRICT,
|
|
|
|
|
enabled boolean NOT NULL DEFAULT false,
|
|
|
|
|
poll_interval_seconds integer,
|
|
|
|
|
-- Host-owned per-source prefix rewrites: [{"from": "...", "to": "..."}].
|
|
|
|
|
-- Applied to the raw source-namespace paths the scan_source plugin returns,
|
|
|
|
|
-- before resolving/enqueueing.
|
|
|
|
|
path_rewrites jsonb NOT NULL DEFAULT '[]'::jsonb,
|
|
|
|
|
marker text,
|
|
|
|
|
last_run_at timestamptz,
|
|
|
|
|
last_error text,
|
|
|
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
|
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
|
|
|
CONSTRAINT autoscan_sources_interval_pos CHECK (poll_interval_seconds IS NULL OR poll_interval_seconds > 0)
|
|
|
|
|
-- No UNIQUE(installation_id, capability_id): one installed scan_source plugin
|
|
|
|
|
-- capability backs MANY sources, each bound to a different connection (e.g. 4
|
|
|
|
|
-- arr servers from one plugin install). Operators create sources explicitly.
|
|
|
|
|
);
|
2026-06-06 23:51:30 -04:00
|
|
|
-- +goose StatementEnd
|
|
|
|
|
|
|
|
|
|
-- +goose Down
|
|
|
|
|
-- +goose StatementBegin
|
|
|
|
|
DROP TABLE IF EXISTS public.autoscan_sources;
|
|
|
|
|
DROP TABLE IF EXISTS public.autoscan_connections;
|
|
|
|
|
DROP TABLE IF EXISTS public.autoscan_settings;
|
|
|
|
|
-- +goose StatementEnd
|