From 892767b75ae9953423fca2856e899a059a1cfcb2 Mon Sep 17 00:00:00 2001 From: Patrick Burns Date: Mon, 11 May 2026 15:11:58 -0500 Subject: [PATCH] chore(db): add migration for missing lotw_credentials.name column MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Existing installs bootstrapped before the canonical baseline are missing lotw_credentials.name. The column is declared NOT NULL in drizzle/schema.ts and the certificate upload route (src/app/api/lotw/ certificate/route.ts) INSERTs into it — so on prod, POST /api/lotw/certificate returns 500 with the underlying error "column 'name' of relation 'lotw_credentials' does not exist". Same root cause as 0002_add_propagation_tables: the install-flow backfill marks 0000_baseline_canonical_schema as already-applied on existing installs without verifying every column exists. A full column-by-column diff between prod and canonical (284 columns each) shows this is now the only remaining gap. Strategy: add the column nullable first, backfill any existing rows from callsign (` - LoTW Certificate`), then SET NOT NULL. The SET NOT NULL is wrapped in a DO block that checks information_schema to make the migration safely idempotent. Tested locally against a postgres container loaded with prod schema, seeded with one pre-existing lotw_credentials row (no name) and with drizzle.__drizzle_migrations populated to simulate the backfill state. Migration runs cleanly; pre-existing row gets the auto-generated name; column ends up NOT NULL; second run is a no-op. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../0003_add_lotw_credentials_name.sql | 30 + drizzle/migrations/meta/0003_snapshot.json | 3609 +++++++++++++++++ drizzle/migrations/meta/_journal.json | 7 + 3 files changed, 3646 insertions(+) create mode 100644 drizzle/migrations/0003_add_lotw_credentials_name.sql create mode 100644 drizzle/migrations/meta/0003_snapshot.json diff --git a/drizzle/migrations/0003_add_lotw_credentials_name.sql b/drizzle/migrations/0003_add_lotw_credentials_name.sql new file mode 100644 index 0000000..015a850 --- /dev/null +++ b/drizzle/migrations/0003_add_lotw_credentials_name.sql @@ -0,0 +1,30 @@ +-- Adds the lotw_credentials.name column that exists in drizzle/schema.ts +-- (declared NOT NULL) but is missing from installs that were bootstrapped +-- before the canonical baseline. Same root cause as 0002: the install-flow +-- backfill marked 0000_baseline_canonical_schema as already-applied without +-- verifying every column existed. +-- +-- Symptom: POST /api/lotw/certificate returns 500 because the INSERT names +-- a `name` column that doesn't exist. +-- +-- Strategy: add the column as nullable, backfill any existing rows from +-- callsign, then SET NOT NULL. Idempotent — re-running is a no-op. + +ALTER TABLE "lotw_credentials" ADD COLUMN IF NOT EXISTS "name" varchar(255); +--> statement-breakpoint +UPDATE "lotw_credentials" +SET "name" = CONCAT(callsign, ' - LoTW Certificate') +WHERE "name" IS NULL; +--> statement-breakpoint +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'lotw_credentials' + AND column_name = 'name' + AND is_nullable = 'YES' + ) THEN + ALTER TABLE "lotw_credentials" ALTER COLUMN "name" SET NOT NULL; + END IF; +END $$; diff --git a/drizzle/migrations/meta/0003_snapshot.json b/drizzle/migrations/meta/0003_snapshot.json new file mode 100644 index 0000000..54872fd --- /dev/null +++ b/drizzle/migrations/meta/0003_snapshot.json @@ -0,0 +1,3609 @@ +{ + "id": "773468de-aa5e-412c-8469-6d2d9a3f8a5f", + "prevId": "a02a3fcb-23b3-42f6-a4fc-aed85a6b664d", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.admin_audit_log": { + "name": "admin_audit_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "admin_user_id": { + "name": "admin_user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "target_id": { + "name": "target_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "old_values": { + "name": "old_values", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "new_values": { + "name": "new_values", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "inet", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_audit_log_action": { + "name": "idx_audit_log_action", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_audit_log_admin_user": { + "name": "idx_audit_log_admin_user", + "columns": [ + { + "expression": "admin_user_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_audit_log_created_at": { + "name": "idx_audit_log_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "first", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_audit_log_target": { + "name": "idx_audit_log_target", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "admin_audit_log_admin_user_id_fkey": { + "name": "admin_audit_log_admin_user_id_fkey", + "tableFrom": "admin_audit_log", + "tableTo": "users", + "columnsFrom": [ + "admin_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.api_keys": { + "name": "api_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "station_id": { + "name": "station_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "key_name": { + "name": "key_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "api_key": { + "name": "api_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "key_hash": { + "name": "key_hash", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{\"read\":true,\"write\":false,\"delete\":false}'::jsonb" + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "read_only": { + "name": "read_only", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "usage_count": { + "name": "usage_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "total_requests": { + "name": "total_requests", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "rate_limit_per_hour": { + "name": "rate_limit_per_hour", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 1000 + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_api_keys_api_key": { + "name": "idx_api_keys_api_key", + "columns": [ + { + "expression": "api_key", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_api_keys_expires_at": { + "name": "idx_api_keys_expires_at", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_api_keys_is_active": { + "name": "idx_api_keys_is_active", + "columns": [ + { + "expression": "is_active", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "bool_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_api_keys_last_used_at": { + "name": "idx_api_keys_last_used_at", + "columns": [ + { + "expression": "last_used_at", + "isExpression": false, + "asc": false, + "nulls": "first", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_api_keys_station_id": { + "name": "idx_api_keys_station_id", + "columns": [ + { + "expression": "station_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_api_keys_user_id": { + "name": "idx_api_keys_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "api_keys_station_id_fkey": { + "name": "api_keys_station_id_fkey", + "tableFrom": "api_keys", + "tableTo": "stations", + "columnsFrom": [ + "station_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "api_keys_user_id_fkey": { + "name": "api_keys_user_id_fkey", + "tableFrom": "api_keys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "api_keys_api_key_key": { + "name": "api_keys_api_key_key", + "nullsNotDistinct": false, + "columns": [ + "api_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contacts": { + "name": "contacts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "station_id": { + "name": "station_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "callsign": { + "name": "callsign", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "frequency": { + "name": "frequency", + "type": "numeric(10, 6)", + "primaryKey": false, + "notNull": false + }, + "mode": { + "name": "mode", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "band": { + "name": "band", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "datetime": { + "name": "datetime", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "rst_sent": { + "name": "rst_sent", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "rst_received": { + "name": "rst_received", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "qth": { + "name": "qth", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "grid_locator": { + "name": "grid_locator", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "latitude": { + "name": "latitude", + "type": "numeric(10, 8)", + "primaryKey": false, + "notNull": false + }, + "longitude": { + "name": "longitude", + "type": "numeric(11, 8)", + "primaryKey": false, + "notNull": false + }, + "country": { + "name": "country", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "dxcc": { + "name": "dxcc", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cont": { + "name": "cont", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "cqz": { + "name": "cqz", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "ituz": { + "name": "ituz", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "cnty": { + "name": "cnty", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "qsl_rcvd": { + "name": "qsl_rcvd", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "qsl_sent": { + "name": "qsl_sent", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "qsl_via": { + "name": "qsl_via", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "eqsl_qsl_rcvd": { + "name": "eqsl_qsl_rcvd", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "eqsl_qsl_sent": { + "name": "eqsl_qsl_sent", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "lotw_qsl_rcvd": { + "name": "lotw_qsl_rcvd", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "lotw_qsl_sent": { + "name": "lotw_qsl_sent", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "qrz_qsl_sent": { + "name": "qrz_qsl_sent", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "qrz_qsl_rcvd": { + "name": "qrz_qsl_rcvd", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "qrz_qsl_sent_date": { + "name": "qrz_qsl_sent_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "qrz_qsl_rcvd_date": { + "name": "qrz_qsl_rcvd_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "qso_date_off": { + "name": "qso_date_off", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "time_off": { + "name": "time_off", + "type": "time", + "primaryKey": false, + "notNull": false + }, + "operator": { + "name": "operator", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "distance": { + "name": "distance", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "qsl_lotw": { + "name": "qsl_lotw", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "qsl_lotw_date": { + "name": "qsl_lotw_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "lotw_match_status": { + "name": "lotw_match_status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "prop_mode": { + "name": "prop_mode", + "type": "varchar(16)", + "primaryKey": false, + "notNull": false + }, + "sat_name": { + "name": "sat_name", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "band_rx": { + "name": "band_rx", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "freq_rx": { + "name": "freq_rx", + "type": "numeric(10, 6)", + "primaryKey": false, + "notNull": false + }, + "iota": { + "name": "iota", + "type": "varchar(16)", + "primaryKey": false, + "notNull": false + }, + "lotw_qslrdate": { + "name": "lotw_qslrdate", + "type": "date", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_contacts_band": { + "name": "idx_contacts_band", + "columns": [ + { + "expression": "band", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_callsign": { + "name": "idx_contacts_callsign", + "columns": [ + { + "expression": "callsign", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_datetime": { + "name": "idx_contacts_datetime", + "columns": [ + { + "expression": "datetime", + "isExpression": false, + "asc": false, + "nulls": "first", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_frequency": { + "name": "idx_contacts_frequency", + "columns": [ + { + "expression": "frequency", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "numeric_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_lotw_match_status": { + "name": "idx_contacts_lotw_match_status", + "columns": [ + { + "expression": "lotw_match_status", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_mode": { + "name": "idx_contacts_mode", + "columns": [ + { + "expression": "mode", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_prop_mode": { + "name": "idx_contacts_prop_mode", + "columns": [ + { + "expression": "prop_mode", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_qrz_qsl_rcvd": { + "name": "idx_contacts_qrz_qsl_rcvd", + "columns": [ + { + "expression": "qrz_qsl_rcvd", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_qrz_qsl_sent": { + "name": "idx_contacts_qrz_qsl_sent", + "columns": [ + { + "expression": "qrz_qsl_sent", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_qsl_lotw": { + "name": "idx_contacts_qsl_lotw", + "columns": [ + { + "expression": "qsl_lotw", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "bool_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_qsl_lotw_date": { + "name": "idx_contacts_qsl_lotw_date", + "columns": [ + { + "expression": "qsl_lotw_date", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "date_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_sat_name": { + "name": "idx_contacts_sat_name", + "columns": [ + { + "expression": "sat_name", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_station_id": { + "name": "idx_contacts_station_id", + "columns": [ + { + "expression": "station_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_contacts_user_id": { + "name": "idx_contacts_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "contacts_user_id_fkey": { + "name": "contacts_user_id_fkey", + "tableFrom": "contacts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "contacts_station_id_fkey": { + "name": "contacts_station_id_fkey", + "tableFrom": "contacts", + "tableTo": "stations", + "columnsFrom": [ + "station_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "contacts_lotw_match_status_check": { + "name": "contacts_lotw_match_status_check", + "value": "(lotw_match_status)::text = ANY ((ARRAY['confirmed'::character varying, 'partial'::character varying, 'mismatch'::character varying, NULL::character varying])::text[])" + }, + "contacts_qrz_qsl_sent_check": { + "name": "contacts_qrz_qsl_sent_check", + "value": "(qrz_qsl_sent IS NULL) OR ((qrz_qsl_sent)::text = ANY ((ARRAY['Y'::character varying, 'N'::character varying, 'R'::character varying, 'M'::character varying, 'I'::character varying, 'Q'::character varying])::text[]))" + }, + "contacts_lotw_qsl_sent_check": { + "name": "contacts_lotw_qsl_sent_check", + "value": "(lotw_qsl_sent IS NULL) OR ((lotw_qsl_sent)::text = ANY ((ARRAY['Y'::character varying, 'N'::character varying, 'R'::character varying, 'M'::character varying, 'I'::character varying, 'Q'::character varying])::text[]))" + } + }, + "isRLSEnabled": false + }, + "public.dxcc_entities": { + "name": "dxcc_entities", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "adif": { + "name": "adif", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cq_zone": { + "name": "cq_zone", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "itu_zone": { + "name": "itu_zone", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "continent": { + "name": "continent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "longitude": { + "name": "longitude", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "latitude": { + "name": "latitude", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "dxcc_entities_adif_key": { + "name": "dxcc_entities_adif_key", + "nullsNotDistinct": false, + "columns": [ + "adif" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.lotw_credentials": { + "name": "lotw_credentials", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "station_id": { + "name": "station_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "callsign": { + "name": "callsign", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "p12_cert": { + "name": "p12_cert", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "cert_created_at": { + "name": "cert_created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "cert_expires_at": { + "name": "cert_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "p12_password": { + "name": "p12_password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cert_serial": { + "name": "cert_serial", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "crl_status": { + "name": "crl_status", + "type": "varchar(16)", + "primaryKey": false, + "notNull": false + }, + "crl_checked_at": { + "name": "crl_checked_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_lotw_credentials_callsign": { + "name": "idx_lotw_credentials_callsign", + "columns": [ + { + "expression": "callsign", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_credentials_cert_serial": { + "name": "idx_lotw_credentials_cert_serial", + "columns": [ + { + "expression": "cert_serial", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_credentials_is_active": { + "name": "idx_lotw_credentials_is_active", + "columns": [ + { + "expression": "is_active", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "bool_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_credentials_station_active": { + "name": "idx_lotw_credentials_station_active", + "columns": [ + { + "expression": "station_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + }, + { + "expression": "is_active", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "bool_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_credentials_station_id": { + "name": "idx_lotw_credentials_station_id", + "columns": [ + { + "expression": "station_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "lotw_credentials_station_id_fkey": { + "name": "lotw_credentials_station_id_fkey", + "tableFrom": "lotw_credentials", + "tableTo": "stations", + "columnsFrom": [ + "station_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.lotw_download_logs": { + "name": "lotw_download_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "station_id": { + "name": "station_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "date_from": { + "name": "date_from", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "date_to": { + "name": "date_to", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "qso_count": { + "name": "qso_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "confirmations_found": { + "name": "confirmations_found", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "confirmations_matched": { + "name": "confirmations_matched", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "confirmations_unmatched": { + "name": "confirmations_unmatched", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "download_method": { + "name": "download_method", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": "'manual'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_lotw_download_logs_started_at": { + "name": "idx_lotw_download_logs_started_at", + "columns": [ + { + "expression": "started_at", + "isExpression": false, + "asc": false, + "nulls": "first", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_download_logs_station_id": { + "name": "idx_lotw_download_logs_station_id", + "columns": [ + { + "expression": "station_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_download_logs_status": { + "name": "idx_lotw_download_logs_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_download_logs_user_id": { + "name": "idx_lotw_download_logs_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "lotw_download_logs_station_id_fkey": { + "name": "lotw_download_logs_station_id_fkey", + "tableFrom": "lotw_download_logs", + "tableTo": "stations", + "columnsFrom": [ + "station_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "lotw_download_logs_user_id_fkey": { + "name": "lotw_download_logs_user_id_fkey", + "tableFrom": "lotw_download_logs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "lotw_download_logs_status_check": { + "name": "lotw_download_logs_status_check", + "value": "(status)::text = ANY ((ARRAY['pending'::character varying, 'processing'::character varying, 'completed'::character varying, 'failed'::character varying])::text[])" + }, + "lotw_download_logs_download_method_check": { + "name": "lotw_download_logs_download_method_check", + "value": "(download_method)::text = ANY ((ARRAY['manual'::character varying, 'automatic'::character varying, 'scheduled'::character varying])::text[])" + } + }, + "isRLSEnabled": false + }, + "public.lotw_job_queue": { + "name": "lotw_job_queue", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "job_type": { + "name": "job_type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "station_id": { + "name": "station_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "job_params": { + "name": "job_params", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "is_running": { + "name": "is_running", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "started_at": { + "name": "started_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 3 + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "result": { + "name": "result", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "priority": { + "name": "priority", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 5 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_lotw_job_queue_is_running": { + "name": "idx_lotw_job_queue_is_running", + "columns": [ + { + "expression": "is_running", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "bool_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_job_queue_job_type": { + "name": "idx_lotw_job_queue_job_type", + "columns": [ + { + "expression": "job_type", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_job_queue_priority": { + "name": "idx_lotw_job_queue_priority", + "columns": [ + { + "expression": "priority", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_job_queue_scheduled_at": { + "name": "idx_lotw_job_queue_scheduled_at", + "columns": [ + { + "expression": "scheduled_at", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_job_queue_station_id": { + "name": "idx_lotw_job_queue_station_id", + "columns": [ + { + "expression": "station_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_job_queue_status": { + "name": "idx_lotw_job_queue_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "lotw_job_queue_station_id_fkey": { + "name": "lotw_job_queue_station_id_fkey", + "tableFrom": "lotw_job_queue", + "tableTo": "stations", + "columnsFrom": [ + "station_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "lotw_job_queue_user_id_fkey": { + "name": "lotw_job_queue_user_id_fkey", + "tableFrom": "lotw_job_queue", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "lotw_job_queue_job_type_check": { + "name": "lotw_job_queue_job_type_check", + "value": "(job_type)::text = ANY ((ARRAY['upload'::character varying, 'download'::character varying])::text[])" + }, + "lotw_job_queue_status_check": { + "name": "lotw_job_queue_status_check", + "value": "(status)::text = ANY ((ARRAY['pending'::character varying, 'processing'::character varying, 'completed'::character varying, 'failed'::character varying, 'cancelled'::character varying])::text[])" + } + }, + "isRLSEnabled": false + }, + "public.lotw_upload_logs": { + "name": "lotw_upload_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "station_id": { + "name": "station_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "qso_count": { + "name": "qso_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "date_from": { + "name": "date_from", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "date_to": { + "name": "date_to", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "file_hash": { + "name": "file_hash", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "file_size_bytes": { + "name": "file_size_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "started_at": { + "name": "started_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "success_count": { + "name": "success_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "error_count": { + "name": "error_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "lotw_response": { + "name": "lotw_response", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "upload_method": { + "name": "upload_method", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": "'manual'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_lotw_upload_logs_started_at": { + "name": "idx_lotw_upload_logs_started_at", + "columns": [ + { + "expression": "started_at", + "isExpression": false, + "asc": false, + "nulls": "first", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_upload_logs_station_id": { + "name": "idx_lotw_upload_logs_station_id", + "columns": [ + { + "expression": "station_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_upload_logs_status": { + "name": "idx_lotw_upload_logs_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_lotw_upload_logs_user_id": { + "name": "idx_lotw_upload_logs_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "lotw_upload_logs_station_id_fkey": { + "name": "lotw_upload_logs_station_id_fkey", + "tableFrom": "lotw_upload_logs", + "tableTo": "stations", + "columnsFrom": [ + "station_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "lotw_upload_logs_user_id_fkey": { + "name": "lotw_upload_logs_user_id_fkey", + "tableFrom": "lotw_upload_logs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "lotw_upload_logs_status_check": { + "name": "lotw_upload_logs_status_check", + "value": "(status)::text = ANY ((ARRAY['pending'::character varying, 'processing'::character varying, 'completed'::character varying, 'failed'::character varying])::text[])" + }, + "lotw_upload_logs_upload_method_check": { + "name": "lotw_upload_logs_upload_method_check", + "value": "(upload_method)::text = ANY ((ARRAY['manual'::character varying, 'automatic'::character varying, 'scheduled'::character varying])::text[])" + } + }, + "isRLSEnabled": false + }, + "public.propagation_alerts": { + "name": "propagation_alerts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "alert_type": { + "name": "alert_type", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true + }, + "severity": { + "name": "severity", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_propagation_alerts_active": { + "name": "idx_propagation_alerts_active", + "columns": [ + { + "expression": "is_active", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "bool_ops" + } + ], + "isUnique": false, + "where": "(is_active = true)", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_propagation_alerts_expires": { + "name": "idx_propagation_alerts_expires", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "where": "(expires_at IS NOT NULL)", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_propagation_alerts_user_id": { + "name": "idx_propagation_alerts_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "propagation_alerts_user_id_fkey": { + "name": "propagation_alerts_user_id_fkey", + "tableFrom": "propagation_alerts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "propagation_alerts_alert_type_check": { + "name": "propagation_alerts_alert_type_check", + "value": "(alert_type)::text = ANY ((ARRAY['solar_storm'::character varying, 'enhanced_propagation'::character varying, 'band_opening'::character varying, 'aurora'::character varying])::text[])" + }, + "propagation_alerts_severity_check": { + "name": "propagation_alerts_severity_check", + "value": "(severity)::text = ANY ((ARRAY['low'::character varying, 'medium'::character varying, 'high'::character varying])::text[])" + }, + "valid_alert_type": { + "name": "valid_alert_type", + "value": "(alert_type)::text = ANY ((ARRAY['solar_storm'::character varying, 'enhanced_propagation'::character varying, 'band_opening'::character varying, 'aurora'::character varying])::text[])" + }, + "valid_severity": { + "name": "valid_severity", + "value": "(severity)::text = ANY ((ARRAY['low'::character varying, 'medium'::character varying, 'high'::character varying])::text[])" + } + }, + "isRLSEnabled": false + }, + "public.propagation_forecasts": { + "name": "propagation_forecasts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "forecast_for": { + "name": "forecast_for", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "band_conditions": { + "name": "band_conditions", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "general_conditions": { + "name": "general_conditions", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_propagation_forecasts_forecast_for": { + "name": "idx_propagation_forecasts_forecast_for", + "columns": [ + { + "expression": "forecast_for", + "isExpression": false, + "asc": false, + "nulls": "first", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_propagation_forecasts_timestamp": { + "name": "idx_propagation_forecasts_timestamp", + "columns": [ + { + "expression": "timestamp", + "isExpression": false, + "asc": false, + "nulls": "first", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "propagation_forecasts_general_conditions_check": { + "name": "propagation_forecasts_general_conditions_check", + "value": "(general_conditions)::text = ANY ((ARRAY['poor'::character varying, 'fair'::character varying, 'good'::character varying, 'excellent'::character varying])::text[])" + }, + "valid_general_conditions": { + "name": "valid_general_conditions", + "value": "(general_conditions)::text = ANY ((ARRAY['poor'::character varying, 'fair'::character varying, 'good'::character varying, 'excellent'::character varying])::text[])" + } + }, + "isRLSEnabled": false + }, + "public.qsl_images": { + "name": "qsl_images", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "contact_id": { + "name": "contact_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "image_type": { + "name": "image_type", + "type": "varchar(10)", + "primaryKey": false, + "notNull": true + }, + "filename": { + "name": "filename", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "original_filename": { + "name": "original_filename", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "file_size": { + "name": "file_size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "mime_type": { + "name": "mime_type", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "storage_path": { + "name": "storage_path", + "type": "varchar(500)", + "primaryKey": false, + "notNull": true + }, + "storage_url": { + "name": "storage_url", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "storage_type": { + "name": "storage_type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": "'azure_blob'" + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_qsl_images_contact_id": { + "name": "idx_qsl_images_contact_id", + "columns": [ + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_qsl_images_created_at": { + "name": "idx_qsl_images_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "first", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_qsl_images_type": { + "name": "idx_qsl_images_type", + "columns": [ + { + "expression": "image_type", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_qsl_images_user_id": { + "name": "idx_qsl_images_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "qsl_images_contact_id_fkey": { + "name": "qsl_images_contact_id_fkey", + "tableFrom": "qsl_images", + "tableTo": "contacts", + "columnsFrom": [ + "contact_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "qsl_images_user_id_fkey": { + "name": "qsl_images_user_id_fkey", + "tableFrom": "qsl_images", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "qsl_images_contact_id_image_type_key": { + "name": "qsl_images_contact_id_image_type_key", + "nullsNotDistinct": false, + "columns": [ + "contact_id", + "image_type" + ] + } + }, + "policies": {}, + "checkConstraints": { + "qsl_images_image_type_check": { + "name": "qsl_images_image_type_check", + "value": "(image_type)::text = ANY ((ARRAY['front'::character varying, 'back'::character varying])::text[])" + }, + "qsl_images_mime_type_check": { + "name": "qsl_images_mime_type_check", + "value": "(mime_type)::text = ANY ((ARRAY['image/jpeg'::character varying, 'image/jpg'::character varying, 'image/png'::character varying, 'image/webp'::character varying])::text[])" + }, + "qsl_images_storage_type_check": { + "name": "qsl_images_storage_type_check", + "value": "(storage_type)::text = ANY ((ARRAY['azure_blob'::character varying, 'aws_s3'::character varying, 'local_storage'::character varying])::text[])" + } + }, + "isRLSEnabled": false + }, + "public.solar_activity": { + "name": "solar_activity", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "solar_flux_index": { + "name": "solar_flux_index", + "type": "numeric(6, 2)", + "primaryKey": false, + "notNull": true + }, + "a_index": { + "name": "a_index", + "type": "numeric(5, 2)", + "primaryKey": false, + "notNull": true + }, + "k_index": { + "name": "k_index", + "type": "numeric(3, 1)", + "primaryKey": false, + "notNull": true + }, + "solar_wind_speed": { + "name": "solar_wind_speed", + "type": "numeric(7, 2)", + "primaryKey": false, + "notNull": false + }, + "solar_wind_density": { + "name": "solar_wind_density", + "type": "numeric(6, 3)", + "primaryKey": false, + "notNull": false + }, + "xray_class": { + "name": "xray_class", + "type": "varchar(5)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "idx_solar_activity_timestamp": { + "name": "idx_solar_activity_timestamp", + "columns": [ + { + "expression": "timestamp", + "isExpression": false, + "asc": false, + "nulls": "first", + "opclass": "timestamp_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "solar_activity_timestamp_key": { + "name": "solar_activity_timestamp_key", + "nullsNotDistinct": false, + "columns": [ + "timestamp" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.states_provinces": { + "name": "states_provinces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "dxcc_entity": { + "name": "dxcc_entity", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cq_zone": { + "name": "cq_zone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "itu_zone": { + "name": "itu_zone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "states_provinces_dxcc_entity_code_key": { + "name": "states_provinces_dxcc_entity_code_key", + "nullsNotDistinct": false, + "columns": [ + "dxcc_entity", + "code" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.stations": { + "name": "stations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "callsign": { + "name": "callsign", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "station_name": { + "name": "station_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "operator_name": { + "name": "operator_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "qth_name": { + "name": "qth_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "street_address": { + "name": "street_address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "city": { + "name": "city", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "county": { + "name": "county", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "state_province": { + "name": "state_province", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false + }, + "country": { + "name": "country", + "type": "varchar(100)", + "primaryKey": false, + "notNull": false + }, + "dxcc_entity_code": { + "name": "dxcc_entity_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "grid_locator": { + "name": "grid_locator", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "latitude": { + "name": "latitude", + "type": "numeric(10, 8)", + "primaryKey": false, + "notNull": false + }, + "longitude": { + "name": "longitude", + "type": "numeric(11, 8)", + "primaryKey": false, + "notNull": false + }, + "itu_zone": { + "name": "itu_zone", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cq_zone": { + "name": "cq_zone", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "power_watts": { + "name": "power_watts", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rig_info": { + "name": "rig_info", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "antenna_info": { + "name": "antenna_info", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "station_equipment": { + "name": "station_equipment", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "qrz_username": { + "name": "qrz_username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "qrz_password": { + "name": "qrz_password", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "qrz_api_key": { + "name": "qrz_api_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "qrz_auto_sync": { + "name": "qrz_auto_sync", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "lotw_username": { + "name": "lotw_username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "club_callsign": { + "name": "club_callsign", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "lotw_password": { + "name": "lotw_password", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "lotw_p12_cert": { + "name": "lotw_p12_cert", + "type": "bytea", + "primaryKey": false, + "notNull": false + }, + "lotw_cert_created_at": { + "name": "lotw_cert_created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "lotw_last_qsl_rcvd_date": { + "name": "lotw_last_qsl_rcvd_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "qrz_last_qsl_rcvd_date": { + "name": "qrz_last_qsl_rcvd_date", + "type": "date", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_stations_callsign": { + "name": "idx_stations_callsign", + "columns": [ + { + "expression": "callsign", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_stations_country": { + "name": "idx_stations_country", + "columns": [ + { + "expression": "country", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_stations_dxcc_entity": { + "name": "idx_stations_dxcc_entity", + "columns": [ + { + "expression": "dxcc_entity_code", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_stations_grid_locator": { + "name": "idx_stations_grid_locator", + "columns": [ + { + "expression": "grid_locator", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_stations_is_active": { + "name": "idx_stations_is_active", + "columns": [ + { + "expression": "is_active", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "bool_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_stations_is_default": { + "name": "idx_stations_is_default", + "columns": [ + { + "expression": "is_default", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "bool_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_stations_user_id": { + "name": "idx_stations_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "int4_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "stations_user_id_fkey": { + "name": "stations_user_id_fkey", + "tableFrom": "stations", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_default_station_per_user": { + "name": "unique_default_station_per_user", + "nullsNotDistinct": false, + "columns": [ + "user_id", + "is_default" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.storage_config": { + "name": "storage_config", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "config_type": { + "name": "config_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "account_name": { + "name": "account_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "account_key": { + "name": "account_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "container_name": { + "name": "container_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "endpoint_url": { + "name": "endpoint_url", + "type": "varchar(500)", + "primaryKey": false, + "notNull": false + }, + "is_enabled": { + "name": "is_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "created_by": { + "name": "created_by", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_storage_config_enabled": { + "name": "idx_storage_config_enabled", + "columns": [ + { + "expression": "is_enabled", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "bool_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_storage_config_type": { + "name": "idx_storage_config_type", + "columns": [ + { + "expression": "config_type", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "storage_config_created_by_fkey": { + "name": "storage_config_created_by_fkey", + "tableFrom": "storage_config", + "tableTo": "users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "storage_config_config_type_key": { + "name": "storage_config_config_type_key", + "nullsNotDistinct": false, + "columns": [ + "config_type" + ] + } + }, + "policies": {}, + "checkConstraints": { + "valid_config_type": { + "name": "valid_config_type", + "value": "(config_type)::text = ANY ((ARRAY['azure_blob'::character varying, 'aws_s3'::character varying, 'local_storage'::character varying])::text[])" + } + }, + "isRLSEnabled": false + }, + "public.system_settings": { + "name": "system_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "setting_key": { + "name": "setting_key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "setting_value": { + "name": "setting_value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "data_type": { + "name": "data_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'string'" + }, + "category": { + "name": "category", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true, + "default": "'general'" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_public": { + "name": "is_public", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_by": { + "name": "updated_by", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_system_settings_category": { + "name": "idx_system_settings_category", + "columns": [ + { + "expression": "category", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_system_settings_key": { + "name": "idx_system_settings_key", + "columns": [ + { + "expression": "setting_key", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_system_settings_public": { + "name": "idx_system_settings_public", + "columns": [ + { + "expression": "is_public", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "bool_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "system_settings_updated_by_fkey": { + "name": "system_settings_updated_by_fkey", + "tableFrom": "system_settings", + "tableTo": "users", + "columnsFrom": [ + "updated_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "system_settings_setting_key_key": { + "name": "system_settings_setting_key_key", + "nullsNotDistinct": false, + "columns": [ + "setting_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_propagation_preferences": { + "name": "user_propagation_preferences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "home_grid_locator": { + "name": "home_grid_locator", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "preferred_bands": { + "name": "preferred_bands", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "alert_solar_storms": { + "name": "alert_solar_storms", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "alert_enhanced_propagation": { + "name": "alert_enhanced_propagation", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "alert_band_openings": { + "name": "alert_band_openings", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "alert_aurora": { + "name": "alert_aurora", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "update_interval_minutes": { + "name": "update_interval_minutes", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 60 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": {}, + "foreignKeys": { + "user_propagation_preferences_user_id_fkey": { + "name": "user_propagation_preferences_user_id_fkey", + "tableFrom": "user_propagation_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_propagation_preferences_user_id_key": { + "name": "user_propagation_preferences_user_id_key", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "user_propagation_preferences_update_interval_minutes_check": { + "name": "user_propagation_preferences_update_interval_minutes_check", + "value": "update_interval_minutes >= 15" + } + }, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "callsign": { + "name": "callsign", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "grid_locator": { + "name": "grid_locator", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "qrz_username": { + "name": "qrz_username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "qrz_password": { + "name": "qrz_password", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "qrz_auto_sync": { + "name": "qrz_auto_sync", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "role": { + "name": "role", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'user'" + }, + "status": { + "name": "status", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "last_login": { + "name": "last_login", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_TIMESTAMP" + }, + "third_party_services": { + "name": "third_party_services", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "idx_users_callsign": { + "name": "idx_users_callsign", + "columns": [ + { + "expression": "callsign", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_users_email": { + "name": "idx_users_email", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_users_role": { + "name": "idx_users_role", + "columns": [ + { + "expression": "role", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_users_status": { + "name": "idx_users_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "text_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_key": { + "name": "users_email_key", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": { + "valid_role": { + "name": "valid_role", + "value": "(role)::text = ANY ((ARRAY['user'::character varying, 'admin'::character varying, 'moderator'::character varying])::text[])" + }, + "valid_status": { + "name": "valid_status", + "value": "(status)::text = ANY ((ARRAY['active'::character varying, 'inactive'::character varying, 'suspended'::character varying])::text[])" + } + }, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/drizzle/migrations/meta/_journal.json b/drizzle/migrations/meta/_journal.json index 4b105a6..34d1523 100644 --- a/drizzle/migrations/meta/_journal.json +++ b/drizzle/migrations/meta/_journal.json @@ -22,6 +22,13 @@ "when": 1778524800000, "tag": "0002_add_propagation_tables", "breakpoints": true + }, + { + "idx": 3, + "version": "7", + "when": 1778530000000, + "tag": "0003_add_lotw_credentials_name", + "breakpoints": true } ] } \ No newline at end of file