PhoenixKitBilling.CoreCompat (PhoenixKitBilling v0.8.1)

Copy Markdown View Source

The PhoenixKit core surface this package calls, in one list, checked against whichever core actually resolved.

mix.exs requires phoenix_kit ~> 2.0 — every core 2.x, and nothing else; core 1.7 is excluded because 2.0.0 squashed the migration chain to a V135 floor this module is verified against (see core_pin_conformance_test.exs). Admitting a minor is not the same as working on one: 2.1 may move or drop anything. What this module buys is a legible failure — the surface is declared here, so a core that moved something reports a named list at boot and in the test suite, instead of raising UndefinedFunctionError at whichever call site a user happens to reach first.

Four lists, because the failure modes differ:

  • runtime_calls/0 — called unguarded. A gap here is a broken feature.
  • optional_calls/0 — already behind Code.ensure_loaded?/1 or function_exported?/3 at the call site, so a gap degrades quietly by design (activity logging, dashboard registry).
  • compile_time_modules/0used or imported. A gap here fails the build before any check in this module can run; they are listed so the inventory of what core owes this package is complete in one place.
  • sibling_calls/0 — a PhoenixKit.* namespace owned by another package rather than by core, checked only when that package is installed.

Not covered: behaviour semantics. A core that keeps Settings.get_setting/2 but changes what it returns passes every check here and still breaks billing. Only the test suite against a real core can catch that.

Summary

Functions

:ok, or {:error, report} naming every gap against the resolved core.

Core modules billing uses or imports.

The resolved core version, or nil when :phoenix_kit is not loaded.

Logs check/0's report when the resolved core is missing something.

Core modules from compile_time_modules/0 that are not loadable.

Guarded core calls the resolved core does not export.

Unguarded core calls the resolved core does not export.

Sibling-package calls whose module is installed but no longer exports them.

Core functions billing calls behind an existence guard.

Core functions billing calls without a guard.

Calls into sibling phoenix_kit_* packages under a PhoenixKit.* namespace.

Types

mfa_tuple()

@type mfa_tuple() :: {module(), atom(), arity()}

Functions

check()

@spec check() :: :ok | {:error, String.t()}

:ok, or {:error, report} naming every gap against the resolved core.

The report is a human-readable string meant for a log line or a test failure message — it names the core version so a bug report says which core it was.

compile_time_modules()

@spec compile_time_modules() :: [module()]

Core modules billing uses or imports.

core_version()

@spec core_version() :: String.t() | nil

The resolved core version, or nil when :phoenix_kit is not loaded.

Read from the application spec rather than a compile-time constant, so it reports the core actually running, not the one this package was built against.

log_check()

@spec log_check() :: :ok

Logs check/0's report when the resolved core is missing something.

Called from the supervisor, so a host that upgraded core past what this package understands is told once at boot, by name, instead of discovering it one crash at a time. Missing unguarded calls log at :error, everything else at :warning — the former is a broken feature, the latter is degradation the call sites already handle.

missing_compile_time_modules()

@spec missing_compile_time_modules() :: [module()]

Core modules from compile_time_modules/0 that are not loadable.

missing_optional_calls()

@spec missing_optional_calls() :: [mfa_tuple()]

Guarded core calls the resolved core does not export.

missing_runtime_calls()

@spec missing_runtime_calls() :: [mfa_tuple()]

Unguarded core calls the resolved core does not export.

missing_sibling_calls()

@spec missing_sibling_calls() :: [mfa_tuple()]

Sibling-package calls whose module is installed but no longer exports them.

An uninstalled sibling returns nothing: not having phoenix_kit_emails is a supported configuration, not a compatibility break.

optional_calls()

@spec optional_calls() :: [mfa_tuple()]

Core functions billing calls behind an existence guard.

runtime_calls()

@spec runtime_calls() :: [mfa_tuple()]

Core functions billing calls without a guard.

sibling_calls()

@spec sibling_calls() :: [mfa_tuple()]

Calls into sibling phoenix_kit_* packages under a PhoenixKit.* namespace.

Checked only when the module is loaded — see missing_sibling_calls/0.