# Project Structure Wave B Verification

> Phase: `DASH.ProjectStructureHygieneCleanup.WaveB`
>
> Date: 2026-08-04
>
> Status: **COMPLETE**
>
> Scope: verification of the existing 27-file horizontal deletion set only.

## 1. Executive result

The architectural deletion proof is successful:

- all 27 approved horizontal files are absent;
- all 27 paths remain represented by the pre-existing Git deletion set;
- every deleted controller and validator has a vertical replacement;
- both deleted Product helpers have module-owned replacements;
- runtime source references to deleted paths: **0**;
- all 14 affected route groups import public vertical module indices;
- focused architecture, route, middleware, CSRF, Product, and module tests pass;
- no runtime, route, middleware, UI, API, Auth, Product, schema, package, or migration change was made by Wave B.

The separately approved blocker-close pass completed the browser proof:

- Package Features mobile context title is readable in two lines at `390x844`;
- Socials list/show/edit/delete-modal states were exercised with one guarded,
  non-production QA record;
- the QA record and its local image were removed after evidence capture;
- final combined browser metrics are all **0**, including `clippedTextCount` and
  `DATA_BLOCKED`;
- Wave B is now `COMPLETE`.

## 2. Change accounting

Wave B adds only:

- `test/dashboardStructureWaveB.test.js`;
- this verification document;
- ignored browser screenshots/manifests under
  `public/admin/ui-lab/screenshots/project-structure-wave-b/`.

The approved blocker-close pass additionally adds:

- one narrow mobile shell CSS correction in `public/admin/assets/css/components.css`;
- `scripts/qa/ensureWaveBSocialsRecord.js` with mandatory `--qa-only`, production
  refusal, dry-run, reuse, and cleanup behavior;
- `test/dashboardWaveBBlockerClose.test.js`;
- ignored final evidence under
  `public/admin/ui-lab/screenshots/project-structure-wave-b-final/`.

No additional file was deleted. The 17 staged `.DS_Store` removals belong to the already
completed Wave A. All other modified/deleted/untracked runtime and presentation files
predate Wave B and were preserved without change.

## 3. Exact controller replacement map

| Deleted horizontal controller | Vertical replacement ownership | Module public import | Route surface | Result |
|---|---|---|---|---|
| `src/controllers/dashboard/attributesController/attributesController.js` | `attributes.controller/service/repository/viewModel/validation/constants/policy/query.js`; value handlers moved to `attribute-values.*` | `@root/modules/dashboard/attributes`, `@root/modules/dashboard/attribute-values` | `/attributes`, `/attributes/colors`, `/attributes/sizes` | `SAFE_REPLACED` |
| `src/controllers/dashboard/cityController/cityController.js` | `src/modules/dashboard/cities/cities.*.js` | `@root/modules/dashboard/cities` | `/cities` | `SAFE_REPLACED` |
| `src/controllers/dashboard/countryController/countryController.js` | `src/modules/dashboard/countries/countries.*.js` | `@root/modules/dashboard/countries` | `/countries` | `SAFE_REPLACED` |
| `src/controllers/dashboard/couponController/couponController.js` | `src/modules/dashboard/coupons/coupons.*.js` | `@root/modules/dashboard/coupons` | `/coupons` | `SAFE_REPLACED` |
| `src/controllers/dashboard/departmentsController/departmentsController.js` | `src/modules/dashboard/departments/departments.*.js` | `@root/modules/dashboard/departments` | `/departments` | `SAFE_REPLACED` |
| `src/controllers/dashboard/packageController/packageController.js` | `src/modules/dashboard/packages/packages.*.js` | `@root/modules/dashboard/packages` | `/packages` | `SAFE_REPLACED` |
| `src/controllers/dashboard/packageFeatureController/packageFeatureController.js` | `src/modules/dashboard/package-features/package-features.*.js` | `@root/modules/dashboard/package-features` | `/packageFeatures` | `SAFE_REPLACED` |
| `src/controllers/dashboard/premiumPackageController/premiumPackageController.js` | `src/modules/dashboard/premium-packages/premium-packages.*.js` | `@root/modules/dashboard/premium-packages` | `/premiumPackages` | `SAFE_REPLACED` |
| `src/controllers/dashboard/productController/productController.js` | `src/modules/dashboard/products/products.controller/service/repository/viewModel/validation/constants/policy/query/uploads/moderation.js` | `@root/modules/dashboard/products` | `/products`, `/products/goldRequests` | `SAFE_REPLACED` |
| `src/controllers/dashboard/reasonsController/reasonsController.js` | `src/modules/dashboard/reasons/reasons.*.js` | `@root/modules/dashboard/reasons` | `/reasons` | `SAFE_REPLACED` |
| `src/controllers/dashboard/socialMediaController/socialMediaController.js` | `src/modules/dashboard/socials/socials.*.js` | `@root/modules/dashboard/socials` | `/socials` | `SAFE_REPLACED` |
| `src/controllers/dashboard/subDepartmentsController/subDepartmentsController.js` | `src/modules/dashboard/sub-departments/sub-departments.*.js` | `@root/modules/dashboard/sub-departments` | `/subDepartments` | `SAFE_REPLACED` |
| `src/controllers/dashboard/subscriptionController/subscriptionController.js` | `src/modules/dashboard/subscriptions/subscriptions.controller/service/repository/viewModel/constants/policy.js` | `@root/modules/dashboard/subscriptions` | `/subscriptions` | `SAFE_REPLACED` |

Every listed folder contains `index.js` and exports the owned layers through its public
module boundary.

## 4. Exact helper replacement map

| Deleted helper | Vertical replacement | Index export | Result |
|---|---|---|---|
| `src/helpers/products/dashboardProductMedia.js` | `src/modules/dashboard/products/products.uploads.js` | `productsModule.uploads` | `SAFE_REPLACED` |
| `src/helpers/products/productModerationDashboard.js` | `src/modules/dashboard/products/products.moderation.js` | `productsModule.moderation` | `SAFE_REPLACED` |

Product upload, media rollback, moderation, visibility, delete guards, variants, AI
preservation, notification payloads, and expiry behavior remain protected by the existing
Wave 3B, Wave 3C, and Product contract tests.

## 5. Exact validator replacement map

| Deleted dashboard validator | Module-local replacement | Result |
|---|---|---|
| `src/utils/validations/dashboard/attributes.js` | `attributes/attributes.validation.js` and `attribute-values/attribute-values.validation.js` | `SAFE_REPLACED` |
| `src/utils/validations/dashboard/city.js` | `cities/cities.validation.js` | `SAFE_REPLACED` |
| `src/utils/validations/dashboard/country.js` | `countries/countries.validation.js` | `SAFE_REPLACED` |
| `src/utils/validations/dashboard/coupon.js` | `coupons/coupons.validation.js` | `SAFE_REPLACED` |
| `src/utils/validations/dashboard/departments.js` | `departments/departments.validation.js` | `SAFE_REPLACED` |
| `src/utils/validations/dashboard/package.js` | `packages/packages.validation.js` | `SAFE_REPLACED` |
| `src/utils/validations/dashboard/packageFeature.js` | `package-features/package-features.validation.js` | `SAFE_REPLACED` |
| `src/utils/validations/dashboard/premiumPackage.js` | `premium-packages/premium-packages.validation.js` | `SAFE_REPLACED` |
| `src/utils/validations/dashboard/product.js` | `products/products.validation.js` | `SAFE_REPLACED` |
| `src/utils/validations/dashboard/reasons.js` | `reasons/reasons.validation.js` | `SAFE_REPLACED` |
| `src/utils/validations/dashboard/socials.js` | `socials/socials.validation.js` | `SAFE_REPLACED` |
| `src/utils/validations/dashboard/subDepartments.js` | `sub-departments/sub-departments.validation.js` | `SAFE_REPLACED` |

Subscriptions has no deleted dashboard validator and remains a read-only module surface.

## 6. Import-reference proof

The exact deleted-path scan covers `src`, `test`, and `docs` with path boundaries so the
live `productReports` validator is not misclassified as the deleted `product` validator.

| Reference class | Count | Classification |
|---|---:|---|
| Runtime references in `src/` | 0 | Required and passing |
| Documentation/test proof references | 83 | Acceptable |
| Unresolved deleted-path imports | 0 | Required and passing |

Acceptable references occur only in:

- `docs/PROJECT_STRUCTURE_HYGIENE_REPORT.md`;
- `docs/PROJECT_STRUCTURE_WAVE_B_VERIFICATION.md`;
- `test/dashboardArchitectureRefactor.test.js`;
- `test/dashboardStructureWaveB.test.js`.

## 7. Route and middleware verification

`adminRoute.js` imports all affected modules through:

- `@root/modules/dashboard/reasons`;
- `@root/modules/dashboard/subscriptions`;
- `@root/modules/dashboard/package-features`;
- `@root/modules/dashboard/packages`;
- `@root/modules/dashboard/premium-packages`;
- `@root/modules/dashboard/socials`;
- `@root/modules/dashboard/countries`;
- `@root/modules/dashboard/cities`;
- `@root/modules/dashboard/coupons`;
- `@root/modules/dashboard/departments`;
- `@root/modules/dashboard/sub-departments`;
- `@root/modules/dashboard/attributes`;
- `@root/modules/dashboard/attribute-values`;
- `@root/modules/dashboard/products`.

The Wave B snapshot test freezes representative route chains for all 14 module surfaces,
including authentication, authorization, permission guards, upload parser position,
CSRF position, validators, `showErrorsApi`, and final handler binding.

The broader existing architecture tests additionally freeze:

- complete Reasons, Subscriptions, Packages, Package Features, Premium Packages,
  Socials, Countries, Cities, Coupons, and Product route inventories;
- catalogue handler contracts and multipart ordering;
- every Product form action and Product mutation CSRF contract;
- central-router public handler compatibility.

Comparison with the pre-migration tracked router shows controller/validator import
rewiring, Attribute Value ownership delegation, and the previously approved Product
create-route contract restoration. Wave B itself changes no path, method, ordering,
middleware, permission, validator, CSRF, upload, or handler registration.

Result:

- route snapshot: **PASS**;
- middleware order snapshot: **PASS**;
- module index import snapshot: **PASS**.

## 8. Automated architecture tests

Focused pre-documentation verification:

- existing architecture/Product gates: **49/49 passed**;
- Wave B deletion/replacement gate: **5/5 passed**;
- syntax check for the new Wave B test: **passed**.

Final repository verification:

- full `npm test`: **1007/1007 passed** across 24 suites;
- failed, skipped, cancelled, and todo tests: **0**;
- `node --check` for the Wave B architecture test, blocker-close test, and guarded QA
  helper: **passed**;
- `git diff --check`: **passed**;
- staged-diff whitespace check: **passed**;
- `postman/.export-meta.json`: test-generated timestamp restored; final status clean.

`test/dashboardStructureWaveB.test.js` enforces:

1. the exact 27-file set remains absent;
2. every deleted file has an explicit replacement;
3. runtime source imports no deleted path;
4. all route groups consume module indices;
5. route/middleware sequences remain frozen;
6. vertical ownership layers and Product-specific engines remain present.

## 9. Record-backed browser QA

The existing package-free CDP harness ran against the configured database with:

- real active dashboard admin context;
- HTTP mutations blocked;
- Mongoose writes blocked;
- no fixture or fake production data insertion.

### Pass 1 — list/create

- routes: 29;
- scenarios: 174;
- normal viewport screenshots: 87;
- delete modal screenshots: 3;
- Light desktop, Dark desktop, compact desktop, Dark tablet, Light mobile, and System
  mobile were exercised.

### Pass 2 — real details/edit links

- real record-backed routes: 25;
- scenarios: 150;
- normal viewport screenshots: 75;
- Reasons, Subscriptions, Package Features, Packages, Premium Packages, Countries,
  Cities, Coupons, Departments, SubDepartments, Attributes, Attribute Values, and
  Products were covered.

### Initial combined metrics (before blocker close)

| Metric | Result |
|---|---:|
| scenarios | 324 |
| normal viewport screenshots | 162 |
| console errors | 0 |
| failed requests | 0 |
| HTTP errors | 0 |
| navigation errors | 0 |
| unexpected redirects | 0 |
| horizontal overflow | 0 |
| overflow elements | 0 |
| broken images | 0 |
| duplicate IDs | 0 |
| unknown/raw object text | 0 |
| raw HTML text | 0 |
| debug panels | 0 |
| table alignment failures | 0 |
| forms missing CSRF | 0 |
| clipped modals | 0 |
| modal layout shifts | 0 |
| dark/light surface leaks | 0 |
| clipped text | **2** |

The two clipped-text results are identical shell findings:

- route: `/dashboard/packageFeatures/create`;
- selector: `span.kt-page-nav-context__title`;
- text: `إضافة ميزات باقات تسعير الـ AI`;
- scenarios: Light mobile and System mobile;
- measured content height: 56px;
- measured visible height: 38px.

### Data-blocked browser states

The current Socials list did not provide a record-backed link for:

- `/dashboard/socials/show/:id`;
- `/dashboard/socials/edit/:id`.

Socials list/create and all six theme/viewport scenarios rendered without measured
errors. No record was inserted because Wave B is read-only.

## 10. Browser evidence

All evidence remains ignored by Git:

- combined manifest:
  `public/admin/ui-lab/screenshots/project-structure-wave-b/browser-qa-wave-b-manifest.json`;
- list/create manifest:
  `public/admin/ui-lab/screenshots/project-structure-wave-b/list-create/browser-qa-list-create-manifest.json`;
- details/edit manifest:
  `public/admin/ui-lab/screenshots/project-structure-wave-b/details/browser-qa-details-manifest.json`;
- individual screenshots:
  `public/admin/ui-lab/screenshots/project-structure-wave-b/{list-create,details}/<module>/`.

Generated evidence files: 168. Git status entries for the evidence directory: 0.

## 11. Blocker closure

### 11.1 Package Features mobile title

Root cause: the global shell correctly allowed two title lines, but the inner-page action
dock reserved enough horizontal space at `390px` to force
`إضافة ميزات باقات تسعير الـ AI` onto a third line. The two-line clamp then reported a
real vertical clip.

The narrow mobile fix:

- gives the page context a zero-basis flexible lane;
- reduces only the context gap;
- keeps the theme icon as the full accessible trigger;
- removes the redundant chevron zone on mobile and reserves the recovered width for the
  context title;
- leaves desktop and tablet geometry unchanged.

Result at `390x844`, Light and System: title visible in two lines, no overflow, overlap,
or clipped text.

### 11.2 Socials record-backed QA

The configured development database contained no Socials records. The approved QA helper
was therefore executed in this sequence:

```text
node scripts/qa/ensureWaveBSocialsRecord.js --qa-only --dry-run
node scripts/qa/ensureWaveBSocialsRecord.js --qa-only
node scripts/qa/ensureWaveBSocialsRecord.js --qa-only --cleanup
```

The helper refuses missing `--qa-only`, `NODE_ENV=production`, and production-like
database labels. It created one `QA WaveB Social` record and one uniquely named local QA
image, then removed both after list/show/edit/delete-modal evidence was captured.

Final cleanup proof:

- QA record count: **0**;
- QA image exists: **false**;
- no production fixture remains.

### 11.3 Final combined browser gate

The final gate reran the original 54 routes plus Socials show/edit:

| Metric | Result |
|---|---:|
| routes | 56 |
| scenarios | 336 |
| viewport screenshots | 168 |
| delete modal interactions | 6 |
| data blocked states | 0 |
| clipped text | 0 |
| horizontal overflow / overflow elements | 0 / 0 |
| console / failed request / HTTP / navigation errors | 0 / 0 / 0 / 0 |
| unexpected redirects | 0 |
| broken images / duplicate IDs | 0 / 0 |
| raw object / raw HTML / debug panel findings | 0 / 0 / 0 |
| table alignment / missing CSRF | 0 / 0 |
| clipped modals / modal layout shifts | 0 / 0 |
| dark-theme surface leaks | 0 |

Final evidence:

- `public/admin/ui-lab/screenshots/project-structure-wave-b-final/browser-qa-wave-b-final-manifest.json`;
- `public/admin/ui-lab/screenshots/project-structure-wave-b-final/combined/`;
- `public/admin/ui-lab/screenshots/project-structure-wave-b-final/targeted/`.

All evidence remains ignored by Git. The architectural proof for the exact 27 deletions
and the required browser gate are both complete.

## 12. Final status

**COMPLETE**

The 27 horizontal deletions are architecturally replaced and have zero runtime import
references. The separately approved blocker-close pass resolved the mobile title and
record-backed Socials gaps. The final combined browser gate reports zero clipped text,
zero data-blocked states, and zero measured UI/runtime defects.
