Fixed
Jun 25, 2026
Community landing page hides expired announcements
The public community page (your bellaircondos.com landing) was showing every announcement including expired ones. It now shows only currently-active announcements, matching the dashboard and lobby TV.
Fixed
Jun 25, 2026
Member notes and contact log are now one
Notes added from the directory (the 📋 badge) and entries in a member’s Contact log were stored separately and didn’t show together. They’re now merged into a single timeline on the member’s profile, and the directory note count reflects both. The 📋 badge now opens the member’s Contact log.
Fixed
Jun 25, 2026
Dashboard hides expired announcements
The dashboard was listing announcements that had already expired (and the count tile included them). It now shows only currently-active announcements — published and not past their expiry — matching the Announcements page, including the resident view and the emergency banner.
Fixed
Jun 20, 2026
Consistent spacing/colors + login hardening
Fixed a set of spacing and accent-color values that were silently rendering wrong in a few spots (meeting pages, broadcasts, signing). Also hardened the post-login redirect against open-redirect tricks.
Quick Reference page now has proper top/bottom margin
soshiny.com/florida/quick-reference (and the NY/TX/AZ siblings) were rendering flush against the site header with no breathing room above the first card. Two issues: the template was opening a duplicate <main> element inside the one header.php already opens (invalid HTML), and the container had no vertical padding to separate the cards from the header. Fix: dropped the duplicate <main>; added padding-top/bottom on the container so the printable cards visually float in the middle of the page on screen. Print CSS unchanged so the printed PDF still paginates cleanly to two letter-size pages.
Tenant email links now disambiguate when an association has no custom domain
Lightweight version of the slug-routing brief. The tenant_dashboard_url() helper appends ?from_assoc={id} to outbound email links only when the sending association lacks a verified custom domain — for tenants with a custom domain (bellaircondos.com, badassdemo.com), the domain itself is the disambiguator and nothing is appended. Both live associations today have custom domains, so behavior is unchanged in production; this is forward-looking infrastructure for the next tenant who onboards without a domain. Also: deep links through login. When an unauthenticated visitor clicks a dashboard email link, require_login() now stashes the original URL as ?next= on the login page, and login.php redirects back to it after successful sign-in (open-redirect-guarded — only local /paths, never /login itself). Dashboard bootstrap rejects requests where ?from_assoc differs from the user's actual association_id with a clear 'sign in with the correct account' message instead of a confusing 404.
Tenant notification emails now link to the right domain
A board email about a Bellair Condos concern was linking to soshiny.com/dashboard/concerns.php?id=30 instead of bellaircondos.com — the same bug existed across every notification email the platform sends. Audit + fix: 14 hardcoded https://soshiny.com/dashboard/... URLs across concerns, ARC, search, forms, amenities, and documents now use a new association_base_url() helper that returns the association's verified custom domain (bellaircondos.com, badassdemo.com, etc.) when one is set, falling back to soshiny.com otherwise. The same helper is wired into the invite + password-reset emails (send_password_link()) and the new-member invite send (dashboard/send-invite.php), so a Bellair board admin sending an invite from soshiny.com still produces a bellaircondos.com link in the recipient's inbox. Brand-anchor links to soshiny.com in email footers ('Powered by SoShiny') are unchanged — those should always point at the platform.
Comparison pages now use SoftwareApplication schema (fixes GSC warnings)
The three head-to-head comparison pages (soshiny.com/vs/hoalife, /vs/condo-control, /vs/runhoa) had been emitting Product structured data, which Google Search Console flagged for missing aggregateRating and review fields. We don't have real verified customer reviews yet, and fabricating them violates Google's structured-data guidelines and triggers manual actions — so the right fix is to use the correct schema type. Switched all three pages to SoftwareApplication (the same schema homepage and pricing already use), via a one-line include that points at the existing canonical partial. One source of truth for the pricing schema across all 5 pages. No pricing data changed.
Fixed visible JSON text on blog posts (Quill stripped the FAQ schema)
Four published blog posts (Hidden Cost, Five Jobs, Florida Compliance, and What Does Community Software Cost) were showing a raw FAQPage JSON blob as visible text on the page. Root cause: the rich-text editor in /admin/blog.php (Quill) strips <script>, <details>, and <summary> tags on every save — so the FAQ accordions and their structured-data scripts were getting eaten the moment any admin opened a post to edit it. Visible content was preserved but the schema and the collapsible UI were lost, and the JSON-LD body leaked into the rendered HTML as plain text. Fix: rewrote the FAQ section on every blog post (4 published + 11 drafts, 15 total) to use plain h3/p HTML that Quill preserves. The Q&A is still visible and readable; the FAQPage rich-snippet eligibility is gone for now. A separate small software change to post.php would restore the schema by moving the FAQ to its own field on the post (rendered outside the Quill editor's reach).
Restored the deep rewrite of the HOA Units & Parking feature page
An earlier admin edit (the slug rename from parking-units to hoa-units-parking-fees) saved over the deep content rewrite that had landed on the page minutes before, bringing back two empty H3 sections. The full rewrite is now restored at the new URL (soshiny.com/features/hoa-units-parking-fees) — including the field-list bodies for "What's on each unit record" and "And every parking spot is its own record too", the FAQ section with FAQPage structured data, the 8 distinct benefit icons, the trimmed meta description, and the og:image alt text. Five inline links from blog posts (Hidden Cost plus four drafts) were also updated from the old slug to the new one.