defmodule MoundHunters.Application do @moduledoc false use Application require Logger @impl true def start(_type, _args) do # Ensure log directory exists ensure_log_dir() # Initialize Mnesia before starting supervision tree setup_mnesia() children = [ # Tile processing GenServer MoundHunters.TileProcessor, # HTTP server {Plug.Cowboy, scheme: :http, plug: MoundHuntersWeb.Router, options: [port: http_port()]} ] opts = [strategy: :one_for_one, name: MoundHunters.Supervisor] Supervisor.start_link(children, opts) end defp ensure_log_dir do log_dir = Application.get_env(:mound_hunters, :log_dir, "priv/logs") File.mkdir_p!(log_dir) end defp http_port do Application.get_env(:mound_hunters, :http_port, 4000) end defp setup_mnesia do mnesia_dir = Application.get_env(:mound_hunters, :mnesia_dir) # Ensure mnesia directory exists mnesia_dir |> to_string() |> File.mkdir_p!() # Stop mnesia if running :mnesia.stop() # Create schema if it doesn't exist case :mnesia.create_schema([node()]) do :ok -> Logger.info("Created Mnesia schema") {:error, {_, {:already_exists, _}}} -> Logger.debug("Mnesia schema already exists") {:error, reason} -> Logger.warning("Failed to create Mnesia schema: #{inspect(reason)}") end # Start Mnesia :ok = :mnesia.start() Logger.info("Mnesia started") # Create tables if they don't exist create_tables() end defp create_tables do # Tiles table case :mnesia.create_table(:tiles, attributes: [ :id, :min_lat, :max_lat, :min_lng, :max_lng, :status, :error_message, :jpg_available, :png_available, :created_at, :updated_at ], disc_copies: [node()], type: :set ) do {:atomic, :ok} -> Logger.info("Created :tiles table") {:aborted, {:already_exists, :tiles}} -> Logger.debug(":tiles table already exists") {:aborted, reason} -> Logger.error("Failed to create :tiles table: #{inspect(reason)}") end # Geometries table case :mnesia.create_table(:geometries, attributes: [:id, :geojson, :created_at], disc_copies: [node()], type: :set ) do {:atomic, :ok} -> Logger.info("Created :geometries table") {:aborted, {:already_exists, :geometries}} -> Logger.debug(":geometries table already exists") {:aborted, reason} -> Logger.error("Failed to create :geometries table: #{inspect(reason)}") end # Wait for tables to be ready :mnesia.wait_for_tables([:tiles, :geometries], 5000) end end