diff --git a/docs/changelog.adoc b/docs/changelog.adoc new file mode 100644 index 0000000..e4ce9d8 --- /dev/null +++ b/docs/changelog.adoc @@ -0,0 +1,158 @@ += Changelog +:toc: +:toc-placement: preamble +:toclevels: 2 + +A chronological record of all semantic anchors added to the catalog. Community contributors are credited with thanks. + +== 2026-03-09 + +* *CQRS* — contributed by https://github.com/Nantero1[@Nantero1] in https://github.com/LLM-Coding/Semantic-Anchors/pull/137[#137]. Thank you! +* *GoF Design Patterns* — contributed by https://github.com/Nantero1[@Nantero1] in https://github.com/LLM-Coding/Semantic-Anchors/pull/140[#140]. Thank you! +* *Test Double (Meszaros)* — contributed by https://github.com/Nantero1[@Nantero1] in https://github.com/LLM-Coding/Semantic-Anchors/pull/142[#142]. Thank you! +* *Event-Driven Architecture* — contributed by https://github.com/Nantero1[@Nantero1] in https://github.com/LLM-Coding/Semantic-Anchors/pull/143[#143]. Thank you! +* *BDD (Given-When-Then)* — contributed by https://github.com/Nantero1[@Nantero1] in https://github.com/LLM-Coding/Semantic-Anchors/pull/138[#138], merged via https://github.com/LLM-Coding/Semantic-Anchors/pull/152[#152]. Thank you! +* *YAGNI* — contributed by https://github.com/Nantero1[@Nantero1] in https://github.com/LLM-Coding/Semantic-Anchors/pull/139[#139], merged via https://github.com/LLM-Coding/Semantic-Anchors/pull/152[#152]. Thank you! + +== 2026-03-06 + +* *ATAM* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/133[#133] +* *LASR* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/135[#135] + +== 2026-03-04 + +* *OWASP Top 10* — proposed by https://github.com/Advisior[@Advisior] in https://github.com/LLM-Coding/Semantic-Anchors/issues/130[#130]. Thank you! + +== 2026-03-01 + +* *GoM (Grundsätze ordnungsmäßiger Modellierung)* — proposed by https://github.com/raifdmueller[@raifdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/126[#126] + +== 2026-02-23 + +* *Regulated Environment* — proposed by https://github.com/bit-jkraushaar[@bit-jkraushaar] in https://github.com/LLM-Coding/Semantic-Anchors/issues/120[#120]. Thank you! + +== 2026-02-22 + +* *MoSCoW* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/115[#115] + +== 2026-02-17 + +* *Chatham House Rule* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/101[#101] + +== 2026-02-16 + +* *Fowler Patterns (PEAA)* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/99[#99] + +== 2026-02-13 + +* *Morphological Box* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/67[#67] +* *IEC 61508 SIL Levels* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/67[#67] +* Split from monolithic README.adoc into individual anchor files (https://github.com/LLM-Coding/Semantic-Anchors/pull/38[#38]) + +== 2026-02-12 + +* *Socratic Method* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/31[#31] +* *BLUF* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/31[#31] +* *Rubber Duck Debugging* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/31[#31] +* *Chain of Thought* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/31[#31] +* *Devil's Advocate* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/31[#31] +* *Five Whys* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/31[#31] +* *Feynman Technique* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/31[#31] +* *MADR* — proposed by https://github.com/raifdmueller[@raifdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/29[#29] + +== 2026-02-11 + +* *TIMTOWTDI* — contributed by https://github.com/rehsack[@rehsack] in https://github.com/LLM-Coding/Semantic-Anchors/pull/28[#28]. Thank you! + +== 2026-02-07 + +* *MECE Principle* — proposed by https://github.com/ingo-eichhorst[@ingo-eichhorst] in https://github.com/LLM-Coding/Semantic-Anchors/issues/26[#26]. Thank you! + +== 2026-02-05 + +* *Nelson Rules* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/20[#20] +* *Control Chart (Shewhart)* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/21[#21] +* *SPC* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/22[#22] + +== 2026-02-03 + +* *DRY Principle* — added in https://github.com/LLM-Coding/Semantic-Anchors/pull/19[#19] +* *SPOT Principle* — added in https://github.com/LLM-Coding/Semantic-Anchors/pull/19[#19] +* *SSOT Principle* — added in https://github.com/LLM-Coding/Semantic-Anchors/pull/19[#19] +* *SOTA* — proposed by https://github.com/raifdmueller[@raifdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/16[#16] +* *todo.txt-flavoured Markdown* — proposed by https://github.com/raifdmueller[@raifdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/14[#14] + +== 2026-01-21 + +* *Pyramid Principle* — proposed by https://github.com/rdmueller[@rdmueller] in https://github.com/LLM-Coding/Semantic-Anchors/issues/12[#12] + +== 2025-11-18 + +* *Mutation Testing* — contributed by ThomasPeuss. Thank you! + +== 2025-11-13 + +* *BEM Methodology* — contributed by Robert Nimax. Thank you! + +== 2025-11-11 + +* *Conventional Commits* — contributed by https://github.com/rehsack[@rehsack] in https://github.com/LLM-Coding/Semantic-Anchors/pull/4[#4]. Thank you! +* *Semantic Versioning* — contributed by https://github.com/rehsack[@rehsack] in https://github.com/LLM-Coding/Semantic-Anchors/pull/4[#4]. Thank you! +* *SOLID Principles* — contributed by https://github.com/bit-jkraushaar[@bit-jkraushaar]. Thank you! + +== 2025-11-10 — Initial Catalog + +First commit by https://github.com/rdmueller[@rdmueller] with 23 founding anchors: + +* *TDD, London School* +* *TDD, Chicago School* +* *Problem Space NVC* +* *Mental Model (Naur)* +* *EARS Requirements* +* *arc42* +* *ADR (Nygard)* +* *Pugh Matrix* +* *C4 Diagrams* +* *Docs-as-Code* +* *Domain-Driven Design* +* *Hexagonal Architecture* +* *Clean Architecture* +* *User Story Mapping* +* *Impact Mapping* +* *Jobs To Be Done* +* *Cynefin Framework* +* *Wardley Mapping* +* *Property-Based Testing* +* *Testing Pyramid* +* *Diátaxis Framework* +* *What Qualifies as a Semantic Anchor* + +== Community Contributors + +Thank you to everyone who has contributed anchors to the catalog! + +[cols="1,3"] +|=== +| Contributor | Contributions + +| https://github.com/rehsack[@rehsack] +| Conventional Commits, Semantic Versioning, TIMTOWTDI + +| https://github.com/bit-jkraushaar[@bit-jkraushaar] +| SOLID Principles, Regulated Environment + +| Robert Nimax +| BEM Methodology + +| ThomasPeuss +| Mutation Testing + +| https://github.com/ingo-eichhorst[@ingo-eichhorst] +| MECE Principle + +| https://github.com/Advisior[@Advisior] +| OWASP Top 10 + +| https://github.com/Nantero1[@Nantero1] +| CQRS, GoF Design Patterns, Test Double (Meszaros), Event-Driven Architecture, BDD, YAGNI +|=== diff --git a/website/src/components/header.js b/website/src/components/header.js index 0f23205..587f9a9 100644 --- a/website/src/components/header.js +++ b/website/src/components/header.js @@ -37,6 +37,7 @@ export function renderHeader() { ${i18n.t('nav.catalog')} ${i18n.t('nav.about')} ${i18n.t('nav.contributing')} + ${i18n.t('nav.changelog')}
diff --git a/website/src/main.js b/website/src/main.js index b162018..6fb5541 100644 --- a/website/src/main.js +++ b/website/src/main.js @@ -102,6 +102,7 @@ function initApp() { addRoute('/', renderHomePage) addRoute('/about', renderAboutPage) addRoute('/contributing', renderContributingPage) + addRoute('/changelog', renderChangelogPage) addRoute('/all-anchors', renderAllAnchorsPage) const app = document.querySelector('#app') @@ -178,6 +179,15 @@ function renderContributingPage() { loadDocContent('CONTRIBUTING.adoc') } +function renderChangelogPage() { + const pageContent = document.getElementById('page-content') + if (!pageContent) return + + pageContent.innerHTML = renderDocPage() + updateActiveNavLink() + loadDocContent('docs/changelog.adoc') +} + function renderAllAnchorsPage() { const pageContent = document.getElementById('page-content') if (!pageContent) return @@ -381,6 +391,8 @@ function handleLanguageChange() { loadDocContent('docs/about.adoc') } else if (currentRoute === '/contributing') { loadDocContent('CONTRIBUTING.adoc') + } else if (currentRoute === '/changelog') { + loadDocContent('docs/changelog.adoc') } else if (currentRoute === '/all-anchors') { loadDocContent('docs/all-anchors.adoc') } else if (currentRoute === '/') { diff --git a/website/src/translations/de.json b/website/src/translations/de.json index e710ddf..f07a1b1 100644 --- a/website/src/translations/de.json +++ b/website/src/translations/de.json @@ -8,6 +8,7 @@ "nav.catalog": "Katalog", "nav.about": "Über", "nav.contributing": "Mitwirken", + "nav.changelog": "Änderungsprotokoll", "main.heading": "Semantic Anchors erkunden", "main.subheading": "Ein kuratierter Katalog klar definierter Begriffe, Methoden und Frameworks für effektive LLM-Kommunikation.", "main.aboutLink": "Über", diff --git a/website/src/translations/en.json b/website/src/translations/en.json index 6ea0531..22a551d 100644 --- a/website/src/translations/en.json +++ b/website/src/translations/en.json @@ -8,6 +8,7 @@ "nav.catalog": "Catalog", "nav.about": "About", "nav.contributing": "Contributing", + "nav.changelog": "Changelog", "main.heading": "Explore Semantic Anchors", "main.subheading": "A curated catalog of well-defined terms, methodologies, and frameworks for effective LLM communication.", "main.aboutLink": "About", diff --git a/website/tests/e2e/website.spec.js b/website/tests/e2e/website.spec.js index 8989d9d..3216dba 100644 --- a/website/tests/e2e/website.spec.js +++ b/website/tests/e2e/website.spec.js @@ -1,5 +1,12 @@ import { test, expect } from '@playwright/test' +// Dismiss onboarding modal before all tests +test.beforeEach(async ({ page }) => { + await page.addInitScript(() => { + localStorage.setItem('onboarding-seen', 'true') + }) +}) + test.describe('Homepage - Card Grid', () => { test.beforeEach(async ({ page }) => { await page.goto('/') @@ -7,7 +14,7 @@ test.describe('Homepage - Card Grid', () => { test('should load homepage successfully', async ({ page }) => { await expect(page).toHaveTitle(/Semantic Anchors/) - await expect(page.locator('h1')).toContainText('Semantic Anchors') + await expect(page.locator('h2').first()).toContainText('Semantic Anchors') }) test('should display header with navigation', async ({ page }) => { @@ -41,14 +48,18 @@ test.describe('Homepage - Card Grid', () => { }) test('should display search and filter controls', async ({ page }) => { - await expect(page.locator('#search-input')).toBeVisible() - await expect(page.locator('#role-filter')).toBeVisible() + // On desktop, search and filter are in the header + await expect(page.locator('#header-search-input')).toBeVisible() + await expect(page.locator('#header-role-filter')).toBeVisible() - // Role filter should have options - const roleFilter = page.locator('#role-filter') + // Role filter should have options (wait for data to load) + await page.waitForSelector('.anchor-card', { timeout: 10000 }) + const roleFilter = page.locator('#header-role-filter') const options = roleFilter.locator('option') - const count = await options.count() - expect(count).toBeGreaterThan(1) // At least "All Roles" + 1 role + await expect(async () => { + const count = await options.count() + expect(count).toBeGreaterThan(1) + }).toPass({ timeout: 10000 }) }) test('should filter cards by role', async ({ page }) => { @@ -58,8 +69,8 @@ test.describe('Homepage - Card Grid', () => { const initialCount = await page.locator('.anchor-card').count() expect(initialCount).toBeGreaterThan(0) - // Select a role - await page.selectOption('#role-filter', 'software-developer') + // Select a role (use header filter on desktop) + await page.selectOption('#header-role-filter', 'software-developer') // Some cards should still be visible const filteredCount = await page.locator('.anchor-card:visible').count() @@ -69,15 +80,15 @@ test.describe('Homepage - Card Grid', () => { test('should filter cards by search query', async ({ page }) => { await page.waitForSelector('.anchor-card', { timeout: 10000 }) - // Type in search - await page.fill('#search-input', 'TDD') + // Type in search (use header search on desktop) + await page.fill('#header-search-input', 'TDD') // Some cards should be visible with TDD const visibleCards = await page.locator('.anchor-card:visible').count() expect(visibleCards).toBeGreaterThan(0) // Clear search - await page.fill('#search-input', '') + await page.fill('#header-search-input', '') // All cards should be visible again const allCards = await page.locator('.anchor-card:visible').count() @@ -212,8 +223,8 @@ test.describe('Routing - Documentation Pages', () => { }) test('should navigate to About page', async ({ page }) => { - // Click About link - await page.click('a[data-route="/about"]') + // Click About link (use first for desktop nav) + await page.locator('a[data-route="/about"]').first().click() // URL should update expect(page.url()).toContain('#/about') @@ -228,8 +239,8 @@ test.describe('Routing - Documentation Pages', () => { }) test('should navigate to Contributing page', async ({ page }) => { - // Click Contributing link - await page.click('a[data-route="/contributing"]') + // Click Contributing link (use first for desktop nav) + await page.locator('a[data-route="/contributing"]').first().click() // URL should update expect(page.url()).toContain('#/contributing') @@ -244,11 +255,11 @@ test.describe('Routing - Documentation Pages', () => { }) test('should navigate back to Catalog from About', async ({ page }) => { - // Go to About - await page.click('a[data-route="/about"]') + // Go to About (use first for desktop nav) + await page.locator('a[data-route="/about"]').first().click() // Go back to Catalog - await page.click('a[data-route="/"]') + await page.locator('a[data-route="/"]').first().click() // URL should be home expect(page.url()).toMatch(/#\/$|#$/) @@ -271,8 +282,8 @@ test.describe('Routing - Documentation Pages', () => { }) test('should handle browser back button', async ({ page }) => { - // Navigate to About - await page.click('a[data-route="/about"]') + // Navigate to About (use first for desktop nav) + await page.locator('a[data-route="/about"]').first().click() // Go back await page.goBack() @@ -287,14 +298,14 @@ test.describe('Responsive Design', () => { await page.goto('/') await page.setViewportSize({ width: 375, height: 667 }) - // Page should still be visible - await expect(page.locator('h1')).toBeVisible() + // Page should still be visible (heading is h2 in current layout) + await expect(page.locator('h2').first()).toBeVisible() await page.waitForSelector('.anchor-card', { timeout: 10000 }) await expect(page.locator('.anchor-card').first()).toBeVisible() - // Navigation should be hidden on mobile - const nav = page.locator('.nav-link').first() - const isVisible = await nav.isVisible() + // Desktop navigation should be hidden on mobile + const desktopNav = page.locator('.hidden.sm\\:flex .nav-link').first() + const isVisible = await desktopNav.isVisible() expect(isVisible).toBe(false) }) @@ -302,7 +313,7 @@ test.describe('Responsive Design', () => { await page.goto('/') await page.setViewportSize({ width: 768, height: 1024 }) - await expect(page.locator('h1')).toBeVisible() + await expect(page.locator('h2').first()).toBeVisible() await page.waitForSelector('.anchor-card', { timeout: 10000 }) await expect(page.locator('.anchor-card').first()).toBeVisible() @@ -314,7 +325,7 @@ test.describe('Responsive Design', () => { await page.goto('/') await page.setViewportSize({ width: 1920, height: 1080 }) - await expect(page.locator('h1')).toBeVisible() + await expect(page.locator('h2').first()).toBeVisible() await page.waitForSelector('.anchor-card', { timeout: 10000 }) await expect(page.locator('.anchor-card').first()).toBeVisible() }) @@ -354,12 +365,13 @@ test.describe('Accessibility', () => { }) test('should have proper heading hierarchy', async ({ page }) => { - // Check h1 exists - await expect(page.locator('h1')).toBeVisible() + // Check page heading exists (h2 in current layout) + await expect(page.locator('h2').first()).toBeVisible() - // Check h2 headings (category headings) - const h2s = page.locator('h2') - const count = await h2s.count() + // Check h3 headings (category headings) + await page.waitForSelector('.category-section', { timeout: 10000 }) + const h3s = page.locator('.category-heading') + const count = await h3s.count() expect(count).toBeGreaterThan(0) }) }) @@ -393,7 +405,7 @@ test.describe('Performance', () => { test('should load search index asynchronously', async ({ page }) => { await page.waitForSelector('.anchor-card', { timeout: 10000 }) - const searchInput = page.locator('#search-input') + const searchInput = page.locator('#header-search-input') await searchInput.fill('tdd') await expect(searchInput).toHaveAttribute('placeholder', /full-text/, { timeout: 15000 }) })