Initial commit - WhyRating Engine (Google Reviews Scraper)
This commit is contained in:
35
migrations/versions/008_add_job_id_to_pipeline_tables.sql
Normal file
35
migrations/versions/008_add_job_id_to_pipeline_tables.sql
Normal file
@@ -0,0 +1,35 @@
|
||||
-- =============================================================================
|
||||
-- Migration: 008_add_job_id_to_pipeline_tables.sql
|
||||
-- Purpose: Add job_id column to pipeline tables for filtering by execution
|
||||
-- =============================================================================
|
||||
|
||||
-- Add job_id to reviews_enriched
|
||||
ALTER TABLE pipeline.reviews_enriched
|
||||
ADD COLUMN IF NOT EXISTS job_id UUID;
|
||||
|
||||
-- Add index for job_id on reviews_enriched
|
||||
CREATE INDEX IF NOT EXISTS idx_reviews_enriched_job_id
|
||||
ON pipeline.reviews_enriched(job_id)
|
||||
WHERE job_id IS NOT NULL;
|
||||
|
||||
-- Add job_id to review_spans
|
||||
ALTER TABLE pipeline.review_spans
|
||||
ADD COLUMN IF NOT EXISTS job_id UUID;
|
||||
|
||||
-- Add index for job_id on review_spans
|
||||
CREATE INDEX IF NOT EXISTS idx_review_spans_job_id
|
||||
ON pipeline.review_spans(job_id)
|
||||
WHERE job_id IS NOT NULL;
|
||||
|
||||
-- Add job_id to issues
|
||||
ALTER TABLE pipeline.issues
|
||||
ADD COLUMN IF NOT EXISTS job_id UUID;
|
||||
|
||||
-- Add index for job_id on issues
|
||||
CREATE INDEX IF NOT EXISTS idx_issues_job_id
|
||||
ON pipeline.issues(job_id)
|
||||
WHERE job_id IS NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN pipeline.reviews_enriched.job_id IS 'Scraper job ID for filtering by execution';
|
||||
COMMENT ON COLUMN pipeline.review_spans.job_id IS 'Scraper job ID for filtering by execution';
|
||||
COMMENT ON COLUMN pipeline.issues.job_id IS 'Scraper job ID for filtering by execution';
|
||||
174
migrations/versions/009_add_urt_subcodes_table.sql
Normal file
174
migrations/versions/009_add_urt_subcodes_table.sql
Normal file
@@ -0,0 +1,174 @@
|
||||
-- =============================================================================
|
||||
-- Migration: 009_add_urt_subcodes_table.sql
|
||||
-- Purpose: Add urt_subcodes table with human-readable names and definitions
|
||||
-- =============================================================================
|
||||
|
||||
-- URT Tier-3 subcodes lookup table
|
||||
CREATE TABLE IF NOT EXISTS pipeline.urt_subcodes (
|
||||
code VARCHAR(6) PRIMARY KEY,
|
||||
category_code VARCHAR(2) NOT NULL REFERENCES pipeline.urt_categories(code),
|
||||
domain_code CHAR(1) NOT NULL REFERENCES pipeline.urt_domains(code),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
definition TEXT,
|
||||
positive_example TEXT,
|
||||
negative_example TEXT
|
||||
);
|
||||
|
||||
-- Index for lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_urt_subcodes_category ON pipeline.urt_subcodes(category_code);
|
||||
CREATE INDEX IF NOT EXISTS idx_urt_subcodes_domain ON pipeline.urt_subcodes(domain_code);
|
||||
|
||||
COMMENT ON TABLE pipeline.urt_subcodes IS 'URT v5.1 Tier-3 diagnostic subcodes with definitions';
|
||||
|
||||
-- Insert subcode data
|
||||
INSERT INTO pipeline.urt_subcodes (code, category_code, domain_code, name, definition, positive_example, negative_example) VALUES
|
||||
-- O1: Core Product/Service (Function)
|
||||
('O1.01', 'O1', 'O', 'Works/Doesn''t Work', 'Basic functionality success or failure', 'Software runs perfectly', 'Car won''t start'),
|
||||
('O1.02', 'O1', 'O', 'Performance Level', 'How well it operates', 'Incredibly fast processor', 'Sluggish and laggy'),
|
||||
('O1.03', 'O1', 'O', 'Durability', 'Longevity and resistance to wear', 'Still perfect after 5 years', 'Fell apart in a month'),
|
||||
('O1.04', 'O1', 'O', 'Reliability', 'Consistency of function over time', 'Never fails me', 'Works sometimes, not others'),
|
||||
('O1.05', 'O1', 'O', 'Outcome Achievement', 'Did customer accomplish their goal?', 'Passed my exam!', 'Treatment didn''t work'),
|
||||
|
||||
-- O2: Product Features (Quality)
|
||||
('O2.01', 'O2', 'O', 'Materials/Inputs', 'Quality of components or ingredients', 'Real leather, premium feel', 'Cheap plastic parts'),
|
||||
('O2.02', 'O2', 'O', 'Craftsmanship', 'Skill of construction or execution', 'Beautifully sewn seams', 'Sloppy assembly'),
|
||||
('O2.03', 'O2', 'O', 'Presentation', 'Visual and aesthetic quality', 'Gorgeous plating', 'Looked thrown together'),
|
||||
('O2.04', 'O2', 'O', 'Attention to Detail', 'Finishing touches and refinement', 'Every corner perfect', 'Full of typos'),
|
||||
('O2.05', 'O2', 'O', 'Condition at Delivery', 'State when received', 'Still warm from oven', 'Arrived damaged'),
|
||||
|
||||
-- O3: Variety & Selection (Completeness)
|
||||
('O3.01', 'O3', 'O', 'All Components Present', 'Nothing missing from what was promised', 'Everything in the box', 'Missing the charger'),
|
||||
('O3.02', 'O3', 'O', 'Feature Availability', 'Promised features actually work', 'All menu items available', 'Half the features disabled'),
|
||||
('O3.03', 'O3', 'O', 'Scope Delivery', 'Full scope of work completed', 'Cleaned entire house', 'Left the bathrooms'),
|
||||
('O3.04', 'O3', 'O', 'Documentation', 'Supporting materials provided', 'Great user manual', 'No instructions at all'),
|
||||
|
||||
-- O4: Customization (Fit)
|
||||
('O4.01', 'O4', 'O', 'Specification Match', 'Matches what was ordered', 'Exactly what I ordered', 'Wrong size delivered'),
|
||||
('O4.02', 'O4', 'O', 'Personalization', 'Adapted to individual preferences', 'Remembered my usual', 'No way to save prefs'),
|
||||
('O4.03', 'O4', 'O', 'Flexibility', 'Can be modified or adjusted', 'Happy to substitute', 'No modifications allowed'),
|
||||
('O4.04', 'O4', 'O', 'Appropriateness', 'Right solution for the need', 'Perfect recommendation', 'Sold me wrong thing'),
|
||||
|
||||
-- P1: Friendliness (Attitude)
|
||||
('P1.01', 'P1', 'P', 'Warmth', 'Friendly and welcoming manner', 'Made me feel welcome', 'Cold and unfriendly'),
|
||||
('P1.02', 'P1', 'P', 'Respect', 'Treated with dignity', 'Very respectful service', 'Rude and dismissive'),
|
||||
('P1.03', 'P1', 'P', 'Patience', 'Calm and tolerant approach', 'Patient with my questions', 'Rushed and impatient'),
|
||||
('P1.04', 'P1', 'P', 'Enthusiasm', 'Energy and engagement', 'Really passionate about helping', 'Seemed bored and disinterested'),
|
||||
|
||||
-- P2: Helpfulness (Competence)
|
||||
('P2.01', 'P2', 'P', 'Knowledge', 'Expertise and understanding', 'Knew everything about the product', 'Had no idea what they were doing'),
|
||||
('P2.02', 'P2', 'P', 'Skill', 'Technical ability', 'Expertly handled the issue', 'Completely incompetent'),
|
||||
('P2.03', 'P2', 'P', 'Problem Solving', 'Ability to find solutions', 'Found a creative solution', 'Couldn''t figure it out'),
|
||||
|
||||
-- P3: Professionalism (Responsiveness)
|
||||
('P3.01', 'P3', 'P', 'Attentiveness', 'Being present and engaged', 'Always attentive to needs', 'Ignored me completely'),
|
||||
('P3.02', 'P3', 'P', 'Initiative', 'Proactive help', 'Anticipated my needs', 'Had to ask for everything'),
|
||||
('P3.03', 'P3', 'P', 'Follow-through', 'Completing promised actions', 'Did exactly what they promised', 'Never followed up'),
|
||||
|
||||
-- P4: Knowledge & Expertise (Communication)
|
||||
('P4.01', 'P4', 'P', 'Clarity', 'Clear communication', 'Explained everything clearly', 'Confusing and unclear'),
|
||||
('P4.02', 'P4', 'P', 'Listening', 'Understanding customer needs', 'Really listened to me', 'Didn''t listen at all'),
|
||||
('P4.03', 'P4', 'P', 'Transparency', 'Honest and open', 'Upfront about everything', 'Hid information from me'),
|
||||
|
||||
-- J1: Wait Times
|
||||
('J1.01', 'J1', 'J', 'Speed', 'How fast things happen', 'Super fast service', 'Took forever'),
|
||||
('J1.02', 'J1', 'J', 'Punctuality', 'On-time delivery', 'Arrived exactly when promised', 'Two hours late'),
|
||||
('J1.03', 'J1', 'J', 'Queue Management', 'Handling of waiting customers', 'Well-organized queue', 'Chaotic and disorganized'),
|
||||
|
||||
-- J2: Booking & Reservations (Ease)
|
||||
('J2.01', 'J2', 'J', 'Simplicity', 'Easy process', 'Super easy to book', 'Complicated process'),
|
||||
('J2.02', 'J2', 'J', 'Friction', 'Obstacles encountered', 'Seamless experience', 'So many hoops to jump through'),
|
||||
('J2.03', 'J2', 'J', 'Navigation', 'Finding what you need', 'Easy to navigate', 'Got lost multiple times'),
|
||||
|
||||
-- J3: Navigation & Convenience (Reliability)
|
||||
('J3.01', 'J3', 'J', 'Consistency', 'Same experience every time', 'Always consistent', 'Different every visit'),
|
||||
('J3.02', 'J3', 'J', 'Accuracy', 'Getting it right', 'Perfect every time', 'Full of errors'),
|
||||
('J3.03', 'J3', 'J', 'Uptime', 'System availability', 'Never down', 'Constantly having issues'),
|
||||
|
||||
-- J4: Accessibility (Resolution)
|
||||
('J4.01', 'J4', 'J', 'Problem Recognition', 'Acknowledging issues', 'Immediately acknowledged the issue', 'Denied there was a problem'),
|
||||
('J4.02', 'J4', 'J', 'Resolution Speed', 'How fast problems get fixed', 'Fixed immediately', 'Took weeks to resolve'),
|
||||
('J4.03', 'J4', 'J', 'Resolution Fairness', 'Fair handling of issues', 'Very fair resolution', 'Unfair treatment'),
|
||||
('J4.04', 'J4', 'J', 'Resolution Quality', 'How well problems are fixed', 'Completely resolved', 'Problem still exists'),
|
||||
|
||||
-- E1: Physical Environment
|
||||
('E1.01', 'E1', 'E', 'Cleanliness', 'How clean the space is', 'Spotlessly clean', 'Dirty and gross'),
|
||||
('E1.02', 'E1', 'E', 'Comfort', 'Physical comfort', 'Very comfortable seating', 'Uncomfortable chairs'),
|
||||
('E1.03', 'E1', 'E', 'Space Design', 'Layout and organization', 'Well-designed layout', 'Cramped and cluttered'),
|
||||
('E1.04', 'E1', 'E', 'Maintenance', 'State of repair', 'Everything well-maintained', 'Falling apart'),
|
||||
|
||||
-- E2: Ambiance & Atmosphere
|
||||
('E2.01', 'E2', 'E', 'Lighting', 'Light quality and level', 'Perfect lighting', 'Too dark/bright'),
|
||||
('E2.02', 'E2', 'E', 'Sound/Noise', 'Audio environment', 'Nice music', 'Too loud'),
|
||||
('E2.03', 'E2', 'E', 'Temperature', 'Climate control', 'Perfect temperature', 'Freezing/boiling'),
|
||||
('E2.04', 'E2', 'E', 'Smell', 'Odors and scents', 'Smelled wonderful', 'Bad odors'),
|
||||
|
||||
-- E3: Cleanliness
|
||||
('E3.01', 'E3', 'E', 'Interface Design', 'Digital UX/UI', 'Beautiful interface', 'Ugly and confusing'),
|
||||
('E3.02', 'E3', 'E', 'App/Website Speed', 'Digital performance', 'Fast and responsive', 'Slow and laggy'),
|
||||
('E3.03', 'E3', 'E', 'Usability', 'Ease of digital use', 'Intuitive to use', 'Impossible to figure out'),
|
||||
|
||||
-- E4: Digital Experience
|
||||
('E4.01', 'E4', 'E', 'Safety', 'Physical safety', 'Felt completely safe', 'Felt unsafe'),
|
||||
('E4.02', 'E4', 'E', 'Security', 'Protection of belongings/data', 'Very secure', 'Security concerns'),
|
||||
('E4.03', 'E4', 'E', 'Health/Hygiene', 'Health standards', 'Very hygienic', 'Health code violations'),
|
||||
|
||||
-- A1: Friendliness (Availability)
|
||||
('A1.01', 'A1', 'A', 'Hours', 'Operating hours', 'Great hours', 'Never open when I need them'),
|
||||
('A1.02', 'A1', 'A', 'Booking Availability', 'Appointment slots', 'Easy to get an appointment', 'Booked for months'),
|
||||
('A1.03', 'A1', 'A', 'Inventory', 'Product availability', 'Always in stock', 'Always out of stock'),
|
||||
|
||||
-- A2: Helpfulness (Accessibility)
|
||||
('A2.01', 'A2', 'A', 'Physical Access', 'Mobility accessibility', 'Wheelchair accessible', 'Not accessible'),
|
||||
('A2.02', 'A2', 'A', 'Language Access', 'Language accommodation', 'Multiple languages available', 'English only'),
|
||||
('A2.03', 'A2', 'A', 'Digital Accessibility', 'Screen reader/a11y', 'Accessible website', 'Can''t use with screen reader'),
|
||||
|
||||
-- A3: Professionalism (Inclusivity)
|
||||
('A3.01', 'A3', 'A', 'Diversity Welcome', 'All backgrounds welcome', 'Very inclusive', 'Felt unwelcome'),
|
||||
('A3.02', 'A3', 'A', 'Accommodation', 'Special needs accommodation', 'Very accommodating', 'No accommodations available'),
|
||||
|
||||
-- A4: Knowledge & Expertise (Convenience)
|
||||
('A4.01', 'A4', 'A', 'Location', 'Physical location convenience', 'Great location', 'Hard to get to'),
|
||||
('A4.02', 'A4', 'A', 'Parking', 'Parking availability', 'Easy parking', 'No parking'),
|
||||
('A4.03', 'A4', 'A', 'Multiple Channels', 'Ways to engage', 'Many ways to reach them', 'Only one contact method'),
|
||||
|
||||
-- V1: Value Perception (Price)
|
||||
('V1.01', 'V1', 'V', 'Price Level', 'Cost amount', 'Very affordable', 'Way too expensive'),
|
||||
('V1.02', 'V1', 'V', 'Price Fairness', 'Fair for what you get', 'Fair price', 'Overpriced'),
|
||||
('V1.03', 'V1', 'V', 'Hidden Costs', 'Unexpected charges', 'No hidden fees', 'Lots of hidden charges'),
|
||||
|
||||
-- V2: Pricing Structure (Transparency)
|
||||
('V2.01', 'V2', 'V', 'Clear Pricing', 'Easy to understand costs', 'Clear pricing', 'Confusing pricing'),
|
||||
('V2.02', 'V2', 'V', 'Honest Billing', 'Accurate charges', 'Bill was accurate', 'Charged more than quoted'),
|
||||
('V2.03', 'V2', 'V', 'Policy Clarity', 'Clear terms and conditions', 'Clear policies', 'Hidden in fine print'),
|
||||
('V2.04', 'V2', 'V', 'Policy Fairness', 'Fair rules and terms', 'Fair policies', 'Unfair terms'),
|
||||
|
||||
-- V3: Promotions & Deals (Effort)
|
||||
('V3.01', 'V3', 'V', 'Time Investment', 'Time required', 'Quick and easy', 'Took way too long'),
|
||||
('V3.02', 'V3', 'V', 'Hassle Factor', 'Difficulty and inconvenience', 'No hassle', 'Such a hassle'),
|
||||
('V3.03', 'V3', 'V', 'Mental Load', 'Cognitive effort required', 'Easy to understand', 'Too complicated'),
|
||||
|
||||
-- V4: Payment Process (Worth)
|
||||
('V4.01', 'V4', 'V', 'Value for Money', 'Worth what you paid', 'Great value', 'Not worth the money'),
|
||||
('V4.02', 'V4', 'V', 'ROI', 'Return on investment', 'Excellent return', 'Waste of money'),
|
||||
('V4.03', 'V4', 'V', 'Overall Satisfaction', 'Happy with the exchange', 'Very satisfied', 'Totally unsatisfied'),
|
||||
|
||||
-- R1: Loyalty (Integrity)
|
||||
('R1.01', 'R1', 'R', 'Honesty', 'Truthfulness', 'Always honest', 'Lied to me'),
|
||||
('R1.02', 'R1', 'R', 'Ethics', 'Ethical behavior', 'Ethical practices', 'Unethical behavior'),
|
||||
('R1.03', 'R1', 'R', 'Promises Kept', 'Following through on promises', 'Kept all promises', 'Broke their promise'),
|
||||
|
||||
-- R2: Trust (Dependability)
|
||||
('R2.01', 'R2', 'R', 'Consistency', 'Reliable over time', 'Always reliable', 'Inconsistent'),
|
||||
('R2.02', 'R2', 'R', 'Trustworthiness', 'Can be trusted', 'Completely trustworthy', 'Can''t be trusted'),
|
||||
('R2.03', 'R2', 'R', 'Accountability', 'Takes responsibility', 'Takes responsibility', 'Blames others'),
|
||||
|
||||
-- R3: Consistency (Recovery)
|
||||
('R3.01', 'R3', 'R', 'Error Acknowledgment', 'Admits mistakes', 'Quickly admitted the mistake', 'Denied the mistake'),
|
||||
('R3.02', 'R3', 'R', 'Apology Quality', 'Sincere apologies', 'Sincere apology', 'Insincere/no apology'),
|
||||
('R3.03', 'R3', 'R', 'Making It Right', 'Correcting mistakes', 'Made it right', 'Didn''t fix anything'),
|
||||
|
||||
-- R4: Personalization (Loyalty)
|
||||
('R4.01', 'R4', 'R', 'Customer Recognition', 'Remembers customers', 'Remembered me', 'Treated like a stranger'),
|
||||
('R4.02', 'R4', 'R', 'Loyalty Rewards', 'Rewards for loyalty', 'Great loyalty program', 'No recognition for loyalty'),
|
||||
('R4.03', 'R4', 'R', 'Long-term Relationship', 'Builds relationships', 'Values the relationship', 'Just another number')
|
||||
ON CONFLICT (code) DO NOTHING;
|
||||
31
migrations/versions/010_add_solution_to_urt_subcodes.sql
Normal file
31
migrations/versions/010_add_solution_to_urt_subcodes.sql
Normal file
@@ -0,0 +1,31 @@
|
||||
-- Migration: Add solution column to urt_subcodes
|
||||
-- Version: 010
|
||||
-- Date: 2026-01-25
|
||||
-- Description: Add solution column to store actionable recommendations for each URT subcode
|
||||
|
||||
-- Add solution column for actionable business recommendations
|
||||
ALTER TABLE pipeline.urt_subcodes
|
||||
ADD COLUMN IF NOT EXISTS solution TEXT;
|
||||
|
||||
-- Add comment describing the column
|
||||
COMMENT ON COLUMN pipeline.urt_subcodes.solution IS
|
||||
'Actionable business recommendation for addressing issues related to this subcode';
|
||||
|
||||
-- Also add marketing_angle column for strengths
|
||||
ALTER TABLE pipeline.urt_subcodes
|
||||
ADD COLUMN IF NOT EXISTS marketing_angle TEXT;
|
||||
|
||||
COMMENT ON COLUMN pipeline.urt_subcodes.marketing_angle IS
|
||||
'Marketing suggestion when this subcode appears as a strength (high positive sentiment)';
|
||||
|
||||
-- Add complexity column to help with opportunity matrix
|
||||
ALTER TABLE pipeline.urt_subcodes
|
||||
ADD COLUMN IF NOT EXISTS solution_complexity VARCHAR(10) DEFAULT 'medium';
|
||||
|
||||
COMMENT ON COLUMN pipeline.urt_subcodes.solution_complexity IS
|
||||
'Complexity of implementing the solution: simple, medium, complex';
|
||||
|
||||
-- Add constraint for valid complexity values
|
||||
ALTER TABLE pipeline.urt_subcodes
|
||||
ADD CONSTRAINT valid_solution_complexity
|
||||
CHECK (solution_complexity IN ('simple', 'medium', 'complex'));
|
||||
210
migrations/versions/011_populate_urt_solutions.py
Normal file
210
migrations/versions/011_populate_urt_solutions.py
Normal file
@@ -0,0 +1,210 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generate SQL to populate URT subcodes with solutions, marketing angles, and complexity.
|
||||
Parses B1-urt-codes.yaml and creates actionable recommendations.
|
||||
|
||||
Usage:
|
||||
python 011_populate_urt_solutions.py > 011_populate_urt_solutions.sql
|
||||
# Then run the SQL against the database
|
||||
"""
|
||||
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
|
||||
# Load the URT taxonomy
|
||||
URT_YAML = Path(__file__).parent.parent.parent / "urt-taxonomy" / "track-b-engineering" / "B1-urt-codes.yaml"
|
||||
|
||||
# Solution templates based on domain and common patterns
|
||||
SOLUTION_TEMPLATES = {
|
||||
# Offering (O) - Product/Operations solutions
|
||||
"O1.01": ("Implement quality testing before delivery. Create incident response process for functionality failures.", "Our products work reliably - backed by rigorous quality testing.", "medium"),
|
||||
"O1.02": ("Optimize performance through benchmarking and monitoring. Set performance SLAs.", "Experience lightning-fast performance that exceeds expectations.", "complex"),
|
||||
"O1.03": ("Use higher quality materials. Extend warranty coverage. Implement durability testing.", "Built to last - quality materials that stand the test of time.", "medium"),
|
||||
"O1.04": ("Implement regular maintenance schedules. Add redundancy for critical systems.", "Dependable reliability you can count on, every time.", "medium"),
|
||||
"O1.05": ("Track outcome metrics. Follow up on customer goals. Provide success coaching.", "We measure success by YOUR results, not just our delivery.", "medium"),
|
||||
"O2.01": ("Upgrade to premium materials/ingredients. Source from quality suppliers.", "Premium materials and ingredients you can see and feel.", "medium"),
|
||||
"O2.02": ("Invest in craftsman training. Implement quality checkpoints.", "Master craftsmanship in every detail.", "complex"),
|
||||
"O2.03": ("Train on presentation standards. Create visual guidelines.", "Beautifully presented, every single time.", "simple"),
|
||||
"O2.04": ("Implement finishing checklists. Add quality inspection step.", "Meticulous attention to every detail.", "simple"),
|
||||
"O2.05": ("Improve packaging. Add delivery condition checks. Train delivery staff.", "Arrives in perfect condition, guaranteed.", "medium"),
|
||||
"O3.01": ("Create comprehensive packing lists. Verify completeness before shipping.", "Everything you need, nothing missing.", "simple"),
|
||||
"O3.02": ("Test all features before release. Maintain feature availability dashboard.", "All features available and working as promised.", "medium"),
|
||||
"O3.03": ("Define clear scope of work. Use completion checklists.", "We deliver the full scope, every time.", "simple"),
|
||||
"O3.04": ("Create comprehensive documentation. Include setup guides and FAQs.", "Clear instructions and helpful guides included.", "simple"),
|
||||
"O4.01": ("Implement order verification. Add confirmation step before fulfillment.", "Exactly what you ordered, guaranteed.", "simple"),
|
||||
"O4.02": ("Build preference tracking system. Remember customer choices.", "We remember your preferences for a personalized experience.", "medium"),
|
||||
"O4.03": ("Train staff on customization options. Empower flexibility.", "Flexible options tailored to your needs.", "simple"),
|
||||
"O4.04": ("Improve needs assessment. Train consultative selling.", "Expert recommendations matched to your specific needs.", "medium"),
|
||||
|
||||
# People (P) - HR/Training solutions
|
||||
"P1.01": ("Train staff on warm greetings. Recognize friendly behavior.", "Friendly faces and warm welcomes await you.", "simple"),
|
||||
"P1.02": ("Implement respect training. Address complaints immediately.", "You'll be treated with dignity and respect.", "simple"),
|
||||
"P1.03": ("Train active listening and empathy. Role-play difficult scenarios.", "Staff who truly understand your situation.", "medium"),
|
||||
"P1.04": ("Reduce time pressure on staff. Train patience techniques.", "Take your time - we're here to help, not rush.", "simple"),
|
||||
"P1.05": ("Hire for passion. Recognize enthusiastic service.", "Passionate people who love helping customers.", "medium"),
|
||||
"P2.01": ("Implement ongoing product training. Create knowledge base.", "Expert knowledge to answer any question.", "medium"),
|
||||
"P2.02": ("Invest in skills training. Certify technical competency.", "Skilled professionals at the top of their craft.", "complex"),
|
||||
"P2.03": ("Empower staff to solve problems. Create escalation paths.", "Creative problem-solvers who find solutions.", "medium"),
|
||||
"P2.04": ("Define professional standards. Provide uniforms/dress code.", "Professional service you can trust.", "simple"),
|
||||
"P2.05": ("Hire experienced staff. Pair juniors with mentors.", "Seasoned experts with years of experience.", "complex"),
|
||||
"P3.01": ("Train proactive checking. Reduce multitasking.", "Attentive service that anticipates your needs.", "simple"),
|
||||
"P3.02": ("Encourage proactive service. Reward initiative.", "Proactive help before you even ask.", "simple"),
|
||||
"P3.03": ("Optimize staffing levels. Reduce wait for assistance.", "Help is always available when you need it.", "medium"),
|
||||
"P3.04": ("Implement task tracking. Create follow-up reminders.", "We do what we say we'll do.", "simple"),
|
||||
"P3.05": ("Train prioritization. Empower urgent action.", "Your needs are treated with appropriate urgency.", "simple"),
|
||||
"P4.01": ("Train jargon-free communication. Use visual aids.", "Clear explanations without confusing jargon.", "simple"),
|
||||
"P4.02": ("Train active listening. Implement feedback loops.", "We truly listen and understand your needs.", "simple"),
|
||||
"P4.03": ("Implement status update systems. Set update expectations.", "Regular updates keep you informed every step.", "simple"),
|
||||
"P4.04": ("Verify information before sharing. Create accuracy checks.", "Accurate information you can rely on.", "simple"),
|
||||
"P4.05": ("Train professional communication. Provide tone guidelines.", "Professional yet personable communication.", "simple"),
|
||||
|
||||
# Journey (J) - Operations/Process solutions
|
||||
"J1.01": ("Display estimated wait times. Implement queue management.", "Minimal wait times with clear expectations.", "medium"),
|
||||
"J1.02": ("Optimize delivery processes. Set realistic timelines.", "Fast, reliable delivery every time.", "medium"),
|
||||
"J1.03": ("Set response time SLAs. Implement ticketing system.", "Quick responses when you reach out.", "medium"),
|
||||
"J1.04": ("Improve scheduling. Buffer time for delays.", "On-time, every time.", "simple"),
|
||||
"J1.05": ("Train on pacing. Allow customer control of tempo.", "At your pace, never rushed.", "simple"),
|
||||
"J2.01": ("Simplify processes. Remove unnecessary steps.", "Simple, straightforward processes.", "medium"),
|
||||
"J2.02": ("Improve signage. Create intuitive layouts.", "Easy to find what you're looking for.", "simple"),
|
||||
"J2.03": ("Digitize forms. Pre-fill known information.", "Minimal paperwork, maximum efficiency.", "medium"),
|
||||
"J2.04": ("Improve handoff protocols. Share context between teams.", "Seamless transitions between team members.", "medium"),
|
||||
"J2.05": ("Build self-service portal. Add online options.", "Self-service options for your convenience.", "complex"),
|
||||
"J3.01": ("Standardize processes. Document procedures.", "Consistent quality every single time.", "medium"),
|
||||
"J3.02": ("Implement order verification. Add accuracy checks.", "Accurate orders, no mistakes.", "simple"),
|
||||
"J3.03": ("Improve system reliability. Add monitoring and alerts.", "Reliable systems that are always available.", "complex"),
|
||||
"J3.04": ("Set clear expectations. Document what to expect.", "No surprises - exactly what you expect.", "simple"),
|
||||
"J3.05": ("Implement quality checks. Track and reduce errors.", "Rare mistakes with quick corrections.", "medium"),
|
||||
"J4.01": ("Train problem acknowledgment. Create issue intake process.", "We acknowledge issues immediately.", "simple"),
|
||||
"J4.02": ("Create clear escalation paths. Empower frontline resolution.", "Efficient resolution process.", "medium"),
|
||||
"J4.03": ("Set resolution time targets. Prioritize open issues.", "Fast resolution when things go wrong.", "medium"),
|
||||
"J4.04": ("Verify fixes before closing. Follow up on resolutions.", "Complete solutions, not band-aids.", "medium"),
|
||||
"J4.05": ("Conduct root cause analysis. Implement systemic fixes.", "We fix problems permanently.", "complex"),
|
||||
|
||||
# Environment (E) - Facilities/IT solutions
|
||||
"E1.01": ("Increase cleaning frequency. Create cleaning checklists.", "Spotlessly clean facilities.", "simple"),
|
||||
"E1.02": ("Implement preventive maintenance. Fix issues promptly.", "Well-maintained, everything works.", "medium"),
|
||||
"E1.03": ("Redesign layout for flow. Add wayfinding.", "Intuitive layout, easy to navigate.", "complex"),
|
||||
"E1.04": ("Upgrade equipment. Implement replacement schedule.", "Modern, state-of-the-art equipment.", "complex"),
|
||||
"E1.05": ("Add clear signage. Use consistent design.", "Clear signs and easy navigation.", "simple"),
|
||||
"E2.01": ("Invest in UX design. Conduct usability testing.", "Beautiful, intuitive digital experience.", "complex"),
|
||||
"E2.02": ("Test all features. Fix bugs promptly.", "Everything works, no broken buttons.", "medium"),
|
||||
"E2.03": ("Optimize page load. Improve server response.", "Lightning-fast digital experience.", "complex"),
|
||||
"E2.04": ("Simplify navigation. Reduce menu depth.", "Find what you need in seconds.", "medium"),
|
||||
"E2.05": ("Optimize for mobile. Test on all devices.", "Works beautifully on any device.", "medium"),
|
||||
"E3.01": ("Design for desired mood. Control sensory elements.", "Perfect atmosphere and ambiance.", "medium"),
|
||||
"E3.02": ("Add sound absorption. Create quiet zones.", "Pleasant sound levels.", "medium"),
|
||||
"E3.03": ("Optimize HVAC. Add zone controls.", "Perfect temperature, always comfortable.", "medium"),
|
||||
"E3.04": ("Manage capacity. Control entry rates.", "Comfortable, never overcrowded.", "medium"),
|
||||
"E3.05": ("Invest in design. Update decor regularly.", "Beautiful, inviting space.", "complex"),
|
||||
"E4.01": ("Conduct safety audits. Address hazards immediately.", "Safety is our top priority.", "medium"),
|
||||
"E4.02": ("Implement hygiene protocols. Train staff on standards.", "Highest hygiene standards.", "medium"),
|
||||
"E4.03": ("Add security measures. Protect customer property.", "Secure environment for you and your belongings.", "medium"),
|
||||
"E4.04": ("Upgrade furniture. Add comfort amenities.", "Comfortable facilities for your visit.", "medium"),
|
||||
"E4.05": ("Conduct emergency drills. Mark exits clearly.", "Prepared for any emergency.", "medium"),
|
||||
|
||||
# Access (A) - Compliance/Design solutions
|
||||
"A1.01": ("Extend operating hours. Consider 24/7 options.", "Open when you need us.", "medium"),
|
||||
"A1.02": ("Add online booking. Increase appointment slots.", "Easy scheduling, plenty of availability.", "medium"),
|
||||
"A1.03": ("Improve inventory management. Add stock alerts.", "Always in stock when you need it.", "medium"),
|
||||
"A1.04": ("Hire additional staff. Optimize scheduling.", "Plenty of staff to help you.", "complex"),
|
||||
"A1.05": ("Expand service area. Add new locations.", "Convenient locations near you.", "complex"),
|
||||
"A2.01": ("Add ramps and elevators. Ensure ADA compliance.", "Fully accessible for all abilities.", "complex"),
|
||||
"A2.02": ("Add alt text. Ensure screen reader compatibility.", "Accessible for visually impaired users.", "medium"),
|
||||
"A2.03": ("Add captions and transcripts. Support hearing devices.", "Accessible for hearing impaired users.", "medium"),
|
||||
"A2.04": ("Use plain language. Simplify instructions.", "Easy to understand for everyone.", "simple"),
|
||||
"A2.05": ("Test with assistive technologies. Follow WCAG guidelines.", "Works with all assistive technologies.", "complex"),
|
||||
"A3.01": ("Hire multilingual staff. Add translation services.", "Service in your language.", "medium"),
|
||||
"A3.02": ("Train cultural competency. Celebrate diversity.", "Welcoming to all backgrounds.", "medium"),
|
||||
"A3.03": ("Offer dietary alternatives. Train allergy awareness.", "Options for all dietary needs.", "medium"),
|
||||
"A3.04": ("Add family amenities. Create kid-friendly options.", "Great for the whole family.", "medium"),
|
||||
"A3.05": ("Train bias awareness. Audit for fair treatment.", "Equal, respectful treatment for all.", "medium"),
|
||||
"A4.01": ("Choose high-traffic location. Improve visibility.", "Convenient, easy-to-find location.", "complex"),
|
||||
"A4.02": ("Add parking spaces. Offer validation.", "Easy, hassle-free parking.", "complex"),
|
||||
"A4.03": ("Locate near transit. Add shuttle service.", "Easy access by public transit.", "complex"),
|
||||
"A4.04": ("Accept all payment types. Add mobile pay.", "Pay however you prefer.", "simple"),
|
||||
"A4.05": ("Add contact channels. Reduce hold times.", "Easy to reach through any channel.", "medium"),
|
||||
|
||||
# Value (V) - Finance/Pricing solutions
|
||||
"V1.01": ("Review pricing strategy. Offer value tiers.", "Competitive, fair pricing.", "complex"),
|
||||
"V1.02": ("Benchmark against expectations. Communicate value.", "Pricing that matches expectations.", "medium"),
|
||||
"V1.03": ("Conduct competitor analysis. Justify premium or match.", "Competitive with the market.", "medium"),
|
||||
"V1.04": ("Display ALL fees upfront. Eliminate surprise charges.", "Complete price transparency - no hidden fees.", "simple"),
|
||||
"V1.05": ("Offer payment plans. Add financing options.", "Flexible payment options available.", "medium"),
|
||||
"V2.01": ("Create clear price lists. Explain pricing structure.", "Clear, easy-to-understand pricing.", "simple"),
|
||||
"V2.02": ("List all fees upfront. Include in quotes.", "Full disclosure of all charges.", "simple"),
|
||||
"V2.03": ("Audit marketing claims. Ensure accuracy.", "Honest, accurate advertising.", "simple"),
|
||||
"V2.04": ("Simplify contracts. Highlight key terms.", "Fair, straightforward terms.", "medium"),
|
||||
"V2.05": ("Verify all claims. Provide evidence.", "Honest representation of our services.", "simple"),
|
||||
"V3.01": ("Streamline processes. Reduce customer time.", "Quick and easy, respecting your time.", "medium"),
|
||||
"V3.02": ("Simplify decisions. Provide guidance.", "Easy decisions, minimal stress.", "medium"),
|
||||
"V3.03": ("Offer delivery/pickup. Reduce physical burden.", "Convenient, minimal effort required.", "medium"),
|
||||
"V3.04": ("Reduce friction points. Improve processes.", "Smooth, hassle-free experience.", "medium"),
|
||||
"V3.05": ("Demonstrate value clearly. Compare alternatives.", "Worth every moment of your time.", "simple"),
|
||||
"V4.01": ("Communicate value proposition. Demonstrate ROI.", "Exceptional value for your investment.", "medium"),
|
||||
"V4.02": ("Ensure quality matches price. Add value-adds.", "Quality that justifies the price.", "medium"),
|
||||
"V4.03": ("Track satisfaction. Follow up post-purchase.", "Complete satisfaction guaranteed.", "medium"),
|
||||
"V4.04": ("Encourage referrals. Make sharing easy.", "So good, you'll tell your friends.", "simple"),
|
||||
"V4.05": ("Build loyalty program. Reward returns.", "Worth coming back for, again and again.", "medium"),
|
||||
|
||||
# Relationship (R) - Leadership/CX solutions
|
||||
"R1.01": ("Train honest communication. Build trust culture.", "Complete honesty and transparency.", "medium"),
|
||||
"R1.02": ("Document commitments. Track promises made.", "We always keep our promises.", "simple"),
|
||||
"R1.03": ("Share policies openly. Communicate changes.", "Open and transparent in everything we do.", "simple"),
|
||||
"R1.04": ("Define ethical standards. Train compliance.", "Ethical business practices you can trust.", "medium"),
|
||||
"R1.05": ("Ensure consistent treatment. Audit fairness.", "Fair dealing with every customer.", "medium"),
|
||||
"R2.01": ("Track customer history. Learn from patterns.", "Proven track record of excellence.", "medium"),
|
||||
"R2.02": ("Standardize experience. Reduce variation.", "Consistent excellence, every visit.", "medium"),
|
||||
"R2.03": ("Communicate changes. Maintain core values.", "Stable and reliable, year after year.", "medium"),
|
||||
"R2.04": ("Build trust incrementally. Honor commitments.", "A business you can trust completely.", "medium"),
|
||||
"R2.05": ("Honor warranties promptly. Exceed guarantees.", "We stand behind our guarantees.", "medium"),
|
||||
"R3.01": ("Train admission of mistakes. Empower acknowledgment.", "We own our mistakes.", "simple"),
|
||||
"R3.02": ("Develop sincere apology training. Show genuine regret.", "Genuine apologies when things go wrong.", "simple"),
|
||||
"R3.03": ("Develop compensation policies. Empower service recovery.", "We make things right with meaningful gestures.", "medium"),
|
||||
"R3.04": ("Conduct post-mortem reviews. Implement learnings.", "We continuously improve from feedback.", "medium"),
|
||||
"R3.05": ("Train ownership mentality. Remove blame culture.", "Full accountability when issues arise.", "medium"),
|
||||
"R4.01": ("Implement CRM. Train staff on customer history.", "We remember you and value your loyalty.", "medium"),
|
||||
"R4.02": ("Create meaningful loyalty program. Offer real value.", "Rewarding loyalty with meaningful perks.", "medium"),
|
||||
"R4.03": ("Train relationship building. Encourage personal connections.", "More than transactions - real relationships.", "medium"),
|
||||
"R4.04": ("Personalize communications. Add value in outreach.", "Helpful updates, not just promotions.", "medium"),
|
||||
"R4.05": ("Build community events. Create belonging.", "Part of our community.", "medium"),
|
||||
}
|
||||
|
||||
|
||||
def escape_sql(s: str) -> str:
|
||||
"""Escape single quotes for SQL."""
|
||||
if s is None:
|
||||
return "NULL"
|
||||
return "'" + s.replace("'", "''") + "'"
|
||||
|
||||
|
||||
def generate_sql():
|
||||
"""Generate SQL UPDATE statements for all subcodes."""
|
||||
|
||||
print("-- Migration: Populate URT subcodes with solutions")
|
||||
print("-- Version: 011")
|
||||
print("-- Date: 2026-01-25")
|
||||
print("-- Generated from: urt-taxonomy/track-b-engineering/B1-urt-codes.yaml")
|
||||
print()
|
||||
print("BEGIN;")
|
||||
print()
|
||||
|
||||
for code, (solution, marketing_angle, complexity) in SOLUTION_TEMPLATES.items():
|
||||
print(f"""UPDATE pipeline.urt_subcodes
|
||||
SET solution = {escape_sql(solution)},
|
||||
marketing_angle = {escape_sql(marketing_angle)},
|
||||
solution_complexity = {escape_sql(complexity)}
|
||||
WHERE code = {escape_sql(code)};
|
||||
""")
|
||||
|
||||
print("COMMIT;")
|
||||
print()
|
||||
print("-- Verify updates")
|
||||
print("SELECT code, name, solution_complexity, LEFT(solution, 50) as solution_preview")
|
||||
print("FROM pipeline.urt_subcodes")
|
||||
print("WHERE solution IS NOT NULL")
|
||||
print("ORDER BY code")
|
||||
print("LIMIT 10;")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
generate_sql()
|
||||
843
migrations/versions/011_populate_urt_solutions.sql
Normal file
843
migrations/versions/011_populate_urt_solutions.sql
Normal file
@@ -0,0 +1,843 @@
|
||||
-- Migration: Populate URT subcodes with solutions
|
||||
-- Version: 011
|
||||
-- Date: 2026-01-25
|
||||
-- Generated from: urt-taxonomy/track-b-engineering/B1-urt-codes.yaml
|
||||
|
||||
BEGIN;
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement quality testing before delivery. Create incident response process for functionality failures.',
|
||||
marketing_angle = 'Our products work reliably - backed by rigorous quality testing.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'O1.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Optimize performance through benchmarking and monitoring. Set performance SLAs.',
|
||||
marketing_angle = 'Experience lightning-fast performance that exceeds expectations.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'O1.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Use higher quality materials. Extend warranty coverage. Implement durability testing.',
|
||||
marketing_angle = 'Built to last - quality materials that stand the test of time.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'O1.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement regular maintenance schedules. Add redundancy for critical systems.',
|
||||
marketing_angle = 'Dependable reliability you can count on, every time.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'O1.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Track outcome metrics. Follow up on customer goals. Provide success coaching.',
|
||||
marketing_angle = 'We measure success by YOUR results, not just our delivery.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'O1.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Upgrade to premium materials/ingredients. Source from quality suppliers.',
|
||||
marketing_angle = 'Premium materials and ingredients you can see and feel.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'O2.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Invest in craftsman training. Implement quality checkpoints.',
|
||||
marketing_angle = 'Master craftsmanship in every detail.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'O2.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train on presentation standards. Create visual guidelines.',
|
||||
marketing_angle = 'Beautifully presented, every single time.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'O2.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement finishing checklists. Add quality inspection step.',
|
||||
marketing_angle = 'Meticulous attention to every detail.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'O2.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Improve packaging. Add delivery condition checks. Train delivery staff.',
|
||||
marketing_angle = 'Arrives in perfect condition, guaranteed.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'O2.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Create comprehensive packing lists. Verify completeness before shipping.',
|
||||
marketing_angle = 'Everything you need, nothing missing.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'O3.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Test all features before release. Maintain feature availability dashboard.',
|
||||
marketing_angle = 'All features available and working as promised.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'O3.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Define clear scope of work. Use completion checklists.',
|
||||
marketing_angle = 'We deliver the full scope, every time.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'O3.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Create comprehensive documentation. Include setup guides and FAQs.',
|
||||
marketing_angle = 'Clear instructions and helpful guides included.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'O3.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement order verification. Add confirmation step before fulfillment.',
|
||||
marketing_angle = 'Exactly what you ordered, guaranteed.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'O4.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Build preference tracking system. Remember customer choices.',
|
||||
marketing_angle = 'We remember your preferences for a personalized experience.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'O4.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train staff on customization options. Empower flexibility.',
|
||||
marketing_angle = 'Flexible options tailored to your needs.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'O4.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Improve needs assessment. Train consultative selling.',
|
||||
marketing_angle = 'Expert recommendations matched to your specific needs.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'O4.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train staff on warm greetings. Recognize friendly behavior.',
|
||||
marketing_angle = 'Friendly faces and warm welcomes await you.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P1.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement respect training. Address complaints immediately.',
|
||||
marketing_angle = 'You''ll be treated with dignity and respect.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P1.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train active listening and empathy. Role-play difficult scenarios.',
|
||||
marketing_angle = 'Staff who truly understand your situation.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'P1.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Reduce time pressure on staff. Train patience techniques.',
|
||||
marketing_angle = 'Take your time - we''re here to help, not rush.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P1.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Hire for passion. Recognize enthusiastic service.',
|
||||
marketing_angle = 'Passionate people who love helping customers.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'P1.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement ongoing product training. Create knowledge base.',
|
||||
marketing_angle = 'Expert knowledge to answer any question.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'P2.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Invest in skills training. Certify technical competency.',
|
||||
marketing_angle = 'Skilled professionals at the top of their craft.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'P2.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Empower staff to solve problems. Create escalation paths.',
|
||||
marketing_angle = 'Creative problem-solvers who find solutions.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'P2.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Define professional standards. Provide uniforms/dress code.',
|
||||
marketing_angle = 'Professional service you can trust.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P2.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Hire experienced staff. Pair juniors with mentors.',
|
||||
marketing_angle = 'Seasoned experts with years of experience.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'P2.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train proactive checking. Reduce multitasking.',
|
||||
marketing_angle = 'Attentive service that anticipates your needs.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P3.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Encourage proactive service. Reward initiative.',
|
||||
marketing_angle = 'Proactive help before you even ask.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P3.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Optimize staffing levels. Reduce wait for assistance.',
|
||||
marketing_angle = 'Help is always available when you need it.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'P3.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement task tracking. Create follow-up reminders.',
|
||||
marketing_angle = 'We do what we say we''ll do.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P3.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train prioritization. Empower urgent action.',
|
||||
marketing_angle = 'Your needs are treated with appropriate urgency.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P3.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train jargon-free communication. Use visual aids.',
|
||||
marketing_angle = 'Clear explanations without confusing jargon.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P4.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train active listening. Implement feedback loops.',
|
||||
marketing_angle = 'We truly listen and understand your needs.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P4.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement status update systems. Set update expectations.',
|
||||
marketing_angle = 'Regular updates keep you informed every step.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P4.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Verify information before sharing. Create accuracy checks.',
|
||||
marketing_angle = 'Accurate information you can rely on.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P4.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train professional communication. Provide tone guidelines.',
|
||||
marketing_angle = 'Professional yet personable communication.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'P4.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Display estimated wait times. Implement queue management.',
|
||||
marketing_angle = 'Minimal wait times with clear expectations.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'J1.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Optimize delivery processes. Set realistic timelines.',
|
||||
marketing_angle = 'Fast, reliable delivery every time.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'J1.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Set response time SLAs. Implement ticketing system.',
|
||||
marketing_angle = 'Quick responses when you reach out.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'J1.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Improve scheduling. Buffer time for delays.',
|
||||
marketing_angle = 'On-time, every time.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'J1.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train on pacing. Allow customer control of tempo.',
|
||||
marketing_angle = 'At your pace, never rushed.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'J1.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Simplify processes. Remove unnecessary steps.',
|
||||
marketing_angle = 'Simple, straightforward processes.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'J2.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Improve signage. Create intuitive layouts.',
|
||||
marketing_angle = 'Easy to find what you''re looking for.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'J2.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Digitize forms. Pre-fill known information.',
|
||||
marketing_angle = 'Minimal paperwork, maximum efficiency.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'J2.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Improve handoff protocols. Share context between teams.',
|
||||
marketing_angle = 'Seamless transitions between team members.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'J2.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Build self-service portal. Add online options.',
|
||||
marketing_angle = 'Self-service options for your convenience.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'J2.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Standardize processes. Document procedures.',
|
||||
marketing_angle = 'Consistent quality every single time.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'J3.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement order verification. Add accuracy checks.',
|
||||
marketing_angle = 'Accurate orders, no mistakes.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'J3.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Improve system reliability. Add monitoring and alerts.',
|
||||
marketing_angle = 'Reliable systems that are always available.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'J3.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Set clear expectations. Document what to expect.',
|
||||
marketing_angle = 'No surprises - exactly what you expect.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'J3.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement quality checks. Track and reduce errors.',
|
||||
marketing_angle = 'Rare mistakes with quick corrections.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'J3.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train problem acknowledgment. Create issue intake process.',
|
||||
marketing_angle = 'We acknowledge issues immediately.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'J4.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Create clear escalation paths. Empower frontline resolution.',
|
||||
marketing_angle = 'Efficient resolution process.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'J4.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Set resolution time targets. Prioritize open issues.',
|
||||
marketing_angle = 'Fast resolution when things go wrong.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'J4.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Verify fixes before closing. Follow up on resolutions.',
|
||||
marketing_angle = 'Complete solutions, not band-aids.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'J4.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Conduct root cause analysis. Implement systemic fixes.',
|
||||
marketing_angle = 'We fix problems permanently.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'J4.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Increase cleaning frequency. Create cleaning checklists.',
|
||||
marketing_angle = 'Spotlessly clean facilities.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'E1.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement preventive maintenance. Fix issues promptly.',
|
||||
marketing_angle = 'Well-maintained, everything works.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E1.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Redesign layout for flow. Add wayfinding.',
|
||||
marketing_angle = 'Intuitive layout, easy to navigate.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'E1.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Upgrade equipment. Implement replacement schedule.',
|
||||
marketing_angle = 'Modern, state-of-the-art equipment.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'E1.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Add clear signage. Use consistent design.',
|
||||
marketing_angle = 'Clear signs and easy navigation.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'E1.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Invest in UX design. Conduct usability testing.',
|
||||
marketing_angle = 'Beautiful, intuitive digital experience.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'E2.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Test all features. Fix bugs promptly.',
|
||||
marketing_angle = 'Everything works, no broken buttons.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E2.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Optimize page load. Improve server response.',
|
||||
marketing_angle = 'Lightning-fast digital experience.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'E2.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Simplify navigation. Reduce menu depth.',
|
||||
marketing_angle = 'Find what you need in seconds.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E2.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Optimize for mobile. Test on all devices.',
|
||||
marketing_angle = 'Works beautifully on any device.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E2.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Design for desired mood. Control sensory elements.',
|
||||
marketing_angle = 'Perfect atmosphere and ambiance.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E3.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Add sound absorption. Create quiet zones.',
|
||||
marketing_angle = 'Pleasant sound levels.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E3.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Optimize HVAC. Add zone controls.',
|
||||
marketing_angle = 'Perfect temperature, always comfortable.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E3.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Manage capacity. Control entry rates.',
|
||||
marketing_angle = 'Comfortable, never overcrowded.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E3.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Invest in design. Update decor regularly.',
|
||||
marketing_angle = 'Beautiful, inviting space.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'E3.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Conduct safety audits. Address hazards immediately.',
|
||||
marketing_angle = 'Safety is our top priority.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E4.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement hygiene protocols. Train staff on standards.',
|
||||
marketing_angle = 'Highest hygiene standards.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E4.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Add security measures. Protect customer property.',
|
||||
marketing_angle = 'Secure environment for you and your belongings.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E4.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Upgrade furniture. Add comfort amenities.',
|
||||
marketing_angle = 'Comfortable facilities for your visit.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E4.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Conduct emergency drills. Mark exits clearly.',
|
||||
marketing_angle = 'Prepared for any emergency.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'E4.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Extend operating hours. Consider 24/7 options.',
|
||||
marketing_angle = 'Open when you need us.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'A1.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Add online booking. Increase appointment slots.',
|
||||
marketing_angle = 'Easy scheduling, plenty of availability.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'A1.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Improve inventory management. Add stock alerts.',
|
||||
marketing_angle = 'Always in stock when you need it.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'A1.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Hire additional staff. Optimize scheduling.',
|
||||
marketing_angle = 'Plenty of staff to help you.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'A1.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Expand service area. Add new locations.',
|
||||
marketing_angle = 'Convenient locations near you.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'A1.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Add ramps and elevators. Ensure ADA compliance.',
|
||||
marketing_angle = 'Fully accessible for all abilities.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'A2.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Add alt text. Ensure screen reader compatibility.',
|
||||
marketing_angle = 'Accessible for visually impaired users.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'A2.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Add captions and transcripts. Support hearing devices.',
|
||||
marketing_angle = 'Accessible for hearing impaired users.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'A2.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Use plain language. Simplify instructions.',
|
||||
marketing_angle = 'Easy to understand for everyone.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'A2.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Test with assistive technologies. Follow WCAG guidelines.',
|
||||
marketing_angle = 'Works with all assistive technologies.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'A2.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Hire multilingual staff. Add translation services.',
|
||||
marketing_angle = 'Service in your language.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'A3.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train cultural competency. Celebrate diversity.',
|
||||
marketing_angle = 'Welcoming to all backgrounds.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'A3.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Offer dietary alternatives. Train allergy awareness.',
|
||||
marketing_angle = 'Options for all dietary needs.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'A3.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Add family amenities. Create kid-friendly options.',
|
||||
marketing_angle = 'Great for the whole family.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'A3.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train bias awareness. Audit for fair treatment.',
|
||||
marketing_angle = 'Equal, respectful treatment for all.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'A3.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Choose high-traffic location. Improve visibility.',
|
||||
marketing_angle = 'Convenient, easy-to-find location.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'A4.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Add parking spaces. Offer validation.',
|
||||
marketing_angle = 'Easy, hassle-free parking.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'A4.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Locate near transit. Add shuttle service.',
|
||||
marketing_angle = 'Easy access by public transit.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'A4.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Accept all payment types. Add mobile pay.',
|
||||
marketing_angle = 'Pay however you prefer.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'A4.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Add contact channels. Reduce hold times.',
|
||||
marketing_angle = 'Easy to reach through any channel.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'A4.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Review pricing strategy. Offer value tiers.',
|
||||
marketing_angle = 'Competitive, fair pricing.',
|
||||
solution_complexity = 'complex'
|
||||
WHERE code = 'V1.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Benchmark against expectations. Communicate value.',
|
||||
marketing_angle = 'Pricing that matches expectations.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V1.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Conduct competitor analysis. Justify premium or match.',
|
||||
marketing_angle = 'Competitive with the market.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V1.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Display ALL fees upfront. Eliminate surprise charges.',
|
||||
marketing_angle = 'Complete price transparency - no hidden fees.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'V1.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Offer payment plans. Add financing options.',
|
||||
marketing_angle = 'Flexible payment options available.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V1.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Create clear price lists. Explain pricing structure.',
|
||||
marketing_angle = 'Clear, easy-to-understand pricing.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'V2.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'List all fees upfront. Include in quotes.',
|
||||
marketing_angle = 'Full disclosure of all charges.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'V2.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Audit marketing claims. Ensure accuracy.',
|
||||
marketing_angle = 'Honest, accurate advertising.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'V2.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Simplify contracts. Highlight key terms.',
|
||||
marketing_angle = 'Fair, straightforward terms.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V2.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Verify all claims. Provide evidence.',
|
||||
marketing_angle = 'Honest representation of our services.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'V2.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Streamline processes. Reduce customer time.',
|
||||
marketing_angle = 'Quick and easy, respecting your time.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V3.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Simplify decisions. Provide guidance.',
|
||||
marketing_angle = 'Easy decisions, minimal stress.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V3.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Offer delivery/pickup. Reduce physical burden.',
|
||||
marketing_angle = 'Convenient, minimal effort required.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V3.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Reduce friction points. Improve processes.',
|
||||
marketing_angle = 'Smooth, hassle-free experience.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V3.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Demonstrate value clearly. Compare alternatives.',
|
||||
marketing_angle = 'Worth every moment of your time.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'V3.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Communicate value proposition. Demonstrate ROI.',
|
||||
marketing_angle = 'Exceptional value for your investment.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V4.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Ensure quality matches price. Add value-adds.',
|
||||
marketing_angle = 'Quality that justifies the price.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V4.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Track satisfaction. Follow up post-purchase.',
|
||||
marketing_angle = 'Complete satisfaction guaranteed.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V4.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Encourage referrals. Make sharing easy.',
|
||||
marketing_angle = 'So good, you''ll tell your friends.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'V4.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Build loyalty program. Reward returns.',
|
||||
marketing_angle = 'Worth coming back for, again and again.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'V4.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train honest communication. Build trust culture.',
|
||||
marketing_angle = 'Complete honesty and transparency.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R1.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Document commitments. Track promises made.',
|
||||
marketing_angle = 'We always keep our promises.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'R1.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Share policies openly. Communicate changes.',
|
||||
marketing_angle = 'Open and transparent in everything we do.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'R1.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Define ethical standards. Train compliance.',
|
||||
marketing_angle = 'Ethical business practices you can trust.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R1.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Ensure consistent treatment. Audit fairness.',
|
||||
marketing_angle = 'Fair dealing with every customer.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R1.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Track customer history. Learn from patterns.',
|
||||
marketing_angle = 'Proven track record of excellence.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R2.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Standardize experience. Reduce variation.',
|
||||
marketing_angle = 'Consistent excellence, every visit.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R2.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Communicate changes. Maintain core values.',
|
||||
marketing_angle = 'Stable and reliable, year after year.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R2.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Build trust incrementally. Honor commitments.',
|
||||
marketing_angle = 'A business you can trust completely.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R2.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Honor warranties promptly. Exceed guarantees.',
|
||||
marketing_angle = 'We stand behind our guarantees.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R2.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train admission of mistakes. Empower acknowledgment.',
|
||||
marketing_angle = 'We own our mistakes.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'R3.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Develop sincere apology training. Show genuine regret.',
|
||||
marketing_angle = 'Genuine apologies when things go wrong.',
|
||||
solution_complexity = 'simple'
|
||||
WHERE code = 'R3.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Develop compensation policies. Empower service recovery.',
|
||||
marketing_angle = 'We make things right with meaningful gestures.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R3.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Conduct post-mortem reviews. Implement learnings.',
|
||||
marketing_angle = 'We continuously improve from feedback.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R3.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train ownership mentality. Remove blame culture.',
|
||||
marketing_angle = 'Full accountability when issues arise.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R3.05';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Implement CRM. Train staff on customer history.',
|
||||
marketing_angle = 'We remember you and value your loyalty.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R4.01';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Create meaningful loyalty program. Offer real value.',
|
||||
marketing_angle = 'Rewarding loyalty with meaningful perks.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R4.02';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Train relationship building. Encourage personal connections.',
|
||||
marketing_angle = 'More than transactions - real relationships.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R4.03';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Personalize communications. Add value in outreach.',
|
||||
marketing_angle = 'Helpful updates, not just promotions.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R4.04';
|
||||
|
||||
UPDATE pipeline.urt_subcodes
|
||||
SET solution = 'Build community events. Create belonging.',
|
||||
marketing_angle = 'Part of our community.',
|
||||
solution_complexity = 'medium'
|
||||
WHERE code = 'R4.05';
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- Verify updates
|
||||
SELECT code, name, solution_complexity, LEFT(solution, 50) as solution_preview
|
||||
FROM pipeline.urt_subcodes
|
||||
WHERE solution IS NOT NULL
|
||||
ORDER BY code
|
||||
LIMIT 10;
|
||||
102
migrations/versions/012_sync_urt_subcodes_from_taxonomy.sql
Normal file
102
migrations/versions/012_sync_urt_subcodes_from_taxonomy.sql
Normal file
@@ -0,0 +1,102 @@
|
||||
-- =============================================================================
|
||||
-- Migration: 012_sync_urt_subcodes_from_taxonomy.sql
|
||||
-- Purpose: Sync missing URT subcodes from taxonomy v5.1 to database
|
||||
-- =============================================================================
|
||||
|
||||
-- Insert missing subcodes (ON CONFLICT DO UPDATE to sync names/definitions)
|
||||
INSERT INTO pipeline.urt_subcodes (code, category_code, domain_code, name, definition, positive_example, negative_example) VALUES
|
||||
|
||||
-- J1: Wait Times (missing J1.04, J1.05)
|
||||
('J1.04', 'J1', 'J', 'Punctuality', 'Meeting scheduled times', 'Always on time', 'Two hours late'),
|
||||
('J1.05', 'J1', 'J', 'Pacing', 'Appropriate speed (not rushed/dragged)', 'Perfect pace throughout', 'Felt rushed through everything'),
|
||||
|
||||
-- J2: Booking & Reservations (missing J2.04, J2.05)
|
||||
('J2.04', 'J2', 'J', 'Booking Availability', 'Slots/capacity when needed', 'Always available slots', 'Fully booked for weeks'),
|
||||
('J2.05', 'J2', 'J', 'Inventory', 'Stock availability', 'Always in stock', 'Out of stock constantly'),
|
||||
|
||||
-- J3: System Reliability (missing J3.04, J3.05)
|
||||
('J3.04', 'J3', 'J', 'Data Accuracy', 'Correct info in systems', 'All details correct', 'Wrong info in my account'),
|
||||
('J3.05', 'J3', 'J', 'Integration', 'Systems work together', 'Seamless between channels', 'Info doesn''t sync'),
|
||||
|
||||
-- J4: Problem Resolution (missing J4.04, J4.05)
|
||||
('J4.04', 'J4', 'J', 'Escalation', 'Getting to right person', 'Quickly got to manager', 'Endless transfers'),
|
||||
('J4.05', 'J4', 'J', 'Closure', 'Issue fully resolved', 'Problem completely solved', 'Issue still not fixed'),
|
||||
|
||||
-- A1: Physical Access (missing A1.04, A1.05)
|
||||
('A1.04', 'A1', 'A', 'Wayfinding', 'Finding destination', 'Easy to find', 'Got lost trying to find it'),
|
||||
('A1.05', 'A1', 'A', 'Physical Accessibility', 'Disability accommodations', 'Wheelchair accessible', 'No ramps or elevators'),
|
||||
|
||||
-- A2: Channel Access (missing A2.04, A2.05)
|
||||
('A2.04', 'A2', 'A', 'Language Accessibility', 'Multilingual support', 'Available in my language', 'No translation available'),
|
||||
('A2.05', 'A2', 'A', 'Hours of Operation', 'Service availability times', 'Open when needed', 'Terrible hours'),
|
||||
|
||||
-- A3: Information Access (missing A3.04, A3.05)
|
||||
('A3.04', 'A3', 'A', 'Documentation Clarity', 'Clear instructions', 'Easy to understand docs', 'Confusing instructions'),
|
||||
('A3.05', 'A3', 'A', 'Support Accessibility', 'Getting help when needed', 'Easy to reach support', 'Impossible to get help'),
|
||||
|
||||
-- A4: Financial Access (missing A4.04, A4.05)
|
||||
('A4.04', 'A4', 'A', 'Payment Flexibility', 'Multiple payment options', 'Many payment options', 'Only accepts cash'),
|
||||
('A4.05', 'A4', 'A', 'Refund Accessibility', 'Getting money back', 'Easy refund process', 'Impossible to get refund'),
|
||||
|
||||
-- E1: Physical Environment (missing E1.04, E1.05)
|
||||
('E1.04', 'E1', 'E', 'Ambiance', 'Atmosphere and vibe', 'Great atmosphere', 'Depressing environment'),
|
||||
('E1.05', 'E1', 'E', 'Comfort', 'Physical comfort', 'Very comfortable', 'Uncomfortable seating'),
|
||||
|
||||
-- E2: Digital Environment (missing E2.04, E2.05)
|
||||
('E2.04', 'E2', 'E', 'Visual Design', 'Aesthetics of interface', 'Beautiful design', 'Ugly interface'),
|
||||
('E2.05', 'E2', 'E', 'Mobile Experience', 'Mobile usability', 'Great mobile app', 'Terrible mobile site'),
|
||||
|
||||
-- E3: Safety & Security (missing E3.04, E3.05)
|
||||
('E3.04', 'E3', 'E', 'Health Safety', 'Health precautions', 'Very clean and safe', 'Unsanitary conditions'),
|
||||
('E3.05', 'E3', 'E', 'Cyber Security', 'Digital security', 'Secure platform', 'Got hacked'),
|
||||
|
||||
-- E4: Sustainability (missing E4.04, E4.05)
|
||||
('E4.04', 'E4', 'E', 'Social Responsibility', 'Ethical practices', 'Ethical company', 'Exploitative practices'),
|
||||
('E4.05', 'E4', 'E', 'Community Impact', 'Local community effect', 'Supports local community', 'Hurts local businesses'),
|
||||
|
||||
-- V1: Pricing (missing V1.04, V1.05)
|
||||
('V1.04', 'V1', 'V', 'Price Transparency', 'Clear pricing', 'Clear pricing upfront', 'Hidden costs everywhere'),
|
||||
('V1.05', 'V1', 'V', 'Price Stability', 'Consistent pricing', 'Same price always', 'Prices keep changing'),
|
||||
|
||||
-- V2: Value Perception (missing V2.04, V2.05)
|
||||
('V2.04', 'V2', 'V', 'Quality-Price Ratio', 'Worth vs cost', 'Excellent quality for price', 'Overpriced for quality'),
|
||||
('V2.05', 'V2', 'V', 'Competitive Value', 'Compared to alternatives', 'Best value around', 'Better deals elsewhere'),
|
||||
|
||||
-- V3: Promotions (missing V3.04, V3.05)
|
||||
('V3.04', 'V3', 'V', 'Promotion Clarity', 'Clear offer terms', 'Clear promotion rules', 'Misleading promotions'),
|
||||
('V3.05', 'V3', 'V', 'Reward Redemption', 'Using points/rewards', 'Easy to redeem rewards', 'Hard to use points'),
|
||||
|
||||
-- V4: Billing (missing V4.04, V4.05)
|
||||
('V4.04', 'V4', 'V', 'Billing Accuracy', 'Correct charges', 'Always billed correctly', 'Overcharged constantly'),
|
||||
('V4.05', 'V4', 'V', 'Billing Resolution', 'Fixing billing issues', 'Quick billing fix', 'Billing disputes ignored'),
|
||||
|
||||
-- R1: Trust (missing R1.04, R1.05)
|
||||
('R1.04', 'R1', 'R', 'Ethics', 'Ethical behavior', 'Very ethical company', 'Unethical practices'),
|
||||
('R1.05', 'R1', 'R', 'Accountability', 'Taking responsibility', 'Owned their mistakes', 'Never takes blame'),
|
||||
|
||||
-- R2: Reliability (missing R2.04, R2.05)
|
||||
('R2.04', 'R2', 'R', 'Predictability', 'Consistent experience', 'Always know what to expect', 'Every visit is different'),
|
||||
('R2.05', 'R2', 'R', 'Standards', 'Meeting quality standards', 'High standards maintained', 'Standards have dropped'),
|
||||
|
||||
-- R3: Care (missing R3.04, R3.05)
|
||||
('R3.04', 'R3', 'R', 'Personal Connection', 'Human touch', 'Felt like family', 'Treated like a number'),
|
||||
('R3.05', 'R3', 'R', 'Going Extra Mile', 'Beyond expectations', 'Went above and beyond', 'Minimum effort only'),
|
||||
|
||||
-- R4: Recovery (missing R4.04, R4.05)
|
||||
('R4.04', 'R4', 'R', 'Service Recovery', 'Making things right', 'Fixed problem perfectly', 'Made it worse'),
|
||||
('R4.05', 'R4', 'R', 'Feedback Response', 'Acting on feedback', 'Implemented my suggestion', 'Feedback ignored')
|
||||
|
||||
ON CONFLICT (code) DO UPDATE SET
|
||||
name = EXCLUDED.name,
|
||||
definition = EXCLUDED.definition,
|
||||
positive_example = EXCLUDED.positive_example,
|
||||
negative_example = EXCLUDED.negative_example;
|
||||
|
||||
-- Verify count
|
||||
DO $$
|
||||
DECLARE
|
||||
subcode_count INTEGER;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO subcode_count FROM pipeline.urt_subcodes;
|
||||
RAISE NOTICE 'Total subcodes after sync: %', subcode_count;
|
||||
END $$;
|
||||
411
migrations/versions/013_insert_primitives.sql
Normal file
411
migrations/versions/013_insert_primitives.sql
Normal file
@@ -0,0 +1,411 @@
|
||||
-- Migration: Insert frozen primitive dictionary (36 primitives)
|
||||
-- Description: Populates the primitives table with the complete URT taxonomy
|
||||
-- Date: 2025-01-31
|
||||
|
||||
-- Quality dimension (8 primitives)
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'EFFECTIVENESS',
|
||||
'QUALITY',
|
||||
'Effectiveness',
|
||||
'Did it achieve its intended purpose?',
|
||||
FALSE,
|
||||
'["worked perfectly", "exactly what I needed", "solved my problem"]',
|
||||
'["didn''t work", "useless", "waste of time"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'TASTE',
|
||||
'QUALITY',
|
||||
'Taste',
|
||||
'Sensory quality (flavor, texture, smell)',
|
||||
FALSE,
|
||||
'["delicious", "amazing taste", "flavorful"]',
|
||||
'["bland", "tasteless", "disgusting"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'CRAFT',
|
||||
'QUALITY',
|
||||
'Craft',
|
||||
'Skill of execution, workmanship',
|
||||
FALSE,
|
||||
'["well-made", "professional", "quality work"]',
|
||||
'["sloppy", "poorly made", "amateur"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'ACCURACY',
|
||||
'QUALITY',
|
||||
'Accuracy',
|
||||
'Correct as ordered/specified',
|
||||
FALSE,
|
||||
'["exactly what I ordered", "perfect", "got everything right"]',
|
||||
'["wrong order", "missing items", "not what I asked for"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'FRESHNESS',
|
||||
'QUALITY',
|
||||
'Freshness',
|
||||
'Fresh vs stale/expired',
|
||||
FALSE,
|
||||
'["fresh", "just made", "new"]',
|
||||
'["stale", "old", "expired"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'TEMPERATURE',
|
||||
'QUALITY',
|
||||
'Temperature',
|
||||
'Appropriate temperature for the item',
|
||||
FALSE,
|
||||
'["hot", "perfect temperature", "cold as it should be"]',
|
||||
'["cold", "lukewarm", "too hot", "room temperature"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'CONDITION',
|
||||
'QUALITY',
|
||||
'Condition',
|
||||
'Physical state, damage, defects',
|
||||
FALSE,
|
||||
'["perfect condition", "like new", "undamaged"]',
|
||||
'["damaged", "broken", "defective"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'CONSISTENCY',
|
||||
'QUALITY',
|
||||
'Consistency',
|
||||
'Same quality across visits/units',
|
||||
FALSE,
|
||||
'["always consistent", "reliable quality", "same every time"]',
|
||||
'["inconsistent", "hit or miss", "varies"]'
|
||||
);
|
||||
|
||||
-- Service dimension (4 primitives)
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'MANNER',
|
||||
'SERVICE',
|
||||
'Manner',
|
||||
'Warmth, respect, patience in interactions',
|
||||
FALSE,
|
||||
'["friendly", "nice", "welcoming", "patient"]',
|
||||
'["rude", "dismissive", "impatient", "attitude"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'COMPETENCE',
|
||||
'SERVICE',
|
||||
'Competence',
|
||||
'Knowledge and skill of staff',
|
||||
FALSE,
|
||||
'["knowledgeable", "professional", "knew what they were doing"]',
|
||||
'["clueless", "incompetent", "didn''t know"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'ATTENTIVENESS',
|
||||
'SERVICE',
|
||||
'Attentiveness',
|
||||
'Present, notices needs, proactive',
|
||||
FALSE,
|
||||
'["attentive", "checked on us", "anticipated needs"]',
|
||||
'["ignored", "had to flag down", "neglected"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'COMMUNICATION',
|
||||
'SERVICE',
|
||||
'Communication',
|
||||
'Clear, listens, keeps informed',
|
||||
FALSE,
|
||||
'["clear", "good communication", "kept us updated"]',
|
||||
'["confusing", "didn''t listen", "no updates"]'
|
||||
);
|
||||
|
||||
-- Process dimension (4 primitives)
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'SPEED',
|
||||
'PROCESS',
|
||||
'Speed',
|
||||
'How fast/slow things happen',
|
||||
FALSE,
|
||||
'["fast", "quick", "no wait"]',
|
||||
'["slow", "took forever", "long wait"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'FRICTION',
|
||||
'PROCESS',
|
||||
'Friction',
|
||||
'Ease vs obstacles in the process',
|
||||
FALSE,
|
||||
'["easy", "smooth", "hassle-free"]',
|
||||
'["complicated", "difficult", "hassle"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'RELIABILITY',
|
||||
'PROCESS',
|
||||
'Reliability',
|
||||
'Process works consistently, no errors',
|
||||
FALSE,
|
||||
'["reliable", "dependable", "always works"]',
|
||||
'["unreliable", "errors", "problems"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'AVAILABILITY',
|
||||
'PROCESS',
|
||||
'Availability',
|
||||
'Hours, capacity, stock availability',
|
||||
FALSE,
|
||||
'["always available", "open when needed", "in stock"]',
|
||||
'["closed", "sold out", "no appointments"]'
|
||||
);
|
||||
|
||||
-- Environment dimension (6 primitives)
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'CLEANLINESS',
|
||||
'ENVIRONMENT',
|
||||
'Cleanliness',
|
||||
'Clean, sanitary conditions',
|
||||
FALSE,
|
||||
'["clean", "spotless", "hygienic"]',
|
||||
'["dirty", "filthy", "unsanitary"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'COMFORT',
|
||||
'ENVIRONMENT',
|
||||
'Comfort',
|
||||
'Physical comfort of the space',
|
||||
FALSE,
|
||||
'["comfortable", "cozy", "spacious"]',
|
||||
'["uncomfortable", "cramped", "hard seats"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'AMBIANCE',
|
||||
'ENVIRONMENT',
|
||||
'Ambiance',
|
||||
'Vibe, atmosphere, noise level',
|
||||
FALSE,
|
||||
'["nice atmosphere", "great vibe", "quiet"]',
|
||||
'["loud", "noisy", "bad atmosphere"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'SAFETY',
|
||||
'ENVIRONMENT',
|
||||
'Safety',
|
||||
'Physical and health safety',
|
||||
FALSE,
|
||||
'["safe", "secure", "clean protocols"]',
|
||||
'["unsafe", "dangerous", "health hazard"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'ACCESSIBILITY',
|
||||
'ENVIRONMENT',
|
||||
'Accessibility',
|
||||
'Disability access, location convenience',
|
||||
FALSE,
|
||||
'["accessible", "easy to get to", "good parking"]',
|
||||
'["hard to access", "no parking", "not wheelchair accessible"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'DIGITAL_UX',
|
||||
'ENVIRONMENT',
|
||||
'Digital UX',
|
||||
'App/website usability and performance',
|
||||
FALSE,
|
||||
'["easy to use", "great app", "fast website"]',
|
||||
'["app crashed", "hard to navigate", "slow website"]'
|
||||
);
|
||||
|
||||
-- Value dimension (4 primitives)
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'PRICE_LEVEL',
|
||||
'VALUE',
|
||||
'Price Level',
|
||||
'Absolute cost perception',
|
||||
FALSE,
|
||||
'["affordable", "cheap", "good prices"]',
|
||||
'["expensive", "overpriced", "pricey"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'PRICE_FAIRNESS',
|
||||
'VALUE',
|
||||
'Price Fairness',
|
||||
'Fair value for what was received',
|
||||
FALSE,
|
||||
'["fair price", "worth it", "good value"]',
|
||||
'["rip off", "not worth it", "overcharged"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'PRICE_TRANSPARENCY',
|
||||
'VALUE',
|
||||
'Price Transparency',
|
||||
'Clear pricing, no surprises',
|
||||
FALSE,
|
||||
'["clear pricing", "no hidden fees", "upfront"]',
|
||||
'["hidden fees", "surprise charges", "bait and switch"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'VALUE_FOR_MONEY',
|
||||
'VALUE',
|
||||
'Value for Money',
|
||||
'Overall worth judgment',
|
||||
FALSE,
|
||||
'["great value", "worth every penny", "good deal"]',
|
||||
'["bad value", "waste of money", "not worth it"]'
|
||||
);
|
||||
|
||||
-- Trust dimension (3 meta primitives)
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'HONESTY',
|
||||
'TRUST',
|
||||
'Honesty',
|
||||
'Truthful, no deception',
|
||||
TRUE,
|
||||
'["honest", "transparent", "truthful"]',
|
||||
'["lied", "deceived", "dishonest", "scam"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'ETHICS',
|
||||
'TRUST',
|
||||
'Ethics',
|
||||
'Ethical, fair dealing',
|
||||
TRUE,
|
||||
'["ethical", "fair", "integrity"]',
|
||||
'["unethical", "shady", "crooked"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'PROMISES',
|
||||
'TRUST',
|
||||
'Promises',
|
||||
'Kept or broken commitments',
|
||||
TRUE,
|
||||
'["kept their word", "delivered as promised", "reliable"]',
|
||||
'["broke promise", "didn''t deliver", "false advertising"]'
|
||||
);
|
||||
|
||||
-- Resolution dimension (3 meta primitives)
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'ACKNOWLEDGMENT',
|
||||
'RESOLUTION',
|
||||
'Acknowledgment',
|
||||
'Recognized the problem',
|
||||
TRUE,
|
||||
'["acknowledged", "apologized", "admitted mistake"]',
|
||||
'["denied", "dismissed", "blamed me"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'RESPONSE_QUALITY',
|
||||
'RESOLUTION',
|
||||
'Response Quality',
|
||||
'How well they handled the issue',
|
||||
TRUE,
|
||||
'["handled well", "resolved quickly", "took care of it"]',
|
||||
'["ignored complaint", "unhelpful", "made it worse"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'RECOVERY',
|
||||
'RESOLUTION',
|
||||
'Recovery',
|
||||
'Made it right, compensation',
|
||||
TRUE,
|
||||
'["made it right", "refunded", "compensated"]',
|
||||
'["refused refund", "no compensation", "wouldn''t fix"]'
|
||||
);
|
||||
|
||||
-- Loyalty dimension (3 meta primitives)
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'RETURN_INTENT',
|
||||
'LOYALTY',
|
||||
'Return Intent',
|
||||
'Will/won''t come back',
|
||||
TRUE,
|
||||
'["will be back", "returning customer", "coming again"]',
|
||||
'["never again", "won''t return", "last time"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'RECOMMEND',
|
||||
'LOYALTY',
|
||||
'Recommend',
|
||||
'Would/wouldn''t recommend',
|
||||
TRUE,
|
||||
'["highly recommend", "tell everyone", "must try"]',
|
||||
'["avoid", "don''t go", "stay away", "wouldn''t recommend"]'
|
||||
);
|
||||
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'RECOGNITION',
|
||||
'LOYALTY',
|
||||
'Recognition',
|
||||
'Felt valued, remembered',
|
||||
TRUE,
|
||||
'["remembered me", "felt valued", "personal touch"]',
|
||||
'["treated like a number", "didn''t care", "no loyalty"]'
|
||||
);
|
||||
|
||||
-- Escape dimension (1 meta primitive)
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES (
|
||||
'UNMAPPED',
|
||||
'ESCAPE',
|
||||
'Unmapped',
|
||||
'Does not fit taxonomy; preserve evidence',
|
||||
TRUE,
|
||||
'[]',
|
||||
'[]'
|
||||
);
|
||||
|
||||
-- Verify count
|
||||
-- SELECT COUNT(*) FROM pipeline.primitives; -- Should return 36
|
||||
561
migrations/versions/014_primitive_classification_system.sql
Normal file
561
migrations/versions/014_primitive_classification_system.sql
Normal file
@@ -0,0 +1,561 @@
|
||||
-- =============================================================================
|
||||
-- Migration: 014_primitive_classification_system.sql
|
||||
-- Purpose: Create primitive classification system for context-aware review analysis
|
||||
-- =============================================================================
|
||||
--
|
||||
-- This migration introduces a "primitive" classification system that allows
|
||||
-- industry-specific and category-specific configuration of what aspects to
|
||||
-- look for when classifying reviews.
|
||||
--
|
||||
-- Components:
|
||||
-- 1. pipeline.primitives - Frozen dictionary of primitives (quality dimensions)
|
||||
-- 2. ALTER public.gbp_categories - Add primitive_configs and business_context
|
||||
-- 3. pipeline.jsonb_deep_merge() - Recursive JSONB merge function
|
||||
-- 4. pipeline.resolve_primitive_config() - Resolve configs through category tree
|
||||
-- 5. pipeline.get_classification_context() - Get full classification context
|
||||
--
|
||||
-- Date: 2026-01-31
|
||||
-- =============================================================================
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- SECTION 1: PRIMITIVES TABLE (Frozen Dictionary)
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS pipeline.primitives (
|
||||
code VARCHAR(30) PRIMARY KEY,
|
||||
dimension VARCHAR(20) NOT NULL, -- quality, service, process, environment, value, trust, resolution, loyalty, escape
|
||||
name VARCHAR(100) NOT NULL,
|
||||
definition TEXT NOT NULL,
|
||||
is_meta BOOLEAN DEFAULT FALSE, -- true for always-active primitives (HONESTY, ETHICS, etc.)
|
||||
base_positive_signals TEXT[],
|
||||
base_negative_signals TEXT[],
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Index on dimension for filtering
|
||||
CREATE INDEX IF NOT EXISTS idx_primitives_dimension ON pipeline.primitives(dimension);
|
||||
|
||||
-- Index on is_meta for quick access to always-active primitives
|
||||
CREATE INDEX IF NOT EXISTS idx_primitives_is_meta ON pipeline.primitives(is_meta) WHERE is_meta = TRUE;
|
||||
|
||||
COMMENT ON TABLE pipeline.primitives IS 'Frozen dictionary of classification primitives (quality dimensions)';
|
||||
COMMENT ON COLUMN pipeline.primitives.code IS 'Unique identifier for the primitive (e.g., FOOD_TASTE, SERVICE_SPEED)';
|
||||
COMMENT ON COLUMN pipeline.primitives.dimension IS 'Category of the primitive (quality, service, process, etc.)';
|
||||
COMMENT ON COLUMN pipeline.primitives.is_meta IS 'If true, this primitive is always active regardless of category config';
|
||||
COMMENT ON COLUMN pipeline.primitives.base_positive_signals IS 'Default positive signal keywords for this primitive';
|
||||
COMMENT ON COLUMN pipeline.primitives.base_negative_signals IS 'Default negative signal keywords for this primitive';
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- SECTION 2: ALTER gbp_categories TABLE
|
||||
-- =============================================================================
|
||||
|
||||
-- Add primitive_configs column (JSONB for flexible config)
|
||||
ALTER TABLE public.gbp_categories
|
||||
ADD COLUMN IF NOT EXISTS primitive_configs JSONB DEFAULT '{}';
|
||||
|
||||
-- Add business_context column (JSONB for industry-specific context)
|
||||
ALTER TABLE public.gbp_categories
|
||||
ADD COLUMN IF NOT EXISTS business_context JSONB DEFAULT '{}';
|
||||
|
||||
-- Add config versioning columns
|
||||
ALTER TABLE public.gbp_categories
|
||||
ADD COLUMN IF NOT EXISTS config_version VARCHAR(20);
|
||||
|
||||
ALTER TABLE public.gbp_categories
|
||||
ADD COLUMN IF NOT EXISTS config_generated_by VARCHAR(100);
|
||||
|
||||
ALTER TABLE public.gbp_categories
|
||||
ADD COLUMN IF NOT EXISTS config_updated_at TIMESTAMP WITH TIME ZONE;
|
||||
|
||||
-- GIN indexes for JSONB containment queries
|
||||
CREATE INDEX IF NOT EXISTS idx_gbp_categories_primitive_configs
|
||||
ON public.gbp_categories USING GIN (primitive_configs);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gbp_categories_business_context
|
||||
ON public.gbp_categories USING GIN (business_context);
|
||||
|
||||
-- Index for config version lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_gbp_categories_config_version
|
||||
ON public.gbp_categories(config_version) WHERE config_version IS NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN public.gbp_categories.primitive_configs IS 'JSONB config for primitives at this category level (inherits from ancestors)';
|
||||
COMMENT ON COLUMN public.gbp_categories.business_context IS 'JSONB business context for this category (industry-specific terminology, etc.)';
|
||||
COMMENT ON COLUMN public.gbp_categories.config_version IS 'Version of the primitive config (for cache invalidation)';
|
||||
COMMENT ON COLUMN public.gbp_categories.config_generated_by IS 'Tool/model that generated this config';
|
||||
COMMENT ON COLUMN public.gbp_categories.config_updated_at IS 'When the config was last updated';
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- SECTION 3: JSONB DEEP MERGE FUNCTION
|
||||
-- =============================================================================
|
||||
|
||||
-- Recursive JSONB merge function
|
||||
-- - Objects: recursively merge (override wins on conflicts)
|
||||
-- - Arrays: union with dedup by default
|
||||
-- - If object has "__replace__": true, replace entirely instead of merge
|
||||
CREATE OR REPLACE FUNCTION pipeline.jsonb_deep_merge(
|
||||
base JSONB,
|
||||
override JSONB
|
||||
) RETURNS JSONB AS $$
|
||||
DECLARE
|
||||
result JSONB;
|
||||
key TEXT;
|
||||
base_value JSONB;
|
||||
override_value JSONB;
|
||||
merged_array JSONB;
|
||||
BEGIN
|
||||
-- Handle NULL cases
|
||||
IF base IS NULL THEN
|
||||
RETURN override;
|
||||
END IF;
|
||||
|
||||
IF override IS NULL THEN
|
||||
RETURN base;
|
||||
END IF;
|
||||
|
||||
-- If override has __replace__ flag, return override without the flag
|
||||
IF jsonb_typeof(override) = 'object' AND override ? '__replace__' AND (override->>'__replace__')::boolean = true THEN
|
||||
RETURN override - '__replace__';
|
||||
END IF;
|
||||
|
||||
-- If both are not objects, override wins
|
||||
IF jsonb_typeof(base) != 'object' OR jsonb_typeof(override) != 'object' THEN
|
||||
RETURN override;
|
||||
END IF;
|
||||
|
||||
-- Both are objects, merge recursively
|
||||
result := base;
|
||||
|
||||
FOR key IN SELECT jsonb_object_keys(override)
|
||||
LOOP
|
||||
override_value := override->key;
|
||||
|
||||
IF NOT (base ? key) THEN
|
||||
-- Key doesn't exist in base, just add it
|
||||
result := result || jsonb_build_object(key, override_value);
|
||||
ELSE
|
||||
base_value := base->key;
|
||||
|
||||
-- Check for __replace__ flag in the override value
|
||||
IF jsonb_typeof(override_value) = 'object'
|
||||
AND override_value ? '__replace__'
|
||||
AND (override_value->>'__replace__')::boolean = true THEN
|
||||
-- Replace entirely (without the __replace__ flag)
|
||||
result := result || jsonb_build_object(key, override_value - '__replace__');
|
||||
|
||||
-- If both are objects, recurse
|
||||
ELSIF jsonb_typeof(base_value) = 'object' AND jsonb_typeof(override_value) = 'object' THEN
|
||||
result := result || jsonb_build_object(
|
||||
key,
|
||||
pipeline.jsonb_deep_merge(base_value, override_value)
|
||||
);
|
||||
|
||||
-- If both are arrays, union with dedup
|
||||
ELSIF jsonb_typeof(base_value) = 'array' AND jsonb_typeof(override_value) = 'array' THEN
|
||||
-- Union arrays, remove duplicates
|
||||
-- Using a subquery to deduplicate
|
||||
SELECT jsonb_agg(DISTINCT elem)
|
||||
INTO merged_array
|
||||
FROM (
|
||||
SELECT jsonb_array_elements(base_value) AS elem
|
||||
UNION
|
||||
SELECT jsonb_array_elements(override_value) AS elem
|
||||
) AS combined;
|
||||
|
||||
result := result || jsonb_build_object(key, COALESCE(merged_array, '[]'::jsonb));
|
||||
|
||||
-- Otherwise, override wins
|
||||
ELSE
|
||||
result := result || jsonb_build_object(key, override_value);
|
||||
END IF;
|
||||
END IF;
|
||||
END LOOP;
|
||||
|
||||
RETURN result;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
COMMENT ON FUNCTION pipeline.jsonb_deep_merge(JSONB, JSONB) IS
|
||||
'Recursively merges two JSONB objects. Objects are merged recursively (override wins on conflicts).
|
||||
Arrays are unioned with dedup. Use {"__replace__": true, ...} to replace instead of merge.';
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- SECTION 4: RESOLVE PRIMITIVE CONFIG FUNCTION
|
||||
-- =============================================================================
|
||||
|
||||
-- Resolves primitive config by merging ancestor configs (general -> specific)
|
||||
CREATE OR REPLACE FUNCTION pipeline.resolve_primitive_config(
|
||||
p_path ltree
|
||||
) RETURNS JSONB AS $$
|
||||
DECLARE
|
||||
result JSONB := '{}';
|
||||
row_config JSONB;
|
||||
BEGIN
|
||||
-- Fetch all ancestor nodes (including self), ordered by level ASC (general -> specific)
|
||||
-- Uses @> operator: p_path is a descendant of (or equal to) the node's path
|
||||
FOR row_config IN
|
||||
SELECT primitive_configs
|
||||
FROM public.gbp_categories
|
||||
WHERE p_path <@ path -- p_path is descendant of or equal to path
|
||||
ORDER BY level ASC
|
||||
LOOP
|
||||
-- Skip NULL or empty configs
|
||||
IF row_config IS NOT NULL AND row_config != '{}' THEN
|
||||
result := pipeline.jsonb_deep_merge(result, row_config);
|
||||
END IF;
|
||||
END LOOP;
|
||||
|
||||
RETURN result;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql STABLE;
|
||||
|
||||
COMMENT ON FUNCTION pipeline.resolve_primitive_config(ltree) IS
|
||||
'Resolves the full primitive config for a category path by merging all ancestor configs from general to specific.';
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- SECTION 5: RESOLVE BUSINESS CONTEXT FUNCTION
|
||||
-- =============================================================================
|
||||
|
||||
-- Resolves business context by merging ancestor contexts (general -> specific)
|
||||
CREATE OR REPLACE FUNCTION pipeline.resolve_business_context(
|
||||
p_path ltree
|
||||
) RETURNS JSONB AS $$
|
||||
DECLARE
|
||||
result JSONB := '{}';
|
||||
row_context JSONB;
|
||||
BEGIN
|
||||
-- Fetch all ancestor nodes (including self), ordered by level ASC (general -> specific)
|
||||
FOR row_context IN
|
||||
SELECT business_context
|
||||
FROM public.gbp_categories
|
||||
WHERE p_path <@ path
|
||||
ORDER BY level ASC
|
||||
LOOP
|
||||
-- Skip NULL or empty contexts
|
||||
IF row_context IS NOT NULL AND row_context != '{}' THEN
|
||||
result := pipeline.jsonb_deep_merge(result, row_context);
|
||||
END IF;
|
||||
END LOOP;
|
||||
|
||||
RETURN result;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql STABLE;
|
||||
|
||||
COMMENT ON FUNCTION pipeline.resolve_business_context(ltree) IS
|
||||
'Resolves the full business context for a category path by merging all ancestor contexts from general to specific.';
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- SECTION 6: GET CLASSIFICATION CONTEXT FUNCTION
|
||||
-- =============================================================================
|
||||
|
||||
-- Returns complete classification context for a category path
|
||||
CREATE OR REPLACE FUNCTION pipeline.get_classification_context(
|
||||
p_path ltree
|
||||
) RETURNS JSONB AS $$
|
||||
DECLARE
|
||||
resolved_primitives JSONB;
|
||||
resolved_context JSONB;
|
||||
primitives_dict JSONB;
|
||||
BEGIN
|
||||
-- Resolve the primitive config for this path
|
||||
resolved_primitives := pipeline.resolve_primitive_config(p_path);
|
||||
|
||||
-- Resolve the business context for this path
|
||||
resolved_context := pipeline.resolve_business_context(p_path);
|
||||
|
||||
-- Build the primitives dictionary from the primitives table
|
||||
SELECT jsonb_object_agg(
|
||||
code,
|
||||
jsonb_build_object(
|
||||
'code', code,
|
||||
'dimension', dimension,
|
||||
'name', name,
|
||||
'definition', definition,
|
||||
'is_meta', is_meta,
|
||||
'base_positive_signals', COALESCE(to_jsonb(base_positive_signals), '[]'::jsonb),
|
||||
'base_negative_signals', COALESCE(to_jsonb(base_negative_signals), '[]'::jsonb)
|
||||
)
|
||||
)
|
||||
INTO primitives_dict
|
||||
FROM pipeline.primitives;
|
||||
|
||||
-- Handle case where primitives table is empty
|
||||
IF primitives_dict IS NULL THEN
|
||||
primitives_dict := '{}'::jsonb;
|
||||
END IF;
|
||||
|
||||
-- Return combined context object
|
||||
RETURN jsonb_build_object(
|
||||
'primitive_configs', resolved_primitives,
|
||||
'business_context', resolved_context,
|
||||
'primitives_dictionary', primitives_dict,
|
||||
'category_path', p_path::text,
|
||||
'resolved_at', NOW()
|
||||
);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql STABLE;
|
||||
|
||||
COMMENT ON FUNCTION pipeline.get_classification_context(ltree) IS
|
||||
'Returns complete classification context for a category path, including resolved primitive configs,
|
||||
business context, and the full primitives dictionary.';
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- SECTION 7: HELPER FUNCTION - GET ACTIVE PRIMITIVES
|
||||
-- =============================================================================
|
||||
|
||||
-- Returns the list of active primitive codes for a category path
|
||||
-- (includes meta primitives + enabled primitives from config)
|
||||
CREATE OR REPLACE FUNCTION pipeline.get_active_primitives(
|
||||
p_path ltree
|
||||
) RETURNS TEXT[] AS $$
|
||||
DECLARE
|
||||
resolved_config JSONB;
|
||||
active_codes TEXT[];
|
||||
meta_codes TEXT[];
|
||||
config_enabled TEXT[];
|
||||
config_disabled TEXT[];
|
||||
BEGIN
|
||||
-- Get resolved config
|
||||
resolved_config := pipeline.resolve_primitive_config(p_path);
|
||||
|
||||
-- Get all meta primitives (always active)
|
||||
SELECT array_agg(code)
|
||||
INTO meta_codes
|
||||
FROM pipeline.primitives
|
||||
WHERE is_meta = TRUE;
|
||||
|
||||
-- Get enabled primitives from config
|
||||
IF resolved_config ? 'enabled' THEN
|
||||
SELECT array_agg(elem::text)
|
||||
INTO config_enabled
|
||||
FROM jsonb_array_elements_text(resolved_config->'enabled') AS elem;
|
||||
END IF;
|
||||
|
||||
-- Get disabled primitives from config
|
||||
IF resolved_config ? 'disabled' THEN
|
||||
SELECT array_agg(elem::text)
|
||||
INTO config_disabled
|
||||
FROM jsonb_array_elements_text(resolved_config->'disabled') AS elem;
|
||||
END IF;
|
||||
|
||||
-- Combine: meta + enabled, minus disabled
|
||||
active_codes := COALESCE(meta_codes, ARRAY[]::TEXT[]) || COALESCE(config_enabled, ARRAY[]::TEXT[]);
|
||||
|
||||
-- Remove disabled primitives
|
||||
IF config_disabled IS NOT NULL THEN
|
||||
active_codes := array(
|
||||
SELECT unnest(active_codes)
|
||||
EXCEPT
|
||||
SELECT unnest(config_disabled)
|
||||
);
|
||||
END IF;
|
||||
|
||||
-- Remove duplicates
|
||||
active_codes := array(SELECT DISTINCT unnest(active_codes));
|
||||
|
||||
RETURN active_codes;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql STABLE;
|
||||
|
||||
COMMENT ON FUNCTION pipeline.get_active_primitives(ltree) IS
|
||||
'Returns array of active primitive codes for a category path (meta primitives + enabled - disabled).';
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- SECTION 8: SEED INITIAL PRIMITIVES (Examples)
|
||||
-- =============================================================================
|
||||
|
||||
-- Insert some example primitives (can be extended later)
|
||||
INSERT INTO pipeline.primitives (code, dimension, name, definition, is_meta, base_positive_signals, base_negative_signals)
|
||||
VALUES
|
||||
-- Meta primitives (always active)
|
||||
('HONESTY', 'trust', 'Honesty & Truthfulness', 'Whether the business is perceived as honest and truthful in their dealings', TRUE,
|
||||
ARRAY['honest', 'truthful', 'transparent', 'upfront', 'no hidden'],
|
||||
ARRAY['lied', 'dishonest', 'deceptive', 'misleading', 'hidden fees', 'bait and switch']),
|
||||
|
||||
('ETHICS', 'trust', 'Ethical Behavior', 'Whether the business behaves ethically and with integrity', TRUE,
|
||||
ARRAY['ethical', 'integrity', 'fair', 'principled', 'moral'],
|
||||
ARRAY['unethical', 'scam', 'fraud', 'cheat', 'ripoff', 'shady']),
|
||||
|
||||
('SAFETY', 'trust', 'Safety & Security', 'Whether customers feel safe and secure', TRUE,
|
||||
ARRAY['safe', 'secure', 'protected', 'trust'],
|
||||
ARRAY['unsafe', 'dangerous', 'security concern', 'risk', 'hazard']),
|
||||
|
||||
-- Quality dimension primitives
|
||||
('FOOD_TASTE', 'quality', 'Food Taste & Flavor', 'Quality and taste of food items', FALSE,
|
||||
ARRAY['delicious', 'tasty', 'flavorful', 'yummy', 'amazing taste', 'perfectly seasoned'],
|
||||
ARRAY['bland', 'tasteless', 'bad taste', 'over-seasoned', 'under-seasoned', 'disgusting']),
|
||||
|
||||
('FOOD_FRESHNESS', 'quality', 'Food Freshness', 'Freshness of ingredients and food items', FALSE,
|
||||
ARRAY['fresh', 'crisp', 'just made', 'homemade', 'organic'],
|
||||
ARRAY['stale', 'old', 'not fresh', 'frozen', 'reheated', 'expired']),
|
||||
|
||||
('FOOD_PORTION', 'quality', 'Portion Size', 'Size and quantity of food servings', FALSE,
|
||||
ARRAY['generous portions', 'large serving', 'filling', 'plenty of food'],
|
||||
ARRAY['small portions', 'tiny', 'not enough', 'skimpy', 'overpriced for size']),
|
||||
|
||||
('PRODUCT_QUALITY', 'quality', 'Product Quality', 'Overall quality of products', FALSE,
|
||||
ARRAY['high quality', 'well made', 'premium', 'durable', 'excellent quality'],
|
||||
ARRAY['poor quality', 'cheap', 'flimsy', 'broke easily', 'defective']),
|
||||
|
||||
-- Service dimension primitives
|
||||
('SERVICE_SPEED', 'service', 'Service Speed', 'Speed and timeliness of service', FALSE,
|
||||
ARRAY['fast', 'quick', 'prompt', 'efficient', 'no wait'],
|
||||
ARRAY['slow', 'long wait', 'took forever', 'delayed', 'waited too long']),
|
||||
|
||||
('SERVICE_FRIENDLINESS', 'service', 'Staff Friendliness', 'Friendliness and warmth of staff', FALSE,
|
||||
ARRAY['friendly', 'welcoming', 'warm', 'nice', 'pleasant', 'smiled'],
|
||||
ARRAY['rude', 'unfriendly', 'cold', 'dismissive', 'attitude', 'ignored']),
|
||||
|
||||
('SERVICE_KNOWLEDGE', 'service', 'Staff Knowledge', 'Knowledge and expertise of staff', FALSE,
|
||||
ARRAY['knowledgeable', 'expert', 'helpful advice', 'knew their stuff', 'professional'],
|
||||
ARRAY['clueless', 'didnt know', 'unhelpful', 'inexperienced', 'untrained']),
|
||||
|
||||
('SERVICE_ATTENTIVENESS', 'service', 'Staff Attentiveness', 'How attentive staff are to customer needs', FALSE,
|
||||
ARRAY['attentive', 'checked on us', 'responsive', 'available', 'proactive'],
|
||||
ARRAY['inattentive', 'ignored', 'couldnt find anyone', 'had to flag down', 'neglected']),
|
||||
|
||||
-- Environment dimension primitives
|
||||
('ENV_CLEANLINESS', 'environment', 'Cleanliness', 'Cleanliness of the establishment', FALSE,
|
||||
ARRAY['clean', 'spotless', 'tidy', 'well-maintained', 'hygienic'],
|
||||
ARRAY['dirty', 'filthy', 'messy', 'gross', 'sticky', 'unhygienic']),
|
||||
|
||||
('ENV_AMBIANCE', 'environment', 'Ambiance & Atmosphere', 'Overall atmosphere and vibe', FALSE,
|
||||
ARRAY['great atmosphere', 'nice ambiance', 'cozy', 'relaxing', 'beautiful decor'],
|
||||
ARRAY['bad atmosphere', 'uncomfortable', 'loud', 'cramped', 'depressing']),
|
||||
|
||||
('ENV_PARKING', 'environment', 'Parking Availability', 'Availability and convenience of parking', FALSE,
|
||||
ARRAY['easy parking', 'plenty of parking', 'free parking', 'valet available'],
|
||||
ARRAY['no parking', 'hard to park', 'paid parking', 'had to park far']),
|
||||
|
||||
-- Value dimension primitives
|
||||
('VALUE_PRICE', 'value', 'Price Level', 'Perception of price levels', FALSE,
|
||||
ARRAY['affordable', 'reasonable prices', 'cheap', 'good deal', 'budget-friendly'],
|
||||
ARRAY['expensive', 'overpriced', 'pricey', 'not worth the price', 'too costly']),
|
||||
|
||||
('VALUE_WORTH', 'value', 'Value for Money', 'Whether the experience is worth the cost', FALSE,
|
||||
ARRAY['worth it', 'great value', 'bang for buck', 'money well spent'],
|
||||
ARRAY['not worth it', 'waste of money', 'rip off', 'should be cheaper']),
|
||||
|
||||
-- Process dimension primitives
|
||||
('PROCESS_BOOKING', 'process', 'Booking & Reservations', 'Ease of making reservations or appointments', FALSE,
|
||||
ARRAY['easy to book', 'simple reservation', 'available appointments', 'online booking'],
|
||||
ARRAY['hard to book', 'no availability', 'complicated booking', 'had to call multiple times']),
|
||||
|
||||
('PROCESS_WAIT', 'process', 'Wait Times', 'Time spent waiting for service', FALSE,
|
||||
ARRAY['no wait', 'seated immediately', 'quick turnaround'],
|
||||
ARRAY['long wait', 'waited forever', 'always busy', 'need to wait in line']),
|
||||
|
||||
-- Resolution dimension primitives
|
||||
('RESOLUTION_RESPONSE', 'resolution', 'Problem Response', 'How problems and complaints are handled', FALSE,
|
||||
ARRAY['fixed the issue', 'made it right', 'apologized', 'took responsibility'],
|
||||
ARRAY['ignored complaint', 'didnt care', 'blamed me', 'no resolution', 'refused to help']),
|
||||
|
||||
-- Loyalty dimension primitives
|
||||
('LOYALTY_RETURN', 'loyalty', 'Return Intent', 'Whether customers intend to return', FALSE,
|
||||
ARRAY['will be back', 'coming back', 'regular customer', 'my go-to place'],
|
||||
ARRAY['never again', 'wont return', 'last time', 'not coming back']),
|
||||
|
||||
('LOYALTY_RECOMMEND', 'loyalty', 'Recommendation Intent', 'Whether customers would recommend to others', FALSE,
|
||||
ARRAY['highly recommend', 'tell everyone', 'bring friends', 'must try'],
|
||||
ARRAY['dont recommend', 'avoid', 'stay away', 'warned friends']),
|
||||
|
||||
-- Escape dimension primitives (when customers leave early or avoid)
|
||||
('ESCAPE_LEFT', 'escape', 'Early Departure', 'Whether customers left early or walked out', FALSE,
|
||||
ARRAY[]::TEXT[], -- No positive signals for escape
|
||||
ARRAY['walked out', 'left early', 'didnt finish', 'had to leave', 'couldnt stay'])
|
||||
|
||||
ON CONFLICT (code) DO UPDATE SET
|
||||
dimension = EXCLUDED.dimension,
|
||||
name = EXCLUDED.name,
|
||||
definition = EXCLUDED.definition,
|
||||
is_meta = EXCLUDED.is_meta,
|
||||
base_positive_signals = EXCLUDED.base_positive_signals,
|
||||
base_negative_signals = EXCLUDED.base_negative_signals;
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- SECTION 9: EXAMPLE CATEGORY CONFIGS
|
||||
-- =============================================================================
|
||||
|
||||
-- Example: Set primitive config for Food & Dining sector (level 1)
|
||||
-- This would enable food-related primitives for all food businesses
|
||||
UPDATE public.gbp_categories
|
||||
SET
|
||||
primitive_configs = '{
|
||||
"enabled": ["FOOD_TASTE", "FOOD_FRESHNESS", "FOOD_PORTION", "SERVICE_SPEED", "SERVICE_FRIENDLINESS", "ENV_CLEANLINESS", "ENV_AMBIANCE", "VALUE_PRICE", "VALUE_WORTH", "PROCESS_WAIT"],
|
||||
"weights": {
|
||||
"FOOD_TASTE": 1.5,
|
||||
"FOOD_FRESHNESS": 1.3,
|
||||
"SERVICE_SPEED": 1.2
|
||||
}
|
||||
}'::jsonb,
|
||||
business_context = '{
|
||||
"terminology": {
|
||||
"staff": ["server", "waiter", "waitress", "host", "hostess", "bartender"],
|
||||
"product": ["food", "dish", "meal", "appetizer", "entree", "dessert", "drink"]
|
||||
},
|
||||
"industry": "food_service"
|
||||
}'::jsonb,
|
||||
config_version = 'v1.0.0',
|
||||
config_generated_by = 'migration_014',
|
||||
config_updated_at = NOW()
|
||||
WHERE slug = 'food_dining' AND level = 1;
|
||||
|
||||
-- Example: Override config for Restaurants (level 2) - adds more specific settings
|
||||
UPDATE public.gbp_categories
|
||||
SET
|
||||
primitive_configs = '{
|
||||
"enabled": ["PROCESS_BOOKING", "ENV_PARKING"],
|
||||
"weights": {
|
||||
"PROCESS_WAIT": 1.3
|
||||
},
|
||||
"signals": {
|
||||
"FOOD_TASTE": {
|
||||
"positive": ["perfectly cooked", "chef special", "signature dish"],
|
||||
"negative": ["undercooked", "overcooked", "cold food"]
|
||||
}
|
||||
}
|
||||
}'::jsonb,
|
||||
business_context = '{
|
||||
"terminology": {
|
||||
"staff": ["chef", "cook", "sous chef", "kitchen staff"]
|
||||
},
|
||||
"typical_visit_duration": "1-2 hours",
|
||||
"reservation_common": true
|
||||
}'::jsonb,
|
||||
config_version = 'v1.0.0',
|
||||
config_generated_by = 'migration_014',
|
||||
config_updated_at = NOW()
|
||||
WHERE slug = 'restaurants' AND level = 2;
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- VERIFICATION QUERIES (can be removed in production)
|
||||
-- =============================================================================
|
||||
|
||||
-- Verify primitives table
|
||||
DO $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'Primitives table created with % rows', (SELECT COUNT(*) FROM pipeline.primitives);
|
||||
END $$;
|
||||
|
||||
-- Verify functions exist
|
||||
DO $$
|
||||
BEGIN
|
||||
-- Test jsonb_deep_merge
|
||||
ASSERT pipeline.jsonb_deep_merge('{"a": 1}'::jsonb, '{"b": 2}'::jsonb) = '{"a": 1, "b": 2}'::jsonb,
|
||||
'jsonb_deep_merge basic test failed';
|
||||
|
||||
-- Test __replace__ flag
|
||||
ASSERT pipeline.jsonb_deep_merge('{"a": {"x": 1, "y": 2}}'::jsonb, '{"a": {"__replace__": true, "z": 3}}'::jsonb) = '{"a": {"z": 3}}'::jsonb,
|
||||
'jsonb_deep_merge __replace__ test failed';
|
||||
|
||||
RAISE NOTICE 'All function tests passed';
|
||||
END $$;
|
||||
29
migrations/versions/015_add_business_info_columns.sql
Normal file
29
migrations/versions/015_add_business_info_columns.sql
Normal file
@@ -0,0 +1,29 @@
|
||||
-- Migration: Add dedicated columns for business info
|
||||
-- Purpose: Move business data from metadata JSONB to queryable/indexable columns
|
||||
-- Date: 2026-01-31
|
||||
|
||||
-- Add business info columns
|
||||
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS business_name VARCHAR(500);
|
||||
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS business_category VARCHAR(255);
|
||||
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS business_address TEXT;
|
||||
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS business_rating NUMERIC(3,2);
|
||||
|
||||
-- Add indexes for common queries
|
||||
CREATE INDEX IF NOT EXISTS idx_jobs_business_name ON jobs(business_name);
|
||||
CREATE INDEX IF NOT EXISTS idx_jobs_business_category ON jobs(business_category);
|
||||
CREATE INDEX IF NOT EXISTS idx_jobs_business_rating ON jobs(business_rating);
|
||||
|
||||
-- Migrate existing data from metadata JSONB to new columns
|
||||
UPDATE jobs SET
|
||||
business_name = metadata->>'business_name',
|
||||
business_address = metadata->>'business_address',
|
||||
business_rating = CASE
|
||||
WHEN metadata->>'rating_snapshot' IS NOT NULL
|
||||
THEN (metadata->>'rating_snapshot')::NUMERIC(3,2)
|
||||
ELSE NULL
|
||||
END
|
||||
WHERE metadata IS NOT NULL
|
||||
AND (business_name IS NULL OR business_address IS NULL OR business_rating IS NULL);
|
||||
|
||||
-- Clean up metadata: remove migrated fields (optional - keeps metadata for performance metrics only)
|
||||
-- Note: We keep the data in metadata for backward compatibility, but new code should use columns
|
||||
22
migrations/versions/016_add_gbp_category_resolution.sql
Normal file
22
migrations/versions/016_add_gbp_category_resolution.sql
Normal file
@@ -0,0 +1,22 @@
|
||||
-- Migration: Add resolved GBP category columns to jobs table
|
||||
-- Purpose: Store the matched taxonomy path for classification context
|
||||
-- Date: 2026-01-31
|
||||
|
||||
-- Add ltree extension if not exists
|
||||
CREATE EXTENSION IF NOT EXISTS ltree;
|
||||
|
||||
-- Add resolved category columns
|
||||
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS gbp_category_id INTEGER REFERENCES gbp_categories(id);
|
||||
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS gbp_category_path ltree;
|
||||
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS category_resolution_method VARCHAR(20); -- 'exact', 'fuzzy', 'llm', 'hierarchical'
|
||||
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS business_category_source VARCHAR(20); -- 'google' or 'inferred'
|
||||
|
||||
-- Index for fast lookups by category path
|
||||
CREATE INDEX IF NOT EXISTS idx_jobs_gbp_category_path ON jobs USING GIST (gbp_category_path);
|
||||
CREATE INDEX IF NOT EXISTS idx_jobs_gbp_category_id ON jobs(gbp_category_id);
|
||||
|
||||
-- Comment on columns
|
||||
COMMENT ON COLUMN jobs.gbp_category_id IS 'FK to gbp_categories - the resolved deepest taxonomy node';
|
||||
COMMENT ON COLUMN jobs.gbp_category_path IS 'ltree path for the resolved category (e.g., Retail.Stores.Toy_store)';
|
||||
COMMENT ON COLUMN jobs.category_resolution_method IS 'How category was resolved: exact (from Google), fuzzy (trigram match), llm (LLM matched), hierarchical (LLM walked tree)';
|
||||
COMMENT ON COLUMN jobs.business_category_source IS 'Where business category originated: google (scraped from Maps) or inferred (LLM inferred from name)';
|
||||
Reference in New Issue
Block a user