Compare commits

...

10 Commits

Author SHA1 Message Date
root b6df4dbb92 Snapshot: MLS sync fixes, image refresh, plugin/theme updates
MLS plugin fixes from this session:
- Fix silent insert failures: location column NOT NULL was rejecting wpdb->insert calls,
  causing ~18k new properties since Dec 2025 to be lost. Inserts now build raw SQL
  with ST_PointFromText so the spatial column is populated atomically.
- Auto-refresh expired media URLs in MLS_Media_Handler::fetch_and_cache(), guarded by
  a property-level GET_LOCK so concurrent fetches share one API refresh.
- Normalize WP_Error to null in mls_get_property_image() so callers can rely on the
  documented string|null contract.
- Support comma-separated property_type filters in MLS_Query and MLS_Cluster so the
  homepage "View All Commercial" link (?property_type=Commercial+Sale,Land,Farm)
  actually filters correctly.
- Incremental sync now looks back 10 minutes past the latest modification timestamp
  as a safety margin against missed records.
- Smart sync exits silently (info-level, not warning) when a full sync is in progress.

Operational:
- New cron: weekly full sync Sundays at 3 AM (/usr/local/bin/mls-full-sync).
- New cron: hourly 2GB cap on mls-thumbnails/ and cache/transformed-images/
  (/usr/local/bin/mls-image-cache-cap).
- Logrotate config for wp-content/debug.log (2-day retention, daily rotation,
  delaycompress).

Repo policy:
- CLAUDE.md updated with explicit "commit everything except build artifacts" policy.
- .gitignore: untrack runtime image caches and debug.log rotations.

Other modifications in this snapshot are pre-existing in-flight theme/plugin/db_content_updates work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 15:32:23 +00:00
root 57b752f54e Manual property enhancements: MLS status sync, agent clone, description formatting
- Manual properties linked to MLS now inherit status (Active/Pending/Closed) and
  days_on_market from the MLS listing dynamically
- Properties not in MLS default to Closed status
- Clone feature now auto-populates listing agent by matching MLS ID to Agent CPT
- Description formatter detects embedded headers (unpunctuated text after sentences)
  and splits them into separate paragraphs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 21:28:44 +00:00
Hanson.xyz Dev c2d5b2248d Add WebP conversion and garbage collection to MLS plugin
Image handling improvements:
- Convert PNG and images >500KB to WebP format
- Resize images wider than 1600px maintaining aspect ratio
- Check for .webp version before falling back to original
- WebP quality set to 80 (equivalent to JPEG 90%)

Garbage collection for disk space management:
- New MLS_Garbage_Collector class runs after each sync
- Only active when MLS_GC_DISK_THRESHOLD defined in wp-config
- Deletes image directories older than 24 hours, oldest first
- Stops when free space reaches 5GB or 2GB deleted per run
- Protects recently accessed images from deletion

Documentation:
- Added Garbage Collection section to README
- Updated Features list and File Structure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 20:48:57 -06:00
Hanson.xyz Dev 25608a5327 Add db_content_updates directory for production sync
- Create db_content_updates/ for documenting database changes
- Add README with required document format and template
- Update CLAUDE.md with mandatory documentation requirement
- All content changes must be documented for production team

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 20:12:05 -06:00
Hanson.xyz Dev f0ca867605 Add wp-config.php to gitignore, create dist template
- Remove wp-config.php from tracking (contains secrets)
- Add wp-config.php.dist as template for new installs

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 19:23:20 -06:00
Hanson.xyz Dev 91a90ea622 db 2026-01-04 17:51:00 -06:00
Hanson.xyz Dev acc8ac87a0 wip 2026-01-04 17:50:08 -06:00
Hanson.xyz Dev 7e45ce0756 Fix homeprozAjax not defined on properties page
Update localization condition to check for properties page template
instead of the removed property post type archive.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 13:14:21 -06:00
Hanson.xyz Dev 9bf45416d5 Add properties page template to replace CPT archive
Creates page-properties.php template and Properties page to handle
/properties/ URL after removing the property post type.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 13:13:01 -06:00
Hanson.xyz Dev 361007d36b Add homepage section ordering and switch to MLS-only data source
Homepage Improvements:
- Add Section Order tab with enable/disable toggles and order numbers
- Support up to 2 custom WYSIWYG content areas with titles
- All 4 sections (Service Cards, Property Types, Custom 1, Custom 2)
  can be reordered and toggled independently

Property Type Boxes:
- Convert to ACF repeater (remove MLS count queries)
- Add red accent color to icons
- Center-align icons, increase title size, add spacing

MLS Data Source:
- Remove property CPT and taxonomies (MLS Editor is now source of truth)
- Commercial section now pulls from MLS with priority:
  1. Featured (favorited) commercial properties
  2. HomeProz-listed commercial properties
  3. Random commercial/land/farm properties
- Featured Homes section updated to same priority order

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 13:00:33 -06:00
9498 changed files with 1078620 additions and 253016 deletions
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# Read JSON input from stdin and extract the prompt field
prompt=$(cat | jq -r '.prompt // empty')
# Check if the prompt ends with a question mark (ignoring trailing whitespace)
if echo "$prompt" | grep -qE '\?\s*$'; then
# Use JSON additionalContext for discrete injection (not shown to user)
cat <<'EOF'
{
"hookSpecificOutput": {
"hookEventName": "UserPromptSubmit",
"additionalContext": "STOP: This is a QUESTION. Suspend the current task, if any, and answer the question directly and concisely. Do NOT take any further actions, run any tools (except as necessary to answer the question), or continue previous work until instructed to 'resume' or otherwise continue the task. Wait for the user's next instruction."
}
}
EOF
fi
+56 -1
View File
@@ -29,7 +29,51 @@
"Bash(bd ready:*)",
"Bash(bd close:*)",
"WebFetch(domain:homeprozrealestate.com)",
"Bash(npm init:*)"
"Bash(npm init:*)",
"Bash(bd sync:*)",
"Bash(git push:*)",
"Bash(wp-content/plugins/mls-by-hansonxyz/includes/class-mls-query.php )",
"Bash(wp-content/plugins/mls-by-hansonxyz/mls-by-hansonxyz.php )",
"Bash(wp-content/themes/homeproz/archive-property.php )",
"Bash(wp-content/themes/homeproz/dist/ )",
"Bash(wp-content/themes/homeproz/inc/ajax-handlers.php )",
"Bash(wp-content/themes/homeproz/template-parts/property/property-filters.js )",
"Bash(wp-content/themes/homeproz/template-parts/property/property-filters.scss )",
"Bash(wp-content/themes/homeproz/template-parts/property/property-results.php)",
"Bash(/var/www/html/wp-content/themes/homeproz/archive-property.php )",
"Bash(/var/www/html/wp-content/themes/homeproz/dist/assets/main.css )",
"Bash(/var/www/html/wp-content/themes/homeproz/dist/assets/main.js )",
"Bash(/var/www/html/wp-content/themes/homeproz/template-parts/property/property-filters.js )",
"Bash(/var/www/html/wp-content/themes/homeproz/template-parts/property/property-filters.scss)",
"Bash(bd list:*)",
"Bash(.beads/ )",
"Bash(FEATURES_PENDING_12_15.md )",
"Bash(wp-content/plugins/mls-by-hansonxyz/ )",
"Bash(wp-content/themes/homeproz/front-page.php )",
"Bash(wp-content/themes/homeproz/inc/ )",
"Bash(wp-content/themes/homeproz/page-about.php )",
"Bash(wp-content/themes/homeproz/page-contact.php )",
"Bash(wp-content/themes/homeproz/src/main.js )",
"Bash(wp-content/themes/homeproz/template-parts/)",
"Bash(mv:*)",
"Bash(git -C /var/www/html log --oneline -5)",
"Bash(git -C /var/www/html add wp-content/plugins/mls-by-hansonxyz/includes/class-mls-db.php wp-content/plugins/mls-by-hansonxyz/includes/class-mls-query.php wp-content/plugins/mls-by-hansonxyz/mls-by-hansonxyz.php wp-content/plugins/mls-by-hansonxyz/data/ wp-content/themes/homeproz/inc/ajax-handlers.php wp-content/themes/homeproz/template-parts/property/property-filters.js wp-content/themes/homeproz/dist/assets/main.js)",
"Bash(npx playwright test:*)",
"WebFetch(domain:homeproz.dev.hanson.xyz)",
"Bash(python3:*)",
"Bash(git -C /var/www/html status --short wp-content/themes/homeproz/)",
"Bash(git -C /var/www/html diff --stat wp-content/themes/homeproz/template-parts/property/property-filters.js wp-content/themes/homeproz/template-parts/property/property-filters.scss wp-content/themes/homeproz/template-parts/property/property-filters-sticky.php)",
"Bash(git -C /var/www/html add wp-content/themes/homeproz/template-parts/property/property-filters.js wp-content/themes/homeproz/template-parts/property/property-filters.scss wp-content/themes/homeproz/template-parts/property/property-filters-sticky.php wp-content/themes/homeproz/dist/assets/main.css wp-content/themes/homeproz/dist/assets/main.js)",
"Bash(find:*)",
"WebFetch(domain:www.parkdental.com)",
"Bash(git -C /var/www/html status --short)",
"Bash(git -C /var/www/html add:*)",
"Bash(git -C /var/www/html diff --cached --stat)",
"Bash(git -C /var/www/html commit -m \"$\\(cat <<''EOF''\nAdd 6 reusable page templates with ACF integration\n\nIntroduces layout-focused templates for marketing pages:\n- Content with Sidebar: 70/30 grid with callout boxes\n- Alternating Blocks: Zigzag image/text sections\n- Service Detail: Hero + features grid + FAQ accordion\n- Card Grid: Configurable 2/3/4 column card layouts\n- Long-Form Article: Clean reading layout with related links\n- Landing Page: Conversion-focused with benefits and testimonial\n\nEach template has corresponding ACF field groups for content\nmanagement. Sample pages created under /page-template-examples/.\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
"Bash(cat:*)",
"Bash(rsync -av /var/www/vhosts/homeprozrealestate.com/httpdocs/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-query.php /var/www/vhosts/homeprozrealestate.com/staging/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-query.php && rsync -av /var/www/vhosts/homeprozrealestate.com/httpdocs/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-cluster.php /var/www/vhosts/homeprozrealestate.com/staging/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-cluster.php)",
"Bash(crontab:*)",
"Bash(rsync:*)"
],
"deny": [],
"ask": []
@@ -56,6 +100,17 @@
}
]
}
],
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/question-guard.sh"
}
]
}
]
}
}
+11 -2
View File
@@ -9,8 +9,8 @@
.env.local
.env.*.local
# WordPress config with secrets (keep sample)
# wp-config.php # Commenting out - we want to track this for snapshots
# WordPress config with secrets (use wp-config.php.dist as template)
wp-config.php
# Uploads (too large for git, backup separately)
wp-content/uploads/
@@ -29,6 +29,15 @@ Thumbs.db
# Debug
wp-content/debug.log
wp-content/debug.log.*
# Runtime image caches (regenerable, capped by mls-image-cache-cap)
wp-content/cache/transformed-images/
wp-content/uploads/mls-thumbnails/
wp-content/uploads/mls-listings/
# Local Claude CLI tooling
node_modules/claude-cli/
# Vite
*.local
+55 -5
View File
@@ -13,6 +13,18 @@ Custom WordPress theme for HomeProz Real Estate (Albert Lea, MN). Dark/rust bran
7. **No custom animations** - keep it static and fast
8. **ASK before architectural decisions**
9. **No git commits unless asked** - commits are for checkpoints before major work or major milestones, not for small single-file changes
10. **Sync to staging** - after modifying theme or plugin files, sync them to `/var/www/vhosts/homeprozrealestate.com/staging/` using rsync
## Version Control Policy
Git is a snapshot tool and the historical record of what changed on the site. **If it's not in git, it may as well not exist.**
When asked to commit, commit **everything except build artifacts** — do not pick a "scope" or hand-select files. The point is the snapshot.
- **Commit:** all source (PHP, SCSS, JS), configs, `package.json`/`package-lock.json`, `db_content_updates/`, `node_modules/`, `dist/`, DB snapshots (`*.sql.gz`), plugins, themes, `CLAUDE.md`. `node_modules/` and `dist/` are tracked intentionally — see comments in `.gitignore`.
- **Do not commit:** runtime caches (`wp-content/cache/transformed-images/`), log files (`wp-content/debug.log*`), and other transient/regenerable runtime output. These belong in `.gitignore`.
If you find untracked files in scope of a commit, include them. If something looks ambiguous, default to committing it — under-tracking loses history; over-tracking is reversible.
## Build
@@ -26,17 +38,35 @@ npm run build
- **WP-CLI**: `wp --allow-root <command>`
- **Dev commits**: `./dev_commit.sh "message"` (includes DB snapshot)
## WordPress Admin
- **URL**: `/wp-admin/`
- **Username**: `admin`
- **Password**: `Byg2X2sqbHeVvHLYRz5e`
## Theme Options
Access via `homeproz_get_option('key')`:
- `phone`, `email`, `address`, `facebook`, `tiktok`
## Custom Post Types
## Database Content Changes (MANDATORY)
### Property (`/properties/`)
- ACF: price, address, beds/baths/sqft, gallery, documents, listing_agent
- Taxonomies: `property_status` (Active/Pending/Sold), `property_type`, `property_location`
- Location dropdown only shows communities with active/pending properties
This site has a production fork. All database changes must be documented for production sync.
**Schema changes** (new tables, columns, indexes): Use migration files in the MLS plugin (`wp-content/plugins/mls-by-hansonxyz/`).
**Content changes** (options, ACF fields, posts, menus, terms): Create a timestamped document in `db_content_updates/` with:
- Filename: `YYYY-MM-DD_HH-MM_description.md`
- What was changed (exact field names, option keys, post IDs)
- The exact values set (copy/paste the WP-CLI commands or SQL)
- Why it was changed
- Any dependencies or order of operations
Example: `2026-01-04_19-30_add-footer-menu.md`
**DO NOT** make database content changes without creating the corresponding document. The production team relies on these files to sync changes.
## Custom Post Types
### Agent (`/agents/`)
- ACF: phone, email, bio, gallery, social links, order, disabled toggle
@@ -55,3 +85,23 @@ $url = add_query_arg('property', urlencode($title), home_url('/contact/'));
## Page Classes
`Home_Page`, `Properties_Archive`, `Single_Property`, `About_Page`, `Contact_Page`, `Blog_Archive`, `Single_Post`, `Agents_Archive`, `Single_Agent`, `Search_Page`, `Error_404`
## MLS Property Overrides
### Force a non-HomeProz listing to appear as HomeProz
Some properties (e.g., LandProz listings) may need to appear on the HomeProz site. The `is_homeproz` flag overrides the office name check.
1. Find the property's `listing_key`:
```bash
wp --allow-root db query "SELECT listing_key, listing_id, street_name, city, list_office_name, is_homeproz FROM wp_mls_properties WHERE listing_id LIKE '%<MLS_ID>%'"
```
2. Set the override flag:
```bash
wp --allow-root db query "UPDATE wp_mls_properties SET is_homeproz = 1 WHERE listing_key = '<LISTING_KEY>'"
```
3. Document the change in `db_content_updates/` per the Database Content Changes policy.
**Example**: 121 Main St, Glenville (NST7785198) is listed under "LandProz Real Estate, LLC" but appears on HomeProz via `is_homeproz = 1`.
Regular → Executable
View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before

Width:  |  Height:  |  Size: 5.0 MiB

After

Width:  |  Height:  |  Size: 5.0 MiB

View File
View File
View File
View File
View File
View File
View File

Some files were not shown because too many files have changed in this diff Show More