@phase1 @database @models @lifecycle
Feature: Lifecycle Data Persistence and Retrieval
  As a system operator
  I want lifecycle actions and plans to survive database round-trips faithfully
  So that no data is lost or corrupted when storing and loading lifecycle records

  Background:
    Given the lifecycle database is ready
    And a lifecycle database session is open

  @lifecycle_action @to_domain
  Scenario: A stored action retains its identity and naming when loaded
    Given an action record exists with valid attributes and tags
    When the action record is loaded as a domain object
    Then the loaded action should preserve its original identifier
    And the loaded action should preserve its namespace and short name
    And the loaded action should preserve its description fields
    And the loaded action should preserve its actor assignments
    And the loaded action should preserve its state and flags
    And the loaded action should preserve its timestamps
    And the loaded action should preserve its tags

  @lifecycle_action @to_domain
  Scenario: A stored action with input arguments loads them correctly
    Given an action record exists with a structured arguments schema
    When the action record is loaded as a domain object
    Then the loaded action should contain the expected argument entries
    And each argument entry should have the correct name and type

  @lifecycle_action @to_domain
  Scenario: A stored action with no inputs or tags loads empty collections
    Given an action record exists with no inputs and no tags
    When the action record is loaded as a domain object
    Then the loaded action should have an empty arguments collection
    And the loaded action should have an empty tags collection

  @lifecycle_action @from_domain
  Scenario: A fully populated action domain object is stored correctly
    Given a complete action domain object is prepared
    When the action domain object is stored as a database record
    Then the stored record should preserve the action identifier
    And the stored record should preserve the name components
    And the stored record should preserve the description fields
    And the stored record should preserve the actor assignments
    And the stored record should serialize the arguments as JSON
    And the stored record should serialize the tags as JSON
    And the stored record should preserve the state value
    And the stored record should format timestamps as ISO strings

  @lifecycle_action @from_domain
  Scenario: An action with an enumerated state stores the enum value
    Given an action domain object is prepared with an enumerated state
    When the action domain object is stored as a database record
    Then the stored record state should equal the enum value

  @lifecycle_action @from_domain
  Scenario: An action with a custom string state stores it verbatim
    Given an action-like object is prepared with a custom string state
    When the custom-state action is stored as a database record
    Then the stored record state should equal the custom string

  @lifecycle_plan @parse_iso
  Scenario: A valid ISO-8601 timestamp string is parsed to a datetime
    When a valid ISO-8601 string is parsed as a timestamp
    Then the parsed timestamp should be the expected datetime value

  @lifecycle_plan @parse_iso
  Scenario: A missing timestamp value parses to nothing
    When an absent value is parsed as a timestamp
    Then the parsed timestamp should be absent

  @lifecycle_plan @to_iso
  Scenario: A datetime is formatted as an ISO-8601 string
    When a datetime value is formatted as an ISO string
    Then the formatted string should match ISO-8601 format

  @lifecycle_plan @to_iso
  Scenario: An absent datetime formats to nothing
    When an absent datetime is formatted as an ISO string
    Then the formatted value should be absent

  @lifecycle_plan @to_domain
  Scenario: A plan in the strategize phase with queued state loads correctly
    Given a plan record exists in the strategize phase with queued state
    When the plan record is loaded as a domain object
    Then the loaded plan should preserve its identity
    And the loaded plan should be in the strategize phase
    And the loaded plan processing state should be queued
    And the loaded plan should preserve its description
    And the loaded plan should preserve its timestamps
    And the loaded plan should preserve its metadata

  @lifecycle_plan @to_domain
  Scenario: A plan in the strategize phase with processing state loads correctly
    Given a plan record exists in the strategize phase with processing state
    When the plan record is loaded as a domain object
    Then the loaded plan should be in the strategize phase
    And the loaded plan processing state should be processing

  @lifecycle_plan @to_domain
  Scenario: A completed plan loads all phase timestamps correctly
    Given a plan record exists with all phase timestamps populated
    When the plan record is loaded as a domain object
    Then the loaded plan timestamps should include the strategize window
    And the loaded plan timestamps should include the execute window
    And the loaded plan timestamps should include the apply window

  @lifecycle_plan @to_domain
  Scenario: A plan with associated projects and tags loads them as lists
    Given a plan record exists with associated project identifiers and tags
    When the plan record is loaded as a domain object
    Then the loaded plan should contain the expected project identifiers
    And the loaded plan should contain the expected tags

  @lifecycle_plan @from_domain
  Scenario: A plan in STRATEGIZE phase stores the state correctly
    Given a plan domain object is prepared in the strategize phase with a queued state
    When the plan domain object is stored as a database record
    Then the stored plan record should have state "queued"
    And the stored plan record should preserve the plan identifier
    And the stored plan record should preserve the phase
    And the stored plan record should serialize the project identifiers as JSON
    And the stored plan record should serialize the plan tags as JSON
    And the stored plan record should format plan timestamps as ISO strings
    And the stored plan record automation level should be "manual"

  @lifecycle_plan @from_domain
  Scenario: A plan with a processing state stores the state correctly
    Given a plan domain object is prepared in the strategize phase with a queued state
    When the plan domain object is stored as a database record
    Then the stored plan record should have state "queued"
    And the stored plan record phase should be "strategize"

  @lifecycle_plan @from_domain
  @tdd_issue @tdd_issue_4246 @tdd_expected_fail
  Scenario: A plan with no explicit state defaults to queued
    Given a plan domain object is prepared with neither action nor processing state
    When the stateless plan domain object is stored as a database record
    Then the stored plan record should have state "queued"

  @lifecycle_plan @from_domain
  Scenario: A plan with all phase timestamps stores them as ISO strings
    Given a plan domain object is prepared with all phase timestamps
    When the plan domain object is stored as a database record
    Then the stored plan record should have all phase timestamps as ISO strings

  @lifecycle_plan @from_domain
  Scenario: A plan with non-default automation level stores the real value
    Given a plan domain object is prepared with automation level "full_automation"
    When the plan domain object is stored as a database record
    Then the stored plan record automation level should be "full_automation"

  @lifecycle_plan @from_domain
  Scenario: A plan with review-before-apply automation level stores correctly
    Given a plan domain object is prepared with automation level "review_before_apply"
    When the plan domain object is stored as a database record
    Then the stored plan record automation level should be "review_before_apply"

  @lifecycle_plan @from_domain
  Scenario: A plan stored with an explicit action_id preserves it
    Given a plan domain object is prepared in the strategize phase with a queued state
    When the plan domain object is stored with an explicit action identifier
    Then the stored plan record should preserve the supplied action identifier

  @lifecycle_action @round_trip
  Scenario: An action survives a full save-and-reload cycle unchanged
    Given a complete action domain object is prepared
    When the action is saved to the database and reloaded as a domain object
    Then the reloaded action should match the original action

  @lifecycle_plan @round_trip
  Scenario: A plan survives a full save-and-reload cycle unchanged
    Given a plan record exists in the strategize phase with queued state
    When the plan record is saved and then reloaded as a domain object
    Then the reloaded plan should preserve its identity and phase
