Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .credo.exs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,26 @@
## Design Checks
#
{Credo.Check.Design.AliasUsage,
[priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 0]},
[
priority: :low,
if_nested_deeper_than: 2,
if_called_more_often_than: 0,
excluded_namespaces: [
# External optional modules — can't be aliased because they may not be installed
"PhoenixKitEntities",
"PhoenixKitAI",
"PhoenixKitPosts",
# Internal modules used behind Code.ensure_loaded? guards
"Igniter"
],
excluded_lastnames: [
# Extracted utility modules used with full paths for clarity
"Multilang",
"HtmlSanitizer",
# Used behind Code.ensure_loaded? in module enable/disable
"Registry"
]
]},
{Credo.Check.Design.TagTODO, [priority: :low]},
{Credo.Check.Design.TagFIXME, []},

Expand Down
22 changes: 7 additions & 15 deletions .dialyzer_ignore.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
{"lib/phoenix_kit/install/migration_strategy.ex", :unknown_function},
{"lib/mix/tasks/phoenix_kit.status.ex", :unknown_function},
{"lib/phoenix_kit/migrations/postgres.ex", :unknown_function},
{"lib/mix/tasks/phoenix_kit/entities/export.ex", :unknown_function},
{"lib/mix/tasks/phoenix_kit/entities/import.ex", :unknown_function},
{"lib/mix/tasks/phoenix_kit.cleanup_orphaned_files.ex", :unknown_function},

# Mix.Task behaviour callbacks (expected in Mix tasks)
Expand All @@ -28,15 +26,9 @@
{"lib/mix/tasks/phoenix_kit.modernize_layouts.ex", :callback_info_missing, 1},
{"lib/mix/tasks/phoenix_kit.assets.rebuild.ex", :callback_info_missing, 1},
{"lib/mix/tasks/phoenix_kit.status.ex", :callback_info_missing, 1},
{"lib/mix/tasks/phoenix_kit/entities/export.ex", :callback_info_missing, 1},
{"lib/mix/tasks/phoenix_kit/entities/import.ex", :callback_info_missing, 1},
{"lib/mix/tasks/phoenix_kit.cleanup_orphaned_files.ex", :callback_info_missing, 1},

# Publishing module defensive fallbacks and settings_call dynamic dispatch
{"lib/modules/publishing/publishing.ex", :guard_fail},
{"lib/modules/publishing/publishing.ex", :pattern_match_cov},
{"lib/modules/publishing/publishing.ex", :pattern_match},
{"lib/modules/publishing/shared.ex", :guard_fail},
# Publishing module (extracted) — dynamic dispatch through publishing_module() helper
# Ecto.Multi opaque type false positives (code works correctly)
~r/lib\/phoenix_kit\/users\/auth\.ex:.*call_without_opaque/,

Expand All @@ -49,11 +41,7 @@
~r/lib\/modules\/legal\/schemas\/consent_log\.ex:.*no_return/,
~r/lib\/modules\/legal\/schemas\/consent_log\.ex:.*call/,

# Publishing Editor submodules - with-chain type inference false positives
~r/lib\/modules\/publishing\/web\/editor\/.*\.ex:.*pattern_match/,
~r/lib\/modules\/publishing\/web\/editor\/.*\.ex:.*pattern_match_cov/,

# Pages module - same type inference false positives as Publishing (copied codebase)
# Pages module - type inference false positives
~r/lib\/modules\/pages\/listing_cache\.ex:.*pattern_match/,
~r/lib\/modules\/pages\/storage\/.*\.ex:.*pattern_match/,
~r/lib\/modules\/pages\/storage\/.*\.ex:.*call/,
Expand Down Expand Up @@ -92,14 +80,18 @@
# Entity form - defensive catch-all clauses for mb_to_bytes and parse_accept_list
# Dialyzer proves previous clauses cover all actual call-site types but
# catch-alls are kept intentionally for safety with dynamic form params
{"lib/modules/entities/web/entity_form.ex", :pattern_match_cov},

# tab_callback_context/1 has a :user_dashboard_tabs clause for future use
# but compile_module_admin_routes only passes :admin_tabs and :settings_tabs currently
{"lib/phoenix_kit_web/integration.ex", :pattern_match},

# External optional modules guarded by Code.ensure_loaded? at runtime
{"lib/modules/sitemap/sources/posts.ex", :unknown_function},
{"lib/modules/sitemap/sources/publishing.ex", :unknown_function},
{"lib/modules/pages/renderer.ex", :unknown_function},
{"lib/modules/pages/page_builder/renderer.ex", :unknown_function},
{"lib/phoenix_kit/dashboard/registry.ex", :unknown_function},
{"lib/phoenix_kit/install/css_integration.ex", :unknown_function},
{"lib/phoenix_kit/scheduled_jobs/workers/process_scheduled_jobs_worker.ex", :unknown_function},

# ExUnit internal functions — false positives when test/support is compiled in MIX_ENV=test
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ git status
PhoenixKit has two levels of tests:

1. **Unit tests** (`test/phoenix_kit/`, `test/modules/`) — Pure logic, no DB required
2. **Integration tests** (`test/integration/`, `test/modules/publishing/integration/`) — Real PostgreSQL via Ecto sandbox
2. **Integration tests** (`test/integration/`) — Real PostgreSQL via Ecto sandbox

#### Test database setup

Expand Down
4 changes: 0 additions & 4 deletions config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ config :phoenix_kit,
session_fingerprint_enabled: true,
session_fingerprint_strict: false

# Future: Configure FakeSettings when publishing tests are implemented
# config :phoenix_kit,
# publishing_settings_module: PhoenixKit.Test.FakeSettings

# Configure logger for tests
config :logger, level: :warning

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ PhoenixKit modules can be independently installable as separate hex packages. Th

### PhoenixKit.Module Behaviour

All 21 internal modules implement `use PhoenixKit.Module`, which provides:
All internal modules implement `use PhoenixKit.Module`, which provides:

**Required callbacks:**
- `module_key/0` — unique string identifier (e.g., `"tickets"`)
Expand All @@ -33,14 +33,14 @@ All 21 internal modules implement `use PhoenixKit.Module`, which provides:
### PhoenixKit.ModuleRegistry

GenServer using `:persistent_term` for zero-cost reads. Loads modules from two sources:
1. **Internal modules** — hardcoded list in `internal_modules/0` (the ONE place that enumerates all 21 bundled modules)
1. **Internal modules** — hardcoded list in `internal_modules/0` (the ONE place that enumerates all bundled modules)
2. **External modules** — auto-discovered from beam files via `PhoenixKit.ModuleDiscovery`, with `Application.get_env(:phoenix_kit, :modules, [])` as fallback

Provides aggregated queries: `all_admin_tabs/0`, `all_settings_tabs/0`, `all_permission_metadata/0`, `feature_enabled_checks/0`, `get_by_key/1`, etc.

### Core Files Refactored

Seven core files that previously hardcoded references to all 21 modules now use the registry:
Seven core files that previously hardcoded references to all modules now use the registry:

| File | What Changed |
|------|-------------|
Expand Down
Loading
Loading