Skip to content

chore: remove unused PlatformRules registry and rule classes#27

Merged
paulocastellano merged 4 commits into
mainfrom
chore/remove-unused-platform-rules
May 12, 2026
Merged

chore: remove unused PlatformRules registry and rule classes#27
paulocastellano merged 4 commits into
mainfrom
chore/remove-unused-platform-rules

Conversation

@paulocastellano
Copy link
Copy Markdown
Contributor

Summary

The whole `app/Ai/PlatformRules/` system was scaffolding that got registered in `AppServiceProvider` but never read anywhere in production code. Confirmed via grep across `app/`, `resources/`, `config/`, `database/`, `tests/` — the only consumers were:

  • `AppServiceProvider::configurePlatformRules()` registering classes in the `Registry` (which nothing then called)
  • `tests/Feature/Ai/PlatformRules/RegistryTest.php` asserting the registrations it had just performed

The real consumer of per-platform AI rules is `PostContentGenerator` — it pulls `Platform::maxContentLength()` and `Platform::recommendedAiContentLength()` straight from the enum and feeds them into the prompt template, bypassing this layer entirely.

Removed

  • `app/Ai/PlatformRules/` — 12 files (Contract, Registry, and 10 Rule classes)
  • `tests/Feature/Ai/PlatformRules/RegistryTest.php`
  • 11 `use` imports + the `boot()` call + the `configurePlatformRules()` method body in `AppServiceProvider`

Stats

`14 files changed, 516 deletions(-)` — zero additions.

Test plan

  • `vendor/bin/pint --dirty --format agent` — passed
  • `php artisan test --compact --parallel` — 1487 passed, 2 skipped, 16154 assertions (was 1504; -17 from the deleted `RegistryTest`, expected)
  • Grep confirmation: zero remaining references to `PlatformRules` outside the removed directories

The whole app/Ai/PlatformRules/ system was registered in AppServiceProvider
but never read in production code. Confirmed via grep across app/, resources/,
config/, database/, tests/ — only consumers were:

- AppServiceProvider::configurePlatformRules() registering everything in the
  Registry (which nothing then called)
- tests/Feature/Ai/PlatformRules/RegistryTest.php asserting the registrations
  it had just performed

The actual AI text agent (PostContentGenerator) reads the per-platform caps
straight from the Platform enum (maxContentLength / recommendedAiContentLength)
and feeds them into the prompt template — bypassing this layer entirely.

Removed:
- app/Ai/PlatformRules/ (12 files: Contract, Registry, 10 Rule classes)
- tests/Feature/Ai/PlatformRules/RegistryTest.php
- 11 use imports + boot() call + configurePlatformRules() method in
  AppServiceProvider
Left over from the PostEditorHeader extraction in #26 — the header now
derives its own isPublished from the post prop, and Edit.vue itself
doesn't use it anywhere. ESLint caught it on CI.
Two more pieces in app/Ai/ that were registered but never reached by any
production caller, same audit as the PlatformRules cleanup.

DebugGeminiRequest middleware: zero references — not registered in the
laravel/ai middleware pipeline, no agent imports it. Pure dev-time
scaffolding that got left behind.

ExtendedGeminiProvider: registered via Ai::extend('gemini', ...) so the
class IS resolvable when AI_DEFAULT=gemini, but its only override —
defaultImageOptions — is unreachable in practice:

- All text agents (PostContentGenerator, PostContentHumanizer,
  PostContentReviewer, PostContentStreamer, BrandAnalyzer) only call
  text generation, never defaultImageOptions.
- Image generation (AiImageClient) hardcodes OpenAI's `gpt-image-2`
  model, so the Gemini provider isn't on the image path either.

Removed:
- app/Ai/Middleware/DebugGeminiRequest.php
- app/Ai/Providers/ExtendedGeminiProvider.php
- tests/Unit/Ai/Providers/ExtendedGeminiProviderTest.php
- Ai::extend('gemini', ...) wiring + configureAi() method and its four
  imports (ExtendedGeminiProvider, Ai, GeminiGateway, Dispatcher) in
  AppServiceProvider.
…t + loading state)

The inline "Generate post with AI" dialog never showed any output, even
after the queue job finished. Three independent issues stacked:

1. Event name mismatch in useAiStream. Listeners were CamelCased
   (.TextDelta, .StreamEnd, .Error) but laravel/ai broadcasts events
   with snake_case names via StreamEvent::type() (text_delta, stream_end,
   error). Echo never matched, the listener never fired, status stuck on
   'streaming' forever. Renamed to snake_case.

2. The streamer agent shares the structured-output prompt template with
   PostContentGenerator, so the stream emits a JSON object like
   {"content":"...","image_title":"...","image_keywords":[...]}, not
   plain caption text. Added a previewText computed in AiGenerateDialog
   that JSON.parse's the accumulated text and grabs .content. Mid-stream
   the parse fails, so the preview stays empty (showing the existing
   '...' placeholder) until stream_end produces a complete JSON.

3. The Generate button used v-if="status === 'idle'" — it disappeared
   the instant generation started, leaving the user with no feedback.
   Swapped to v-if="status === 'idle' || status === 'streaming'" and
   used the Button component's built-in :loading prop so it stays
   visible with a spinner inside while the agent runs.
@paulocastellano paulocastellano merged commit f8f5cba into main May 12, 2026
2 checks passed
@paulocastellano paulocastellano deleted the chore/remove-unused-platform-rules branch May 12, 2026 00:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant