Passa al contenuto principale

RIC-136 — Candidates "select all" + redesigned toolbar (docs) Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Update docs/acquisti/step.mdx (and check faq.mdx) so the "Selezione fornitori" section matches the redesigned candidates-list toolbar — the Seleziona tutti i candidati / Cancella selezione button, the Filtra: toggles, Contatta Fornitori, and the per-card Aggiungi ai contatti — and re-capture the affected screenshots from the running app.

Architecture: Docs-only change in the factorybook-user-guide Docusaurus repo. Prose is rewritten from a verified model of the UI (webapp source). Screenshots are re-captured against the local ../factorybook stack using a new demo seeder that puts an RFQ into SELEZIONE FORNITORI. The Aggiungi ai contatti dialog is already documented in connessioni/elenco.mdx, so step.mdx only mentions it and cross-links.

Tech Stack: Docusaurus (MDX), pnpm; Laravel seeders (../factorybook/backend); chrome-devtools MCP for screenshots.

Reference: Spec at docs/superpowers/specs/2026-07-18-ric-136-candidates-select-all-design.md.

Global Constraints

  • User-facing doc content is Italian; code, seeders, commit messages, and file names are English (per CLAUDE.md).
  • UI labels must be copied verbatim from the app: Aggiungi fornitori, Importa fornitori, Ricerca automatica, Seleziona tutti i candidati, Cancella selezione, Filtra:, Con quotazione, Con messaggi, Contatta Fornitori, Aggiungi ai contatti, Nei contatti.
  • Screenshots: viewport 1423×867 @2x, saved to static/img/screenshots/ with kebab-case Italian names. Reuse the existing filenames (acquisti-lista-candidati.png, acquisti-candidati-selezione-free.png, acquisti-candidati-stati.png) so MDX references don't change.
  • Demo account: [email protected] / password, company Tecnomec S.r.l., via DemoUserSeeder. Demo data must be realistic Italian (company names, provinces) — never lorem ipsum.
  • All docs-repo commands run in the worktree: /Users/ricventu/code/Factorybook/factorybook-user-guide/.claude/worktrees/ricventu+ric-136-seleziona-tutti-nella-lista-candidati. Seeder/app commands run in /Users/ricventu/code/Factorybook/factorybook.
  • Docusaurus build must pass (broken-link check runs during pnpm build).

File Structure

  • Modify (docs worktree):
    • docs/acquisti/step.mdx — rewrite the "Selezione fornitori" toolbar + selection/contact prose; add the Aggiungi ai contatti paragraph.
    • docs/faq.mdx — consistency check only (likely unchanged).
    • static/img/screenshots/acquisti-lista-candidati.png, acquisti-candidati-selezione-free.png, acquisti-candidati-stati.png — re-captured (binary).
  • Create (app repo ../factorybook):
    • backend/database/seeders/DocsCandidatesSelectAllSeeder.php — RFQ in SELEZIONE FORNITORI with realistic candidates, for the demo account.

Task 1: Rewrite the "Selezione fornitori" toolbar + selection/contact prose in step.mdx

Files:

  • Modify: docs/acquisti/step.mdx (section "Selezione fornitori", ≈ lines 42–61, plus audit through line ~99)

Interfaces:

  • Consumes: existing screenshot references (unchanged filenames), existing <StateLabel> usage, existing cross-link style /docs/....

  • Produces: accurate prose describing the two-row toolbar + per-card Aggiungi ai contatti (consumed by the reader; screenshots in Task 4 must match it).

  • Step 1: Read the current section

Run: open docs/acquisti/step.mdx and re-read lines 29–99 to anchor the edits.

  • Step 2: Replace the "Sopra l'elenco si trovano" bullets (≈ lines 42–46)

Replace the current single-row bullet list with a two-row description. Use exactly this content (Italian):

Sopra la lista sono presenti due file di comandi.

La prima riga raccoglie le azioni per popolare l'elenco:

- **Aggiungi fornitori** — apre una finestra per aggiungere manualmente fornitori specifici, cercandoli per nome o scegliendoli da una lista di contatti;
- **Importa fornitori** — consente il caricamento in blocco di più fornitori;
- il box di **ricerca**, a destra, per filtrare i candidati per nome.

Quando è possibile ampliare l'elenco compare inoltre il riquadro **Ricerca automatica**, che avvia (o ripete) la ricerca automatica dei fornitori in base alla descrizione della richiesta e alle aree di lavoro.

La seconda riga gestisce selezione, filtri e contatto:

- **Seleziona tutti i candidati** — il pulsante seleziona in blocco tutti i candidati; una volta selezionati tutti, la stessa etichetta diventa **Cancella selezione** per azzerare la scelta;
- **Filtra:** — gli interruttori **Con quotazione** e **Con messaggi** restringono la lista ai soli fornitori che hanno interagito;
- **Contatta Fornitori** — il pulsante, a destra, invia la richiesta ai fornitori selezionati; resta disattivato finché non è selezionato almeno un candidato.
  • Step 3: Rewrite the select/contact prose (the old ≈ line 61 sentence)

Ensure the prose after the plan subsection reflects the button (not a checkbox). Replace the "Una volta definita la selezione, premere CONTATTA FORNITORI…" sentence with:

Definita la selezione — in blocco con **Seleziona tutti i candidati**, oppure una alla volta con la checkbox sulla card (funzione dei piani Base e Premium) — premere **Contatta Fornitori** per inviare la richiesta ai candidati scelti. La selezione può essere rimandata e ripresa in un secondo momento.
  • Step 4: Keep and reconcile "Selezione dei candidati e piani" (≈ lines 48–58)

Leave the plan-tier subsection and its Free alert quote as-is (verified still accurate). Only change the phrase "la checkbox Seleziona tutti" if it still appears, so it refers to the Seleziona tutti i candidati button. The Free-plan alert text and the "contatto gratuito" info admonition stay unchanged.

  • Step 5: Add the "Aggiungi ai contatti" paragraph

After the contact prose (before the "Analisi delle offerte" heading), add:

:::tip[Salvare un fornitore tra i contatti]
Ogni card dispone del pulsante **Aggiungi ai contatti**, che salva il fornitore nella tua rubrica e nelle [liste di contatti](/docs/connessioni/liste), indipendentemente dal fatto che lo si contatti per questa richiesta. Una volta salvato, il pulsante mostra **Nei contatti**; la freccia accanto apre la finestra completa di gestione del contatto (tipo contatto, referente, note, liste). Per i dettagli vedi [Elenco Connessioni](/docs/connessioni/elenco).
:::
  • Step 6: Audit the rest of the section

Skim lines ~63–99 ("Analisi delle offerte", "Feedback dai fornitori"). Confirm the filters mention (≈ line 83) is consistent with the toggles ("opzioni Con quotazione e Con messaggi" is fine). Fix any remaining "checkbox"/"a destra la checkbox Seleziona tutti" wording. Make no other content changes.

  • Step 7: Build to verify MDX + links

Run (in the worktree): pnpm build Expected: build completes; no MDX parse error; no "Docusaurus found broken links" for the new /docs/connessioni/liste and /docs/connessioni/elenco anchors.

  • Step 8: Commit
git add docs/acquisti/step.mdx
git commit -m "docs(acquisti): document redesigned candidates toolbar & select-all (RIC-136)"

Task 2: FAQ consistency check

Files:

  • Modify (only if needed): docs/faq.mdx (≈ lines 106, 308)

Interfaces:

  • Consumes: the select-all/plan wording finalized in Task 1.

  • Produces: a FAQ consistent with step.mdx.

  • Step 1: Read the two FAQ passages

Run: read docs/faq.mdx around lines 100–110 and 305–312.

  • Step 2: Compare against Task 1 wording

Both passages already say: bulk Seleziona tutti on all plans; single-supplier selection on Base/Premium. Confirm they still match step.mdx. If they contradict the rewritten section, make the minimal edit to align (keep the existing [Vai alla guida →](/docs/acquisti/step) link).

  • Step 3: Build (only if a change was made)

Run: pnpm build Expected: build passes.

  • Step 4: Commit (only if a change was made)
git add docs/faq.mdx
git commit -m "docs(faq): align candidates selection wording with RIC-136"

If no change was needed, note "FAQ already consistent — no edit" and skip the commit.


Task 3: Seed a SELEZIONE FORNITORI candidates list for the demo account

Files:

  • Create: ../factorybook/backend/database/seeders/DocsCandidatesSelectAllSeeder.php
  • Reference/template: ../factorybook/backend/database/seeders/Ric75CandidateStatesSeeder.php

Interfaces:

  • Consumes: DemoUserSeeder (demo user + Tecnomec company), the QuotationRequest/QuotationCandidate factories, and the CANDIDATE_SELECTION request-state class.

  • Produces: one RFQ (order_number = 'RIC136-DEMO') in SELEZIONE FORNITORI with ~6 verified, uncontacted candidates → the data Task 4 screenshots.

  • Step 1: Confirm the CANDIDATE_SELECTION state class and demo seeder constants

Run (in ../factorybook): grep -rn "class CandidateSelection" backend/app/States/QuotationRequest/ and grep -n "USER_EMAIL\|COMPANY_NAME\|const " backend/database/seeders/DemoUserSeeder.php Expected: a App\States\QuotationRequest\CandidateSelection class exists, and DemoUserSeeder exposes the demo email/company (or seeds [email protected] / Tecnomec S.r.l.). Use whichever accessor DemoUserSeeder provides to look up the user/company (mirror how Ric75CandidateStatesSeeder looks them up, but bound to DemoUserSeeder, not LocalTestUserSeeder).

  • Step 2: Write the seeder

Create DocsCandidatesSelectAllSeeder.php, modeled on Ric75CandidateStatesSeeder but:

  • ORDER_NUMBER = 'RIC136-DEMO', subject e.g. 'RIC-136 · Selezione fornitori'.

  • Bootstraps via DemoUserSeeder (call it if the demo user is missing), and resolves the demo User + Company from it.

  • RFQ state: App\States\QuotationRequest\CandidateSelection (SELEZIONE FORNITORI), so the Seleziona tutti i candidati button is enabled and no offers/badges are present.

  • ~6 verified, registered candidates with realistic Italian names + provinces and an ai_motivation, all uncontacted (sent_at = null, no quotations, no messages, not preselected) so the list shows the clean pre-contact state. Realistic names, e.g.: Meccanica Alpina S.r.l. (Cuneo, CN), Ferrari e figli (Verona, VR), Officine Padane S.p.A. (Rovigo, RO), CarpenterIa Adriatica S.r.l. (Ancona, AN), Tornerie Lombarde S.r.l. (Brescia, BS), Precisione Emiliana S.r.l. (Modena, MO). (Fix the intentional typo — use Carpenteria Adriatica S.r.l.)

  • Idempotent cleanPreviousDemo() keyed on ORDER_NUMBER (copy the pattern from the template).

  • Print the RFQ uuid at the end.

  • Step 3: Run the seeder

Run (in ../factorybook/backend): php artisan db:seed --class=DocsCandidatesSelectAllSeeder Expected: Seeded demo RFQ 'RIC136-DEMO' (<uuid>) for [email protected].

  • Step 4: Verify idempotency

Run the same command again. Expected: it succeeds again with a single RIC136-DEMO RFQ (no duplicate) — confirm with php artisan tinker --execute="echo \App\Models\QuotationRequest::withTrashed()->where('order_number','RIC136-DEMO')->count();" Expected output: 1.

  • Step 5: Commit the seeder (in the app repo, on a safe branch)

The seeder lives in ../factorybook, not the docs branch. Do NOT commit it to the docs worktree. In ../factorybook, commit it on a non-default branch (or leave it staged for the maintainer per their preference):

cd /Users/ricventu/code/Factorybook/factorybook
git add backend/database/seeders/DocsCandidatesSelectAllSeeder.php
git commit -m "test(seeders): DocsCandidatesSelectAllSeeder for RIC-136 docs screenshots"

If committing to the app repo is out of scope for this session, note that the seeder was created + run and leave it for the maintainer.


Task 4: Re-capture the screenshots

Files:

  • Modify (docs worktree, binary): static/img/screenshots/acquisti-lista-candidati.png, static/img/screenshots/acquisti-candidati-selezione-free.png, and conditionally static/img/screenshots/acquisti-candidati-stati.png

Interfaces:

  • Consumes: the seeded RIC136-DEMO RFQ (Task 3) and, for the badges shot, the RIC75-DEMO RFQ (existing seeder).

  • Produces: updated PNGs matching the Task 1 prose.

  • Step 1: Boot the local stack

In ../factorybook: ensure minio is running, then start backend and webapp: cd backend && php artisan serve --port=8000 and (separate shell) cd webapp && pnpm dev. Confirm hosts app.factorybook.test / api.factorybook.test resolve to 127.0.0.1. Expected: the app loads at http://app.factorybook.test.

  • Step 2: Log in as the demo account (chrome-devtools MCP)

Set viewport to 1423×867 @2x. Navigate to /login, use the Password tab, log in as [email protected] / password. Expected: dashboard loads for Tecnomec S.r.l.

  • Step 3: Open the seeded RFQ candidates list

Navigate to Acquisti > Richieste di Quotazione, open RIC136-DEMO (SELEZIONE FORNITORI). Confirm the candidates list shows the redesigned toolbar (Aggiungi fornitori / Importa fornitori / search; then Seleziona tutti i candidati + Filtra: toggles + Contatta Fornitori) and cards with the Aggiungi ai contatti button.

  • Step 4: Capture acquisti-lista-candidati.png

Frame the toolbar + at least one full card (showing Aggiungi ai contatti). Save/overwrite to static/img/screenshots/acquisti-lista-candidati.png in the docs worktree. Expected: PNG at 2× width (~2846 px wide), replacing the old file.

  • Step 5: Capture acquisti-candidati-selezione-free.png (Free plan)

Reproduce the Free-plan state (per-card checkbox gated + the plan alert visible). First check how the current file was produced: git log --oneline -- static/img/screenshots/acquisti-candidati-selezione-free.png and inspect any related seeder. If no dedicated mechanism exists, temporarily set the demo company's subscription to a Free/Presenza plan (via the app admin or php artisan tinker), capture, then restore the original plan. Save/overwrite to static/img/screenshots/acquisti-candidati-selezione-free.png. Expected: the shot shows the alert "Con il tuo piano puoi contattare tutti i fornitori candidati insieme…" and the select-all button.

  • Step 6: Re-capture acquisti-candidati-stati.png only if the toolbar is visible

Open the RIC75-DEMO RFQ (ANALISI OFFERTE, badge states — run php artisan db:seed --class=Ric75CandidateStatesSeeder if not present). If the redesigned toolbar appears above the badge cards in the framing, re-capture so it stays consistent; otherwise leave the file unchanged and note "badges shot unaffected". Save/overwrite to static/img/screenshots/acquisti-candidati-stati.png if re-captured.

  • Step 7: Verify the images changed

Run (in the worktree): git status --short static/img/screenshots/ Expected: the re-captured PNG(s) listed as modified. Spot-check one by opening it — the new toolbar must be visible.

  • Step 8: Commit the screenshots
git add static/img/screenshots/acquisti-lista-candidati.png static/img/screenshots/acquisti-candidati-selezione-free.png
# add acquisti-candidati-stati.png only if re-captured
git commit -m "docs(acquisti): refresh candidates-list screenshots for RIC-136"

Task 5: Final verification

Files: none (verification only)

  • Step 1: Clean build

Run (in the worktree): pnpm build Expected: build succeeds; no broken links; no MDX errors.

  • Step 2: Visual check

Run: pnpm start, open /docs/acquisti/step, scroll to "Selezione fornitori". Expected: the prose matches the new toolbar; the Aggiungi ai contatti tip and cross-links render; the new screenshots display and are legible; the plan-tier subsection reads correctly.

  • Step 3: Confirm success criteria (from the spec)

Verify each spec success criterion: two-row toolbar described; select-all/clear button; Filtra: toggles; Contatta Fornitori; per-card Aggiungi ai contatti with cross-links; plan-tier rules consistent between step.mdx and faq.mdx; screenshots current; no stale "checkbox" wording; build clean.

  • Step 4: Report status

Summarize what changed (files, screenshots, seeder) and confirm all criteria met. The branch is ready for review.


Self-Review

  • Spec coverage: Toolbar rewrite → Task 1; Aggiungi ai contatti mention + cross-links → Task 1 Step 5; plan-tier text preserved → Task 1 Step 4; FAQ check → Task 2; screenshots (3 files) → Task 4; demo data/seeder → Task 3; build/link verification → Tasks 1, 5. All spec sections mapped.
  • Placeholder scan: No TBD/TODO; all doc prose is provided verbatim; screenshot/seeder steps give exact commands. The one investigative step (Free-plan mechanism, Task 4 Step 5) has a concrete fallback (temporarily set the subscription plan).
  • Consistency: Screenshot filenames identical across Tasks 4 and the spec and existing step.mdx references; ORDER_NUMBER = 'RIC136-DEMO' used consistently across Task 3 steps; UI labels match the Global Constraints verbatim list.