Files
marketplaces/docs/SPRINT-PLAN-NEXT.md
sdarbinyan 6d075fc5b9
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
perf: drop @lucide/angular, hand-roll used icons - initial bundle 13.68MB -> 2.64MB
@lucide/angular shipped its entire ~1500-icon set in the initial bundle
despite the app only using 85 named-imported icons - confirmed upstream
tree-shaking failure (sideEffects:false, clean named imports, single
non-splittable fesm file). Replaced icon-registry.ts/icon.component.ts
with hand-rolled inline SVG rendering of just the 85 used icons,
transcribed from lucide's own node data for pixel-identical output.
Zero call-site changes - AppIconName and app-icon's public API unchanged.

Also: karma-coverage wired (npm run test:coverage), baseline captured
in docs/SPRINT-PLAN-NEXT.md (32% statements / 18.5% branches).

Cart-modal -> app-dialog migration was attempted and reverted - real
conflicts (backdrop-close, nested-modal escape priority, iframe sizing),
documented in docs/FUTURE_FEATURES.md for a properly scoped follow-up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 10:55:00 +04:00

14 KiB
Raw Blame History

Sprint Plan — Next Wave (G onward)

Continues the sprint lettering from docs/GLOBAL-SPRINT-PLAN.md (Sprints AF, all closed 2026-08-05: stub-page closure + widget layout/carousel fixes). Created 2026-08-05.

Relationship to docs/NEXT_PHASE.md: that file stays the one phase-level roadmap and owns the backend-integration sequencing. This file is the task-level tracker for work that is actionable now, plus an explicit parking list for what is blocked and on what. Where the two overlap, NEXT_PHASE.md wins on ordering.


Tier 1 — Actionable now (nothing blocks these)

Sprint G — Dead-config sweep

Why: This is a config-driven multi-tenant product, so "setting exists in the editor, nothing reads it at runtime" is the signature failure mode — and it reaches clients directly. Three instances were found by accident during other work: theme mode (data-theme-mode set, no CSS reads it), HeaderConfig.showProfile (fixed, Sprint A), layout.columns (fixed, Sprint F, and was the root cause of a real client bug report). A mechanical sweep finds the rest in one pass instead of one complaint at a time.

  • Enumerate every field in BootstrapConfig and its sub-models (src/app/shared/models/config/*.model.ts) — produce the full field inventory as a working list
  • For each field, grep for a real runtime consumer (a component/service that reads it and changes behavior), distinguishing: live (read + has effect), dead (never read), inert (read but effect is unreachable/no-op — the data-theme-mode case)
  • Cross-check against the editor: which dead/inert fields are user-editable today (those are the client-facing ones, highest priority)
  • Produce a findings table: field → status → editable? → recommendation (wire it / hide the control / delete the field)
  • Fix the trivially-wireable ones in the same pass (a field with an obvious consumer that was simply never connected)
  • For each remaining dead field, either hide its editor control or open a scoped follow-up — do not leave an editable control for a field nothing reads
  • Record findings in docs/KNOWN-ISSUES.md (real defects) / docs/PRODUCT_BACKLOG.md (needs a decision), matching how the earlier audit was folded in

Known starting points (already confirmed dead/inert): theme mode (PRODUCT_BACKLOG.md, needs a dark-mode decision — not a wiring fix). Verify no others in HeaderConfig, FooterConfig, CatalogConfig, ProductPageConfig, UserExperienceConfig, FeatureFlags, SeoConfig.

What shipped: Full findings table in docs/DEAD-CONFIG-AUDIT.md. Fixed and wired: footer.logoUrl (new LogoComponent.srcOverride input), company.address.street + company.contacts.phone (new UiRuntimeFacade.companyAddress()/contactPhone(), rendered in footer bottom bar), catalog.suggestionsEnabled (SearchFacade.autocomplete() now gates on it). Left dead but tracked (needs a business/design decision, not a mechanical fix): layout.type site-layout selector, company.companyName copyright-fallback wording (both → PRODUCT_BACKLOG.md), navigation.header top-nav rendering (→ KNOWN-ISSUES.md). catalog.navigationMode confirmed intentionally inert (labeled placeholder card, not a bug). No editor control was hidden — every remaining dead field's saved value stays visible and none risked losing already-saved client data.

Sprint H — Test suite foundation

Why: 5 .spec.ts files exist in the entire repository. Project standards mandate 80% coverage and a TDD workflow; neither is happening. NEXT_PHASE.md Phase 2 defers testing until after backend integration — this sprint deliberately front-runs part of that, on the argument that tests written against the current mock gateways lock in today's behavior and make the eventual real-gateway swap far safer. Post-backend E2E work stays in Phase 2 where it is.

  • Confirm the test runner actually works end to end (npm testng test --watch=false --browsers=ChromeHeadlessNoSandbox) and fix the harness if it doesn't
  • Establish the house pattern with one exemplar spec per layer, so later tests have something to copy: a pure util, a service, a facade, a component
  • Facade-level tests against existing mock gateways for the highest-risk domains first: ProjectEditorFacade (undo/redo, draft persistence, validation gating on publish), AdminAnalyticsFacade (the never-fabricate-a-number contract)
  • Unit tests for the pure validator primitives (project-editor/schema/validators/primitives.ts) — zero-dependency, highest value per line of test
  • Regression tests for the bugs fixed this cycle so they cannot silently return (carousel layout.columns sizing, hero layout.columns panel count, header profile login/logout gating)
  • Wire coverage reporting — done: installed karma-coverage as a devDependency, added it to karma.conf.js (coverage reporter + coverageReporter block emitting text-summary, html, and lcovonly into coverage/). npx ng test --watch=false --code-coverage runs clean (83/83 specs pass). Baseline: Statements 32.02% (1025/3201), Branches 18.53% (353/1904), Functions 21.73% (220/1012), Lines 32.76% (946/2887).
  • Decide whether to gate CI on it — no, not yet: 11 spec files is a foundation, not the coverage floor CI gating implies; gate once coverage reporting exists and a real floor number can be set, not before.

What shipped: Harness confirmed working (npm test was already green, 57/57). Added 6 new spec files (test count 57 → 75): ProjectEditorFacade facade spec (undo/redo, draft-persistence round-trip via a second facade instance reading the same localStorage draft, publish blocked/allowed on hasBlockingIssues()) mocking CONFIG_PROVIDER as the gateway boundary; AdminAnalyticsFacade facade spec asserting summary().conversionRate stays null and performance/backend-connectivity health checks stay 'unknown' rather than being guessed, mocking all 4 gateways + AdminDashboardFacade; HeroWidgetComponent and ProductCarouselWidgetComponent component specs regression-covering layout.columns (panel count / items-per-page); HeaderComponent component spec regression-covering the login/logout profile toggle (asserts on icon name, not translated aria-label text, since Russian is the default active language in tests). primitives.ts and the pure-util/service exemplar layers were already covered by pre-existing specs — verified, not re-done. Cart/checkout facade tests and a "manifest-filtered layout options" regression were scoped out to stay within this sprint's time budget — breadth across the 4 required layers (util/service/facade/component) was prioritized over a 5th facade.

Sprint I — Widget settingsSchema enforcement

Why: Same disease Sprint E cured for supportedLayouts. Every widget in widget-manifest.json declares a JSON Schema for its props under settingsSchema, and nothing reads it — verified: only supportedDataSources is consumed anywhere (and only by a diagnostics validator, not the editor). Consequences: widget props are never validated against their own declared contract, and unknown widget types fall back to raw JSON editing in the Widgets section. (enabled is honored correctly — widget-registry.bootstrap.service.ts filters on it.)

  • Read settingsSchema in the Widgets editor section and validate widget props against it, surfacing failures through the existing ProjectValidator issue pipeline (fieldKey/section/severity) rather than a parallel mechanism
  • Add a widgetSettingsSchema validator alongside the existing widgetConfig check in project-validator.service.ts
  • Evaluate replacing the raw-JSON fallback editor with schema-generated fields for widget types that have no hand-authored editor — scope this honestly; if the schemas are too thin to generate a decent UI, keep the JSON fallback and just add validation on top
  • Confirm the diagnostics page (features/diagnostics/) reflects schema violations too, since it already consumes the manifest

What shipped: validateAgainstSchemaLite(value, schema) (schema/validators/primitives.ts) — a shallow, dependency-free type+required checker (no nested schemas/enums/$ref; checked first, no existing schema-validation utility or library in the repo). ProjectValidator.widgetSettingsSchemaIssues() runs it against every widget's props vs. its manifest entry's settingsSchema, added to the same validate() composition as a widgets-section warning tagged fieldKey: 'pages' — it surfaces automatically through the existing fieldError('pages') call already in widgets-section.component.html, no template changes needed. WidgetManifestService gained a synchronous getManifestSnapshot() (same pattern as ConfigService.getBootstrapSnapshot()) since ProjectValidator.validate() is called synchronously and can't await the manifest HTTP fetch; the check no-ops (matching RuntimeDiagnosticsValidator's existing null-manifest convention) until the manifest has loaded once elsewhere in the app (it always has, by the time a user reaches the editor). Schema-generated form fields were evaluated and explicitly skipped: every widget's settingsSchema.properties tops out at 7 flat string/number fields with zero required arrays and zero enums/nesting across all 10 widget types in widget-manifest.json — too thin to justify generated UI over the existing JSON fallback (widgets-section.component.ts's updateJson/widgetJsonError), so the JSON editor stays and only gets the new validation layered on top. Diagnostics: BootstrapDiagnosticsValidator gained a sibling validateWidgetSettingsSchema() next to its existing validateUnknownWidgetTypes(), reusing the identical validateAgainstSchemaLite call so the editor and diagnostics page can never disagree about what counts as a violation — one check, two surfaces, not a parallel one.


Tier 2 — Blocked on backend

Sequencing is owned by docs/BACKEND.md §9 and docs/NEXT_PHASE.md Phase 1. Not re-planned here — that checklist is already the authoritative task list. Frontend-side items that unblock the moment backend lands:

  • Ed25519 auth error codes (docs/KNOWN-ISSUES.md Open #1) — session-expired and invalid-signature recovery screens are built and wired but permanently unreachable, because toAuthErrorShape() derives the code purely from HTTP status and never reads a body-level code. Needs: backend returning a distinguishable error.code (BACKEND.md §6), then a small frontend change to prefer it over the status fallback.
  • Swap every mock gateway for its real counterpart behind the existing DI tokens, in the dependency order BACKEND.md §8 specifies
  • Maintenance-mode frontend UI (BACKEND.md §10 flags full-page takeover, per-module banners, scheduled countdown as not existing) — deliberately not built during Sprint C for exactly this reason
  • Real Monitoring data source — page currently renders mock activity (NEXT_PHASE.md Phase 4)
  • Re-profile performance under real latency (NEXT_PHASE.md Phase 3) — mock responses are instant, real ones won't be; loading/skeleton timing is untested against reality

Tier 3 — Blocked on a business decision

No engineering work should start on these until answered. Full detail in docs/PRODUCT_BACKLOG.md.

  • Dark mode — does the client want it? If yes it's a real project (dark palette + CSS strategy + matchMedia for "system"), not a wiring fix. Blocks the theme-mode selector, which is inert today.
  • Brand color contrast (WCAG AA)--border-color fails 3:1 in every theme; several status colors fail 4.5:1 as text. Fixing means visibly changing the brand — needs theme-owner sign-off.
  • Stars rating glyph token — literal hex with no matching design token; add a token or reuse an existing one (visual shift either way).
  • Contacts page content — nothing written for it at all. Content question.
  • Advanced analytics — no data source exists for traffic/funnels/heatmaps. Build vs. buy, and launch vs. later.
  • Additional payment providers — which ones, if any, before integration work starts.

Tier 4 — Deferred, non-blocking

From docs/FUTURE_FEATURES.md. No decision needed, just not worth doing now.

  • Angular 22 upgrade — researched, ~23.5 days, needs a dependency fix and Node bump first. Plan: docs/ANGULAR22_PLAN.md. Run as its own dedicated session — framework upgrades don't share a session with feature work.
  • Bundle splittingproject-editor (~896 kB) and catalog-container (~330 kB) lazy chunks are large; no mechanical split found, needs a dedicated profiling task, ideally under real backend latency
  • Cart payment modal → app-dialog — composition cleanup, functionally and accessibly complete as-is
  • Homepage hero-to-categories spacing — traces to mock fixture padding values, not a confirmed defect; needs reproduction with real tenant data before it's worth investigating

Tier 5 — Infrastructure

  • Server deploy — no deploy pipeline exists in this repo (only .github/workflows/architecture-governance.yml). Deploys are currently manual/out-of-band. Worth deciding whether a real pipeline should exist; separately, SSH from the agent harness is blocked, so agent-driven deploys need either a permission rule or a different mechanism.

Suggested order

G → H → I. Sprint G is cheap, mechanical, and directly prevents more client-reported ghost settings (it is the same class of bug as the one already reported). Sprint H is the highest-value thing available that isn't blocked on anything, and it gets more valuable the earlier it lands, since every later change rides on it. Sprint I is real but narrower — it hardens an editor path rather than fixing something users hit today.

Tier 2 starts the moment backend Phase 1 lands. Tier 3 needs answers, not engineering. Tier 4 is genuinely optional.