# Project Structure Hygiene Audit

> Phase: `DASH.ProjectStructureHygieneAudit`
>
> Audit date: 2026-08-04
>
> Branch: `dev`
>
> Mode: report-only; this phase performs no cleanup, move, rename, import rewrite, route change, or runtime change.

> Historical-snapshot note: sections 3–20 describe the pre-Wave-A/B worktree that was
> audited at the time. Wave A and Wave B have since completed. See section 22 for the
> current reconciliation; the historical evidence is intentionally retained.

## 1. Executive summary

The repository is in a transitional but explainable state:

- Fourteen dashboard domains now have vertical slices under `src/modules/dashboard/`.
- Those vertical slices contain 118 source files and are wired into the central dashboard route aggregator.
- `src/routes/dashboard/adminRoute/adminRoute.js` is still a 2,357-line central aggregator with 321 executable route registrations.
- It imports all 14 migrated modules, but it also imports 25 old horizontal dashboard controllers. The route aggregator therefore must remain centralized until the remaining domains migrate.
- The old horizontal `src/services/dashboard/`, `src/repositories/dashboard/`, and `src/viewModels/dashboard/` trees contain no files. The remaining horizontal dashboard implementation is concentrated in 33 controller files and the dashboard validation directory.
- The current working tree already contains 27 pre-existing deletions from the vertical-module migration. They were not created by this audit. All have been classified and must stay part of the existing migration review.
- Static dependency analysis found 3,197 resolved JavaScript edges, 69 source files with no incoming static reference, 69 dynamic EJS render expressions, 180 EJS files with no provable static render/include reference, and 51 custom CSS/JS files with no textual production reference.
- These numbers are **candidate signals**, not deletion proof. Dynamic controller view selection, EJS naming conventions, locale loading, Mongoose/domain lookup, and browser-loaded assets prevent automatic deletion decisions.
- Exact-content hashing found seven duplicate groups containing 17 files.
- Five tracked `.DS_Store` files exist inside the mandatory audit roots. Six more generated/development artifacts exist outside those roots.
- The mandated folder set contains 63,268 files, dominated by 59,512 ignored QA screenshots. The broader non-ignored repository contains 5,879 existing files. Combining both gives a classified audit surface of **65,391 files with zero unclassified files**.

No file is approved for deletion by this report alone. Cleanup requires a separately approved wave, temporary-removal proof, tests, and browser QA.

## 2. Scope and methodology

### 2.1 Mandatory roots

The file-level scan covered:

```text
src/
views/admin/
public/admin/assets/
public/admin/images/          (directory currently absent)
public/admin/ui-lab/
test/
docs/
scripts/
```

The audit also classified the remaining non-ignored project surface so that root files, listeners, public API docs, Postman artifacts, non-admin views/assets, and developer metadata are not left unexplained.

### 2.2 Static checks used

- recursive file inventory;
- `git ls-files -co --exclude-standard` for tracked and visible untracked files;
- static `require(...)` / `import ... from` resolution with the project aliases;
- route-registration parsing from `adminRoute.js`;
- `res.render(...)` and EJS `include(...)` parsing;
- EJS/CSS/JS asset reference lookup;
- `package.json` script entry-point lookup;
- SHA-256 exact-content duplicate detection;
- targeted `rg` checks for deleted horizontal imports and dynamic paths;
- existing tests and Git whitespace validation.

### 2.3 Important limits

Static analysis cannot prove absence when code uses:

- template literals such as ``admin/<module>/${type}``;
- controller-provided values such as `data.viewPage` or `viewPath`;
- dynamic locale catalogue loading;
- file names loaded by browser bundles or CSS `url(...)` chains;
- convention-based EJS CRUD names;
- optional scripts or operational one-shots invoked outside `package.json`.

Every such case is retained or classified as manual review. It is not called dead code merely because a direct edge is absent.

## 3. Current folder tree summary

### 3.1 Mandatory-root file counts

| Root | Files | Notes |
|---|---:|---|
| `src/` | 680 | Runtime source, modules, models, routes, helpers, validations, locales |
| `views/admin/` | 492 | Dashboard layouts, pages, fragments, and legacy views |
| `public/admin/assets/` | 2,374 | 120 custom CSS/JS/source files plus vendor/font/image/library trees |
| `public/admin/images/` | 0 | Directory does not exist |
| `public/admin/ui-lab/` | 59,539 | 27 static lab files plus 59,512 ignored screenshot/QA artifacts |
| `test/` | 118 | Node test files |
| `docs/` | 53 | Architecture, contracts, guides, and modular OpenAPI YAML |
| `scripts/` | 12 | QA, audit, seed, documentation export, and legacy one-shots |
| **Total** | **63,268** | Mandatory audit universe |

### 3.2 Broader repository surface

`git ls-files -co --exclude-standard` returned 5,879 existing, non-ignored files. Important additional families are:

| Family | Files | Classification approach |
|---|---:|---|
| `public/admin/app-assets/` | 1,487 | Shared template/vendor bundle; retain as a unit pending a bundle manifest audit |
| non-admin `public/` | 534 | Shared includes, API docs, info-site/webview assets, notification scripts |
| `.cursor/` | 39 | Developer/reference material |
| `views/infoSite/`, `views/webview/`, `views/.DS_Store` | 20 | Non-dashboard views plus one generated file |
| `listeners/` | 10 | Active Socket.IO runtime |
| `tasks/` | 9 | Project delivery/audit documentation |
| root files | 13 | Runtime/config/governance, including tracked `.env` |
| `postman/` | 6 | Generated/delivery API collection and environments |
| `.vscode/` | 2 | Developer configuration |
| `images/` | 1 | Unreferenced image requiring manual review |

The 59,512 ignored screenshot files are not returned by Git, so the complete classified surface is:

```text
5,879 non-ignored existing files
+ 59,512 ignored UI-lab screenshot files
= 65,391 classified files
```

## 4. File classification manifest

### 4.1 Classification legend

| Code | Meaning |
|---|---|
| A | Active module-owned |
| B | Active shared/global |
| C | Active API/non-dashboard |
| D | Legacy dashboard horizontal/template leftover; may still be active |
| E | Duplicate implementation/content candidate |
| F | Test/QA/developer-only helper |
| G | Generated/delivery artifact |
| H | Temporary/editor artifact |
| I | Unknown or manual review required |

### 4.2 Full-project classification totals

| Code | Files |
|---|---:|
| A | 232 |
| B | 4,675 |
| C | 280 |
| D | 334 |
| E | 17 |
| F | 189 |
| G | 59,522 |
| H | 11 |
| I | 131 |
| **Total classified** | **65,391** |
| **Unclassified** | **0** |

### 4.3 Non-overlapping ownership rules

The following rules account for every file. Exact duplicate-file rules override broader path rules.

| Rule | Class | Count/coverage |
|---|---|---|
| `src/modules/dashboard/**` | A | 118 source files |
| migrated module view folders under `views/admin/` | A | Module CRUD/page files except exact duplicates |
| referenced migrated-module page assets | A | 13 CSS/JS files |
| global layouts/includes/design system/vendor/font/image/library assets | B | Shared dashboard surface |
| active runtime/config/docs and shared source not caught by another rule | B | Shared/global surface |
| API controllers/routes/helpers/validators, domain models, seed CLI, listeners, info-site/webview/notification surface | C | API/non-dashboard |
| remaining `src/controllers/dashboard/**` and dashboard validations | D | Active or legacy horizontal dashboard implementation |
| remaining unmigrated dashboard view folders | D | Active legacy dashboard UI |
| 47 unreferenced template CSS/JS files | D | Legacy asset candidates; not deletion-approved |
| seven exact-content duplicate groups | E | 17 files |
| `test/**`, 27 UI-lab concept files, approved QA scripts, `.cursor/**`, `.vscode/**` | F | Test/QA/developer-only |
| 59,512 UI-lab screenshots, API/Postman export artifacts | G | Generated/delivery |
| tracked `.DS_Store` and equivalent editor artifacts | H | Temporary/generated |
| 69 no-incoming source files, nine view directories, two unregistered scripts, root `.env`, `images/image.png` | I | Manual review/security review |

The classification is conservative: `D` means horizontal/legacy ownership, not necessarily unused; `I` means there is insufficient proof for deletion.

## 5. Current dirty worktree accounting

The worktree contained 190 entries before this report was created:

| Existing change family | Count | Classification | Ownership |
|---|---:|---|---|
| untracked vertical module source files | 118 | A | Migrated modules |
| modified migrated-module EJS files | 22 | A | Module-owned views |
| pre-existing deleted horizontal controllers/validators/product helpers | 27 | E | Replaced by vertical modules; deletion is part of the earlier migration, not this audit |
| shared route/CSS/permissions/locales/docs | 8 | B | Shared/global/documentation |
| modified/untracked architecture and module tests | 15 | F | Tests |
| **Total** | **190** | — | All explained |

The report file is the only new file authored by this audit. No pre-existing user change was reverted or rewritten.

### 5.1 Pre-existing deletion set

The 27 deleted paths are:

```text
src/controllers/dashboard/attributesController/attributesController.js
src/controllers/dashboard/cityController/cityController.js
src/controllers/dashboard/countryController/countryController.js
src/controllers/dashboard/couponController/couponController.js
src/controllers/dashboard/departmentsController/departmentsController.js
src/controllers/dashboard/packageController/packageController.js
src/controllers/dashboard/packageFeatureController/packageFeatureController.js
src/controllers/dashboard/premiumPackageController/premiumPackageController.js
src/controllers/dashboard/productController/productController.js
src/controllers/dashboard/reasonsController/reasonsController.js
src/controllers/dashboard/socialMediaController/socialMediaController.js
src/controllers/dashboard/subDepartmentsController/subDepartmentsController.js
src/controllers/dashboard/subscriptionController/subscriptionController.js
src/helpers/products/dashboardProductMedia.js
src/helpers/products/productModerationDashboard.js
src/utils/validations/dashboard/attributes.js
src/utils/validations/dashboard/city.js
src/utils/validations/dashboard/country.js
src/utils/validations/dashboard/coupon.js
src/utils/validations/dashboard/departments.js
src/utils/validations/dashboard/package.js
src/utils/validations/dashboard/packageFeature.js
src/utils/validations/dashboard/premiumPackage.js
src/utils/validations/dashboard/product.js
src/utils/validations/dashboard/reasons.js
src/utils/validations/dashboard/socials.js
src/utils/validations/dashboard/subDepartments.js
```

No runtime source imports any deleted controller/validator path. The two deleted product-helper names remain only in architecture documentation/tests that assert their replacement and absence.

## 6. Dashboard module ownership map

All 118 files under `src/modules/dashboard/` are reachable through module indices or the shared module dependency chain. No private implementation file is imported by a sibling module. Cross-module imports are limited to `../shared/dashboard.constants` and `../shared/dashboard.query`.

| Module | Files | Structural status | Optional files | Horizontal/shared dependency | View owner |
|---|---:|---|---|---|---|
| `reasons` | 8 | Complete vertical core | validation, policy | `sharedControllerSite` | `views/admin/reasons/` |
| `subscriptions` | 7 | Complete for read-only scope | no mutation validator needed today | no old controller dependency | `views/admin/subscriptions/` |
| `package-features` | 8 | Complete vertical core | validation, policy | `sharedControllerSite` | `views/admin/packageFeatures/` |
| `packages` | 8 | Complete vertical core | validation, policy | `sharedControllerSite` | `views/admin/packages/` |
| `premium-packages` | 8 | Complete vertical core | validation, policy | `sharedControllerSite` | `views/admin/premiumPackages/` |
| `socials` | 8 | Complete vertical core | validation, policy | dashboard/API shared upload helpers | `views/admin/socials/` |
| `countries` | 8 | Complete vertical core | validation, policy | dashboard/API shared upload helpers | `views/admin/countries/` |
| `cities` | 8 | Complete vertical core | validation, policy | `sharedControllerSite` | `views/admin/cities/` |
| `coupons` | 8 | Complete vertical core | validation, policy | `sharedControllerSite`, cron services | `views/admin/coupons/` |
| `departments` | 8 | Complete vertical core | validation, policy | dashboard/API shared upload helpers | `views/admin/departments/` |
| `sub-departments` | 8 | Complete vertical core | validation, policy | dashboard/API shared upload helpers | `views/admin/subDepartments/` |
| `attributes` | 9 | Complete vertical core | query, validation, policy | `sharedControllerSite` | `views/admin/attributes/` |
| `attribute-values` | 9 | Complete vertical core | query, validation, policy; kind config replaces generic routes | `sharedControllerSite` | `views/admin/attributeValues/` |
| `products` | 11 | Complete high-risk vertical core | query, validation, uploads, moderation, policy | shared controller, auth, cron, notification, upload/model services | `views/admin/products/` and `productsGold/` |
| `shared` | 2 | Partial public boundary | constants and query only; no `index.js` | intentionally imported by module internals | no direct view |

### 6.1 Module completeness conclusion

- The 14 business modules are structurally complete for their current route contracts.
- Thirteen module controllers still import `src/controllers/dashboard/sharedController/sharedControllerSite.js`. This helper is genuinely shared today, but its horizontal path prevents a fully self-contained dashboard module architecture.
- `shared/` should eventually expose an `index.js` and a stable shared dashboard API. Do not move `sharedControllerSite` directly: legacy controllers also import it. Use a compatibility re-export in a later wave.
- The products module has the widest dependency boundary and should remain the last module touched in any cleanup.

## 7. Old horizontal folder status

### 7.1 `src/controllers/dashboard/`

There are 33 existing JavaScript files.

#### ACTIVE_LEGACY_IMPORT via `adminRoute.js` — 25 controllers

```text
adminController
advertisementController
archiveController
auctionController
clientController
complaintsController
contactUsController
fqsController
generalSettingsController
homeController
infoSiteController
introController
notificationController
orderController
paymentController
permissionController
productReportsController
profitController
providerController
providerMetaController
reportsController
settingController
settlementProvidersController
sliderController
usersController
```

These are unsafe to delete. They own active route handlers.

#### ACTIVE_LEGACY_IMPORT outside `adminRoute.js` — 2 files

- `authController/authController.js`: used by the dashboard auth route and logout tests.
- `sharedController/sharedControllerSite.js`: used by migrated modules and legacy dashboard controllers.

#### MANUAL_REVIEW / no incoming static edge — 6 files

```text
districtController/districtController.js
financialController/financialController.js
partnerController/partnerController.js
settlementController/settlementController.js
sharedController/sharedController.js
villageController/villageController.js
```

Evidence and cautions:

- partner routes are commented out in `adminRoute.js`;
- district/village controllers use dynamic CRUD view names, but have no registered dashboard edge;
- financial dashboard controller is not the API financial controller;
- `sharedController.js` is distinct from the actively used `sharedControllerSite.js`;
- absence of a static edge is not enough to delete operational one-shots or convention-loaded code.

### 7.2 Other old horizontal dashboard folders

| Folder | Existing files | Status |
|---|---:|---|
| `src/services/dashboard/` | 0 | Empty/absent; no cleanup content |
| `src/repositories/dashboard/` | 0 | Empty/absent; no cleanup content |
| `src/viewModels/dashboard/` | 0 | Empty/absent; no cleanup content |
| `src/utils/validations/dashboard/` | 29 current files | Shared and unmigrated dashboard validation; class D unless module-owned replacement already exists |

## 8. Import/dependency graph summary

### 8.1 JavaScript graph

| Metric | Result |
|---|---:|
| Runtime JavaScript files scanned (`app.js`, `src`, `listeners`) | 578 |
| Test JavaScript files scanned | 118 |
| Resolved static edges | 3,197 |
| Runtime/script roots | 9 |
| Files reachable from runtime/script roots | 508 |
| Source files not reachable from those roots | 77 |
| Source files with no incoming static edge | 69 |
| Source files imported only by tests | 1 (`src/middlewares/rbacPolicy.js`) |
| Unresolved local/alias specifiers | 11 |

The 77 unreachable count is a discovery signal, not a dead-code count. Some routes, models, validators, locale files, and operational utilities are intentionally outside the application root graph or depend on dynamic conventions.

### 8.2 Unresolved static specifiers

The scanner could not resolve these local/alias references:

```text
src/controllers/api/providerController.js -> @root/helpers/api/Provider
src/controllers/dashboard/partnerController/partnerController.js -> @root/models/translateModel
src/services/authenticationWebsite/verify.js -> ../../middlewares/checkPermission
src/services/cache/cleanCache.js -> ../services/cache
src/utils/validations/dashboard/addNewTranslate.js -> @root/models/translateModel
src/utils/validations/dashboard/delegate.js -> @root/models/delegateModel
src/utils/validations/dashboard/delegate.js -> @root/models/delegateMetaModel
src/utils/validations/dashboard/exam.js -> @root/models/specializationModel
src/utils/validations/dashboard/services.js -> @root/models/departmentsModel
```

Two additional unresolved names are external Vonage packages, not project files. The nine project-local failures align with legacy/manual-review code and are high-value cleanup-audit targets.

### 8.3 Package script audit

Active script entries resolve to permissions generation, API-check generation, AccountIdentity audit, Postman export, and three explicitly approved seed/QA scripts.

Stale/broken script entries:

| Script | Missing target |
|---|---|
| `run-all-files` | `src/seeder/index.js` |
| `export` | `src/collections/export.js` |
| `import` | `src/collections/import.js` |
| `seed` | several missing `src/seeder/*` targets |
| `destroy` | several missing `src/seeder/*` targets |

These are package-contract cleanup candidates. They must not be repaired or removed in a structure-report phase because some are destructive/operational contracts.

## 9. Route ownership map

### 9.1 Aggregator metrics

| Metric | Value |
|---|---:|
| `adminRoute.js` lines | 2,357 |
| Executable route registrations | 321 |
| GET | 157 |
| POST | 96 |
| DELETE | 36 |
| PATCH | 29 |
| PUT | 3 |
| Module imports | 14 |
| Old horizontal controller imports | 25 |
| Total top-level static imports | 68 |

The 321 count excludes eight commented-out route declarations.

### 9.2 Migrated route groups

| Module import | Route group ownership |
|---|---|
| `reasons` | `/reasons` |
| `subscriptions` | `/subscriptions` |
| `package-features` | `/packageFeatures` |
| `packages` | `/packages` |
| `premium-packages` | `/premiumPackages` |
| `socials` | `/socials` |
| `countries` | `/countries` |
| `cities` | `/cities` |
| `coupons` | `/coupons` |
| `departments` | `/departments` |
| `sub-departments` | `/subDepartments` |
| `attributes` | `/attributes` base operations |
| `attribute-values` | `/attributes/colors` and `/attributes/sizes` |
| `products` | `/products`, including gold-request operations |

### 9.3 Middleware-order findings

- Every parsed POST/PUT/PATCH/DELETE route contains `csrfProtection`.
- Forty-six multipart routes contain `uploadsFiles()` and CSRF.
- Forty-four of those place upload parsing before CSRF, matching the project rule.
- Two routes require review because CSRF appears before multipart parsing:

```text
POST /infoServices/create   (adminRoute.js:1206)
POST /infoServices/edit/:id (adminRoute.js:1214)
```

This is a **high-risk route-order finding**, not fixed here.

Filter routes are registered before generic dynamic list/detail routes for subscriptions, orders, settlement providers, contact, FAQ, auctions, products, and product reports. Apparent ordering warnings for permissions/advertisements are not direct catch-all collisions: their earlier dynamic routes are explicit edit/detail shapes. They should still receive route-level regression tests before registrar extraction.

### 9.4 Route recommendation

Keep `adminRoute.js` as the central aggregator now. Later extract one module registrar at a time only after:

1. route snapshot tests preserve method/path/order;
2. middleware identity and order are asserted;
3. permission-catalog generation remains unchanged;
4. module browser QA is green;
5. the aggregator imports only each module's public `index.js`.

Products, settings, people, auctions, orders, and info-site routes should remain centralized until their contract tests explicitly cover the full middleware chain.

## 10. EJS view ownership map

### 10.1 Migrated module views

| Module | View folder | Files | Current composition |
|---|---|---:|---|
| reasons | `views/admin/reasons` | 8 | index/create/edit/show/dataTable/tds/includes/form partial |
| subscriptions | `views/admin/subscriptions` | 7 | index/create/edit/show/dataTable/tds/includes |
| package-features | `views/admin/packageFeatures` | 7 | CRUD/list fragments |
| packages | `views/admin/packages` | 9 | CRUD/list plus form fields and feature picker |
| premium-packages | `views/admin/premiumPackages` | 7 | CRUD/list fragments |
| socials | `views/admin/socials` | 8 | CRUD/list plus shared form partial |
| countries | `views/admin/countries` | 7 | CRUD/list fragments |
| cities | `views/admin/cities` | 8 | CRUD/list plus shared form partial |
| coupons | `views/admin/coupons` | 8 | CRUD/list plus custom modal/model fragment |
| departments | `views/admin/departments` | 7 | CRUD/list fragments |
| sub-departments | `views/admin/subDepartments` | 7 | CRUD/list fragments |
| attributes | `views/admin/attributes` | 8 | CRUD/list plus section navigation |
| attribute-values | `views/admin/attributeValues` | 6 | create/edit/index/list fragments; no show view |
| products | `views/admin/products` | 8 | create/edit/show/index/dataTable/tds/form/includes |

`views/admin/productsGold/` is also actively rendered by the products module and should remain co-owned by products until a deliberate name consolidation.

### 10.2 Render/include graph

| Metric | Result |
|---|---:|
| Admin EJS files | 492 |
| Static `res.render` references | 146 |
| Resolved directly rendered views | 131 |
| Dynamic render expressions | 69 |
| Resolved EJS include edges | 909 |
| EJS files with no static render/include incoming edge | 180 |
| Unresolved include expressions/paths | 10 |

Dynamic CRUD rendering explains many apparently unreferenced `create.ejs`, `edit.ejs`, and `show.ejs` files. They are retained.

### 10.3 Manual-review view families

The following directories contain 59 files and have no active route/controller ownership proven by the current static graph:

| Folder | Files |
|---|---:|
| `views/admin/areas` | 5 |
| `views/admin/features` | 7 |
| `views/admin/roles` | 8 |
| `views/admin/services` | 7 |
| `views/admin/support` | 7 |
| `views/admin/districts` | 7 |
| `views/admin/villages` | 7 |
| `views/admin/partners` | 7 |
| `views/admin/settlements` | 4 |

They are `MANUAL_REVIEW`, not safe-delete entries. Some match dynamic controller naming even though those controllers are not currently mounted.

### 10.4 Unresolved include findings

- Four unresolved include paths occur in `views/admin/features/**`.
- Four occur in `views/admin/layouts/layoutnew1.ejs`.
- Two occur in `views/admin/roles/**`.

All three families already lack an active static route/layout edge. This strengthens their legacy-candidate status but still does not authorize deletion.

### 10.5 Inline logic findings

| Finding | Count |
|---|---:|
| EJS files containing `<script>` | 152 |
| EJS files containing `<style>` | 33 |
| EJS files containing inline DOM event attributes | 26 |
| EJS control blocks (`if`, `for`, `switch`, `while`) | 459 |
| EJS files with direct status/type/active-state comparisons | 42 |

Recommended ownership direction:

- move module-specific interaction code from EJS into existing page assets;
- move status/type decisions into view-models/policies before extracting partials;
- keep layout bootstrap and minimal progressive-enhancement scripts shared;
- do not mass-extract scripts: each module needs browser regression coverage first.

## 11. Public CSS/JS asset ownership map

### 11.1 Asset tree

| Folder | Files | Ownership |
|---|---:|---|
| `public/admin/assets/vendor` | 1,064 | Shared third-party/vendor |
| `public/admin/assets/fonts` | 554 | Shared fonts |
| `public/admin/assets/img` | 345 | Shared/template images |
| `public/admin/assets/libs` | 290 | Shared third-party libraries |
| `public/admin/assets/css` | 67 | Shared and page/module CSS |
| `public/admin/assets/js` | 53 | Shared and page/module JS/source |
| `.DS_Store` | 1 | Temporary artifact |

### 11.2 Custom CSS/JS reference results

| Metric | Count |
|---|---:|
| CSS/JS/source files scanned | 120 |
| Referenced from production `views`/`src` | 69 |
| No production, test, docs, or UI-lab textual reference | 51 |
| Exact duplicate asset files | 4 |

Shared files that must remain shared include:

```text
public/admin/assets/css/design-system.css
public/admin/assets/css/components.css
public/admin/assets/css/animations.css
public/admin/assets/css/pages/dashboard-home.css
public/admin/assets/js/admin-ui.js
public/admin/assets/js/config.js
public/admin/assets/js/helpers.js
public/admin/assets/js/main.js
public/admin/assets/js/menu.js
```

Page/module assets should remain in `public/admin/assets/{css,js}/pages/` for now. Moving them beside Node modules would break Express static ownership and is not recommended. A naming/manifest cleanup is safer than a physical module move.

### 11.3 Unreferenced custom assets

These 51 files are `LEGACY_ASSET_CANDIDATE` or duplicate candidates:

```text
public/admin/assets/css/page-profile.css
public/admin/assets/css/pages/advanced-wizard.css
public/admin/assets/css/pages/app-academy-details.css
public/admin/assets/css/pages/app-academy.css
public/admin/assets/css/pages/app-calendar.css
public/admin/assets/css/pages/app-chat.css
public/admin/assets/css/pages/app-ecommerce.css
public/admin/assets/css/pages/app-email.css
public/admin/assets/css/pages/app-invoice-print.css
public/admin/assets/css/pages/app-invoice.css
public/admin/assets/css/pages/app-kanban.css
public/admin/assets/css/pages/app-logistics-fleet.css
public/admin/assets/css/pages/app-logistics-overview.css
public/admin/assets/css/pages/cards-advance.css
public/admin/assets/css/pages/front-page-help-center.css
public/admin/assets/css/pages/front-page-landing.css
public/admin/assets/css/pages/front-page-payment.css
public/admin/assets/css/pages/front-page-pricing.css
public/admin/assets/css/pages/front-page.css
public/admin/assets/css/pages/page-account-settings.css
public/admin/assets/css/pages/page-auth.css
public/admin/assets/css/pages/page-faq.css
public/admin/assets/css/pages/page-icons.css
public/admin/assets/css/pages/page-misc.css
public/admin/assets/css/pages/page-pricing.css
public/admin/assets/css/pages/page-profile.css
public/admin/assets/css/pages/page-user-view.css
public/admin/assets/css/pages/ui-carousel.css
public/admin/assets/css/pages/wizard-ex-checkout.css
public/admin/assets/css/rtl/theme-bordered-dark.css
public/admin/assets/css/rtl/theme-bordered.css
public/admin/assets/css/rtl/theme-raspberry-dark.css
public/admin/assets/css/rtl/theme-raspberry.css
public/admin/assets/css/rtl/theme-semi-dark-dark.css
public/admin/assets/css/rtl/theme-semi-dark.css
public/admin/assets/js/_template-customizer/_template-customizer.html
public/admin/assets/js/_template-customizer/_template-customizer.scss
public/admin/assets/js/app-ecommerce-product-list.js
public/admin/assets/js/charts-apex.js
public/admin/assets/js/charts-chartjs.js
public/admin/assets/js/dropdown-hover.js
public/admin/assets/js/form-validation.js
public/admin/assets/js/form-wizard-icons.js
public/admin/assets/js/forms-pickers.js
public/admin/assets/js/forms-selects.js
public/admin/assets/js/mega-dropdown.js
public/admin/assets/js/pages/product-moderation.js
public/admin/assets/js/pages-auth.js
public/admin/assets/js/sweet-alerts.min.js
public/admin/assets/js/zt-charts.js
public/admin/assets/js/zt-swal.js
```

Do not delete these as one batch. Several are third-party template remnants and theme alternatives; the correct proof is a browser route matrix plus a network-request manifest in light/dark/mobile states.

### 11.4 UI-lab and screenshots

- 27 UI-lab HTML/CSS/JS files are intentional QA/reference assets (class F).
- 59,512 files under `public/admin/ui-lab/screenshots/` are generated QA artifacts (class G).
- The screenshot directory is ignored by `.gitignore` and has zero tracked files.
- QA screenshots must not be committed or treated as production assets.

## 12. Shared helpers and utilities classification

### 12.1 Must remain shared/global

The following families have multi-module/runtime ownership and should not move into a single feature module:

- `src/middlewares/` authentication, CSRF, permission, request-context middleware;
- `src/helpers/api/ApiResponse.js`, `ApiError.js`, `ApiFeature.js`;
- `src/helpers/returnObject/returnObject.js` (8,317 lines; high-risk shared DTO surface);
- enums used by API and dashboard;
- pagination, audit reporting, money, slug, locale, and upload/file helpers used by multiple modules;
- error handling, logger, passport, notification, cron, and socket services;
- `src/models/` domain models;
- locale catalogues, loaded dynamically by locale and file name;
- dashboard design-system and shell assets.

### 12.2 Single-module move candidates

Only after reference proof:

- dashboard product media/moderation helpers have already moved into the products module in the current migration;
- any remaining helper with exactly one active module consumer may later move behind that module's public index;
- `sharedControllerSite` should become a shared dashboard utility, not a private module helper, because both migrated and legacy modules depend on it.

### 12.3 Static no-incoming source list

The following 69 files have no incoming static edge. They remain class I pending manual/dynamic verification:

```text
src/controllers/api/providerController.js
src/controllers/api/webhookController.js
src/controllers/dashboard/districtController/districtController.js
src/controllers/dashboard/financialController/financialController.js
src/controllers/dashboard/partnerController/partnerController.js
src/controllers/dashboard/settlementController/settlementController.js
src/controllers/dashboard/sharedController/sharedController.js
src/controllers/dashboard/villageController/villageController.js
src/helpers/LocationDataRetriever/LocationDataRetriever.js
src/helpers/block/block.js
src/helpers/calculate-price/calc-delivery-commission.js
src/helpers/checkCountryCode/checkCountryCode.js
src/helpers/checkMethods/checkMethods.js
src/helpers/convertPlusToZero/convertPlusToZero.js
src/helpers/distance/distance.js
src/helpers/distributionOfTime/distributionOfTime.js
src/helpers/enums/auctionType.enum.js
src/helpers/enums/bidPaymentStatus.enum.js
src/helpers/enums/contactUs.enum.js
src/helpers/enums/mediaType.enum.js
src/helpers/enums/orderProductCurrentStep.enum.js
src/helpers/enums/orderReturnStatus.enum.js
src/helpers/enums/packageCategory.enum.js
src/helpers/enums/paymentType.enum.js
src/helpers/enums/smsProvider.enum.js
src/helpers/enums/socialLogin.enum.js
src/helpers/generateAgoraRtcToken.js
src/helpers/generateQRcode/qrcode.js
src/helpers/imageName-url/imageName-url.js
src/helpers/invitationCode/invitationCode.js
src/helpers/languageTranslate/translateWebsite.js
src/helpers/network/network.js
src/helpers/payment-success-code.js
src/helpers/permissions/localesConfig.js
src/helpers/permissions.js
src/helpers/statusTranslations/statusTranslations.js
src/helpers/stepper/stepper.js
src/middlewares/setLang.js
src/middlewares/verifyToken.js
src/middlewares/verifyTokenAjax.js
src/models/addressModel.js
src/models/commentModel.js
src/models/infoModel.js
src/models/invoiceModel.js
src/models/permissionModel.js
src/models/providerEditRequestModel.js
src/models/shippingAddressModel.js
src/models/siteSettingModel.js
src/routes/api/ShippingRoute/ShippingRoute.js
src/services/authenticationWebsite/verify.js
src/services/cache/cache.js
src/services/cache/cleanCache.js
src/services/convertCurrency/convertCurrency.js
src/services/location/location.js
src/services/notification/pushNotificationVideo.js
src/services/shipping/otoShipping.js
src/services/vonage/credentials.js
src/utils/distance/distance.js
src/utils/requiredFiles/requiredFiles.js
src/utils/validations/api/address.js
src/utils/validations/dashboard/delegate.js
src/utils/validations/dashboard/district.js
src/utils/validations/dashboard/exam.js
src/utils/validations/dashboard/partners.js
src/utils/validations/dashboard/services.js
src/utils/validations/dashboard/sms.js
src/utils/validations/dashboard/specialization.js
src/utils/validations/dashboard/village.js
src/utils/validations/infosite/contactUs.js
```

## 13. Dead-code candidates

No entry is marked `SAFE_DELETE_NOW`. Candidate tiers are:

| Candidate | Evidence | Risk | Required proof before deletion |
|---|---|---|---|
| five tracked `.DS_Store` files in mandatory roots | editor metadata, no runtime refs | Low | remove in approved Wave A; test + diff check |
| 27 pre-existing deleted horizontal files | replacement modules exist; deleted paths have no runtime imports; architecture tests assert absence | Medium | full tests, route snapshots, browser QA, review current diff before commit |
| 47 unreferenced non-duplicate CSS/JS files | no production/test/docs/UI-lab textual refs | Medium | browser network manifest across all layouts/themes; temporary removal test |
| 69 static no-incoming source files | no static reverse edge | High | manual runtime/convention audit, temporary removal, full tests, operational script review |
| nine manual-review view folders | no active static route owner | High | route inventory, dynamic render allowlists, authenticated browser crawl |
| `_ordersSync.js`, `auction-qa-persistence.js` | no package/docs/test/source refs | Medium | owner confirmation; verify not used as an operational one-shot |
| `infoSiteRoute` import/object | imported in app initializer but not mounted | Medium | confirm no external bootstrap consumes it; route tests; remove import and file together later |
| stale `package.json` scripts | target paths missing | High contract risk | explicit operations approval; CI/deployment/search audit |

## 14. Duplicate-code candidates

Exact-content hashing across 1,475 source/view/custom-asset/doc/test files found seven groups:

```text
1. views/admin/archives/includes.ejs
   views/admin/notifications/includes/notifications.ejs
   views/admin/payments/includes.ejs
   views/admin/sms/includes/sms.ejs

2. views/admin/fqs/includes.ejs
   views/admin/intros/includes.ejs
   views/admin/sliders/includes.ejs

3. views/admin/packages/dataTable.ejs
   views/admin/premiumPackages/dataTable.ejs

4. views/admin/permissions/includes/css.ejs
   views/admin/roles/includes/css.ejs

5. views/admin/subscriptions/create.ejs
   views/admin/subscriptions/edit.ejs

6. public/admin/assets/css/page-profile.css
   public/admin/assets/css/pages/page-profile.css

7. public/admin/assets/js/_template-customizer/_template-customizer.html
   public/admin/assets/js/_template-customizer/_template-customizer.scss
```

Interpretation:

- Exact equality does not imply identical future ownership.
- EJS groups should consolidate only if locals, route contracts, and page behavior remain identical.
- The two profile CSS files are strong low-risk consolidation candidates because both are unreferenced.
- The template-customizer `.html` and `.scss` files contain the same SCSS source despite different extensions and are unreferenced; they are strong generated/template cleanup candidates.

## 15. Files safe to delete later vs unsafe to delete

### 15.1 Strongest later-cleanup candidates

These are candidates, not approvals:

1. tracked `.DS_Store` files;
2. exact duplicate/unreferenced profile CSS pair;
3. duplicate/unreferenced template-customizer source pair;
4. pre-existing deleted horizontal migration files after this branch's full tests/browser QA remain green;
5. ignored UI-lab screenshot artifacts may be cleared from disk if the user explicitly requests local QA artifact cleanup; they are already Git-safe.

### 15.2 Unsafe to delete

Do not delete:

- any of the 25 `adminRoute`-owned horizontal controllers;
- `authController` or `sharedControllerSite`;
- `adminRoute.js`, auth route, API index route, or app initializer;
- any module index/controller/service/repository/viewModel/constants/policy/validation/query/upload file;
- models, locale catalogues, middlewares, DTO mapper, error handler, logger, passport, token, cron, notification, socket, or upload infrastructure;
- active layouts/includes/design-system/shell assets;
- any EJS file reachable through a dynamic `type`, `viewPath`, or `data.viewPage` path until allowlist tests prove the complete set;
- `.env`, `.gitlab-cd.yml`, `.htaccess`, certificates, uploads, Postman environments, or deployment files as a cleanup side effect;
- bundled OpenAPI/Postman artifacts without a documentation-specific regeneration plan.

The root `.env` is tracked and classified manual/security review. This report does not inspect or expose its contents and does not alter its Git index state.

## 16. Files that should move later and files that should remain shared

### 16.1 Later move/extraction candidates

| Candidate | Direction | Preconditions |
|---|---|---|
| remaining dashboard domain controllers | `src/modules/dashboard/<domain>/` | contract tests and one-domain-at-a-time migration |
| matching dashboard validators | same module | validator behavior snapshot and middleware-order assertion |
| `sharedControllerSite` implementation | `src/modules/dashboard/shared/` or a stable shared dashboard package | compatibility re-export for all legacy imports |
| module-specific EJS inline JS | existing page JS asset | browser QA and event-handler tests |
| module-specific EJS status logic | viewModel/policy | DTO snapshot tests |
| module route groups | `<module>.routes.js` registrar | route/middleware/order snapshots and stable module index |

### 16.2 Must remain shared/global

- Express app/bootstrap and route aggregators during migration;
- authentication/authorization/CSRF/request middleware;
- Mongoose models and shared API DTO/error primitives;
- logger, error, token, notification, cron, socket, upload, locale, money, pagination, and audit services with multiple consumers;
- `views/admin/layouts`, true shared `views/admin/includes`, and reusable dashboard components;
- `design-system.css`, `components.css`, shell/theme assets, common JS runtime, third-party assets;
- API/OpenAPI/Postman delivery infrastructure in its current documentation-specific roots.

## 17. Recommended cleanup waves

### Wave A — Generated/temp hygiene

**Targets:** tracked `.DS_Store`; verify generated Postman metadata stays unchanged; keep screenshot tree ignored.

**Risk:** Low.

**Tests:** `npm test`, `git diff --check`, static asset smoke.

**Rollback:** restore exact files from Git.

**Approval needed:** Yes.

### Wave B — Commit/verify the existing vertical migration deletion set

**Targets:** the 27 pre-existing deleted horizontal files and their 118 replacements.

**Risk:** Medium to high, especially products.

**Tests:** full suite, architecture tests, route/middleware snapshots, authenticated browser QA for all migrated modules.

**Rollback:** restore deleted path and revert module import for one module at a time.

**Approval needed:** Yes; review existing dirty diff first.

### Wave C — Manual dead-code adjudication

**Targets:** 69 no-incoming source files, two unregistered scripts, nine view folders, unmounted `infoSiteRoute`.

**Risk:** High.

**Tests:** temporary-removal branches/patches one candidate family at a time; startup, API, socket/cron, route, and browser QA.

**Rollback:** restore only the candidate family being tested.

**Approval needed:** Explicit owner/business confirmation.

### Wave D — Shared dashboard boundary extraction

**Targets:** `sharedControllerSite` and shared dashboard constants/query exports.

**Risk:** Medium.

**Tests:** all dashboard contract tests, validation/error-envelope tests, module index tests.

**Rollback:** compatibility re-export preserves old path.

**Approval needed:** Yes.

### Wave E — Route registrar extraction

**Targets:** one stable migrated group at a time, starting with read-only subscriptions or reasons; products last.

**Risk:** High because order and middleware identity are behavior.

**Tests:** route method/path/order snapshot, CSRF/multipart order, permissions regeneration diff, full browser QA.

**Rollback:** re-inline registrar into central aggregator.

**Approval needed:** Yes.

### Wave F — EJS and asset cleanup

**Targets:** exact duplicate partials, 51 unreferenced custom assets, inline scripts/styles, legacy view folders.

**Risk:** Medium/high due dynamic rendering and browser-only dependencies.

**Tests:** full authenticated crawl, light/dark/mobile screenshots, network 404 audit, action/modal/upload validation QA.

**Rollback:** restore per page/asset, never bulk-delete.

**Approval needed:** Yes.

## 18. Exact risk register

| Risk | Severity | Evidence | Mitigation |
|---|---|---|---|
| multipart CSRF order on two info-service routes | High | CSRF before `uploadsFiles()` | separate route-safety phase |
| dynamic EJS render paths | High | 69 dynamic expressions | allowlist each view type before cleanup |
| central route order regression | High | 321 routes in one file | route snapshots before registrar extraction |
| products dependency breadth | High | models, uploads, AI pricing, cron, moderation, notification | products cleanup last; preserve contract tests |
| missing local legacy imports | High for invoked code | nine unresolved project specifiers | determine whether caller is dead before repair/removal |
| stale destructive package scripts | High operational | missing targets | explicit operations decision only |
| unreferenced template assets | Medium | 51 files | browser network manifest before removal |
| inline EJS behavior | Medium | 152 script-bearing views, 26 inline-handler views | migrate per module with browser tests |
| tracked `.env` | Security/manual | tracked root config; contents not inspected | separate Git/security decision; never expose value |
| huge generated screenshot tree | Low Git / high disk | 59,512 ignored files | optional user-approved local artifact cleanup |
| stale documentation statement | Medium | `SWAGGER_GUIDE.md` still states no OpenAPI while OpenAPI exists | documentation-only reconciliation phase |

## 19. Test plan for any cleanup

Minimum checks before and after each approved cleanup item:

1. candidate-specific import/reference scan;
2. `node --check` for every changed JavaScript file;
3. focused module tests;
4. full `npm test`;
5. `git diff --check`;
6. dashboard route snapshot and CSRF/middleware-order assertions;
7. authenticated browser crawl of list/create/edit/show/filter/action states;
8. light/dark/mobile viewport QA;
9. console, network 4xx/5xx, overflow, clipped-text, and broken-image checks;
10. Postman/OpenAPI generation diff when documentation tooling is affected.

For deletion candidates, the required proof is a temporary-removal experiment in a separately approved phase. This report deliberately performs no such deletion.

## 20. Audit verification results

| Check | Result |
|---|---|
| Full `npm test` | Passed: 999 tests, 24 suites, 0 failed, 0 skipped |
| `git diff --check` | Passed with exit code 0 |
| JavaScript syntax | No production JavaScript changed by this report |
| Deleted-path reference scan | No runtime imports of the 25 deleted controller/validator paths; product-helper names only in replacement documentation/tests |
| Classification coverage | 65,391 / 65,391 files; zero unclassified |
| Postman generated status | Test automation changed only `generatedAt`; the generated file was restored to its pre-audit Git state and is clean |

## 21. Final recommendation

Do not start broad cleanup. First finish and review the current vertical-module migration as its own deliverable. Then approve **Wave A** only for generated/editor artifacts, followed by a narrow **Wave B verification** of the existing deleted horizontal files. Keep all `I` files and all dynamically rendered EJS files until a candidate-specific removal proof exists.

Recommended next phase prompt:

> Phase DASH.ProjectStructureHygieneCleanup.WaveA — remove only tracked editor/generated artifacts identified in the approved hygiene report; preserve all runtime, EJS, route, API, schema, and UI behavior; run full tests, browser/static asset smoke, and Git checks; stop before any horizontal-controller or legacy-view deletion.

Current audit status: **COMPLETE_REPORT**.

## 22. Post-Wave-A/B reconciliation

Reconciled on 2026-08-04 for
`ARCH.FullProjectSeniorCleanArchitecture` Wave 0:

- the current `dev` worktree was clean before the new blueprint documents were added;
- tracked `.DS_Store` files are gone;
- the exact 27 replaced horizontal files remain absent and are protected by Wave B
  architecture tests;
- current runtime references to those deleted paths remain zero;
- final Wave B browser QA covered 56 routes and 336 scenarios with zero clipped text,
  data-blocked states, overflow, broken images, console errors, request failures, CSRF
  gaps, modal shifts, or theme leaks;
- the guarded Socials QA record and image were cleaned after capture;
- screenshot evidence remains ignored;
- `postman/.export-meta.json` is tracked but clean.

The pre-cleanup dirty-worktree totals and `.DS_Store` counts above are therefore audit
history, not the present Git status. Candidate decisions that did not receive a separate
proof remain `MANUAL_REVIEW` or `DELETE_CANDIDATE_AFTER_PROOF`.
