PHPackages                             padosoft/product-image-discovery-admin - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Admin Panels](/categories/admin)
4. /
5. padosoft/product-image-discovery-admin

ActiveProject[Admin Panels](/categories/admin)

padosoft/product-image-discovery-admin
======================================

Laravel admin demo application for padosoft/product-image-discovery.

v1.1.0(1mo ago)10Apache-2.0JavaScriptPHP ^8.3CI failing

Since May 1Pushed 1mo agoCompare

[ Source](https://github.com/padosoft/product_image_discovery_admin)[ Packagist](https://packagist.org/packages/padosoft/product-image-discovery-admin)[ RSS](/packages/padosoft-product-image-discovery-admin/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (3)Dependencies (5)Versions (11)Used By (0)

Product Image Discovery Admin
=============================

[](#product-image-discovery-admin)

[![CI](https://github.com/padosoft/product_image_discovery_admin/actions/workflows/ci.yml/badge.svg)](https://github.com/padosoft/product_image_discovery_admin/actions/workflows/ci.yml)[![Release](https://camo.githubusercontent.com/ba7e670ec969c27803861f26358b50a0e3979ee734826c93dff992912c743494/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f7061646f736f66742f70726f647563745f696d6167655f646973636f766572795f61646d696e3f7374796c653d666c61742d737175617265)](https://github.com/padosoft/product_image_discovery_admin/releases)[![PHP](https://camo.githubusercontent.com/f46c300b5c77864d0cce1f4f9568a9c0cd14371eaf8ba6a974e08b487b7ffdeb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332532422d3737376262342e7376673f7374796c653d666c61742d737175617265)](https://www.php.net/)[![Laravel](https://camo.githubusercontent.com/17d33f3731e4506ad548689d60521b32c3c7231d1c07cf78ed81ed59078a4775/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31332e782d6666326432302e7376673f7374796c653d666c61742d737175617265)](https://laravel.com/)[![React](https://camo.githubusercontent.com/edbeca1889810a631226fd7f65a78f808a7279727a3ddd048889b5d9e9cdddb0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f52656163742d31382d3631646166622e7376673f7374796c653d666c61742d737175617265)](https://react.dev/)[![Vite](https://camo.githubusercontent.com/643706f2715825e99f1083d6c7e69c2467d18754223e3b8219b8a2f8ec526e83/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f566974652d382d3634366366662e7376673f7374796c653d666c61742d737175617265)](https://vite.dev/)[![License](https://camo.githubusercontent.com/a39964403b3ad23090c20e0f4e86b834c7f13cd17f0fb9e042c3cce06f6a13b4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4170616368652d2d322e302d626c75652e7376673f7374796c653d666c61742d737175617265)](LICENSE)

Professional Laravel admin console for [`padosoft/product-image-discovery`](https://github.com/padosoft/product_image_discovery): inspect discovery requests, approve or reject candidates, tune provider configuration, run diagnostics, and ship safer product-image workflows without building a back office from scratch.

[![Product Image Discovery Admin overview](resources/screenshoots/ProductImageSearch-dashboard.png)](resources/screenshoots/ProductImageSearch-dashboard.png)

Table of Contents
-----------------

[](#table-of-contents)

- [Why Teams Use It](#why-teams-use-it)
- [What You Get](#what-you-get)
- [Screenshots](#screenshots)
- [Architecture](#architecture)
- [Quickstart](#quickstart)
- [Local Setup](#local-setup)
- [Login](#login)
- [Demo Data](#demo-data)
- [Testing](#testing)
- [CI](#ci)
- [Security Model](#security-model)
- [Admin Routes](#admin-routes)
- [Relationship To The Package](#relationship-to-the-package)
- [Process Docs](#process-docs)
- [License](#license)

Why Teams Use It
----------------

[](#why-teams-use-it)

Product images are operational data. A wrong product-color image can leak into ERP, PIM, marketplaces, catalogs, feeds, and customer-facing storefronts. This admin app gives catalog and operations teams a dense, production-shaped cockpit for the conservative discovery pipeline in `padosoft/product-image-discovery`.

- Review uncertain matches before they publish.
- Compare candidates with source, score, AI, quality, and audit evidence.
- Manage thresholds, providers, trusted sources, and client overrides.
- Run debug flows against real or fake providers.
- Inspect health, queues, storage, AI configuration, and redacted reports.
- Export filtered request data and keep demo operator filters locally.

What You Get
------------

[](#what-you-get)

- **Operations dashboard** with KPI cards, score distribution, provider readiness, queue phase health, latest attention items, and shortcuts.
- **Requests and Manual Review** pages with dense filters, pagination, CSV export, detail drawer, compare mode, protected image previews, approve/reject/retry flows, and audit timeline.
- **Configuration tools** for settings, search providers, provider credential status, trusted sources, trust scores, policies, scopes, and URL patterns.
- **Diagnostics suite** with guided debug-flow runner, report viewer, JSON search, redacted report download, health checks, and API workbench.
- **Offline demo path** with deterministic seeded data for Herno, Nike, and New Balance scenarios.
- **Release gate** through PHPUnit, Vitest, Vite, Playwright, Composer validation, and GitHub Actions.

Screenshots
-----------

[](#screenshots)

### Overview Dashboard

[](#overview-dashboard)

[![Overview dashboard](resources/screenshoots/ProductImageSearch-dashboard.png)](resources/screenshoots/ProductImageSearch-dashboard.png)

### Request Search

[](#request-search)

[![Request search](resources/screenshoots/ProductImageSearch-request.png)](resources/screenshoots/ProductImageSearch-request.png)

### Request Detail And Candidate Review

[](#request-detail-and-candidate-review)

[![Request detail](resources/screenshoots/ProductImageSearch-request-details.png)](resources/screenshoots/ProductImageSearch-request-details.png)

### API Test Workbench

[](#api-test-workbench)

[![API test workbench](resources/screenshoots/ProductImageSearch-API.png)](resources/screenshoots/ProductImageSearch-API.png)

### Debug Flow

[](#debug-flow)

[![Debug flow setup](resources/screenshoots/ProductImageSearch-test-flow.png)](resources/screenshoots/ProductImageSearch-test-flow.png)

### Debug Flow Results

[](#debug-flow-results)

[![Debug flow results](resources/screenshoots/ProductImageSearch-test-flow-results.png)](resources/screenshoots/ProductImageSearch-test-flow-results.png)

### Scoring Configuration

[](#scoring-configuration)

[![Scoring configuration](resources/screenshoots/ProductImageSearch-configuration-scoring.png)](resources/screenshoots/ProductImageSearch-configuration-scoring.png)

### Trusted Sources Configuration

[](#trusted-sources-configuration)

[![Trusted sources configuration](resources/screenshoots/ProductImageSearch-configuration-trusted-sources.png)](resources/screenshoots/ProductImageSearch-configuration-trusted-sources.png)

Architecture
------------

[](#architecture)

This repository is a Laravel 13 admin/demo application, not a reusable UI package. It consumes the sibling headless package through a Composer path repository:

```
..\product_image_discovery
..\product_image_discovery_admin

```

The stack is intentionally boring and inspectable:

- Laravel 13 host app.
- SQLite by default for local development and tests.
- Blade shell at the admin route.
- Vite + React for the operator UI.
- Session/CSRF-protected admin JSON wrappers.
- Package API left available under its own prefix.
- Playwright browser smoke coverage for desktop and tablet layouts.

Quickstart
----------

[](#quickstart)

End-to-end walkthrough from a fresh clone to a working Brave-backed debug run on macOS/Linux. Windows/Herd users have an equivalent block below in [Local Setup](#local-setup).

Prerequisites: PHP 8.3+, Composer, Node 20+ (npm 10+), and a checkout of the sibling package next to this repo:

```
parent/
├─ product_image_discovery/         # headless package
└─ product_image_discovery_admin/   # this repo

```

### 1. Install dependencies

[](#1-install-dependencies)

```
composer install
npm ci
```

### 2. Configure the environment

[](#2-configure-the-environment)

```
cp .env.example .env
php artisan key:generate
touch database/database.sqlite
```

Open `.env` and confirm at minimum:

```
APP_URL=http://127.0.0.1:8000
DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database/database.sqlite   # or leave default
SESSION_DRIVER=file
PID_ADMIN_ROUTE_MIDDLEWARE=web
PID_ADMIN_DEBUG_RUN_MIDDLEWARE=auth
```

`BRAVE_SEARCH_API_KEY` is intentionally **not** read from `.env`. Search-provider credentials live in the database (write-only via the admin UI). See step 6.

### 3. Migrate and seed demo data

[](#3-migrate-and-seed-demo-data)

```
php artisan migrate
php artisan pid-admin:seed-demo
```

This creates:

- the deterministic Herno / Nike / New Balance demo requests,
- a demo `fake-demo` search provider (seeded `is_active=true`, `priority=1`),
- a demo admin user — **email `admin@demo.test`, password `password`**, **only when `APP_ENV` is `local` or `testing`**. In any other environment the seeder skips the user step so a known-credentials operator never lands in a non-dev DB. Use `pid-admin:create-user` for staging/production.

> The artisan command is namespaced. Use `pid-admin:seed-demo`, not `seed-demo`.

If you want a real user instead of the demo one:

```
php artisan pid-admin:create-user you@example.com --name="You" --password=secret
# omit --password to receive a generated one (printed once)
```

### 4. Build the frontend and start the server

[](#4-build-the-frontend-and-start-the-server)

```
npm run build
php artisan serve
```

Leave `php artisan serve` running. For frontend hot reload during development run `npm run dev` in a second terminal instead of `npm run build`.

### 5. Sign in

[](#5-sign-in)

Open `http://127.0.0.1:8000/login`, log in with `admin@demo.test` / `password`, and you'll land on `http://127.0.0.1:8000/admin/product-image-discovery`.

The admin shell (Blade + React) uses the configured `web` middleware, but `/debug-runs` and `POST /requests` sit behind `auth` by default, which is why the login step is required before they respond. The Logout button lives in the topbar.

### 6. Configure a real search provider (Brave)

[](#6-configure-a-real-search-provider-brave)

The demo `fake-demo` provider is intentionally first in priority so out-of-the-box runs work offline. To exercise a real Brave search you need to either disable the fake provider or give Brave a higher priority (lower number).

1. Sign in, then open `http://127.0.0.1:8000/admin/product-image-discovery/providers`.
2. Edit `fake-demo` and set `is_active = false`, **or** keep it active and bump its `priority` to a high number (e.g. `100`).
3. Create or update a Brave provider:
    - `code`: `brave`
    - `driver`: `brave`
    - `name`: `Brave`
    - `base_url`: `https://api.search.brave.com`
    - `api_key`: your Brave API key (write-only — saved encrypted, never echoed back)
    - `is_active`: `true`
    - `priority`: `1` (or any value lower than the rest)

> Provider selection: `SearchProviderManager` orders active providers by `priority` ASC and uses the first that returns non-empty results. The rest are treated as fallbacks.

### 7. Run a debug flow against Brave

[](#7-run-a-debug-flow-against-brave)

1. Open `http://127.0.0.1:8000/admin/product-image-discovery/debug`.
2. Leave the default Herno payload (or paste your own product JSON). The fields the package actually reads are:

    RequiredOptional`client_id`, `erp_model_color_id`, `brand``supplier`, `supplier_sku`, `model_code`, `color_code`, `color_name`, `category`, `description`, `ean`, `season`, `material`, `metadata` (any keys)Anything outside this set is preserved on the request but not used by the search/scoring/AI pipeline. `description` (or its fallbacks `name` / `title` / `metadata.description` / `metadata.title`) is used as a search term when `model_code` is empty, so for products that don't have a clean SKU it's important to fill it in.
3. Recommended options for a first real test:

    - `no_env_brave: true` (default) — keep it; we are using the DB provider, not auto-creating one from env.
    - `no_download: true` (default) — skip downloading the candidate images. You will still see them via the **View Image** column in the report.
    - `max_candidates: 2` (default) or higher.
4. Click **Run debug**. The right panel polls until status becomes `succeeded` or `failed`.

### 8. Inspect the report

[](#8-inspect-the-report)

Open `http://127.0.0.1:8000/admin/product-image-discovery/reports`, click **Open** on the latest run.

The **Request** tab shows two sections:

- `package_request_summary` — the slim summary the package emits in the report (id, status, brand, model\_code, color\_name, scores, candidate pointers).
- `original_request_payload` — the full JSON you submitted to the debug flow, redacted. This is the place to verify that `description`, `ean`, `metadata`, and any other optional field actually arrived at the package.

In the **Candidates** tab the table is sorted by `final_score` desc — the top row is the best match. Each row exposes:

- `View URL` — opens `source_page_url` in a new tab (the page Brave found)
- `View Image` — opens `image_url` in a new tab (works even with `no_download: true`)

Empty/invalid URLs render as a disabled chip.

### Common pitfalls

[](#common-pitfalls)

- **`401 Unauthorized` on `/debug-runs`** — you are not signed in. Visit `/login` (step 5).
- **`Command "seed-demo" is not defined`** — use the prefix: `php artisan pid-admin:seed-demo`.
- **`BRAVE_SEARCH_API_KEY missing` on the Health screen** — the slot label is now `BRAVE_SEARCH_PROVIDER`. It checks the DB, not env. Configure a Brave provider (step 6).
- **Brave never gets called** — the `fake-demo` provider has `priority: 1` and short-circuits the chain. Disable it or raise its priority (step 6).
- **All candidates land in `manual_review` even with high score** — that's expected without trusted sources. Add the candidate's host on `/admin/product-image-discovery/trusted` if you want `verified_match`/`ready_to_publish`.
- **You changed React/CSS and don't see the change** — `npm run build` writes to `public/build/`; the browser may cache the old bundle. Hard refresh (`Cmd+Shift+R` on macOS, `Ctrl+F5` on Linux). For iterative work prefer `npm run dev`.

Local Setup
-----------

[](#local-setup)

Keep the headless package checked out beside this app:

```
..\product_image_discovery
..\product_image_discovery_admin

```

Install and bootstrap the app:

```
composer install
Copy-Item .env.example .env -ErrorAction SilentlyContinue
php artisan key:generate --ansi
New-Item -ItemType File database\database.sqlite -Force
php artisan migrate
php artisan pid-admin:seed-demo --fresh
npm ci
npm run build
php artisan serve
```

Open:

```
http://127.0.0.1:8000/admin/product-image-discovery

```

If `php` is not on PATH, this Windows/Herd workstation uses:

```
%USERPROFILE%\.config\herd\bin\php84\php.exe

```

Login
-----

[](#login)

Debug-run endpoints (`POST /admin/product-image-discovery/debug-runs`, `POST /admin/product-image-discovery/requests`) sit behind the `auth` middleware controlled by `pid-admin.debug_run_middleware`. The admin shell itself runs under `web` only, but operators must sign in before the debug and request-creation surfaces respond.

The app ships with three minimal endpoints, registered outside the admin prefix:

```
GET  /login
POST /login
POST /logout

```

The `pid-admin:seed-demo` command seeds a demo operator suitable for local/offline testing **only when `APP_ENV` is `local` or `testing`**:

- email: `admin@demo.test`
- password: `password`

Outside those environments the seeder skips the demo user, so a well-known credential never lands in a staging or production database. Use `pid-admin:create-user` instead.

Create or update a real user with the artisan helper:

```
php artisan pid-admin:create-user me@example.com --name="Op"
# omit --password to receive a generated one (printed once)
php artisan pid-admin:create-user me@example.com --password=secret
```

The admin topbar exposes a Logout button that submits a CSRF-protected `POST /logout`.

To bypass auth in CI or short-lived local smoke tests, leave `PID_ADMIN_DEBUG_RUN_MIDDLEWARE` empty. The PHPUnit suite already does this in `phpunit.xml`.

Demo Data
---------

[](#demo-data)

The local seeder gives you deterministic, offline-friendly scenarios:

- Herno manual-review fashion request.
- Nike candidate review and retry/no-candidate workflows.
- New Balance ready/selected-image example.
- Fake demo provider and trusted demo sources.
- Inline generated candidate images so previews work without live downloads.

Reset the demo state with:

```
php artisan pid-admin:seed-demo --fresh
```

Testing
-------

[](#testing)

Run the full local release gate:

```
composer validate --strict
npm run phpunit
npm run test
npm run build
npm run e2e
```

`npm run phpunit` is the preferred PHP test entry point on this machine because it resolves Herd PHP 8.4 before falling back to `php` on PATH.

CI
--

[](#ci)

GitHub Actions runs the same release gate on pushes and pull requests:

- checkout this admin app and the sibling `padosoft/product_image_discovery` package
- `composer validate --strict`
- `composer install`
- `npm ci`
- `npm run phpunit`
- `npm run test`
- `npm run build`
- `npm run e2e:ci`
- upload Playwright traces/screenshots on failure

Security Model
--------------

[](#security-model)

- Provider credentials are write-only.
- JSON responses expose credential booleans such as `has_api_key`, never raw secrets or partial previews.
- Debug reports and stored artifacts are redacted before display/download.
- Admin wrappers use same-origin fetch and CSRF/session protection.
- High-impact debug/request creation endpoints support stricter configurable middleware and throttling.
- Candidate source URLs are normalized before browser navigation.
- CSV exports neutralize spreadsheet formula prefixes in untrusted text cells.

Admin Routes
------------

[](#admin-routes)

The admin console lives at:

```
/admin/product-image-discovery

```

Admin JSON wrappers live under:

```
/admin/product-image-discovery/...

```

The package API remains available at:

```
/api/product-image-discovery/...

```

Relationship To The Package
---------------------------

[](#relationship-to-the-package)

Use this app when you want the ready-made professional admin experience. Use [`padosoft/product-image-discovery`](https://github.com/padosoft/product_image_discovery) directly when you only need the headless API, models, jobs, configuration, and package-level integration surface.

The admin app intentionally stays close to the package contracts and avoids exposing implementation-only secrets or internal raw payloads.

Process Docs
------------

[](#process-docs)

Read `AGENTS.md` first when resuming this project. The durable implementation plan is saved at:

```
%USERPROFILE%\Downloads\productimagesearch-admin\plan.md

```

The project history and non-obvious setup lessons are tracked in:

- [`docs/PROGRESS.md`](docs/PROGRESS.md)
- [`docs/LESSON.md`](docs/LESSON.md)
- [`docs/RULES.md`](docs/RULES.md)

License
-------

[](#license)

Apache-2.0. See [LICENSE](LICENSE).

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance93

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 92.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

3

Last Release

36d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/10467699?v=4)[Lorenzo](/maintainers/lopadova)[@lopadova](https://github.com/lopadova)

---

Top Contributors

[![lopadova](https://avatars.githubusercontent.com/u/10467699?v=4)](https://github.com/lopadova "lopadova (104 commits)")[![januabisconti](https://avatars.githubusercontent.com/u/171591409?v=4)](https://github.com/januabisconti "januabisconti (5 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (3 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/padosoft-product-image-discovery-admin/health.svg)

```
[![Health](https://phpackages.com/badges/padosoft-product-image-discovery-admin/health.svg)](https://phpackages.com/packages/padosoft-product-image-discovery-admin)
```

###  Alternatives

[backpack/crud

Quickly build admin interfaces using Laravel, Bootstrap and JavaScript.

3.4k3.6M217](/packages/backpack-crud)[unopim/unopim

UnoPim Laravel PIM

10.1k2.2k](/packages/unopim-unopim)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
