{
  "ok": true,
  "status": "blocked_before_chat_schema_migration",
  "scope": "role_chat_database_schema_plan_preview",
  "roleId": "wf-moonlit-bookseller",
  "roleName": "月下书店老板",
  "sourceDocument": "docs/20角色卡片温度与酒馆系参考补充-2026-06-12.md",
  "historyAccess": {
    "status": "blocked_before_chat_history_access",
    "blockers": [
      "model_api_key_missing",
      "points_charge_not_live",
      "production_chat_storage_missing",
      "user_auth_not_live",
      "chat_turn_transaction_not_live",
      "idempotent_points_reservation_missing",
      "assistant_message_persistence_missing",
      "points_ledger_live_transaction_missing",
      "points_balance_check_missing",
      "refund_transaction_missing",
      "duplicate_turn_charge_guard_missing",
      "model_adapter_live_call_missing",
      "model_response_normalizer_missing",
      "assistant_output_policy_log_missing",
      "model_timeout_and_retry_not_verified",
      "message_transaction_missing",
      "message_status_transition_log_missing",
      "model_call_log_storage_missing",
      "memory_candidate_persistence_missing",
      "production_chat_history_read_missing",
      "chat_history_owner_filter_missing",
      "chat_message_delete_transaction_missing",
      "chat_delete_audit_log_missing",
      "memory_candidate_delete_cascade_missing"
    ],
    "requiredReadFilters": [
      "owner_user_id",
      "session_id",
      "role_id",
      "message_deleted_at_is_null"
    ],
    "deleteStrategy": "soft_delete_message_and_write_audit_log"
  },
  "tables": [
    {
      "name": "role_chat_sessions",
      "purpose": "bind_user_role_and_conversation_state",
      "requiredColumns": [
        "id",
        "user_id",
        "role_id",
        "status",
        "last_message_at",
        "created_at",
        "updated_at",
        "deleted_at"
      ],
      "rlsOwnerColumn": "user_id"
    },
    {
      "name": "role_chat_messages",
      "purpose": "store_user_and_assistant_messages_with_status",
      "requiredColumns": [
        "id",
        "session_id",
        "user_id",
        "role_id",
        "client_turn_id",
        "sender_type",
        "status",
        "content_ref",
        "model_call_id",
        "deleted_at",
        "created_at"
      ],
      "statusValues": [
        "pending",
        "completed",
        "failed",
        "soft_deleted"
      ]
    },
    {
      "name": "role_chat_model_calls",
      "purpose": "track_server_side_model_requests_without_exposing_secrets",
      "requiredColumns": [
        "id",
        "session_id",
        "message_id",
        "provider",
        "status",
        "request_redaction_ref",
        "response_summary_ref",
        "error_code",
        "created_at"
      ],
      "redactionRequired": true
    },
    {
      "name": "role_chat_message_events",
      "purpose": "audit_message_status_transitions_soft_delete_and_refund_links",
      "requiredColumns": [
        "id",
        "message_id",
        "event_type",
        "actor_type",
        "actor_id",
        "reason",
        "created_at"
      ],
      "appendOnly": true
    },
    {
      "name": "points_ledger",
      "purpose": "reuse_existing_points_ledger_with_client_turn_id_idempotency",
      "requiredColumns": [
        "source_type",
        "source_id",
        "client_turn_id",
        "balance_after"
      ],
      "externalTable": true
    },
    {
      "name": "role_memory_candidates",
      "purpose": "reuse_memory_candidates_after_assistant_success_and_delete_reconciliation",
      "requiredColumns": [
        "source_message_id",
        "status",
        "user_id",
        "role_id"
      ],
      "externalTable": true
    }
  ],
  "rlsPolicies": [
    {
      "name": "user_reads_own_chat_sessions",
      "table": "role_chat_sessions",
      "role": "authenticated",
      "rule": "user_id_matches_authenticated_user_and_deleted_at_is_null"
    },
    {
      "name": "user_reads_own_chat_messages",
      "table": "role_chat_messages",
      "role": "authenticated",
      "rule": "message_user_id_matches_authenticated_user_and_session_owner_matches"
    },
    {
      "name": "user_soft_deletes_own_messages",
      "table": "role_chat_messages",
      "role": "authenticated",
      "rule": "only_owner_can_set_deleted_at_without_touching_other_users"
    },
    {
      "name": "admin_reads_chat_audit_for_review",
      "table": "role_chat_message_events",
      "role": "admin",
      "rule": "admin_can_read_audit_without_raw_provider_secret"
    },
    {
      "name": "anon_denied_all_chat_tables",
      "table": "role_chat_%",
      "role": "anon",
      "rule": "no_public_chat_history_access"
    }
  ],
  "replayChecks": [
    "anon_cannot_read_chat_sessions",
    "anon_cannot_read_chat_messages",
    "authenticated_user_reads_only_own_sessions",
    "authenticated_user_cannot_read_other_user_messages",
    "authenticated_user_soft_deletes_only_own_message",
    "deleted_message_excluded_from_prompt_context",
    "message_event_append_only",
    "model_call_log_does_not_expose_provider_secret",
    "points_ledger_links_to_client_turn_id",
    "memory_candidate_removed_or_reopened_after_message_delete"
  ],
  "migrationPlan": {
    "targetDraft": "server/db/migrations/2026-06-14-role-card-core.sql",
    "chatDraft": "server/db/migrations/2026-06-15-role-chat-core.sql",
    "staticQa": "scripts/qa-role-chat-core-migration.cjs",
    "temporaryReplayQa": "scripts/qa-role-chat-postgres-replay.cjs",
    "rollbackRequirements": [
      "drop_chat_rls_policies_before_tables",
      "preserve_points_ledger_history",
      "preserve_redacted_audit_events_for_review",
      "verify_no_raw_prompt_or_model_key_in_tables"
    ],
    "liveExecutionGate": "requires_backup_rls_failure_cases_least_privilege_and_manual_approval"
  },
  "blockers": [
    "model_api_key_missing",
    "points_charge_not_live",
    "production_chat_storage_missing",
    "user_auth_not_live",
    "chat_turn_transaction_not_live",
    "idempotent_points_reservation_missing",
    "assistant_message_persistence_missing",
    "points_ledger_live_transaction_missing",
    "points_balance_check_missing",
    "refund_transaction_missing",
    "duplicate_turn_charge_guard_missing",
    "model_adapter_live_call_missing",
    "model_response_normalizer_missing",
    "assistant_output_policy_log_missing",
    "model_timeout_and_retry_not_verified",
    "message_transaction_missing",
    "message_status_transition_log_missing",
    "model_call_log_storage_missing",
    "memory_candidate_persistence_missing",
    "production_chat_history_read_missing",
    "chat_history_owner_filter_missing",
    "chat_message_delete_transaction_missing",
    "chat_delete_audit_log_missing",
    "memory_candidate_delete_cascade_missing",
    "chat_schema_live_migration_missing",
    "chat_rls_live_failure_cases_missing",
    "chat_message_encryption_or_redaction_policy_missing",
    "chat_table_backup_window_missing"
  ],
  "next": [
    "review_role_chat_core_migration_with_production_database_owner",
    "run_live_backup_and_least_privilege_preflight",
    "execute_chat_migration_in_approved_window",
    "bind_chat_schema_to_points_ledger_and_memory_candidates",
    "review_redaction_policy_before_live_migration"
  ],
  "boundaries": [
    "database_schema_plan_preview_only",
    "does_not_create_database_tables",
    "does_not_run_migration",
    "does_not_touch_live_database",
    "does_not_read_real_chat_history",
    "does_not_delete_real_chat_message",
    "does_not_expose_internal_prompt_blocks"
  ]
}