From 31ed52500a9733e58668a80cd25272183492fa91 Mon Sep 17 00:00:00 2001
From: Nyan Lin Paing <117423022+LinPaing21@users.noreply.github.com>
Date: Tue, 1 Sep 2026 00:16:17 +0700
Subject: [PATCH] add suggestion management
---
.ai/rules/pages.md | 5 +
.claude/settings.local.json | 6 +
.../pages/manage-suggestion-misses.blade.php | 3 +
.../pages/manage-suggestions.blade.php | 15 +
.../Concerns/HandlesBnfexpressErrors.php | 17 +
.../Concerns/PaginatesBnfexpressLists.php | 33 ++
.../Filament/Pages/ManageSuggestionMisses.php | 150 +++++++
.../src/Filament/Pages/ManageSuggestions.php | 414 ++++++++++++++++++
.../Feature/ManageSuggestionMissesTest.php | 89 ++++
.../tests/Feature/ManageSuggestionsTest.php | 187 ++++++++
.../src/Bnfexpress/BnfexpressAdminClient.php | 191 +++++++-
.../tests/Unit/BnfexpressAdminClientTest.php | 121 +++++
12 files changed, 1226 insertions(+), 5 deletions(-)
create mode 100644 .claude/settings.local.json
create mode 100644 app-modules/ai-agent/resources/views/filament/pages/manage-suggestion-misses.blade.php
create mode 100644 app-modules/ai-agent/resources/views/filament/pages/manage-suggestions.blade.php
create mode 100644 app-modules/ai-agent/src/Filament/Concerns/PaginatesBnfexpressLists.php
create mode 100644 app-modules/ai-agent/src/Filament/Pages/ManageSuggestionMisses.php
create mode 100644 app-modules/ai-agent/src/Filament/Pages/ManageSuggestions.php
create mode 100644 app-modules/ai-agent/tests/Feature/ManageSuggestionMissesTest.php
create mode 100644 app-modules/ai-agent/tests/Feature/ManageSuggestionsTest.php
diff --git a/.ai/rules/pages.md b/.ai/rules/pages.md
index c6d36aa..be1918f 100644
--- a/.ai/rules/pages.md
+++ b/.ai/rules/pages.md
@@ -11,3 +11,8 @@ A `Filament\Pages\Page implements HasTable` (not a Resource) does NOT render its
Filament v4 tables default to deferred loading. In Pest/Livewire tests, call `->loadTable()` before any `assertSee()`/`assertCanSeeTableRecords()` on a freshly-mounted component, or the table body won't be in the rendered HTML yet.
For custom-data (`->records()`-backed, non-Eloquent) tables: use `->callTableAction($name, $record, data: [...])` / `->mountTableAction(...)` (not the generic `->callAction()`, which targets page-level actions and misses table header/record actions), and use `->assertMountedActionModalSee(...)` to check `->modalContent()` output — modal content is lazily rendered and won't appear in a plain `->html()`/`->assertSee()` snapshot even after mounting the action. See `[[project_internachi_modular]]`-style module layout in `app-modules/ai-agent`.
+
+## Custom-data table bulk actions: fetchSelectedRecords(false) still hydrates full rows
+On a `Table::records()`-backed (non-Eloquent) page, `BulkAction::make(...)->fetchSelectedRecords(false)` does NOT skip hydration the way it does for an Eloquent table — the `Collection $records` passed to `->action()` still contains full row arrays (keyed by the record key), not bare ids. Use `$records->keys()->all()` to get just the selected ids; `$records->all()`/`$records->values()` gives you full row data instead. See `ManageSuggestions::deleteSelectedBulkAction()` / `ManageSuggestionMisses::promoteBulkAction()`.
+
+Also: `BnfexpressAdminClient`'s non-2xx handling (`errorMessage()`) must handle `detail` being a list of `{msg, ...}` objects, not just a string — FastAPI's own request-validation failures (422s) return `detail` in that shape, and casting it straight to `(string)` silently produces the literal "Array".
diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 0000000..78c8763
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,6 @@
+{
+ "enabledMcpjsonServers": [
+ "laravel-boost"
+ ],
+ "enableAllProjectMcpServers": true
+}
diff --git a/app-modules/ai-agent/resources/views/filament/pages/manage-suggestion-misses.blade.php b/app-modules/ai-agent/resources/views/filament/pages/manage-suggestion-misses.blade.php
new file mode 100644
index 0000000..ce096a2
--- /dev/null
+++ b/app-modules/ai-agent/resources/views/filament/pages/manage-suggestion-misses.blade.php
@@ -0,0 +1,3 @@
+
+ {{ $this->table }}
+
diff --git a/app-modules/ai-agent/resources/views/filament/pages/manage-suggestions.blade.php b/app-modules/ai-agent/resources/views/filament/pages/manage-suggestions.blade.php
new file mode 100644
index 0000000..31378b7
--- /dev/null
+++ b/app-modules/ai-agent/resources/views/filament/pages/manage-suggestions.blade.php
@@ -0,0 +1,15 @@
+
+
+ @if ($syncJobId)
+