Skip to content

refactor: architectural audit — UriRouter SSOT, spec coverage, code cleanliness#54

Merged
ronaldtse merged 5 commits into
mainfrom
refactor/audit-clean-architecture
Jun 12, 2026
Merged

refactor: architectural audit — UriRouter SSOT, spec coverage, code cleanliness#54
ronaldtse merged 5 commits into
mainfrom
refactor/audit-clean-architecture

Conversation

@ronaldtse

Copy link
Copy Markdown
Member

Summary

Architectural audit and cleanup addressing MECE/DRY/OCP violations discovered during codebase review.

1. Revitalize UriRouter as URI Routing SSOT

Problem: UriRouter was defined but never imported — ReferenceResolver absorbed its responsibilities (pattern matching, parseUri, URI resolution) and became a god-class handling both URI routing and reference resolution.

Fix:

  • UriRouter enhanced with wildcard pattern matching, URN prefix mapping, and resolveUri()
  • ReferenceResolver takes UriRouter as constructor dependency, delegates URI matching to it
  • parseUri / URI_REGISTER_RE defined in exactly one place (UriRouter)
  • All callers updated: GraphEngine, GraphDataSource, vocabulary store
  • AdapterFactory creates and exposes UriRouter alongside ReferenceResolver

2. Spec Coverage Additions (27 new tests)

  • GraphDataSource (8 tests): edge extraction, domain edges, section tree mapping, self-reference filtering
  • escape.ts (16 tests): XSS-relevant HTML/attribute escaping with edge cases
  • UriRouter (3 new tests): URN patterns, URN prefix resolution, uriBase lookup

3. Code Cleanliness

  • generate-data.mjs: Extracted stripHtml() helper (was duplicated 3×). Now strips HTML from ALL designation values in index (not just eng), incorporating PR fix: include multilingual designations in index summary #25 intent.
  • AppSidebar.vue: Removed unnecessary as any casts — RuntimeSiteConfig already properly types branding
  • markdown-lite.ts: Moved import from bottom to top of file

Test Results

  • 65 test files, 697 tests passing (up from 670)
  • Type-check passes (vue-tsc --noEmit)

Commits

  1. refactor: revitalize UriRouter as URI routing SSOT — core architectural fix
  2. test: update all resolver tests for UriRouter DI — test infrastructure
  3. test: add GraphDataSource and escape.ts specs — new coverage
  4. refactor: extract stripHtml() helper in generate-data.mjs — DRY
  5. fix: remove unnecessary as any casts, fix import order — cleanliness

UriRouter was defined but never imported — ReferenceResolver absorbed
its responsibilities (pattern matching, parseUri, URI resolution) and
became a god-class handling both URI routing and reference resolution.

This refactoring:
- Enhances UriRouter with wildcard pattern matching, URN prefix mapping
- ReferenceResolver now takes UriRouter as constructor dependency and
  delegates URI pattern matching to it
- parseUri/URI_REGISTER_RE defined in exactly one place (UriRouter)
- All callers updated: GraphEngine, GraphDataSource, vocabulary store
- AdapterFactory creates and exposes UriRouter alongside ReferenceResolver

Fixes: MECE violation between UriRouter/ReferenceResolver
Fixes: DRY violation (parseUri defined 3x)
Fixes: UriRouter was dead code
- Add createResolverPair() helper to test-helpers.ts
- All tests now create UriRouter first, pass to ReferenceResolver
- registerDataset calls moved to uriRouter.registerDataset()
- UriRouter tests updated for new 4-arg registerDataset signature
- Added tests for URN resolution, uriBase lookup, wildcard patterns
GraphDataSource (8 tests):
- resolveRefTarget with null ref, concept-level and localization-level edges
- self-reference filtering, domain edge extraction, section tree mapping

escape.ts (16 tests):
- escapeHtml with <, >, &, combined, empty, unicode, long strings
- escapeAttr with quotes, combined special characters, plain text
The HTML stripping regex appeared 3 times inline. Extracted to a
single stripHtml() function and applied it to all designation values
in the index summary (previously only eng was stripped).

This also incorporates the intent of PR #25 (multilingual designations
in index) — the designations map in index.json is now fully
HTML-stripped.
- AppSidebar.vue: remove as any casts for siteConfig.branding access
  (RuntimeSiteConfig already types branding with ownerName/ownerUrl)
- AppSidebar.vue: type navTitle parameter with optional title field
- markdown-lite.ts: move import to top of file
Comment thread scripts/generate-data.mjs

/** Strip HTML tags and normalize whitespace for plain-text display. */
function stripHtml(s) {
return s.replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();
@ronaldtse ronaldtse merged commit 7094d77 into main Jun 12, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants