Prompt
- goal: '[BBDD8SF] La taula exposa les seves 11 columnes amb els headers correctes' tier: content entry: { url: /bbdd8-distribuidoras?tableTab=salesforce, auth: user:admin } accept: - expect_table_header: { column: 1, text: "_" } - expect_table_header: { column: 2, text: "Id" } - expect_table_header: { column: 3, text: "Name" } - expect_table_header: { column: 4, text: "Clase_de_servicio__c" } - expect_table_header: { column: 5, text: "Nombre_Productor_del__c" } - expect_table_header: { column: 6, text: "Producto_Serv__c" } - expect_table_header: { column: 7, text: "Código_DTB" } - expect_table_header: { column: 8, text: "SECTOR__c" } - expect_table_header: { column: 9, text: "RechazaMultiplo01kw__c" } - expect_table_header: { column: 10, text: "ISU" } - expect_table_header: { column: 11, text: "Fecha datos" } notes: > Combinat de 11 tests atòmics de la suite BBDD8SF (t19303). Un sol test, una navegació, N comprovacions de capçalera com a passos soft (continue_on_fail). Substitueix: 1581,1592,1597,1602,1606,1609,1614,1619,1623,1627,1631.
Detalls
- Estat
- active
- Generació
- none
- Tipus
- Playwright
- Creat
- 17/07/2026 09:05
Tags
Tots els tags afegits
Cap tag assignat
Instruccions IA
Projecte
### 1. Project overview Commercial energy **webforms for Repsol**. Lets the sales network generate energy (luz/gas) offers and contracts, deliver documentation to the client, and administer the catalogs (products, templates, legal texts) that feed the contract PDFs. It integrates with **Salesforce** (SalesUser API) to sync agencies, users, channel enablements and sellable products; when automation can't produce the contract it offers **manual flows** (Contingencia wizard, Multipunto, mass CSV). Roles: **administrador, repsol, cau, agente** (agente is restricted to its own agency). Main areas: context selection (`/inicio` -> `/seleccion`), the four operative paths (Contingencia mass `/solicitudes`, Multipunto mass `/multipunto`, Documentos `/documentos`, Contingencia wizard `/contingencia/*`), QA test generation (`/generacion-pruebas/*`, `/validacion`), and the Filament admin catalogs (products, ratings, families, templates, SSJJ, config, logs, users). ### 2. Tech stack - **Backend:** PHP 8.3 (strict types), Laravel 11. **Hybrid DDD**: `app/` (Laravel MVC) + `src/` (Domain/Application/Infrastructure). - **UI / admin:** **Filament 4** (panel mounted at path `/`) + Livewire 3. Blade views. Tailwind CSS 4, Vite 6. - **Auth/permissions:** manual auth (no Breeze/Jetstream), federated SSO (SAML/Salesforce via `federation_id`); **spatie/laravel-permission** for roles. - **Security headers / CSP:** spatie/laravel-csp, bepsvpt/secure-headers. - **Excel:** maatwebsite/excel + phpoffice/phpspreadsheet. **PDF:** setasign FPDI / SetaPDF Merger (fill + overlay + **merge only - no encryption/signature**), smalot/pdfparser. **Email:** webklex/laravel-imap. - **Testing:** PHPUnit 11 (Unit + Feature) and **Laravel Dusk 8** (browser). Env: DDEV. ### 3. Authentication The Filament panel sits at `/`, so the login page is `/login`. **Credentials are `email` + `federation_id` - there is no password.** ``` Field "Correo Electronico" -> wire:model on data.email (id="data.email") Field "Federacion ID" -> wire:model on data.federation_id (id="data.federation_id") Checkbox "Recuerdame" -> data.remember ``` ```js await page.goto('/login'); await page.fill('#data\\.email', 'albert@twentic.com'); await page.fill('#data\\.federation_id', 'SE101873'); await page.getByRole('button', { name: /acceder|entrar|iniciar/i }).click(); // success -> /inicio ``` Rate limit is **5 attempts/min**. If `config('federation.active')` is true, `/login` **redirects to the SSO** page `/login/federation`. Success indicator: authenticated redirect to **`/inicio`**. Failure: validation error on `data.email` (message `auth/login.messages.failed`); an inactive/unauthorized user is logged out with `auth/login.messages.inactive`. **Test accounts** (seeded when `TWENTIC_TEST_USERS_ENABLED=true`, all in agency **"Gestores GLP"** / `agency_id 0014I00002UodzM`): | Role | email | federation_id | |---|---|---| | administrador | `albert@twentic.com` | `SE101873` | | agente | `agente@test.com` | `AGENTE001` | | cau | `cau@test.com` | `CAU001` | | repsol | `repsol@test.com` | `REPSOL001` | ### 4. Navigation Everything is a **Filament page/resource under path `/`** (no locale prefix; no `api.php`). Filament renders a top bar + sidebar. Page slugs (custom Filament Pages): ``` /inicio context selection (HomeForm cascading filters) /seleccion available operative paths /solicitudes Contingencia mass (CSV -> ZIP of PDFs) /multipunto Multipunto mass (CSV) /documentos document delivery catalog /contingencia/preparacion wizard step 2 (product) /contingencia/cliente wizard step 3 (titular) /contingencia/suministro wizard step 4 (CUPS + address) /contingencia/autorizacion wizard step 5 (consents) /contingencia/contacto wizard step 6 (contact) /contingencia/firma wizard step 7 (GDPR consents; signer name for companies) /contingencia/descarga wizard step 8 (generate PDF) /contingencia/resumen recap /generacion-pruebas QA generation hub (+ /individual, /masiva) /validacion internal PDF validation /atributos-dinamicos dynamic attributes admin ``` Admin **Filament Resources** (slugs follow the resource name): Users, Configs, Logs, Ratings, EnabledPdfFamilies, Families, ContingencyProducts / MultipuntoProducts (paquetes-productos), ContingencySSJJ / MultipuntoSSJJ, Templates, ContingencyWebformsTemplates, Bbdd8Distributors, ChannelMix, DocumentCategories, DocumentSubclusters, Documents, ScreenConfig, etc. ### 5. Custom components and how to interact with them **Filament forms are NOT native HTML controls.** A Filament `Select` is a custom searchable widget; do not use `selectOption()`. Click the control, then click the option in the floating listbox; identify the field by its `wire:model` (`data.<field>`) or its visible label. **`/inicio` cascading filters** (`app/Livewire/HomeForm.php`) - must be filled **in order**, each upstream change **resets** the ones below: ``` data.agencyId (required; DISABLED + defaulted to own agency for 'agente') data.channelId (required; disabled until agencyId set; options depend on agency) data.subchannelId (required; disabled until channelId set) data.channelMixId (required + VISIBLE only if user can 'select-home-channel-mix') data.date (Filament DatePicker, required; disabled if user lacks 'select-home-date') ``` ```js // fill in strict order, waiting for each dependent select to populate await selectFilament(page, 'data.agencyId', 'Gestores GLP'); await selectFilament(page, 'data.channelId', '<channel>'); // wait for options await selectFilament(page, 'data.subchannelId', '<subchannel>'); // channelMixId only if visible; date via the Filament DatePicker ``` **Mass-upload pages** (`/solicitudes`, `/multipunto`, `/generacion-pruebas/masiva`): Filament `FileUpload` (Livewire upload, not a plain `<input type=file>`; wait for the Livewire upload to finish before submitting). Output is a **PDF / ZIP download** (and the Ficha-de-Precios export runs in a **queue**, surfaced as a temp-download link). **Wizard steps:** each `/contingencia/*` page guards the presence of `session('homeForm')`, the filters and the permissions before rendering; the "Firma" step paints GDPR consent values (LOPD2/LOPD3/LOPD5) as text and, **for companies only**, requires the signer name. **Downloads** go through named routes: `documents.download`, `documents.download-zip`, `faker.pdf.download`, `subclusters.show`, `export.temp-download`, `get-test-pdf`. ### 6. How to uniquely identify elements - Filament fields: prefer `wire:model="data.<field>"` or the field **label**; the input `id` is `data.<field>`. - Pages: target by **URL slug** (`/inicio`, `/contingencia/firma`, ...) and headings. - Resource tables/actions: use Filament action **labels** and column headers, plus the resource **URL**. - Avoid Filament's auto-generated `wire:key`/component ids - they are not stable. ### 7. Important data attributes / conventions - Livewire form state is under `data.*`; Livewire updates POST to `/livewire/update`. - Wizard state persists in `session('homeForm')` across the 8 steps. - Snapshots are versioned by `version_date`; future dates are capped to today on resolution. - Timezone is `Europe/Madrid` (ICU requires that exact capitalization). - PDF template codes look like `CE_01_PF_LUZ`, `CE_02_PF_GAS`.
Features Desat!
Cost IA
- Total
- $0.00c
- Generació
- $0.00c
- Execucions
- $0.00c
- Tokens totals
- 0
- Crides API
- 0
Últimes Execucions
Cap execució encara.