Technical Analysis of Villa Stuart Healthcare Website
Enterprise search engineering and cross-platform design alignment for a prestigious Italian healthcare facility.
Executive Summary
Comprehensive modernization of Villa Stuart’s digital presence across two platforms: a complete enterprise search system overhaul for the Italian WordPress site, and a frontend design alignment for the Russian CodeIgniter site. The project involved architecting a sophisticated medical search system with 49 curated configurations, implementing multilingual support, and creating a unified design language across both properties.
Key Achievements
- 151 commits over 4 months of active development
- 96/100 code quality score (Gemini AI review)
- 23 PHP classes in modern PSR-4 architecture
- 49 curated search configurations for medical queries
- 400+ medical terminology synonyms
- Zero breaking changes during 5-week architectural refactor
Project 1: Villa Stuart Italy (villastuart.it)
Technology Stack
| Layer | Technology | Purpose |
|---|---|---|
| CMS | WordPress | Content management |
| Search | Relevanssi PREMIUM | Enterprise search engine |
| Multilingual | WPML 4.8.4 | Italian/English support |
| Page Builder | Elementor Pro | Visual page construction |
| Custom Fields | ACF Pro | Structured medical data |
| Cache | Redis 7 | Object caching |
| Database | MariaDB 10.11 | Data persistence |
| Runtime | PHP 8.3 | Server-side processing |
| Container | Docker | Development environment |
| Autoloading | Composer PSR-4 | Modern PHP architecture |
The Challenge
Villa Stuart needed a search system that could:
- Surface relevant doctors and services for medical queries
- Handle complex Italian medical terminology
- Support bilingual content (Italian/English)
- Prioritize VIP doctors in search results
- Prevent content cross-contamination between medical specialties
- Maintain fast response times with ~800 indexed posts
Architecture Solution
PSR-4 MU-Plugin Bundle
Consolidated three legacy plugins into a modern, maintainable structure:
villa-stuart/
├── src/
│ ├── Bootstrap/
│ │ └── MuPlugin.php # Singleton bootstrapper
│ ├── Support/
│ │ ├── Logger.php # Centralized logging
│ │ ├── Strings.php # UTF-8 text normalization
│ │ └── Cache.php # Two-tier caching wrapper
│ ├── Search/
│ │ ├── Config.php # 49 curated configurations
│ │ ├── ResultOrderer.php # Main ordering orchestrator
│ │ ├── WpmlHandler.php # WPML SQL-level filtering
│ │ ├── DoctorHandler.php # Doctor prioritization
│ │ ├── ServiceHandler.php # Service matching
│ │ ├── Synonyms.php # 400+ medical terms
│ │ └── SettingsValidator.php # Runtime config validation
│ ├── RelationalTags/
│ │ └── Generator.php # Auto-generated taxonomy tags
│ └── Presentation/
│ └── ShortcodeController.php
├── config/
│ └── relational-tags.json # 150+ medical terminology
└── composer.json
Key Principles Applied:
- Service Provider pattern for modular initialization
- Singleton bootstrap ensures single initialization
- Dependency injection promotes testability
- Static methods minimize instantiation overhead
Search System Implementation
12-Tier Result Categorization
/**
* Priority buckets for search result ordering
* Higher tier = appears first in results
*/
const PRIORITY_TIERS = [
1 => 'mariani_services', // VIP automatic pinning
2 => 'featured_doctors', // menu_order = 0
3 => 'ordered_doctors', // ACF equipe_doctor_order
4 => 'other_doctors',
5 => 'manager_doctors', // Extracted from services
6 => 'featured_services',
7 => 'ordered_services',
8 => 'other_services',
9 => 'taxonomy_terms', // service_cat archives
10 => 'blog_posts',
11 => 'insurance_partners',
12 => 'other_content',
];
Weight Configuration
class Config {
/**
* Search result weights by post type and category
* Higher weight = appears first in results
*/
const WEIGHTS = [
'featured_page' => 5.0, // Pages mentioning VIP doctors
'priority_doctor' => 4.0, // Doctors with menu_order = 0
'equipment' => 3.0, // Diagnostic equipment
'service' => 3.0, // Healthcare offerings
'page' => 2.0, // Regular pages
'service_cat_archive' => 1.5, // Service category terms
'regular_doctor' => 1.5, // Standard doctors
'post' => 1.0, // Blog posts
'insurance' => 0.8, // Insurance partners
'default' => 0.5, // Unknown post types
];
/**
* Secondary weight boosts for ACF field matches
*/
const FIELD_BOOSTS = [
'doctor_specialty' => 2.0, // Ortopedia, Cardiologia
'doctor_role' => 2.0, // Chirurgo, Medico
'service_description' => 1.0, // 80/20 title weighting
'service_type' => 1.0,
];
}
Curated Rankings System
For specific medical queries, deterministic result ordering overrides relevance scoring:
/**
* Example: "risonanza" (MRI) search configuration
* Ensures diagnostic equipment appears before generic pages
*/
'risonanza' => [
'exact_match' => true,
'tokens' => ['risonanza', 'magnetica', 'rm', 'mri', '3t', '3 tesla'],
'results' => [
['type' => 'service', 'id' => 2847, 'title' => 'Risonanza Magnetica Ingenia 3.0T'],
['type' => 'service', 'id' => 1456, 'title' => 'Radiologia e diagnostica'],
['type' => 'service', 'id' => 3021, 'title' => 'Ritiro Referti Radiologia'],
['type' => 'term', 'taxonomy' => 'service_cat', 'slug' => 'ortopedia'],
],
],
/**
* Example: Doctor name search with VIP positioning
*/
'mariani' => [
'exact_match' => true,
'tokens' => ['mariani', 'pier paolo', 'pier paolo mariani'],
'results' => [
['type' => 'doctor', 'id' => 1358, 'wpml_en' => 6049], // Always first
['type' => 'service', 'id' => 2156], // Ortopedia
['type' => 'service', 'id' => 2847], // Related services
],
],
Total Configurations: 49 curated rankings covering:
- Medical equipment (risonanza, TAC, robot GPS Excelsius)
- Anatomy (ginocchio, anca, spalla, piede, caviglia, colonna)
- Procedures (protesi, artroscopia, allungamento arti)
- Specialties (neurochirurgia, ortopedia, cardiologia)
- Doctor surnames (22 VIP doctor configurations)
WPML Multilingual Integration
SQL-level language filtering with prepared statements:
class WpmlHandler {
/**
* Modify Relevanssi SQL query for language filtering
* Uses prepared statements to prevent SQL injection
*/
public static function filter_query_for_language($query, $language = null) {
global $wpdb;
$lang = $language ?: self::get_current_language();
// Join with WPML translations table
$query = str_replace(
"FROM {$wpdb->posts}",
"FROM {$wpdb->posts}
INNER JOIN {$wpdb->prefix}icl_translations t
ON {$wpdb->posts}.ID = t.element_id
AND t.element_type LIKE 'post_%'",
$query
);
// Add language condition with prepared statement
$query = $wpdb->prepare(
str_replace("WHERE 1=1", "WHERE 1=1 AND t.language_code = %s", $query),
$lang
);
return $query;
}
/**
* Normalize post ID to current language translation
* With graceful fallback to original if no translation exists
*/
public static function normalize_id($post_id, $target_language = null) {
if (!function_exists('icl_object_id')) {
return $post_id;
}
$lang = $target_language ?: self::get_current_language();
$translated_id = icl_object_id($post_id, get_post_type($post_id), true, $lang);
return $translated_id ?: $post_id;
}
}
Hybrid Équipe Filtering
Prevents content cross-contamination while preserving discoverability:
/**
* Problem: Services appeared in unrelated searches due to équipe indexing
* Example: "Protesi d'Anca" appeared in "gomito" (elbow) searches because
* Prof. Santucci treats elbows AND manages hip replacement service
*
* Solution: Service-linked doctor preservation
*/
public static function apply_hybrid_equipe_filter($results, $context) {
// Build hash map of services in primary results
$service_ids = [];
foreach ($context['primary_results'] as $result) {
if ($result->post_type === 'service') {
$service_ids[$result->ID] = true;
}
}
// Build hash map of doctors managing/staffing those services
$service_linked_doctors = [];
foreach ($service_ids as $service_id => $_) {
// Get manager
$manager_id = get_field('service_manager', $service_id);
if ($manager_id) {
$service_linked_doctors[$manager_id] = true;
}
// Get équipe staff
$equipe = get_field('equipe_doctors', $service_id);
if (is_array($equipe)) {
foreach ($equipe as $doctor) {
$service_linked_doctors[$doctor['doctor_id']] = true;
}
}
}
// Filter fallback results - O(1) lookup
return array_filter($results, function($result) use ($service_linked_doctors, $context) {
// Always keep non-doctors
if ($result->post_type !== 'doctor') {
return true;
}
// EXCEPTION 1: Direct content match
if (self::has_direct_content_match($result, $context['query'])) {
return true;
}
// EXCEPTION 2: Service-linked doctor
if (isset($service_linked_doctors[$result->ID])) {
return true;
}
// Filter out équipe-only matches
return false;
});
}
Medical Synonym System
class Synonyms {
/**
* 400+ medical term mappings for Italian healthcare
*/
const SYNONYM_GROUPS = [
// Anatomy
'ginocchio' => ['ginocchio', 'knee', 'articolazione ginocchio'],
'anca' => ['anca', 'hip', 'bacino', 'coxartrosi'],
'spalla' => ['spalla', 'shoulder', 'cuffia rotatori'],
'caviglia' => ['caviglia', 'ankle', 'tibiotarsica'],
// Equipment
'risonanza' => ['risonanza', 'rm', 'mri', 'magnetica', '3t', '3 tesla', 'ingenia'],
'tac' => ['tac', 'tc', 'ct', 'tomografia'],
'robot' => ['robot', 'gps', 'excelsius', 'robotica', 'navigazione'],
// Procedures
'protesi' => ['protesi', 'prosthesis', 'impianto', 'sostituzione'],
'artroscopia' => ['artroscopia', 'arthroscopy', 'mini invasiva'],
'allungamento' => ['allungamento', 'lengthening', 'ilizarov', 'arti'],
// Specialties (14 groups x 6 terms each)
'andrologia' => ['andrologia', 'andrology', 'urologo', 'andrologist'],
'cardiologia' => ['cardiologia', 'cardiology', 'cuore', 'cardiologo'],
'dermatologia' => ['dermatologia', 'dermatology', 'pelle', 'dermatologo'],
'neurochirurgia' => ['neurochirurgia', 'neurosurgery', 'colonna', 'spinale'],
// ... 10 more specialty groups
// Visit patterns (for "visita X" searches)
'visita_dermatologica' => ['visita dermatologica', 'dermatologia visita'],
'visita_cardiologica' => ['visita cardiologica', 'cardiologia visita'],
'visita_oculistica' => ['visita oculistica', 'oculistica visita'],
];
/**
* Register synonyms with Relevanssi PREMIUM
*/
public static function register() {
if (!function_exists('relevanssi_register_synonym')) {
return; // Fallback to query expansion for FREE version
}
foreach (self::SYNONYM_GROUPS as $primary => $synonyms) {
foreach ($synonyms as $synonym) {
if ($synonym !== $primary) {
relevanssi_register_synonym($primary, $synonym);
}
}
}
}
}
Performance Optimizations
Two-Tier Caching Strategy
class Cache {
const DEFAULT_TTL = 3600; // Object cache: 1 hour
const SHORT_TTL = 300; // Transients: 5 minutes
/**
* Get or compute pattern with graceful fallback
*/
public static function remember($key, callable $callback, $ttl = self::DEFAULT_TTL) {
// Try object cache first (Redis)
$cached = wp_cache_get($key, 'villa_stuart');
if ($cached !== false) {
return $cached;
}
// Compute value
$value = $callback();
// Store in object cache
wp_cache_set($key, $value, 'villa_stuart', $ttl);
return $value;
}
}
Hash Map Deduplication
/**
* O(1) lookups instead of O(N) array_search
*/
$seen_doctors = []; // Hash map: doctor_id => true
foreach ($results as $result) {
if ($result->post_type === 'doctor') {
// O(1) lookup
if (isset($seen_doctors[$result->ID])) {
continue; // Skip duplicate
}
$seen_doctors[$result->ID] = true;
}
$deduplicated[] = $result;
}
Batch Query Optimization
/**
* Single query for all doctor metadata instead of N+1
*/
$doctor_ids = wp_list_pluck($doctors, 'ID');
// Batch ACF field loading
$menu_orders = [];
$specialties = [];
$meta_query = $wpdb->prepare(
"SELECT post_id, meta_key, meta_value
FROM {$wpdb->postmeta}
WHERE post_id IN (" . implode(',', array_fill(0, count($doctor_ids), '%d')) . ")
AND meta_key IN ('menu_order', 'doctor_specialty')",
...$doctor_ids
);
foreach ($wpdb->get_results($meta_query) as $row) {
if ($row->meta_key === 'menu_order') {
$menu_orders[$row->post_id] = (int) $row->meta_value;
} else {
$specialties[$row->post_id] = $row->meta_value;
}
}
WP-CLI Diagnostic Suite
# Validate critical Relevanssi configuration
wp vs-search validate-settings
# Test Premium-specific features
wp vs-search premium-smoke
# Compare DB synonyms with code defaults
wp vs-search diff-synonyms
# Merge code defaults into DB (non-destructive)
wp vs-search diff-synonyms --apply-merge
# Find taxonomy terms missing search_keywords
wp vs-search term-keywords-report
# Auto-populate missing keywords from synonym sets
wp vs-search populate-term-keywords --apply --rebuild-index
Testing Infrastructure
tests/
├── integration/
│ ├── test-mariani-pinning.php # VIP doctor positioning
│ ├── test-hybrid-filter.php # Équipe filtering
│ └── test-wpml-integration.php # Language switching
├── phpunit/
│ ├── ResultOrdererComparisonTest.php # New vs legacy parity
│ ├── SearchPremiumParityTest.php # Premium features
│ └── ConfigTest.php # Configuration validation
└── bin/
└── run-relevanssi-validation.php # CLI test runner
Project 2: Villa Stuart Russia (villastuart.ru)
Technology Stack
| Component | Technology |
|---|---|
| Framework | CodeIgniter 3.x |
| Grid System | Bootstrap 4 |
| Carousel | Owl Carousel |
| Development | Docker |
| Database | MySQL |
The Challenge
Align the Russian website frontend with the Italian site’s modern design, creating a consistent brand experience across both properties while working within CodeIgniter’s MVC architecture.
Design System Implementation
Color Palette (Figma-Based)
:root {
/* Primary Brand Colors */
--color-primary: #003E38; /* Deep teal green */
--color-secondary: #213535; /* Darker gray-green */
--color-white: #FCFCFC; /* Off-white */
/* Accent Colors */
--accent-gold: #F6C744; /* Gold for borders/highlights */
--border-light: #B6D5D4; /* Light teal for subtle borders */
--background-light: #EDF5F4; /* Very light teal background */
/* Text Colors */
--text-primary: #213535;
--text-secondary: #666666;
--text-light: #FCFCFC;
}
Typography System
/* Primary Font: UI Elements & Body */
@import url('https://fonts.googleapis.com/css2?family=Mulish:wght@400;600;700;800&display=swap');
/* Secondary Font: Headings & Titles */
@font-face {
font-family: 'Trajan Pro 3';
src: url('../fonts/TrajanPro3-Regular.woff2') format('woff2');
font-weight: normal;
}
body {
font-family: 'Mulish', sans-serif;
font-size: 16px;
line-height: 1.6;
color: var(--text-primary);
}
h1, h2, h3, .section-title {
font-family: 'Trajan Pro 3', serif;
text-transform: uppercase;
letter-spacing: 0.05em;
}
Header Redesign
/* Pre-navigation bar with language selector */
.pre-nav-new {
background-color: var(--color-primary);
padding: 8px 0;
}
.pre-nav-new .language-selector {
display: flex;
gap: 12px;
}
.pre-nav-new .language-selector a {
color: var(--color-white);
opacity: 0.7;
transition: opacity 0.3s ease;
}
.pre-nav-new .language-selector a.active,
.pre-nav-new .language-selector a:hover {
opacity: 1;
}
/* Main header with centered navigation */
.header-new {
background-color: var(--color-white);
padding: 20px 0;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.header-new .nav-menu {
display: flex;
justify-content: center;
gap: 32px;
}
.header-new .nav-menu a {
font-family: 'Mulish', sans-serif;
font-weight: 600;
color: var(--color-primary);
text-decoration: none;
padding: 8px 0;
border-bottom: 2px solid transparent;
transition: border-color 0.3s ease;
}
.header-new .nav-menu a:hover,
.header-new .nav-menu a.active {
border-bottom-color: var(--accent-gold);
}
Homepage Sections
/* Services Grid - 4 cards with medical icons */
.services-section {
background-color: var(--color-primary);
padding: 80px 0;
}
.service-card {
background: rgba(255, 255, 255, 0.1);
border-radius: 12px;
padding: 32px;
text-align: center;
transition: transform 0.3s ease, background 0.3s ease;
}
.service-card:hover {
transform: translateY(-8px);
background: rgba(255, 255, 255, 0.15);
}
.service-card .icon {
width: 64px;
height: 64px;
margin-bottom: 24px;
}
.service-card h3 {
color: var(--color-white);
font-size: 18px;
margin-bottom: 12px;
}
/* About Section - Image + Content Columns */
.about-section {
background-color: var(--background-light);
padding: 100px 0;
}
.about-section .content-column {
padding-left: 60px;
}
.about-section .section-label {
font-family: 'Mulish', sans-serif;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--accent-gold);
font-size: 12px;
margin-bottom: 16px;
}
/* Contact Section - Coordinator Info */
.contact-section {
background-color: var(--color-secondary);
padding: 80px 0;
}
.coordinator-card {
display: flex;
align-items: center;
gap: 32px;
}
.coordinator-card .photo {
width: 180px;
height: 180px;
border-radius: 50%;
object-fit: cover;
border: 4px solid var(--accent-gold);
}
/* Accreditations - FIFA/FIMS Badges */
.accreditations-section {
padding: 60px 0;
text-align: center;
}
.accreditation-badges {
display: flex;
justify-content: center;
gap: 48px;
align-items: center;
}
.accreditation-badges img {
height: 80px;
filter: grayscale(100%);
opacity: 0.7;
transition: all 0.3s ease;
}
.accreditation-badges img:hover {
filter: grayscale(0%);
opacity: 1;
}
View Template Structure (CodeIgniter)
<!-- application/views/template/bootstrap/frontend/index.php -->
<?php $this->load->view('template/bootstrap/common/header'); ?>
<!-- Services Grid -->
<section class="services-section">
<div class="container">
<div class="row">
<?php foreach ($services as $service): ?>
<div class="col-md-3 col-sm-6">
<div class="service-card">
<img src="<?= base_url('css/images/' . $service['icon']) ?>"
alt="<?= $service['title'] ?>"
class="icon">
<h3><?= $service['title'] ?></h3>
<p><?= $service['description'] ?></p>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<!-- About Section -->
<section class="about-section">
<div class="container">
<div class="row align-items-center">
<div class="col-md-6">
<img src="<?= base_url('img/clinic-exterior.jpg') ?>"
alt="Villa Stuart"
class="img-fluid rounded">
</div>
<div class="col-md-6 content-column">
<span class="section-label">Chi Siamo</span>
<h2><?= $about_title ?></h2>
<p><?= $about_content ?></p>
<a href="<?= site_url('about') ?>" class="btn btn-primary">
Scopri di più
</a>
</div>
</div>
</div>
</section>
<!-- Russian Coordinator -->
<section class="contact-section">
<div class="container">
<div class="coordinator-card">
<img src="<?= base_url('img/coordinator.jpg') ?>"
alt="Максим Долгий"
class="photo">
<div class="info">
<h3>Максим Долгий</h3>
<p class="role">Координатор для русскоязычных пациентов</p>
<p class="phone">+39 XXX XXX XXXX</p>
<p class="email">russia@villastuart.it</p>
</div>
</div>
</div>
</section>
<?php $this->load->view('template/bootstrap/common/footer'); ?>
Design Alignment Results
| Aspect | Before | After |
|---|---|---|
| Color Scheme | Generic template colors | Brand-aligned teal palette |
| Typography | Single sans-serif font | Mulish + Trajan Pro hierarchy |
| Header | Basic navigation | Pre-nav + centered menu |
| Footer | Standard template | Horizontal sections with social |
| Cards | Flat design | Rounded corners, shadows, hover effects |
| Responsive | Basic Bootstrap | Mobile-first with custom breakpoints |
Development Workflow
Git Commit Distribution
| Type | Count | Percentage |
|---|---|---|
| feat (features) | 40 | 26.5% |
| fix (bug fixes) | 28 | 18.5% |
| docs (documentation) | 21 | 13.9% |
| refactor | 4 | 2.6% |
| chore | 3 | 2.0% |
Major Development Phases
- Foundation (July 2025): Initial setup, shortcodes, service management
- Infrastructure (October 2025): Docker environment, database optimization
- Search Overhaul (November 2025): Relevanssi integration, curated rankings
- Refactor (November 14, 2025): 5-week PSR-4 migration completed
- Refinement (November 18-24, 2025): Hybrid filtering, synonym expansion
Quality Assurance
- Gemini AI Code Review: 96/100 score after bug fixes
- Code Quality Score: 10/10
- Production Readiness: 9.5/10
- Test Coverage: Search, WPML, Elementor, security
Documentation System
docs/
├── SEARCH_SYSTEM.md # Complete search reference
├── RELEVANSSI_SETTINGS.md # Critical configuration
├── HYBRID_EQUIPE_FILTERING_DESIGN.md
├── MU_PLUGINS_REFACTOR_PLAN.md
├── MU_PLUGINS_REFACTOR_FIXES.md
├── MARIANI_PINNING_IMPLEMENTATION.md
├── DOCKER_ENVIRONMENT.md
├── DEPLOYMENT_GUIDE.md
└── INDEX.md # Master documentation index
.claude/reports/
├── SEARCH_CHANGELOG.md # Change history
├── SEARCH_GUARDRAILS_2025-11-21.md
├── DEPLOYMENT_PRODUCTION_*.md
└── SECURITY_AUDIT_*.md
Technical Achievements
Search System Metrics
- 49 curated search configurations
- 400+ medical terminology synonyms
- 12 priority tiers for result categorization
- 6 weight levels for post type scoring
- 0 breaking changes during architectural refactor
Code Quality Metrics
- 23 PHP classes in PSR-4 architecture
- 9,480+ lines of organized, documented code
- 3,272 lines in ResultOrderer (main orchestrator)
- 1,751 lines in Config (curated rankings)
- 151 commits with conventional commit messages
Performance Metrics
- O(1) hash map lookups for deduplication
- Two-tier caching (Redis + transients)
- Batch queries instead of N+1 patterns
- Lazy evaluation with early returns
Skills Demonstrated
Backend Development
- PHP 8.3 with modern syntax and type hints
- WordPress plugin architecture (MU-plugins)
- PSR-4 autoloading with Composer
- Service Provider pattern
- WPML multilingual integration
- ACF Pro custom field management
- Redis object caching
Search Engineering
- Relevanssi PREMIUM configuration
- Custom weighting algorithms
- Synonym management systems
- Medical terminology indexing
- Multilingual search optimization
Frontend Development
- CodeIgniter MVC architecture
- Bootstrap 4 responsive design
- CSS custom properties
- Figma-to-code implementation
- Cross-browser compatibility
DevOps
- Docker containerization
- MariaDB/MySQL database management
- WP-CLI automation
- Git version control (conventional commits)
- rsync deployment workflows
Quality Assurance
- PHPUnit testing
- Integration test suites
- AI-assisted code review (Gemini)
- Configuration validation
- Performance profiling
Conclusion
The Villa Stuart project demonstrates comprehensive full-stack development capabilities, from architecting a sophisticated search system with 49 curated configurations to implementing a cohesive design language across multiple platforms. The 5-week architectural refactor achieved zero breaking changes while modernizing the codebase to PSR-4 standards, and the final 96/100 quality score validates the production-ready nature of the implementation.