Files
2026-02-18 01:31:41 +01:00

9.4 KiB

phase, verified, status, score
phase verified status score
15-locale-detection-routing 2026-02-02T01:12:14Z passed 11/11 must-haves verified

Phase 15: Locale Detection & Routing Verification Report

Phase Goal: URL-based locale switching (/pl/, /de/), browser detection for first visit, persistent user preference, language switcher UI Verified: 2026-02-02T01:12:14Z Status: passed Re-verification: No - initial verification

Goal Achievement

Observable Truths

# Truth Status Evidence
1 Manual locale selection via LocalePicker sets 1-year cookie VERIFIED plugins/golem15/quotify/Plugin.php:503-507 - Cookie::queue with manualSelectionCookie config key, 525600 min expiry
2 URL prefix visit (/pl/, /de/) sets manual selection cookie VERIFIED plugins/golem15/translate/routes.php:31-35 - Cookie::queue after loadLocaleFromRequest() succeeds
3 Logged-in user's locale switch updates their DB preference VERIFIED plugins/golem15/quotify/Plugin.php:510-513 - Auth::getUser()->preferred_locale = $locale; $user->save()
4 Browser detection skipped when manual selection cookie exists VERIFIED plugins/golem15/translate/classes/LocaleMiddleware.php:214-228 - hasManualLocaleSelection() checks cookie
5 Language switcher dropdown visible in header VERIFIED themes/quotify/partials/header.htm:15-17 - includes language-switcher partial in header-actions
6 Clicking language option switches locale and reloads page VERIFIED themes/quotify/partials/language-switcher.htm:17 - data-request="localePicker::onSwitchLocale"
7 Current language name shown in native form (Polski, Deutsch, English) VERIFIED themes/quotify/partials/language-switcher.htm:7 - displays activeLocaleName from LocalePicker
8 All pages have hreflang tags for SEO VERIFIED All 3 layouts (default, dashboard, empty) have alternateHrefLangElements component and {% component 'alternateHrefLangElements' %}
9 Account settings has language preference section VERIFIED themes/quotify/partials/account/update.htm:97-118 - Language Preference section with dropdown
10 Logged-in users can select preferred language in profile VERIFIED themes/quotify/partials/account/update.htm:107 - name="preferred_locale" select element in form_ajax onUpdate
11 Language suggestion banner appears when browser language differs VERIFIED plugins/golem15/translate/components/LocaleSuggestionBanner.php - shouldShowBanner() logic with Accept-Language detection
12 Dismissing banner sets cookie to prevent showing again VERIFIED plugins/golem15/translate/components/LocaleSuggestionBanner.php:96 - locale_banner_dismissed cookie, 1 week expiry

Score: 11/11 truths verified (12 listed but 11-12 are sub-items of the same truth)

Required Artifacts

Artifact Expected Status Details
plugins/golem15/quotify/Plugin.php LocalePicker extension with cookie and DB sync VERIFIED extendLocalePicker() method at lines 482-517
plugins/golem15/translate/routes.php Cookie setting on URL prefix detection VERIFIED Cookie::queue at lines 31-35 after locale loaded
themes/quotify/partials/language-switcher.htm Dropdown language switcher UI VERIFIED 58 lines, accessible dropdown with ARIA, JS toggle
themes/quotify/partials/header.htm Header with language switcher VERIFIED Lines 14-17 include language-switcher partial
themes/quotify/layouts/default.htm Layout with hreflang and LocalePicker VERIFIED Components registered, hreflang output at line 23
themes/quotify/layouts/dashboard.htm Layout with hreflang and LocalePicker VERIFIED Components registered lines 7-9, hreflang output at line 22
themes/quotify/layouts/empty.htm Layout with hreflang and LocalePicker VERIFIED Components registered lines 4-5, hreflang output at line 15
themes/quotify/partials/account/update.htm Language preference section in account settings VERIFIED Language Preference section lines 97-118 with preferred_locale field
plugins/golem15/translate/components/LocaleSuggestionBanner.php Component for language mismatch detection VERIFIED 120 lines, shouldShowBanner(), getSuggestedLocale(), onDismissBanner()
plugins/golem15/translate/components/localesuggestionbanner/default.htm Banner template VERIFIED 35 lines, conditional banner with localized text
themes/quotify/assets/css/components/language-switcher.css Language switcher styles VERIFIED 115 lines, responsive design
themes/quotify/assets/css/components/locale-banner.css Banner styles VERIFIED 85 lines, sticky positioning, gradient background
themes/quotify/assets/css/app.css Imports for both CSS files VERIFIED Lines 14-15 import language-switcher.css and locale-banner.css
From To Via Status Details
LocalePicker::onSwitchLocale Cookie::queue Component extension in Plugin.php boot() WIRED Plugin.php:503 - Cookie::queue call inside bindEvent handler
LocalePicker::onSwitchLocale User::preferred_locale Auth::getUser()->save() WIRED Plugin.php:510-513 - Auth check + save
language-switcher.htm localePicker::onSwitchLocale data-request attribute WIRED language-switcher.htm:17 - data-request present
routes.php Cookie::queue After loadLocaleFromRequest() WIRED routes.php:31-35 - Cookie set after locale loaded
LocaleMiddleware hasManualLocaleSelection Cookie read in detection cascade WIRED LocaleMiddleware.php:34 - calls hasManualLocaleSelection
default.htm alternateHrefLangElements Component registration WIRED Component registered line 8, output line 23
account/update.htm Account::onUpdate Form submission with preferred_locale WIRED form_ajax('onUpdate') at line 95, preferred_locale field at line 107
LocaleSuggestionBanner Accept-Language detection detectBrowserLocale() WIRED LocaleSuggestionBanner.php:63-79 - Request::header parsing
onDismissBanner Cookie::queue locale_banner_dismissed cookie WIRED LocaleSuggestionBanner.php:96 - 1-week cookie set

Requirements Coverage

Phase 15 requirements from ROADMAP.md:

  • URL-based locale switching (/pl/, /de/) - SATISFIED
  • Browser detection for first visit - SATISFIED
  • Persistent user preference - SATISFIED
  • Language switcher UI - SATISFIED

Anti-Patterns Found

File Line Pattern Severity Impact
- - None found - -

No stub patterns, placeholder content, or empty implementations detected in any verified artifacts.

Human Verification Required

1. Visual Language Switcher Appearance

Test: Navigate to homepage, check header area Expected: Language switcher dropdown visible near right side of header, styled consistently with site design Why human: Visual appearance and styling cannot be verified programmatically

2. Language Switch Flow

Test: Click language switcher, select "Polski" or "Deutsch" Expected: Page reloads in selected language, switcher shows new language name Why human: Page reload and full interaction flow requires browser testing

3. Mobile Language Switcher

Test: View site on mobile viewport (< 768px) Expected: Language label hidden, globe icon visible, touch targets adequate Why human: Responsive behavior requires actual device/viewport testing

4. hreflang Tags in Source

Test: View page source, search for "hreflang" Expected: <link rel="alternate" hreflang="en/pl/de" href="..."> tags present for all locales Why human: Need to verify rendered HTML output

5. Account Settings Language Preference

Test: Log in, go to account settings, select "Account Info" tab Expected: Language Preference section visible with dropdown showing en/pl/de options Why human: Requires authenticated session and UI interaction

6. Language Suggestion Banner

Test: Clear cookies, set browser language to German, visit English page Expected: Banner appears at top: "Diese Seite ist auf Deutsch verfugbar" with switch button Why human: Requires browser language configuration and cookie clearing

7. Banner Dismissal Persistence

Test: Dismiss the suggestion banner, refresh page Expected: Banner does not reappear (cookie prevents) Why human: Requires cookie behavior verification

Gaps Summary

No gaps found. All must-haves verified as implemented:

Plan 15-01 (Core Locale Infrastructure):

  • LocalePicker extension in Quotify Plugin.php sets 1-year cookie on manual locale switch
  • routes.php sets cookie when URL prefix detected
  • LocaleMiddleware correctly skips browser detection when cookie present
  • Logged-in users' preferences saved to database

Plan 15-02 (Language Switcher UI):

  • Language switcher partial created with accessible dropdown
  • Integrated into header across all pages
  • All three layouts register localePicker and alternateHrefLangElements components
  • hreflang tags output in head section of all layouts

Plan 15-03 (Account Settings & Suggestion Banner):

  • Language Preference section added to account settings
  • LocaleSuggestionBanner component created with browser detection
  • Banner template with localized text in target language
  • Dismissal cookie (1 week) prevents repeated banner display

Verified: 2026-02-02T01:12:14Z Verifier: Claude (gsd-verifier)