Phase 3 (Blueprint) artefact. The design + rollout plan for the Insights content layer that wraps the Advisor. It was adapted to this shipped, client-side SPA after reviewing a generic implementation prompt whose assumptions did not match the codebase — the corrections are in Appendix A. Cross-cutting records live in the SDLC docs (SRS §3.10, the design spec, the test plan) and in root
DECISIONS.md; this file is the single structured home for the plan itself.Status: client-rendered first (no SSG) — Wave A + pipeline and Wave B (Library) implemented. Language: this plan and all code/docs are English; article content + UI strings are fully bilingual EN/ID (EN default since 2026-07-06; article bodies bilingual since 2026-07-15), per the repo convention.
Help both newcomers (awam) and experts genuinely understand software architecture — not just get a score. The Insights layer teaches the why, cites real sources, and links every claim back to the Advisor's frozen decision model so learning and tooling reinforce each other.
Two audiences, one text: a plain-language layer (TL;DR → what / when it fits / what it costs) and a deeper layer (mechanism, evidence, trade-offs, cited journals) — the same dual-audience pattern the Guide uses, toggled by the app's Guided / Expert mode.
- The Advisor: 14 factors → 12 quality attributes → recommendation across 5 dimensions (D1–D5), with a frozen, machine-verified scoring model.
- The Manual / Guide carries in-app, cited D1–D5 explanations
(
src/config/readerContent.ts, canonical architecture-reader.md). - The model as data in
src/config/and the Model Data Sheet — the single source of truth for dimensions, options, qaFit.
Anti-duplication rule: anything about D1–D5 / qaFit / QAs derives from the model, never re-copied. Catalog, Playbook, and Review are therefore all data-driven (see §3), not hand-authored per architecture — and no explanation is repeated across them.
3. Key decisions (rationale also in DECISIONS.md)
| Topic | Decision | Why (fit to this repo) |
|---|---|---|
| Discoverability / SSG | SSG-lite (Wave C, 2026-07-06). The app stays a client-rendered SPA (no router, no hydration); a build-time script emits sitemap.xml, robots.txt, app-shell canonical/OG/JSON-LD, and static crawlable HTML snapshots of every article (dist/insights/…, self-canonical TechArticle). Full SSG of the app itself remains deferred. |
Search discoverability became a stated goal; snapshots give crawlers real content with zero JS-budget impact and no hydration clash with the Advisor's #s= share-state. A guard fails the build if canonical/robots drift from SITE_URL. |
| Routing | Light: a two-item top nav (Advisor · Insights) + in-view section/article state, lazy-loaded. No react-router. |
Avoids a second navigation paradigm; the Advisor keeps sole ownership of the URL hash / share links. |
| Section shape | All four sections are data-driven from the model (readerContent.ts + insightPlaybooks.ts / insightReviews.ts / insightLibrary.ts) → every architecture (all 21 D1–D5 options), grouped by decision, through four structured lenses (Catalog = discover, Playbook = implement, Review = evaluate, Library = reference). Hand-authored Markdown is reserved for cross-cutting guides/methods/further reading listed under each section. |
Comprehensive by construction (a unit test asserts 21×4 parity); cannot go partial or drift from the model. No explanation is duplicated — a per-page LensNav walks the Catalog → Playbook → Review → Library journey. |
| Content format | Markdown + YAML frontmatter for the cross-cutting guides; rendered by a small dependency-free, XSS-safe renderer with :::guided / :::expert blocks. |
Matches the repo's hand-built ethos (no gray-matter / react-markdown / micromark); keeps the Insights chunk small. |
| Diagrams | Hand-built SVG or static images only. No Mermaid. | DECISIONS.md already rejected Mermaid (unreliable + heavy). |
| Frontmatter validation | Dependency-free guard (scripts/check-content.mjs) in the style of the model guards — not zod. |
The repo's guards are proudly dependency-free; it also cross-checks related_advisor against the frozen model. |
| Content index | Build-time via import.meta.glob in src/lib/content.ts. |
Statically analyzable, offline-capable, testable; no backend. |
SITE_URL |
Single source in src/config/site.ts. |
Future custom-domain safe. |
- Frozen gates stay green:
verify-model.mjs+cross-check-docs.mjsexit 0. Do not editsrc/lib/scoring.ts, frozensrc/config/*model values/presets, those scripts, ordocs-integrity.yml. - No backend, DB, accounts, AI calls, or runtime telemetry. 100% client-side, base
/architecture-advisor/. - All UI strings in
src/i18n(EN+ID, default id); EN/ID key parity is test-enforced. - Accessibility: new views keyboard-navigable, axe-clean, AA contrast in both themes, responsive to 360 px — axe + keyboard tests.
- Bundle budget (
check-bundle-size.mjs) stays green; the Insights area is lazy-loaded. Raise budgets only deliberately, with a note.
A Markdown article ships only if it passes content:validate:
- Frontmatter valid against the schema.
- ≥ 1 primary source with a well-formed URL/DOI (format check only — no fetching).
- Honest
evidence_strength∈ {strong, moderate, emerging}. last_reviewedset andreview_due = last_reviewed + 12 months.- At least the id version.
- Every
related_advisordimension/option resolves to a canonical id in the frozen model — the anti-drift contract. - Unique slug + meta.
Link liveness (links:check) and review cadence (content:review) are scheduled /
non-blocking only — never on the build path, so CI can't turn red on its own months later.
title_id / title_en: string
slug: string # unique, kebab-case, matches the filename
section: catalog | playbook | review | library | roadmap | academy | lab
audience: [awam, expert]
summary_tldr_id / summary_tldr_en: string
evidence_strength: strong | moderate | emerging
last_reviewed: YYYY-MM-DD
review_due: YYYY-MM-DD # = last_reviewed + 12 months (validated)
translation_status: id+en # required for every published article (2026-07-15)
related_advisor: { dimensions: [D1..D5], options: [<option-id>] } # must exist in the model
sources: [ { label, venue, year, url } ]
status: draft | published
author: stringThe contract lives in src/config/contentSchema.ts; the
authoring workflow is in EXTENDING.md.
TL;DR → plain explanation (:::guided) → deep dive with evidence (:::expert) → "Try in the
Advisor" → credibility block (multiple sources[], evidence badge, "Terakhir ditinjau", and a
"Perlu ditinjau" flag once review_due passes). The Catalog renders the same shape from the model.
Phase 0 — Pipeline (client-rendered, no SSG): contentSchema.ts (dependency-free types, no zod)
site.ts+sections.ts;content.ts(index viaimport.meta.glob),frontmatter.ts,markdown.tsx(safe renderer +:::guided/:::expert);check-content.mjs+content:validatewired intoci.yml(docs-integrity.ymluntouched);LearnView(lazy) +CredibilityBlock; i18n.
Phase 1 — Wave A:
- Every architecture appears in all sections, data-driven from the model — distinct lenses on
the same 21 D1–D5 options:
- Catalog — what it is / when it fits / what it costs.
- Playbook — how to adopt it (+ 7 cross-cutting decision guides in Markdown: ADRs, Strangler-Fig migration, choosing communication / data / code-structure / frontend, when to use microservices).
- Review — what to check when evaluating it (+ 6 Markdown methods: ATAM checklist, detecting a distributed monolith, fitness functions, data-consistency review, serverless readiness, avoiding premature microservices).
- Each architecture carries several cited references (books + peer-reviewed journals/surveys).
- Guided / Expert reading mode (the app's mode; one control in the header — no duplicate).
- All Markdown guides pass
content:validate.
Wave B — delivered (2026-07-05): the Library section is live with 5 trend articles — GenAI & architecture, green/carbon-efficient software (SCI / ISO/IEC 21031), architectural technical debt, the monolith→microservices decision map, and Conway’s Law / Team Topologies — each with real, current sources and honest evidence_strength.
Holistic coverage + English-first — delivered (2026-07-06):
- All 21 architectures in all four sections. The thin
readerAngles.ts(two paragraphs per lens) was replaced by three structured English datasets —insightPlaybooks.ts(goal/prerequisites/steps/practices/pitfalls),insightReviews.ts(overview/pros/cons/performance/scalability/DX/use-cases/verdict),insightLibrary.ts(definition/concepts/patterns/terminology) — each keyed${dim}:${optionId}, 21 entries per lens, with a unit test asserting 21×4 parity against the frozen model. - Each section is now a distinct reading experience (discover / implement / evaluate / reference) with its own structured layout; a per-page LensNav walks one architecture through the Catalog → Playbook → Review → Library knowledge journey. The Library section carries the reference grid and its evergreen articles as "Further reading".
- English consistency (superseded — see below): the default language is EN; at this wave all 18
Markdown articles shipped English-only bodies and
check-content.mjsrequired at least theenversion.
Full bilingualisation — delivered (2026-07-15, English-first reversed):
- Every Insights surface now responds to the language toggle down to the deepest sub-level. All
six datasets (
insightPlaybooks,insightReviews,insightLibrary,insightRoadmaps,academyQuizzes,labExperiments) becameBilingual {en,id}rendered viatr(); in the Library lens, prose is translated while pattern names / glossary terms stay canonical (English) proper nouns. - All 18 articles are bilingual: each body carries English, then a
<!-- lang:id -->delimiter, then Indonesian;translation_statusisid+en. The pipeline splits the body per language (docBody(doc, lang)); the SEO snapshot keeps the English canonical (body above the delimiter). - The gate now enforces it:
check-content.mjsrequirestranslation_status: id+enand the<!-- lang:id -->delimiter on every article.
Wave C — delivered (2026-07-06): the last three sections are live, each built ON TOP of the lens content (curate / exercise — never duplicate) and each carrying the same 21-architecture holistic parity as the four lenses (unit-tested per section, so Wave C can never mismatch the lens coverage):
- Roadmap — 8 guided learning paths (newcomer → practitioner → architect) in
src/config/insightRoadmaps.ts; every step deep-links to an existing architecture lens page, Markdown article, or the Advisor; every one of the 21 architectures appears in ≥1 path (a unit test resolves every target and asserts the coverage — anti-drift). - Academy — 6 quiz modules (one per dimension + methods; 32 questions) in
src/config/academyQuizzes.ts, scored entirely client-side; each answer explains itself and links back to the page that teaches it; every one of the 21 architectures is reviewed by ≥1 question (links + coverage unit-tested). - Lab — 7 hypothesis-driven experiments (spanning D1–D5) in
src/config/labExperiments.ts; each prepares valid levels for all 14 model factors (unit-tested) and loads them into the Advisor, so the claim is tested on the live engine; each lists its "architectures in play" as deep-link chips and the union covers all 21 (unit-tested).
SEO / SSG-lite — delivered (2026-07-06): discoverability without changing the SPA architecture
(the "SSG deferred" decision is superseded in this narrower form — still no router, no hydration):
scripts/generate-seo.mjs runs after vite build and emits sitemap.xml + static, crawlable HTML
snapshots of all 18 articles (dist/insights/<section>/<slug>/, self-canonical, JSON-LD
TechArticle, linking into the app); public/robots.txt + canonical/OG/JSON-LD on the app shell;
a build guard fails if the canonical/robots URLs drift from SITE_URL. Pure HTML — zero impact on
the JS budgets. hreflang is en + x-default only: the app serves both languages from one
URL via the client-side toggle (bilingual bodies are not separate pages), so English stays the
crawlable canonical and the snapshot takes the body above the <!-- lang:id --> delimiter.
Deferred (own future proposals): full SSG/hydration of the app itself, Academy progress persistence, additional Lab experiment packs.
Advisor + model gates unchanged and green; every article passes content:validate; new views
axe-clean + keyboard-navigable + AA both themes; i18n parity; lint / test / build /
content:validate / bundle budget green; docs-integrity.yml untouched; diagrams hand-built SVG
(no Mermaid); README.md, EXTENDING.md,
DECISIONS.md, the SRS
(§3.10), the design spec, and the test plan
updated.
The generic prompt assumed things that do not hold here; the plan corrects them:
- Missing spec: the referenced plan file did not exist — this document is it (now in the docs).
- zod: not a dependency ("reuse the repo's zod approach" was false) → NOT added; validation is a dependency-free guard.
- Mermaid / Recharts: neither is installed; Mermaid was consciously rejected → not reintroduced.
- SSG /
react-router: the app is a hash-state SPA → deferred. - Script/paths:
verify:model/verify:docsare not npm scripts (guards run asnode scripts/*.mjs);ci.ymlalready existed;src/lib/sensitivity.tsdoes not exist (sensitivity is inscoring.ts); "ADR-0001" is the D4/D5 qaFit ratification, not the scoring contract. - Scope: trimmed to Wave A + pipeline; Wave B/C and SSG deferred.
| Version | Date | Notes |
|---|---|---|
| 1.0 | 2026-07-03 | Relocated into the SDLC docs from the repo root; Wave A delivered (data-driven Catalog of all 21 architectures, Guided/Expert reading mode, 7 Playbook + 6 Review Markdown guides, dependency-free pipeline). |