feat: dead-config sweep, test suite foundation, widget settingsSchema validation
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Sprint G: audited every BootstrapConfig field for a real runtime consumer (docs/DEAD-CONFIG-AUDIT.md). Wired 3 previously-dead editable fields: footer.logoUrl, company.address.street/contacts.phone, catalog.suggestionsEnabled. Remaining dead fields needing a business/design decision tracked in PRODUCT_BACKLOG.md/KNOWN-ISSUES.md, not silently left. Sprint H: 6 new spec files (test count 57 -> 83), covering ProjectEditorFacade (undo/redo, draft persistence, publish gating), AdminAnalyticsFacade (never-fabricate-a-number contract), and regression coverage for this session's carousel/hero/profile-toggle fixes. Sprint I: widget settingsSchema (declared in widget-manifest.json, never validated) now enforced via a new lightweight schema check in ProjectValidator, surfaced through the existing issuesByField pipeline. Same check reused in diagnostics so editor and diagnostics can't disagree. Verification: tsc clean, ng build clean, 83/83 tests pass, barry-cache validate clean (2 pre-existing unrelated warnings only). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
68
docs/DEAD-CONFIG-AUDIT.md
Normal file
68
docs/DEAD-CONFIG-AUDIT.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Dead-Config Audit (Sprint G)
|
||||
|
||||
Mechanical sweep of every field in `BootstrapConfig` and its sub-models
|
||||
(`src/app/shared/models/config/*.model.ts`), cross-referenced against
|
||||
`src/app/features/project-editor/schema/editor-schema.ts` (`SECTION_FIELD_SCHEMAS`)
|
||||
to find fields that are editable in the Project Editor but have no real runtime
|
||||
consumer — the same bug class as `HeaderConfig.showProfile` and `layout.columns`
|
||||
(both fixed earlier this cycle). Non-editable fields are listed for completeness
|
||||
but were not a priority (nothing in the editor lets a client set them, so there's
|
||||
no ghost-setting UX to fix).
|
||||
|
||||
Status legend: **live** (read, has effect) / **dead** (never read outside the
|
||||
editor) / **inert** (read, but the effect is unreachable or a stub) / **n/a**
|
||||
(not client-editable today, lower priority per sprint scope).
|
||||
|
||||
## Editable fields (client-facing — checked first)
|
||||
|
||||
| Field | Status | Recommendation | Outcome |
|
||||
|---|---|---|---|
|
||||
| `header.show*` (8 flags) | live | none | `header.component.html` reads every one |
|
||||
| `theme.palette.*` (12 colors) | live | none | `theme-css-vars.mapper.ts` |
|
||||
| `theme.mode` | inert | needs decision | already tracked in `PRODUCT_BACKLOG.md` |
|
||||
| `layout.type` ("Site Layout") | **dead** | needs decision | see below — not fixed this pass |
|
||||
| `branding.brandName/logoUrl/logoCompactUrl/faviconUrl` | live | none | header/footer/meta consumers |
|
||||
| `seo.default.title/description` | live | none | `seo.service.ts` |
|
||||
| `localization.defaultLocale/supportedLocales` | live | none | language switching |
|
||||
| `tenant.host/websiteBaseUrl` | inert by design | none | frontend never resolves its own tenant (ADR-001) — this is backend routing metadata, not something the SPA is meant to read back |
|
||||
| `company.companyName` | **dead** | needs decision | see below — not fixed this pass |
|
||||
| `company.address.street` | **dead → fixed** | wire | now shown in footer bottom bar |
|
||||
| `company.contacts.phone` | **dead → fixed** | wire | now shown in footer bottom bar (`tel:` link) |
|
||||
| `company.contacts.email` | live | none | `ui-runtime.facade.ts` fallback chain |
|
||||
| `footer.copyrightText/paymentIcons/socialLinks/columns` | live | none | `footer-resolver.service.ts` |
|
||||
| `footer.logoUrl` | **dead → fixed** | wire | `LogoComponent` gained `srcOverride`, footer passes it |
|
||||
| `catalog.navigationMode` | inert (deliberate placeholder) | leave as-is | renders a labeled placeholder card + `catalog.navigationPlaceholder` i18n string; the alternate nav UIs (mega-menu, top-carousel, left-nav) don't exist yet — building them is a real feature, not a wiring fix |
|
||||
| `catalog.suggestionsEnabled` | **dead → fixed** | wire | `SearchFacade.autocomplete()` now short-circuits to no suggestions when false |
|
||||
| `catalog.searchHistoryEnabled` | live | none | `catalog-container.component.ts` |
|
||||
| `productPage.questions.*` | live | none | `product-details-container.component.ts` |
|
||||
| `userExperience.recentlyViewed.enabled` | live | none | multiple consumers |
|
||||
| `navigation.header` | **dead** | needs decision | see below — not fixed this pass |
|
||||
| `navigation.footer` | live | none | `footer-resolver.service.ts` fallback tier |
|
||||
| `pages` / `staticPages` | live | none | core rendering pipeline |
|
||||
|
||||
## Non-editable fields (lower priority — `n/a`)
|
||||
|
||||
`branding.legalName/slogan/supportPhone/appIconUrl/galleryUrls`,
|
||||
`company.registrationNumber/taxId`, `tenant.defaultCurrency/supportedCurrencies/timezone`,
|
||||
`featureFlags.blog/chat/coupons/loyalty/giftCards/invoices`,
|
||||
`features.brands/manufacturers`, `permissions.definitions/roles` (used elsewhere,
|
||||
not via this config path), `userExperience.recentlyViewed.widgetEnabled`,
|
||||
`catalog.showBreadcrumbs/showCategoryBanner/showSubcategoryChips/enabledFilters/availableSorts/defaultSort`
|
||||
— none of these have an editor control today, so no client can create a false
|
||||
expectation by setting them. Flagged here for completeness; no action taken.
|
||||
|
||||
## Fixed this pass (trivially wireable)
|
||||
|
||||
1. **`footer.logoUrl`** — `LogoComponent` (`src/app/components/logo/logo.component.ts`) gained an optional `srcOverride` input; `FooterResolverService`/`FooterComponent` now resolve and pass `footer.logoUrl`, falling back to the brand logo exactly as before when unset.
|
||||
2. **`company.address.street` / `company.contacts.phone`** — `UiRuntimeFacade` gained `contactPhone()`/`companyAddress()` (same fallback pattern as the existing `contactEmail()`); footer bottom bar now renders a `tel:` link and the address next to the existing email link when present.
|
||||
3. **`catalog.suggestionsEnabled`** — `SearchFacade.autocomplete()` now reads the bootstrap snapshot and returns no suggestions when the flag is `false`, instead of always running autocomplete regardless of the toggle.
|
||||
|
||||
## Left dead, tracked (needs a decision, not a mechanical fix)
|
||||
|
||||
- **`layout.type`** ("Site Layout" selector, Theme section) — top-level `BootstrapConfig.layout` is edited but never applied to any page; page layout comes entirely from each `PageConfig.layout` (see `SectionEngineService.resolveLayoutType`), which this global selector doesn't touch. Wiring it requires deciding *which* page(s) it should drive (homepage only? every page without its own override?) — a product decision, not a mechanical fix. Tracked in `docs/PRODUCT_BACKLOG.md`.
|
||||
- **`company.companyName`** — Footer editor has a "Company Name" field with zero runtime consumers. The footer already has a copyright fallback (`© {year} {brandName}`, `footer.component.html`) using `branding.brandName`, not `company.companyName` — these are meant to be distinct (brand vs. legal entity name), so blindly reusing one for the other would be a content decision, not a safe mechanical fix. Tracked in `docs/PRODUCT_BACKLOG.md`.
|
||||
- **`navigation.header`** — editable list of header nav items in the Navigation section, but `HeaderComponent` never reads `NavigationConfig.header` at all; the header's own category menu comes from `CategoryFacade`, not this list. Rendering an actual configurable top-nav (positioning, active-state, children/dropdowns) is real feature work, not a one-line wire. Tracked in `docs/KNOWN-ISSUES.md`.
|
||||
|
||||
## Not touched
|
||||
|
||||
`theme.mode` (dark mode) stays exactly as already tracked in `docs/PRODUCT_BACKLOG.md` — no new information found, confirmed still inert.
|
||||
Reference in New Issue
Block a user