Release notes

Changelog

Every meaningful change to SoShiny, dated and categorized.

July 2026

Fixed Jul 14, 2026

Tide times now come from the ocean, not the river

Beachfront communities were getting tide predictions from the nearest gauge even when it sat on a river — and river tides can run hours off the surf. The tide card now prefers open-coast NOAA stations (Bellair now reads the Daytona Beach Shores ocean pier), and the sunrise & sunset card names its city, just like the forecast.

Fixed Jul 11, 2026

Search takes you to the person, not the whole directory

Clicking a member in search results now lands on that person — managers get their profile, residents get the directory filtered to just them. The directory search also understands full names typed together, like "Karen Swenson."

June 2026

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.

Fixed Jun 5, 2026 View →

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.

Fixed Jun 4, 2026 View →

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.

Fixed Jun 4, 2026 View →

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.

Fixed Jun 3, 2026 View →

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 Jun 3, 2026 View →

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).

Fixed Jun 3, 2026 View →

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.

May 2026

Fixed May 26, 2026 See it live →

Settings — hero banner upload now actually saves

Uploading a hero banner image via Settings was silently failing — the file got written to disk but the database column was never updated, so the page reloaded without the banner. The form submission now writes the new hero path properly.

Fixed May 26, 2026 See it live →

Help link in the sidebar is clickable again

The 'Help' link at the bottom of the sidebar (and the admin Sign-out link too) was being silently swallowed by an invisible scroll-hint overlay sitting on top of it. Clicks now register correctly whether the hint is visible or not.

Fixed May 12, 2026 See it live →

Storage breakdown shows real names + a funny 404 page

The storage breakdown page now lists each file by its title (e.g. '2026 Bylaws.pdf' instead of the UUID filename) for documents and media, with the raw filename underneath. Clicking a document used to return 'Bad request' because the URL was missing the type parameter — fixed in both the storage page and the My documents card on profile (now correctly /dashboard/file.php?type=document&id=N). Also added a friendly 404 page — when a URL doesn't exist, you get a tiny HOA Violation Notice card with a randomized joke instead of Apache's default page.

Fixed May 12, 2026 See it live →

Picking a board office auto-promotes the role

Before: setting a board office on a member whose role was Resident or Renter silently dropped the office (since offices only apply to board roles). The form gave no feedback, which is exactly how Polly and John ended up appearing not to save. Now: picking any board office on a resident or renter auto-promotes them to Board member (least-privilege board role), and the success flash spells out what happened. Property managers keep their existing role.

Fixed May 12, 2026 See it live →

Board landing + directory now include pending members

Imported residents come in with status=pending until they sign in for the first time, but the 'Meet your board' landing section and the dashboard Board card were both filtering for status=active only — so a board member like Scott Bender (imported, marked as Director, set to show on the public landing) was being hidden. Fixed: both views now include everyone except status=inactive. Same fix applied to the Print contacts + board view.

Fixed May 10, 2026 See it live →

Rules page now lists all rules, not just search hits

Visiting /dashboard/search.php with no search term used to show "No rules on file yet" even when hundreds of rules were imported. Now the page defaults to a most-recent listing (200 rows), and search narrows it down. Imports were always landing in the database correctly — just invisible until you typed a query.

Fixed May 10, 2026 See it live →

Landing page silently failing on public-announcement query

The announcements query on /landing.php joined the users table (for author names) but selected `id` unqualified. Both tables have an `id` column, so MySQL threw an ambiguity error and the page died — visitors saw a 302 to /login.php instead of the community page. Qualified the column names. Public announcements feed now renders correctly.

Fixed May 10, 2026 See it live →

Dashboard 'Units' tile now counts actual registered units

Was reading the static unit_count capacity from association settings. Now counts distinct unit numbers across active + pending members — matches what you actually see in /dashboard/directory.php.

Fixed May 10, 2026 See it live →

Board admins can actually add members now

Two issues — labeled the action "+ Add member" instead of "+ Invite", and fixed a real bug where new users were created with status=pending which silently rejected them at login. They now start as status=active and can sign in immediately with the password you set or the auto-generated one we email them.

Fixed May 9, 2026 See it live →

Geocoding now runs on first save when lat/lon is missing

Previously the geocode-on-save check only fired when an address field changed, so associations with an existing address but no stored coordinates never got geocoded — and their map section stayed hidden. The check now also triggers when latitude or longitude is empty, so simply hitting Save once will populate coordinates and reveal the map.

Fixed May 10, 2026 See it live →

Hero CTA contrast over video

Inverted the hero overlay so the darkest pixels sit where copy lives (was backwards). Orange CTA now has a subtle white inner ring + drop shadow so its silhouette holds against any video frame. Ghost button bumped to a stronger frosted-glass treatment.

Fixed May 9, 2026 See it live →

Nav button text now stays white on orange

The site-nav anchor color rule was overriding button text color. Scoped it to :not(.btn) so primary buttons keep their white-on-orange treatment regardless of context.

Fixed May 9, 2026 See it live →

Pricing calculator field can be cleared during typing

Clearing the unit-count input no longer snaps the value back to 50. Empty state is allowed mid-typing; on blur the field falls back to 50 only if it's still empty or invalid.

Fixed May 9, 2026

Pinned every PDO connection to UTC

Discovered during password reset testing — MAMP MySQL ran in EDT while PHP defaulted to UTC, causing 1-hour reset tokens to look already-expired. db.php now sets time_zone='+00:00' on every connection so PHP's time() and MySQL's NOW() agree.