Add Redis caching for lookup data and admin cache management

- Add lookup-specific cache keys and methods to CacheService
- Add cache refresh on lookup CRUD operations in AdminLookupHandler
- Add Redis caching after seed-lookups in AdminSettingsHandler
- Add ETag generation for seeded data to support client-side caching
- Update task template handler with cache invalidation
- Fix route for clear-cache endpoint

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-05 22:35:09 -06:00
parent 1b06c0639c
commit 91a1f7ebed
8 changed files with 856 additions and 100 deletions

View File

@@ -9,86 +9,86 @@
-- 1 = Once, 2 = Daily, 3 = Weekly, 4 = Bi-Weekly, 5 = Monthly
-- 6 = Quarterly, 7 = Semi-Annually, 8 = Annually
-- Task Templates
-- Task Templates from adam_task list
INSERT INTO task_tasktemplate (id, created_at, updated_at, title, description, category_id, frequency_id, icon_ios, icon_android, tags, display_order, is_active)
VALUES
-- PLUMBING (category_id = 9)
(1, NOW(), NOW(), 'Check/Replace Water Heater Anode Rod', 'Inspect anode rod for corrosion and replace if more than 50% depleted', 9, 8, 'wrench.and.screwdriver.fill', 'Build', 'water heater,anode,corrosion,tank', 1, true),
(2, NOW(), NOW(), 'Test Interior Water Shutoffs', 'Turn each shutoff valve to ensure it works properly', 9, 8, 'spigot.fill', 'Water', 'shutoff,valve,water,emergency', 2, true),
(3, NOW(), NOW(), 'Test Water Meter Shutoff', 'Ensure main water shutoff at meter is functional', 9, 8, 'gauge.with.dots.needle.33percent', 'Speed', 'meter,shutoff,main,emergency', 3, true),
(4, NOW(), NOW(), 'Check Water Meter for Leaks', 'Turn off all water and check if meter is still moving', 9, 5, 'drop.triangle.fill', 'WaterDrop', 'leak,meter,water,detection', 4, true),
(5, NOW(), NOW(), 'Run Drain Cleaner', 'Use enzyme-based drain cleaner to prevent clogs', 9, 5, 'arrow.down.to.line.circle.fill', 'VerticalAlignBottom', 'drain,clog,cleaner,pipes', 5, true),
(6, NOW(), NOW(), 'Test Water Heater Pressure Relief Valve', 'Lift lever to release some water and ensure valve works', 9, 8, 'bolt.horizontal.fill', 'Compress', 'water heater,pressure,safety,valve', 6, true),
(7, NOW(), NOW(), 'Replace Water Filters', 'Replace whole-house or point-of-use water filters', 9, 6, 'drop.fill', 'Water', 'filter,water,replacement,drinking', 7, true),
(3, NOW(), NOW(), 'Test Gas Shutoffs', 'Verify gas shutoff valves operate correctly', 9, 8, 'flame.fill', 'LocalGasStation', 'gas,shutoff,valve,safety', 3, true),
(4, NOW(), NOW(), 'Test Water Meter Shutoff', 'Ensure main water shutoff at meter is functional', 9, 8, 'gauge.with.dots.needle.33percent', 'Speed', 'meter,shutoff,main,emergency', 4, true),
(5, NOW(), NOW(), 'Check Water Meter for Leaks', 'Turn off all water and check if meter is still moving', 9, 5, 'drop.triangle.fill', 'WaterDrop', 'leak,meter,water,detection', 5, true),
(6, NOW(), NOW(), 'Run Drain Cleaner', 'Use enzyme-based drain cleaner to prevent clogs', 9, 5, 'arrow.down.to.line.circle.fill', 'VerticalAlignBottom', 'drain,clog,cleaner,pipes', 6, true),
(7, NOW(), NOW(), 'Test Water Heater Pressure Relief Valve', 'Lift lever to release some water and ensure valve works', 9, 8, 'bolt.horizontal.fill', 'Compress', 'water heater,pressure,safety,valve', 7, true),
(8, NOW(), NOW(), 'Replace Water Filters', 'Replace whole-house or point-of-use water filters', 9, 6, 'drop.fill', 'Water', 'filter,water,replacement,drinking', 8, true),
(9, NOW(), NOW(), 'Flush Water Heater', 'Drain sediment from bottom of tank', 9, 6, 'drop.degreesign.fill', 'WaterDamage', 'water heater,sediment,flush,maintenance', 9, true),
(10, NOW(), NOW(), 'Inspect for Leaks', 'Check under sinks and around toilets for water damage', 9, 5, 'exclamationmark.triangle.fill', 'Warning', 'leak,inspection,water damage,plumbing', 10, true),
(11, NOW(), NOW(), 'Inspect Caulking', 'Check bathroom and kitchen caulk for cracks or mold', 9, 5, 'seal.fill', 'LineWeight', 'caulk,bathroom,kitchen,seal', 11, true),
(12, NOW(), NOW(), 'Septic Tank Inspection', 'Have septic system inspected and pumped if needed', 9, 8, 'arrow.down.to.line.circle.fill', 'VerticalAlignBottom', 'septic,tank,pump,inspection', 12, true),
(13, NOW(), NOW(), 'Winterize Outdoor Faucets', 'Shut off water supply and drain lines before freeze', 9, 8, 'snowflake', 'AcUnit', 'winterize,faucet,freeze,outdoor', 13, true),
(14, NOW(), NOW(), 'Replace Fridge Water Line', 'Replace refrigerator water supply hose', 9, 8, 'refrigerator.fill', 'Kitchen', 'refrigerator,hose,water line,replacement', 14, true),
(15, NOW(), NOW(), 'Replace Laundry Hoses', 'Replace washing machine supply hoses to prevent flooding', 9, 8, 'washer.fill', 'LocalLaundryService', 'laundry,hoses,washing machine,flood prevention', 15, true),
(16, NOW(), NOW(), 'Test Water Sensors', 'Test water leak sensors and replace batteries', 9, 6, 'sensor.tag.radiowaves.forward.fill', 'Sensors', 'water sensor,leak detection,battery,test', 16, true),
-- SAFETY (category_id = 10)
(8, NOW(), NOW(), 'Test Smoke Detectors', 'Press test button on each detector and replace batteries if needed', 10, 5, 'smoke.fill', 'Sensors', 'smoke,detector,safety,fire', 8, true),
(9, NOW(), NOW(), 'Test Carbon Monoxide Detectors', 'Press test button and verify alarm sounds', 10, 5, 'sensor.tag.radiowaves.forward.fill', 'Air', 'carbon monoxide,detector,safety,gas', 9, true),
(10, NOW(), NOW(), 'Inspect Fire Extinguisher', 'Check pressure gauge and ensure pin is intact', 10, 8, 'flame.fill', 'LocalFireDepartment', 'fire,extinguisher,safety,inspection', 10, true),
(11, NOW(), NOW(), 'Replace Smoke Detector Batteries', 'Replace batteries in all smoke and CO detectors', 10, 8, 'battery.100', 'Battery5Bar', 'battery,smoke,detector,safety', 11, true),
(12, NOW(), NOW(), 'Test GFCI Outlets', 'Press test/reset buttons on all GFCI outlets', 10, 5, 'poweroutlet.type.b', 'ElectricalServices', 'gfci,outlet,safety,electrical', 12, true),
(13, NOW(), NOW(), 'Check Emergency Exits', 'Verify all exits are clear and doors open freely', 10, 6, 'door.left.hand.open', 'DoorFront', 'emergency,exit,safety,door', 13, true),
(17, NOW(), NOW(), 'Test Smoke and Carbon Monoxide Detectors', 'Press test button on each detector and verify alarm sounds', 10, 5, 'smoke.fill', 'Sensors', 'smoke,carbon monoxide,detector,safety,fire', 17, true),
(18, NOW(), NOW(), 'Check Fire Extinguishers', 'Check pressure gauge and ensure accessibility', 10, 6, 'flame.fill', 'LocalFireDepartment', 'fire,extinguisher,safety,inspection', 18, true),
(19, NOW(), NOW(), 'Replace Smoke and CO Detector Batteries', 'Replace batteries in all smoke and CO detectors', 10, 7, 'battery.100', 'Battery5Bar', 'battery,smoke,detector,safety', 19, true),
(20, NOW(), NOW(), 'Replace Smoke and CO Detectors', 'Replace detectors every 10 years or as recommended', 10, 8, 'smoke.fill', 'Sensors', 'smoke,carbon monoxide,replacement,safety', 20, true),
(21, NOW(), NOW(), 'Test GFCI Outlets', 'Press test/reset buttons on all GFCI outlets', 10, 5, 'poweroutlet.type.b', 'ElectricalServices', 'gfci,outlet,safety,electrical', 21, true),
(22, NOW(), NOW(), 'Schedule Chimney Cleaning', 'Professional chimney inspection and cleaning before heating season', 10, 8, 'flame.fill', 'Fireplace', 'chimney,fireplace,cleaning,inspection', 22, true),
(23, NOW(), NOW(), 'Termite Inspection', 'Professional inspection for wood-destroying insects', 10, 8, 'ant.fill', 'BugReport', 'termite,pest,inspection,wood damage', 23, true),
(24, NOW(), NOW(), 'Pest Control Treatment', 'Inspect for signs of pests; treat or call professional', 10, 6, 'ant.fill', 'BugReport', 'pest,control,inspection,treatment', 24, true),
(25, NOW(), NOW(), 'Check/Charge Security Cameras', 'Ensure wireless cameras are functioning and charged', 10, 3, 'video.fill', 'Videocam', 'security,camera,battery,charge', 25, true),
-- HVAC (category_id = 6)
(14, NOW(), NOW(), 'Replace HVAC Filter', 'Replace air filter to maintain air quality and efficiency', 6, 5, 'air.purifier', 'Air', 'hvac,filter,air,replacement', 14, true),
(15, NOW(), NOW(), 'Clean AC Condensate Drain', 'Clear drain line to prevent clogs and water damage', 6, 6, 'drop.degreesign.fill', 'WaterDamage', 'ac,condensate,drain,clog', 15, true),
(16, NOW(), NOW(), 'Schedule HVAC Service', 'Annual professional maintenance for heating and cooling system', 6, 8, 'wrench.and.screwdriver', 'Build', 'hvac,service,maintenance,professional', 16, true),
(17, NOW(), NOW(), 'Clean Air Vents and Registers', 'Remove dust and debris from all vents', 6, 6, 'wind', 'AirPurifier', 'vent,register,dust,cleaning', 17, true),
(18, NOW(), NOW(), 'Test Thermostat', 'Verify thermostat accurately controls heating and cooling', 6, 7, 'thermometer.sun.fill', 'Thermostat', 'thermostat,hvac,test,calibration', 18, true),
(19, NOW(), NOW(), 'Inspect Ductwork', 'Check for leaks, damage, or disconnected sections', 6, 8, 'rectangle.3.group', 'Hvac', 'duct,ductwork,leak,inspection', 19, true),
(20, NOW(), NOW(), 'Clean Outdoor AC Unit', 'Remove debris and clean condenser coils', 6, 8, 'fan', 'WindPower', 'ac,condenser,outdoor,cleaning', 20, true),
(21, NOW(), NOW(), 'Check Refrigerant Levels', 'Have professional check AC refrigerant', 6, 8, 'snowflake', 'AcUnit', 'refrigerant,ac,freon,professional', 21, true),
(22, NOW(), NOW(), 'Inspect Heat Pump', 'Check heat pump operation and clean coils', 6, 7, 'heat.waves', 'HeatPump', 'heat pump,inspection,coils,maintenance', 22, true),
(26, NOW(), NOW(), 'Change HVAC Filters', 'Replace air conditioning/furnace filters for efficiency', 6, 5, 'air.purifier', 'Air', 'hvac,filter,air,replacement', 26, true),
(27, NOW(), NOW(), 'Flush HVAC Drain Lines', 'Clear condensate drain line to prevent clogs and water damage', 6, 6, 'drop.degreesign.fill', 'WaterDamage', 'hvac,condensate,drain,clog', 27, true),
(28, NOW(), NOW(), 'Clean Return Vents', 'Remove dust and debris from return air vents', 6, 6, 'wind', 'AirPurifier', 'vent,return,dust,cleaning', 28, true),
(29, NOW(), NOW(), 'Clean Floor Registers', 'Remove and clean floor heating/cooling registers', 6, 6, 'rectangle.grid.1x2.fill', 'GridOn', 'register,floor,vent,cleaning', 29, true),
(30, NOW(), NOW(), 'Clean HVAC Compressor Coils', 'Clean outdoor AC unit condenser coils', 6, 8, 'fan', 'WindPower', 'ac,condenser,coils,outdoor,cleaning', 30, true),
(31, NOW(), NOW(), 'Schedule HVAC Inspection and Service', 'Professional maintenance for heating and cooling system', 6, 7, 'wrench.and.screwdriver', 'Build', 'hvac,service,maintenance,professional', 31, true),
-- APPLIANCES (category_id = 1)
(23, NOW(), NOW(), 'Clean Refrigerator Coils', 'Vacuum condenser coils to improve efficiency', 1, 7, 'refrigerator.fill', 'Kitchen', 'refrigerator,coils,cleaning,efficiency', 23, true),
(24, NOW(), NOW(), 'Clean Dishwasher Filter', 'Remove and clean the dishwasher filter', 1, 5, 'dishwasher.fill', 'LocalLaundryService', 'dishwasher,filter,cleaning', 24, true),
(25, NOW(), NOW(), 'Clean Washing Machine', 'Run cleaning cycle or use washing machine cleaner', 1, 5, 'washer.fill', 'LocalLaundryService', 'washing machine,cleaning,maintenance', 25, true),
(26, NOW(), NOW(), 'Clean Dryer Vent', 'Clean lint from dryer vent and ductwork', 1, 8, 'dryer.fill', 'LocalLaundryService', 'dryer,vent,lint,fire hazard', 26, true),
(27, NOW(), NOW(), 'Clean Range Hood Filter', 'Remove and clean grease filter', 1, 6, 'stove.fill', 'Microwave', 'range hood,filter,grease,cleaning', 27, true),
(28, NOW(), NOW(), 'Descale Coffee Maker', 'Run descaling solution through coffee maker', 1, 5, 'cup.and.saucer.fill', 'Coffee', 'coffee,descale,cleaning,appliance', 28, true),
(29, NOW(), NOW(), 'Clean Garbage Disposal', 'Clean and deodorize garbage disposal', 1, 5, 'trash.fill', 'Delete', 'garbage disposal,cleaning,deodorize', 29, true),
(30, NOW(), NOW(), 'Clean Oven', 'Run self-clean cycle or manually clean oven', 1, 6, 'oven.fill', 'Microwave', 'oven,cleaning,grease', 30, true),
(31, NOW(), NOW(), 'Check Refrigerator Seals', 'Inspect door gaskets for cracks or gaps', 1, 7, 'seal.fill', 'DoorSliding', 'refrigerator,seal,gasket,inspection', 31, true),
(32, NOW(), NOW(), 'Clean Microwave', 'Clean interior and exterior of microwave', 1, 5, 'microwave.fill', 'Microwave', 'microwave,cleaning,appliance', 32, true),
(33, NOW(), NOW(), 'Clean Toaster', 'Empty crumb tray and clean toaster interior', 1, 5, 'rectangle.fill', 'BreakfastDining', 'toaster,cleaning,crumbs,appliance', 33, true),
(34, NOW(), NOW(), 'Clean Garbage Disposal', 'Run ice cubes and lemon peels to clean and deodorize', 1, 5, 'trash.fill', 'Delete', 'garbage disposal,cleaning,deodorize', 34, true),
(35, NOW(), NOW(), 'Clean Oven', 'Run self-clean cycle or manually clean oven interior', 1, 6, 'oven.fill', 'Microwave', 'oven,cleaning,grease', 35, true),
(36, NOW(), NOW(), 'Clean Refrigerator Coils', 'Vacuum dust from condenser coils for efficiency', 1, 6, 'refrigerator.fill', 'Kitchen', 'refrigerator,coils,cleaning,efficiency', 36, true),
(37, NOW(), NOW(), 'Clean Dishwasher Filter', 'Remove and clean the dishwasher food trap/filter', 1, 5, 'dishwasher.fill', 'LocalLaundryService', 'dishwasher,filter,cleaning', 37, true),
(38, NOW(), NOW(), 'Clean Vent Hood Filters', 'Soak and scrub range hood filters to remove grease', 1, 5, 'stove.fill', 'Microwave', 'range hood,filter,grease,cleaning', 38, true),
(39, NOW(), NOW(), 'Clean Dryer Vent', 'Remove lint buildup from dryer vent and ductwork to prevent fires', 1, 7, 'dryer.fill', 'LocalLaundryService', 'dryer,vent,lint,fire hazard', 39, true),
-- CLEANING (category_id = 2)
(40, NOW(), NOW(), 'Wipe Kitchen Counters', 'Clean countertops and stovetop after cooking', 2, 2, 'sparkles', 'CleaningServices', 'kitchen,counters,stovetop,cleaning', 40, true),
(41, NOW(), NOW(), 'Take Out Trash', 'Empty full trash cans to prevent odors and pests', 2, 2, 'trash.fill', 'Delete', 'trash,garbage,disposal', 41, true),
(42, NOW(), NOW(), 'Vacuum Floors', 'Vacuum all carpets and rugs, especially high-traffic areas', 2, 3, 'rectangle.and.hand.point.up.left.fill', 'Carpet', 'vacuum,floors,carpet,cleaning', 42, true),
(43, NOW(), NOW(), 'Mop Hard Floors', 'Mop tile, hardwood, and laminate floors', 2, 3, 'square.grid.3x3.fill', 'CleaningServices', 'mop,floors,tile,hardwood', 43, true),
(44, NOW(), NOW(), 'Clean Bathrooms', 'Scrub toilets, sinks, showers, and mirrors', 2, 3, 'shower.fill', 'Bathroom', 'bathroom,toilet,shower,cleaning', 44, true),
(45, NOW(), NOW(), 'Change Bed Linens', 'Wash and replace sheets, pillowcases, and mattress covers', 2, 3, 'bed.double.fill', 'Bed', 'bed,linens,sheets,laundry', 45, true),
(46, NOW(), NOW(), 'Do Laundry', 'Wash, dry, fold, and put away clothes', 2, 3, 'washer.fill', 'LocalLaundryService', 'laundry,clothes,washing', 46, true),
(47, NOW(), NOW(), 'Clean Kitchen Appliances', 'Wipe down microwave, dishwasher exterior, coffee maker', 2, 3, 'refrigerator.fill', 'Kitchen', 'kitchen,appliances,cleaning,exterior', 47, true),
(48, NOW(), NOW(), 'Dust Surfaces', 'Dust furniture, shelves, and decorations', 2, 3, 'sparkles', 'CleaningServices', 'dust,furniture,shelves,cleaning', 48, true),
(49, NOW(), NOW(), 'Clean Out Refrigerator', 'Discard expired food and wipe down shelves', 2, 3, 'refrigerator.fill', 'Kitchen', 'refrigerator,cleaning,expired food', 49, true),
(50, NOW(), NOW(), 'Clean Vacuum', 'Empty canister, clean filters, and check for clogs', 2, 5, 'rectangle.and.hand.point.up.left.fill', 'Carpet', 'vacuum,maintenance,filter,cleaning', 50, true),
(51, NOW(), NOW(), 'Clean Bathroom Exhaust Fans', 'Remove covers and clean dust from exhaust fans', 2, 6, 'fan.fill', 'WindPower', 'bathroom,exhaust,fan,cleaning', 51, true),
(52, NOW(), NOW(), 'Vacuum Under Furniture', 'Move furniture to vacuum underneath, especially beds', 2, 5, 'rectangle.and.hand.point.up.left.fill', 'Carpet', 'vacuum,furniture,deep clean', 52, true),
(53, NOW(), NOW(), 'Clean Inside Trash Cans', 'Wash and disinfect garbage and recycling bins', 2, 5, 'trash.fill', 'Delete', 'trash can,cleaning,disinfect', 53, true),
(54, NOW(), NOW(), 'Clean Window Tracks', 'Remove dirt and debris from window and door tracks', 2, 6, 'window.horizontal', 'Window', 'window,tracks,cleaning,debris', 54, true),
(55, NOW(), NOW(), 'Deep Clean Carpets', 'Professional carpet cleaning or DIY steam clean', 2, 7, 'rectangle.and.hand.point.up.left.fill', 'Carpet', 'carpet,deep clean,steam,professional', 55, true),
(56, NOW(), NOW(), 'Clean and Reverse Ceiling Fans', 'Clean fan blades and reverse direction for season', 2, 7, 'fanblades.fill', 'WindPower', 'ceiling fan,cleaning,seasonal,direction', 56, true),
-- EXTERIOR (category_id = 4)
(32, NOW(), NOW(), 'Clean Gutters', 'Remove leaves and debris from gutters and downspouts', 4, 7, 'house.fill', 'Roofing', 'gutter,cleaning,leaves,debris', 32, true),
(33, NOW(), NOW(), 'Inspect Roof', 'Check for damaged, missing, or loose shingles', 4, 8, 'house.circle.fill', 'Roofing', 'roof,shingles,inspection,damage', 33, true),
(34, NOW(), NOW(), 'Power Wash Exterior', 'Clean siding, walkways, and driveway', 4, 8, 'water.waves', 'CleaningServices', 'power wash,siding,driveway,cleaning', 34, true),
(35, NOW(), NOW(), 'Seal Driveway', 'Apply sealant to asphalt or concrete driveway', 4, 8, 'road.lanes', 'RoundaboutRight', 'driveway,seal,asphalt,concrete', 35, true),
(36, NOW(), NOW(), 'Inspect Foundation', 'Check for cracks or signs of settling', 4, 8, 'building.2.fill', 'Foundation', 'foundation,cracks,inspection,settling', 36, true),
(37, NOW(), NOW(), 'Clean Window Exteriors', 'Wash exterior window surfaces', 4, 7, 'window.horizontal', 'Window', 'window,exterior,cleaning,glass', 37, true),
(38, NOW(), NOW(), 'Inspect Deck/Patio', 'Check for rot, loose boards, or damage', 4, 8, 'rectangle.split.3x1.fill', 'Deck', 'deck,patio,inspection,rot', 38, true),
(39, NOW(), NOW(), 'Stain/Seal Deck', 'Apply stain or sealant to protect wood deck', 4, 8, 'paintbrush.fill', 'FormatPaint', 'deck,stain,seal,wood', 39, true),
-- LAWN & GARDEN (category_id = 4, but could be General category = 5)
(40, NOW(), NOW(), 'Mow Lawn', 'Cut grass to appropriate height', 4, 3, 'leaf.fill', 'Grass', 'lawn,mowing,grass,yard', 40, true),
(41, NOW(), NOW(), 'Trim Trees/Shrubs', 'Prune overgrown branches and shape shrubs', 4, 8, 'tree.fill', 'Park', 'tree,shrub,pruning,trimming', 41, true),
(42, NOW(), NOW(), 'Fertilize Lawn', 'Apply seasonal fertilizer to lawn', 4, 6, 'drop.fill', 'Opacity', 'fertilizer,lawn,grass,seasonal', 42, true),
(43, NOW(), NOW(), 'Aerate Lawn', 'Aerate soil to improve grass health', 4, 8, 'square.grid.3x3.fill', 'GridOn', 'aerate,lawn,soil,grass', 43, true),
(44, NOW(), NOW(), 'Winterize Irrigation', 'Blow out sprinkler lines before winter', 4, 8, 'snowflake', 'AcUnit', 'irrigation,sprinkler,winterize,freeze', 44, true),
(45, NOW(), NOW(), 'Mulch Garden Beds', 'Add fresh mulch to garden beds', 4, 8, 'leaf.fill', 'Forest', 'mulch,garden,beds,landscaping', 45, true),
-- ELECTRICAL (category_id = 3)
(46, NOW(), NOW(), 'Test Surge Protectors', 'Check indicator lights on surge protectors', 3, 8, 'bolt.fill', 'ElectricBolt', 'surge,protector,electrical,safety', 46, true),
(47, NOW(), NOW(), 'Check Circuit Breaker Panel', 'Inspect for signs of damage or overheating', 3, 8, 'bolt.square.fill', 'ElectricalServices', 'circuit,breaker,panel,inspection', 47, true),
(48, NOW(), NOW(), 'Replace Outdoor Light Bulbs', 'Check and replace burned out exterior lights', 3, 6, 'lightbulb.fill', 'LightbulbOutline', 'light,bulb,outdoor,replacement', 48, true),
(49, NOW(), NOW(), 'Test Outdoor Lighting Timer', 'Verify timer settings and functionality', 3, 7, 'clock.fill', 'Schedule', 'timer,lighting,outdoor,test', 49, true),
-- INTERIOR (category_id = 7)
(50, NOW(), NOW(), 'Deep Clean Carpets', 'Steam clean or shampoo carpets', 7, 8, 'rectangle.and.hand.point.up.left.fill', 'Carpet', 'carpet,cleaning,steam,deep clean', 50, true),
(51, NOW(), NOW(), 'Clean Window Interiors', 'Wash interior window surfaces and tracks', 7, 6, 'window.horizontal', 'Window', 'window,interior,cleaning,tracks', 51, true),
(52, NOW(), NOW(), 'Check Caulking', 'Inspect and repair caulk around tubs, showers, sinks', 7, 8, 'sealant.fill', 'LineWeight', 'caulk,bathroom,kitchen,seal', 52, true),
(53, NOW(), NOW(), 'Lubricate Door Hinges', 'Apply lubricant to squeaky hinges', 7, 8, 'door.left.hand.closed', 'MeetingRoom', 'door,hinge,lubricant,squeak', 53, true),
(54, NOW(), NOW(), 'Touch Up Paint', 'Fix scuffs and marks on walls', 7, 8, 'paintbrush.fill', 'ImagesearchRoller', 'paint,walls,touch up,scuffs', 54, true),
(55, NOW(), NOW(), 'Replace Air Fresheners', 'Change out air fresheners throughout home', 7, 5, 'wind', 'Air', 'air freshener,scent,home,fragrance', 55, true),
-- SEASONAL (category_id = 5 General)
(56, NOW(), NOW(), 'Reverse Ceiling Fan Direction', 'Change rotation for heating vs cooling season', 5, 7, 'fanblades.fill', 'WindPower', 'ceiling fan,direction,seasonal,hvac', 56, true),
(57, NOW(), NOW(), 'Store/Retrieve Seasonal Items', 'Rotate seasonal decorations and equipment', 5, 7, 'archivebox.fill', 'Archive', 'seasonal,storage,decorations,rotation', 57, true),
(58, NOW(), NOW(), 'Check Weather Stripping', 'Inspect and replace worn weather stripping on doors/windows', 5, 8, 'wind', 'Air', 'weather stripping,door,window,insulation', 58, true),
(59, NOW(), NOW(), 'Service Snow Blower', 'Prepare snow blower for winter season', 5, 8, 'snowflake', 'AcUnit', 'snow blower,service,winter,maintenance', 59, true),
(60, NOW(), NOW(), 'Service Lawn Mower', 'Change oil, sharpen blade, replace spark plug', 5, 8, 'leaf.fill', 'Grass', 'lawn mower,service,maintenance,spring', 60, true)
(57, NOW(), NOW(), 'Clean Gutters', 'Remove leaves and debris; check for proper drainage', 4, 7, 'house.fill', 'Roofing', 'gutter,cleaning,leaves,debris', 57, true),
(58, NOW(), NOW(), 'Wash Windows', 'Clean interior and exterior glass and screens', 4, 7, 'window.horizontal', 'Window', 'window,cleaning,glass,screens', 58, true),
(59, NOW(), NOW(), 'Inspect Roof', 'Look for missing shingles, damage, or debris', 4, 7, 'house.circle.fill', 'Roofing', 'roof,shingles,inspection,damage', 59, true),
(60, NOW(), NOW(), 'Service Garage Door', 'Lubricate springs, hinges, and rollers', 4, 8, 'door.garage.closed', 'Garage', 'garage door,lubricate,maintenance', 60, true),
(61, NOW(), NOW(), 'Inspect Weather Stripping', 'Check doors and windows; replace worn seals', 4, 8, 'wind', 'Air', 'weather stripping,door,window,insulation', 61, true),
(62, NOW(), NOW(), 'Pressure Wash Exterior', 'Clean siding, driveway, sidewalks, and deck', 4, 8, 'water.waves', 'CleaningServices', 'power wash,siding,driveway,cleaning', 62, true),
(63, NOW(), NOW(), 'Touch Up Exterior Paint', 'Address peeling or cracking paint to prevent moisture damage', 4, 8, 'paintbrush.fill', 'FormatPaint', 'paint,exterior,touch up,maintenance', 63, true),
(64, NOW(), NOW(), 'Service Sprinkler System', 'Inspect heads, adjust coverage, winterize if needed', 4, 8, 'sprinkler.and.droplets.fill', 'Grass', 'sprinkler,irrigation,winterize,lawn', 64, true),
(65, NOW(), NOW(), 'Weed Garden Beds', 'Remove weeds and prune plants as needed', 4, 5, 'leaf.fill', 'Grass', 'garden,weeds,pruning,landscaping', 65, true),
(66, NOW(), NOW(), 'Water Indoor Plants', 'Check soil moisture and water as needed', 4, 3, 'leaf.fill', 'Eco', 'plants,watering,indoor,gardening', 66, true)
ON CONFLICT (id) DO UPDATE SET
title = EXCLUDED.title,