Skip to main content

mix.exs

defmodule Cairnloop.MixProject do
  use Mix.Project

  def project do
    [
      app: :cairnloop,
      version: "0.5.1",
      elixir: "~> 1.19",
      start_permanent: Mix.env() == :prod,
      elixirc_paths: elixirc_paths(Mix.env()),
      aliases: aliases(),
      deps: deps(),
      description:
        "Host-owned customer support automation for Phoenix apps — governed drafting, retrieval-backed answers, and durable workflow tools.",
      source_url: "https://github.com/szTheory/cairnloop",
      homepage_url: "https://github.com/szTheory/cairnloop",
      package: [
        name: "cairnloop",
        files: ~w(lib priv guides mix.exs README.md LICENSE CHANGELOG.md),
        licenses: ["MIT"],
        links: %{
          "GitHub" => "https://github.com/szTheory/cairnloop",
          "Changelog" => "https://hexdocs.pm/cairnloop/changelog.html"
        },
        maintainers: ["szTheory"]
      ],
      docs: [
        main: "readme",
        extras: [
          {"guides/01-quickstart.md", title: "Quickstart"},
          {"guides/02-jtbd-walkthrough.md", title: "JTBD Walkthrough"},
          {"guides/03-host-integration.md", title: "Host Integration"},
          {"guides/07-auth-and-operator-identity.md", title: "Auth & Operator Identity"},
          {"guides/04-troubleshooting.md", title: "Troubleshooting"},
          {"guides/05-mcp-clients.md", title: "MCP Clients"},
          {"guides/06-extending.md", title: "Extending Cairnloop"},
          "README.md",
          "CHANGELOG.md"
        ],
        groups_for_extras: [
          Guides: ~r/^guides\//
        ],
        assets: %{"guides/assets" => "assets"},
        groups_for_modules: [
          Governance: [~r/^Cairnloop\.Governance/, ~r/^Cairnloop\.Tool/],
          "Knowledge Base": [~r/^Cairnloop\.KnowledgeBase/, ~r/^Cairnloop\.KnowledgeAutomation/],
          Retrieval: [~r/^Cairnloop\.Retrieval/],
          MCP: [~r/^Cairnloop\.Web\.MCP/],
          Web: [~r/^Cairnloop\.Web/],
          Core: [~r/^Cairnloop/]
        ]
      ]
    ]
  end

  # Run the integration aliases under MIX_ENV=test without an explicit prefix.
  def cli do
    [preferred_envs: ["test.integration": :test, "test.setup": :test]]
  end

  # test/support holds the integration test host (Repo, Endpoint, Router, case
  # templates). Compiled ONLY under MIX_ENV=test so the published library never
  # ships a stray Repo/Endpoint — the host-owned, zero-children contract holds.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  defp aliases do
    [
      # DB bootstrap for the integration suite (Cairnloop.Repo + Chimeway.Repo boot DB).
      # Host-owned tables (conversations/messages/drafts) are created FIRST via the
      # test-host migration path — the library's own migrations reference but do not
      # create them (the host owns them). Then the library migrations run.
      # One migrate call with BOTH paths (a task runs once per mix invocation). Ecto merges
      # and sorts by version: host tables (20260101…) precede the library migrations, so the
      # library's FKs to cairnloop_conversations resolve.
      # Create BOTH repos in one call (a task runs once per mix invocation; -r is :keep).
      # Chimeway.Repo's DB only needs to EXIST so its unconditional supervisor boots cleanly
      # (no migrations run against it). Migrate only Cairnloop.Repo.
      "test.setup": [
        "ecto.create --quiet -r Cairnloop.Repo -r Chimeway.Repo",
        "ecto.migrate --quiet --migrations-path priv/test_host/migrations --migrations-path priv/repo/migrations"
      ],
      # Default `mix test` stays DB-free and excludes :integration (fast inner loop).
      # Run the DB-backed suite explicitly with `mix test.integration`.
      "test.integration": ["test.setup", "test --include integration test/integration"],
      # Static quality gate (mirrors the CI `quality` job). Tests are NOT bundled here —
      # they run via the `phase-12-shift-left` + `integration` CI jobs (a bare headless
      # `mix test` carries the documented Automation.DraftTest M005-drift baseline failure).
      check: [
        "format --check-formatted",
        "compile --warnings-as-errors",
        "credo --strict",
        "docs --warnings-as-errors",
        "deps.audit"
      ]
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger],
      mod: {Cairnloop.Application, []}
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      {:ecto_sql, "~> 3.10"},
      {:postgrex, ">= 0.0.0"},
      {:pgvector, "~> 0.3.1"},
      {:igniter, "~> 0.5"},
      {:phoenix_live_view, "~> 1.0"},
      {:jason, "~> 1.2"},
      {:nimble_options, "~> 1.0"},
      {:oban, "~> 2.17"},
      {:mailglass, "~> 0.2"},
      {:hackney, "~> 1.9"},
      {:earmark, "~> 1.4"},
      {:req, "~> 0.5"},
      {:chimeway, "~> 1.0", optional: true},
      {:scrypath, ">= 0.0.0", optional: true},
      {:telemetry_metrics_prometheus_core, "~> 1.2", optional: true},
      # phoenix_live_view 1.1 uses lazy_html (not floki) as its test-time HTML parser
      # for Phoenix.LiveViewTest element/form helpers.
      {:lazy_html, ">= 0.1.0", only: :test},
      {:ex_doc, "~> 0.34", only: :dev, runtime: false},
      {:credo, "~> 1.7", only: [:dev, :test], runtime: false},
      {:mix_audit, "~> 2.1", only: [:dev, :test], runtime: false}
    ]
  end
end