# This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # # This file is the source Rails uses to define your schema when running `bin/rails # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to # be faster and is potentially less error prone than running all of your # migrations from scratch. Old migrations may fail to apply correctly if those # migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. ActiveRecord::Schema[8.1].define(version: 2026_09_02_220000) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" create_table "active_storage_attachments", force: :cascade do |t| t.bigint "blob_id", null: false t.datetime "created_at", null: false t.string "name", null: false t.bigint "record_id", null: false t.string "record_type", null: false t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true end create_table "active_storage_blobs", force: :cascade do |t| t.bigint "byte_size", null: false t.string "checksum" t.string "content_type" t.datetime "created_at", null: false t.string "filename", null: false t.string "key", null: false t.text "metadata" t.string "service_name", null: false t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end create_table "active_storage_variant_records", force: :cascade do |t| t.bigint "blob_id", null: false t.string "variation_digest", null: false t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true end create_table "activities", force: :cascade do |t| t.string "activity_type", null: false t.bigint "contact_id" t.datetime "created_at", null: false t.bigint "created_by_id" t.text "description" t.datetime "happened_at", null: false t.bigint "opportunity_id" t.bigint "organization_id", null: false t.string "subject", null: false t.datetime "updated_at", null: false t.bigint "updated_by_id" t.bigint "user_id" t.index ["activity_type"], name: "index_activities_on_activity_type" t.index ["contact_id"], name: "index_activities_on_contact_id" t.index ["happened_at"], name: "index_activities_on_happened_at" t.index ["opportunity_id"], name: "index_activities_on_opportunity_id" t.index ["organization_id", "happened_at"], name: "index_activities_on_organization_id_and_happened_at" t.index ["organization_id"], name: "index_activities_on_organization_id" t.index ["user_id"], name: "index_activities_on_user_id" end create_table "api_tokens", force: :cascade do |t| t.datetime "created_at", null: false t.datetime "last_used_at" t.string "name", null: false t.datetime "revoked_at" t.string "token_digest", null: false t.string "token_prefix", null: false t.datetime "updated_at", null: false t.bigint "user_id", null: false t.index ["revoked_at"], name: "index_api_tokens_on_revoked_at" t.index ["token_digest"], name: "index_api_tokens_on_token_digest", unique: true t.index ["user_id"], name: "index_api_tokens_on_user_id" end create_table "contacts", force: :cascade do |t| t.datetime "created_at", null: false t.bigint "created_by_id" t.string "email" t.string "first_name", null: false t.string "last_name", null: false t.string "mobile" t.text "notes" t.bigint "organization_id", null: false t.string "phone" t.string "preferred_contact_method", default: "email" t.boolean "primary_contact", default: false, null: false t.string "role" t.datetime "updated_at", null: false t.bigint "updated_by_id" t.index ["email"], name: "index_contacts_on_email" t.index ["last_name", "first_name"], name: "index_contacts_on_last_name_and_first_name" t.index ["organization_id"], name: "index_contacts_on_organization_id" t.index ["phone"], name: "index_contacts_on_phone" t.index ["primary_contact"], name: "index_contacts_on_primary_contact" end create_table "mail_identities", force: :cascade do |t| t.boolean "active", default: true, null: false t.datetime "created_at", null: false t.bigint "created_by_id" t.string "encryption", default: "starttls", null: false t.string "from_email", null: false t.string "from_name", null: false t.string "name", null: false t.string "reply_to" t.string "smtp_authentication", default: "plain", null: false t.string "smtp_host", null: false t.text "smtp_password" t.integer "smtp_port", default: 587, null: false t.string "smtp_username" t.datetime "updated_at", null: false t.bigint "updated_by_id" t.boolean "verify_ssl", default: true, null: false t.index ["active"], name: "index_mail_identities_on_active" t.index ["from_email"], name: "index_mail_identities_on_from_email" end create_table "mail_templates", force: :cascade do |t| t.text "body_html", null: false t.datetime "created_at", null: false t.bigint "created_by_id" t.string "name", null: false t.bigint "project_id" t.string "subject", null: false t.datetime "updated_at", null: false t.bigint "updated_by_id" t.index ["name"], name: "index_mail_templates_on_name" t.index ["project_id"], name: "index_mail_templates_on_project_id" end create_table "mailing_recipients", force: :cascade do |t| t.string "ab_variant" t.bigint "contact_id" t.datetime "created_at", null: false t.string "email" t.text "error_message" t.datetime "last_opened_at" t.bigint "mailing_id", null: false t.integer "open_count", default: 0, null: false t.datetime "opened_at" t.bigint "organization_id", null: false t.string "rendered_subject" t.datetime "sent_at" t.string "skip_reason" t.string "status", default: "pending", null: false t.string "tracking_token", null: false t.datetime "updated_at", null: false t.index ["ab_variant"], name: "index_mailing_recipients_on_ab_variant" t.index ["email"], name: "index_mailing_recipients_on_email" t.index ["mailing_id", "organization_id"], name: "idx_mailing_recipients_unique", unique: true t.index ["opened_at"], name: "index_mailing_recipients_on_opened_at" t.index ["status"], name: "index_mailing_recipients_on_status" t.index ["tracking_token"], name: "index_mailing_recipients_on_tracking_token", unique: true end create_table "mailings", force: :cascade do |t| t.string "ab_assignment", default: "from_record", null: false t.boolean "ab_test", default: false, null: false t.string "audience", default: "to_send", null: false t.jsonb "audience_filters", default: {}, null: false t.datetime "authorized_at" t.text "body_html", null: false t.text "body_html_b" t.datetime "completed_at" t.datetime "created_at", null: false t.bigint "created_by_id" t.integer "interval_seconds", default: 0, null: false t.bigint "mail_identity_id", null: false t.bigint "mail_template_b_id" t.bigint "mail_template_id" t.string "name", null: false t.datetime "next_send_at" t.bigint "project_id", null: false t.datetime "queued_at" t.boolean "send_window_enabled", default: false, null: false t.integer "send_window_end_minutes" t.integer "send_window_start_minutes" t.string "status", default: "draft", null: false t.string "subject", null: false t.string "subject_b" t.datetime "test_sent_at" t.string "test_sent_to" t.datetime "updated_at", null: false t.bigint "updated_by_id" t.index ["ab_test"], name: "index_mailings_on_ab_test" t.index ["audience_filters"], name: "index_mailings_on_audience_filters", using: :gin t.index ["mail_identity_id"], name: "index_mailings_on_mail_identity_id" t.index ["project_id"], name: "index_mailings_on_project_id" t.index ["status", "next_send_at"], name: "index_mailings_on_status_and_next_send_at" t.index ["status"], name: "index_mailings_on_status" end create_table "opportunities", force: :cascade do |t| t.string "ab_variant" t.bigint "assigned_user_id" t.boolean "converted", default: false, null: false t.datetime "created_at", null: false t.bigint "created_by_id" t.boolean "demo_trial", default: false, null: false t.decimal "estimated_value", precision: 12, scale: 2 t.date "expected_close_date" t.datetime "first_contacted_at" t.datetime "lost_at" t.string "lost_reason" t.string "name", null: false t.text "notes" t.bigint "organization_id", null: false t.string "outcome" t.string "pipeline_stage", default: "to_contact", null: false t.integer "probability", default: 0 t.string "product" t.bigint "project_id" t.string "send_status" t.date "sent_on" t.datetime "stage_changed_at" t.datetime "updated_at", null: false t.bigint "updated_by_id" t.datetime "won_at" t.index ["ab_variant"], name: "index_opportunities_on_ab_variant" t.index ["assigned_user_id"], name: "index_opportunities_on_assigned_user_id" t.index ["expected_close_date"], name: "index_opportunities_on_expected_close_date" t.index ["lost_reason"], name: "index_opportunities_on_lost_reason" t.index ["organization_id"], name: "index_opportunities_on_organization_id" t.index ["pipeline_stage"], name: "index_opportunities_on_pipeline_stage" t.index ["product"], name: "index_opportunities_on_product" t.index ["project_id"], name: "index_opportunities_on_project_id" t.index ["send_status"], name: "index_opportunities_on_send_status" t.index ["stage_changed_at"], name: "index_opportunities_on_stage_changed_at" end create_table "organization_projects", force: :cascade do |t| t.datetime "created_at", null: false t.bigint "organization_id", null: false t.bigint "project_id", null: false t.datetime "updated_at", null: false t.index ["organization_id", "project_id"], name: "idx_org_projects_unique", unique: true t.index ["organization_id"], name: "index_organization_projects_on_organization_id" t.index ["project_id"], name: "index_organization_projects_on_project_id" end create_table "organizations", force: :cascade do |t| t.string "address" t.bigint "assigned_user_id" t.string "city" t.text "commercial_fit" t.string "country", default: "Italia", null: false t.datetime "created_at", null: false t.bigint "created_by_id" t.string "email" t.string "lead_source" t.string "legal_name" t.integer "list_position" t.string "name", null: false t.text "notes" t.string "organization_type", default: "altro", null: false t.string "phone" t.string "province" t.string "region" t.string "source_url" t.string "sport" t.string "status", default: "prospect", null: false t.string "streaming_status" t.string "team_gender" t.datetime "updated_at", null: false t.bigint "updated_by_id" t.string "vat_number" t.date "verified_at" t.string "website" t.index ["assigned_user_id"], name: "index_organizations_on_assigned_user_id" t.index ["city"], name: "index_organizations_on_city" t.index ["country"], name: "index_organizations_on_country" t.index ["email"], name: "index_organizations_on_email" t.index ["lead_source"], name: "index_organizations_on_lead_source" t.index ["list_position"], name: "index_organizations_on_list_position" t.index ["name"], name: "index_organizations_on_name" t.index ["organization_type"], name: "index_organizations_on_organization_type" t.index ["region"], name: "index_organizations_on_region" t.index ["sport"], name: "index_organizations_on_sport" t.index ["status"], name: "index_organizations_on_status" t.index ["streaming_status"], name: "index_organizations_on_streaming_status" t.index ["team_gender"], name: "index_organizations_on_team_gender" t.index ["website"], name: "index_organizations_on_website" end create_table "products", force: :cascade do |t| t.boolean "active", default: true, null: false t.string "code", null: false t.datetime "created_at", null: false t.bigint "created_by_id" t.string "name", null: false t.integer "position", default: 0, null: false t.datetime "updated_at", null: false t.bigint "updated_by_id" t.index ["code"], name: "index_products_on_code", unique: true t.index ["position"], name: "index_products_on_position" end create_table "projects", force: :cascade do |t| t.boolean "active", default: true, null: false t.string "code", null: false t.string "color", default: "#0f172a" t.datetime "created_at", null: false t.bigint "created_by_id" t.text "description" t.string "name", null: false t.integer "position", default: 0, null: false t.datetime "updated_at", null: false t.bigint "updated_by_id" t.index ["active"], name: "index_projects_on_active" t.index ["code"], name: "index_projects_on_code", unique: true t.index ["position"], name: "index_projects_on_position" end create_table "sales_goals", force: :cascade do |t| t.boolean "active", default: true, null: false t.datetime "created_at", null: false t.bigint "created_by_id" t.date "end_date", null: false t.string "metric", null: false t.string "name", null: false t.bigint "project_id" t.date "start_date", null: false t.decimal "target_value", precision: 12, scale: 2, null: false t.datetime "updated_at", null: false t.bigint "updated_by_id" t.index ["active"], name: "index_sales_goals_on_active" t.index ["metric"], name: "index_sales_goals_on_metric" t.index ["project_id"], name: "index_sales_goals_on_project_id" t.index ["start_date", "end_date"], name: "index_sales_goals_on_start_date_and_end_date" end create_table "tasks", force: :cascade do |t| t.bigint "assigned_user_id" t.datetime "completed_at" t.bigint "contact_id" t.datetime "created_at", null: false t.bigint "created_by_id" t.text "description" t.datetime "due_at", null: false t.bigint "opportunity_id" t.bigint "organization_id", null: false t.string "priority", default: "normal", null: false t.string "status", default: "pending", null: false t.string "task_type", default: "generic", null: false t.string "title", null: false t.datetime "updated_at", null: false t.bigint "updated_by_id" t.index ["assigned_user_id"], name: "index_tasks_on_assigned_user_id" t.index ["contact_id"], name: "index_tasks_on_contact_id" t.index ["due_at"], name: "index_tasks_on_due_at" t.index ["opportunity_id"], name: "index_tasks_on_opportunity_id" t.index ["organization_id"], name: "index_tasks_on_organization_id" t.index ["priority"], name: "index_tasks_on_priority" t.index ["status", "due_at"], name: "index_tasks_on_status_and_due_at" t.index ["status"], name: "index_tasks_on_status" t.index ["task_type"], name: "index_tasks_on_task_type" end create_table "user_projects", force: :cascade do |t| t.datetime "created_at", null: false t.boolean "enabled", default: true, null: false t.bigint "project_id", null: false t.datetime "updated_at", null: false t.bigint "user_id", null: false t.index ["enabled"], name: "index_user_projects_on_enabled" t.index ["project_id"], name: "index_user_projects_on_project_id" t.index ["user_id", "project_id"], name: "index_user_projects_on_user_id_and_project_id", unique: true t.index ["user_id"], name: "index_user_projects_on_user_id" end create_table "users", force: :cascade do |t| t.boolean "active", default: true, null: false t.datetime "created_at", null: false t.bigint "created_by_id" t.string "email", null: false t.string "first_name", null: false t.string "last_name", null: false t.string "password_digest", null: false t.datetime "password_reset_sent_at" t.string "password_reset_token" t.string "role", default: "user", null: false t.datetime "updated_at", null: false t.bigint "updated_by_id" t.index ["email"], name: "index_users_on_email", unique: true t.index ["password_reset_token"], name: "index_users_on_password_reset_token", unique: true t.index ["role"], name: "index_users_on_role" end add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "activities", "contacts" add_foreign_key "activities", "opportunities" add_foreign_key "activities", "organizations" add_foreign_key "activities", "users" add_foreign_key "api_tokens", "users" add_foreign_key "contacts", "organizations" add_foreign_key "mail_templates", "projects" add_foreign_key "mailing_recipients", "contacts" add_foreign_key "mailing_recipients", "mailings" add_foreign_key "mailing_recipients", "organizations" add_foreign_key "mailings", "mail_identities" add_foreign_key "mailings", "mail_templates" add_foreign_key "mailings", "mail_templates", column: "mail_template_b_id" add_foreign_key "mailings", "projects" add_foreign_key "opportunities", "organizations" add_foreign_key "opportunities", "projects" add_foreign_key "opportunities", "users", column: "assigned_user_id" add_foreign_key "organization_projects", "organizations" add_foreign_key "organization_projects", "projects" add_foreign_key "organizations", "users", column: "assigned_user_id" add_foreign_key "sales_goals", "projects" add_foreign_key "tasks", "contacts" add_foreign_key "tasks", "opportunities" add_foreign_key "tasks", "organizations" add_foreign_key "tasks", "users", column: "assigned_user_id" add_foreign_key "user_projects", "projects" add_foreign_key "user_projects", "users" end