diff --git a/alembic/versions/0023_drop_meta_rating_tag_kinds.py b/alembic/versions/0023_drop_meta_rating_tag_kinds.py index 1d2b052..fc65ea1 100644 --- a/alembic/versions/0023_drop_meta_rating_tag_kinds.py +++ b/alembic/versions/0023_drop_meta_rating_tag_kinds.py @@ -30,11 +30,22 @@ def upgrade() -> None: # 1. Delete tags of the retired kinds. CASCADE handles related tables. op.execute("DELETE FROM tag WHERE kind IN ('meta', 'rating')") - # 2. Drop the server default — ALTER COLUMN TYPE can't carry it + # 2. Drop the CHECK constraint that references the enum's literal + # values. Postgres can't resolve `kind = 'character'` across the + # type swap below — the literal would bind to the new tag_kind + # but the column is on tag_kind_old, producing + # "operator does not exist: tag_kind = tag_kind_old". + # (Operator-hit during the v26.05.26.5 deploy attempt; ck was + # originally added by alembic 0002.) Recreated post-swap. + op.drop_constraint( + "ck_tag_fandom_requires_character", "tag", type_="check" + ) + + # 3. Drop the server default — ALTER COLUMN TYPE can't carry it # across the type swap below. op.execute("ALTER TABLE tag ALTER COLUMN kind DROP DEFAULT") - # 3. Recreate the tag_kind enum without meta/rating. + # 4. Recreate the tag_kind enum without meta/rating. op.execute("ALTER TYPE tag_kind RENAME TO tag_kind_old") op.execute( "CREATE TYPE tag_kind AS ENUM (" @@ -49,13 +60,23 @@ def upgrade() -> None: ) op.execute("DROP TYPE tag_kind_old") - # 4. Restore the server default. + # 5. Restore the server default. op.execute("ALTER TABLE tag ALTER COLUMN kind SET DEFAULT 'general'") + # 6. Restore the CHECK constraint (now bound to the new tag_kind). + op.create_check_constraint( + "ck_tag_fandom_requires_character", + "tag", + "(fandom_id IS NULL) OR (kind = 'character')", + ) + def downgrade() -> None: # Add the values back to the enum so old code can boot. The deleted # tag rows are gone permanently — no safe restore. + op.drop_constraint( + "ck_tag_fandom_requires_character", "tag", type_="check" + ) op.execute("ALTER TABLE tag ALTER COLUMN kind DROP DEFAULT") op.execute("ALTER TYPE tag_kind RENAME TO tag_kind_old") op.execute( @@ -71,3 +92,8 @@ def downgrade() -> None: ) op.execute("DROP TYPE tag_kind_old") op.execute("ALTER TABLE tag ALTER COLUMN kind SET DEFAULT 'general'") + op.create_check_constraint( + "ck_tag_fandom_requires_character", + "tag", + "(fandom_id IS NULL) OR (kind = 'character')", + ) diff --git a/extension/manifest.json b/extension/manifest.json index 217f0a0..850a6fa 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "FabledCurator", - "version": "1.0.3", + "version": "1.0.4", "description": "Export cookies from supported platforms to FabledCurator and add creators as sources in one click.", "browser_specific_settings": { @@ -11,6 +11,11 @@ } }, + "content_security_policy": { + "_comment": "Override the MV3 default CSP to OMIT upgrade-insecure-requests. FC runs over plain HTTP per the homelab posture (feedback_homelab_http), and the default MV3 CSP would silently upgrade every fetch(http://curator.../...) to https:// and fail with NS_ERROR_GENERATE_FAILURE. Operator-flagged 2026-05-26 after the 'Test connection' button errored despite a working CORS preflight on the backend.", + "extension_pages": "script-src 'self'; object-src 'self';" + }, + "permissions": [ "cookies", "storage", diff --git a/extension/package.json b/extension/package.json index db94a39..f4c7db4 100644 --- a/extension/package.json +++ b/extension/package.json @@ -1,6 +1,6 @@ { "name": "fabledcurator-extension", - "version": "1.0.3", + "version": "1.0.4", "private": true, "description": "Firefox extension for FabledCurator", "scripts": {