Feature: Database migration lifecycle
  As a CleverAgents administrator
  I want to manage database schema via Alembic migrations
  So that I can safely evolve the schema with rollback capability

  Background:
    Given a fresh in-memory database for migration lifecycle testing

  Scenario: Apply all migrations forward on a fresh database
    When I run all migrations forward to head
    Then the database should have all expected tables
    And the current revision should be the head revision

  Scenario: Spec-parity schema details are present after migration
    Given all migrations have been applied
    Then the "resource_links" table should include "link_type" with default "contains"
    And checkpoint_metadata should enforce decision and resource foreign keys
    And checkpoint_metadata foreign keys should reject orphan references
    And checkpoint_metadata should reject orphan decision_id independently
    And checkpoint_metadata should reject orphan resource_id independently
    And checkpoint_metadata should accept valid decision and resource references
    And the "decisions" table should have partial index "idx_decisions_superseded" on "superseded_by"

  Scenario: Roll back all migrations to base
    Given all migrations have been applied
    When I downgrade all migrations to base
    Then the current revision should be None
    And the database should have no application tables

  Scenario: Round-trip forward then rollback to initial
    Given all migrations have been applied
    When I downgrade to the initial migration "001_initial_schema"
    Then the current revision should be "001_initial_schema"
    When I upgrade back to head
    Then the current revision should be the head revision

  Scenario: CLI db upgrade command applies migrations
    When I invoke the db upgrade CLI command
    Then the CLI should report a successful upgrade
    And the database should have all expected tables

  Scenario: CLI db current command shows revision
    Given all migrations have been applied
    When I invoke the db current CLI command
    Then the CLI should display the current revision

  Scenario: CLI db downgrade command rolls back
    Given all migrations have been applied
    When I invoke the db downgrade CLI command with revision "m6_004_container_metadata_column"
    Then the CLI should report a successful downgrade

  Scenario: Stamp logic detects pre-Alembic database
    Given a database with legacy tables but no alembic_version
    When I run init_or_upgrade on the legacy database
    Then the database should be stamped with alembic_version
    And the database revision should be at head

  Scenario: Migration orphan cleanup nullifies stale checkpoint references
    Given migrations applied up to "m4_003_plan_env_columns"
    And checkpoint_metadata contains orphan decision and resource references
    When I upgrade to the next migration revision
    Then the orphan decision_id values should be NULL
    And the orphan resource_id values should be NULL
    And checkpoint_metadata should enforce decision and resource foreign keys

  Scenario: resource_links.link_type accepts spec-defined non-default values
    Given all migrations have been applied
    Then resource_links should accept link_type "references"
    And resource_links should accept link_type "derived_from"

  Scenario: resource_links.link_type rejects NULL values
    Given all migrations have been applied
    Then resource_links should reject NULL link_type

  Scenario: resource_links.link_type rejects invalid values
    Given all migrations have been applied
    Then resource_links should reject link_type "invalid_type"

  Scenario: Deleting a decision sets checkpoint decision_id to NULL
    Given all migrations have been applied
    And a checkpoint references a valid decision
    When the referenced decision is deleted
    Then the checkpoint decision_id should be NULL

  Scenario: Deleting a resource sets checkpoint resource_id to NULL
    Given all migrations have been applied
    And a checkpoint references a valid resource
    When the referenced resource is deleted
    Then the checkpoint resource_id should be NULL

  Scenario: Spec-parity m4_004 downgrade removes added schema objects
    Given all migrations have been applied
    When I downgrade to revision "m4_003_plan_env_columns"
    Then the "resource_links" table should not include "link_type"
    And the "decisions" table should not have index "idx_decisions_superseded"
    And checkpoint_metadata should not have foreign key "fk_checkpoint_metadata_decision"
    And checkpoint_metadata should not have foreign key "fk_checkpoint_metadata_resource"
    And checkpoint_metadata should not have SQLite triggers for FK enforcement

  Scenario: Migration idempotency: existing link_type column gains CHECK constraint
    Given migrations applied up to "m4_003_plan_env_columns"
    And resource_links already has a link_type column without CHECK constraint
    When I upgrade to the next migration revision
    Then the "resource_links" table should include "link_type" with default "contains"
    And resource_links should reject link_type "invalid_type"

  Scenario: Migration idempotency: existing link_type column with wrong default is corrected
    Given migrations applied up to "m4_003_plan_env_columns"
    And resource_links already has a link_type column with a non-contains default
    When I upgrade to the next migration revision
    Then the "resource_links" table should include "link_type" with default "contains"
    And resource_links should reject link_type "invalid_type"

  Scenario: Positive checkpoint FK test verifies persisted row
    Given all migrations have been applied
    And valid decision and resource rows exist
    When I insert a checkpoint with valid FK references
    Then the checkpoint row should be persisted in the database

  Scenario: UPDATE trigger rejects orphan decision_id on checkpoint_metadata
    Given all migrations have been applied
    And a checkpoint exists with valid FK references
    When I update the checkpoint decision_id to a non-existent value
    Then the update should be rejected with an integrity error

  Scenario: UPDATE trigger rejects orphan resource_id on checkpoint_metadata
    Given all migrations have been applied
    And a checkpoint exists with valid FK references
    When I update the checkpoint resource_id to a non-existent value
    Then the update should be rejected with an integrity error

  Scenario: resource_links.link_type rejects empty string values
    Given all migrations have been applied
    Then resource_links should reject empty string link_type

  Scenario: init_database creates a valid schema
    When I call init_database with an in-memory URL
    Then the resulting engine should have a valid schema

  @issue_4180 @alembic_packaging
  Scenario: MigrationRunner locates alembic.ini from packaged location
    Given the MigrationRunner class is available
    When I call _find_alembic_ini() to locate the configuration file
    Then it should find alembic.ini at the package location
    And the alembic.ini should be readable and valid

  @issue_4180 @alembic_packaging
  Scenario: Database initialization succeeds with packaged alembic files
    Given a fresh in-memory database for migration lifecycle testing
    When I run all migrations forward to head
    Then the database should have all expected tables
    And the database should be stamped with alembic_version
    And the database revision should be at head
