What's New — Admin View
Items shown in red are visible to administrators only and are not shown to regular family members.
August 2026
August 30, 2026 (sign-in cleanup)
- A deceased family member's name no longer appears while typing on the sign-in page — This was harmless (their account was never actually reachable), but it could be an unwelcome surprise to see. Fixed.
- Found while checking a different question — You asked whether two family members who share a first name (Elizabeth) could each sign in using it. Checking that surfaced a third Elizabeth on file who's deceased, still showing up in the same search.
functions/api/people-search.jsnever excluded the deceased — unlike/api/dataand several admin lists, which already do. AddedWHERE date_of_death IS NULL. Verified locally: two deceased test records now return zero results for their nicknames, a living person's search is unaffected, smoke suite 6/6. - Fixed: your saved name from a password manager could get rejected as "not found," even though it looked exactly right — If you set up your passcode a long time ago, your browser or password manager may have saved your name with old, invisible extra text attached from a much earlier version of this page. That could make sign-in fail even though the name shown looked completely correct. This is now fixed — if you ran into "Couldn't find that name" before, please try signing in again.
- Root cause, from Janet's report — Janet's MacBook offered her saved credential, she clicked it and typed her new passcode, and still got "Couldn't find that name." The name field used to be backed by a full-roster dropdown that's been dead code for a while; it appended
" (gen N)"to every name, e.g."Janet Layne (gen 1)". Anyone whose password manager saved a login back then has that suffix baked in permanently — it looks identical to a human but isn't an exact match for what today's search returns.login.jsnow strips a trailing parenthetical before every match attempt. Verified with a genuine negative control: reproduced Janet's exact error first (by filling the field the same way a password manager does, not by typing), then confirmed the fix resolves it end-to-end into a real sign-in. - The shared family password has been retired — everyone now has their own passcode — The single password we all shared no longer works. If you didn't already have a personal passcode, one has been emailed to you: look for a message titled "Your Ratterman.Family passcode" from family@ratterman.family. If it isn't in your inbox, please check your spam or junk folder (and any "Other" or "Focused Inbox" tab). Sign in with your name plus that passcode from now on.
- One passcode, one email — nothing to set up — Previously you'd have received a temporary code and then been given a second, different one the first time you signed in. That's gone. The passcode in your email is your real one to keep, and there's nothing to do on first sign-in but use it.
- A passcode that's never used stops working after 60 days — This is a safeguard so a code sitting unused in an inbox doesn't stay valid forever. Once you've signed in with it even once, it's yours permanently and never expires. If yours does lapse before you get round to using it, just ask Matt or Nick and you'll be sent a new one.
- Already signed in? Nothing changes for you — Being signed in on a device lasts 60 days and isn't affected by any of this. You'll only need your passcode next time you're asked to sign in.
- Both automated jobs had silently failed — for two weeks — The Aug 16 mailout and the Aug 30 rotation were scheduled jobs on GitHub's servers. Both failed the same way: Cloudflare blocks requests coming from GitHub's data centres before they ever reach the site, almost certainly a side effect of the security rules added after the July probing incident. Nothing was wrong with the passcode key — the identical request works fine from your machine. Failure notices went to Nick as repo owner, not to you, which is why it went unnoticed. Both steps were run by hand instead. The two scheduled workflow files are now dead and should be deleted.
- The failure was at least a safe one — The rotation stopped at its very first step, so the family password was never actually changed and nobody was locked out. Confirmed from the run logs and from the database, not assumed. One real side effect: because the "retired" message is triggered by the date, the login page spent most of Aug 30 telling anyone who mistyped the still-working password that it had been retired. Fixed.
- Expiry is enforced on the walk site too —
/api/walk-verifychecks the same passcodes, so enforcing the 60-day rule only on this site would have left the walk site as an easy way around it. Both doors now reject expired codes, and both count as "using" a passcode — signing in on either one makes it permanent. - Three old unused passcodes were back-filled — Codes issued before today that had never been used would otherwise have stayed valid forever, which is the exact thing the rule exists to prevent. Three were affected: Arlo and Asa Frey (both infants, so irrelevant in practice) and Vinnie Boryla. Verified against the live database before running — exactly three, nobody else touched.
- 24 people still have no email address — 10 of them are 13 or older. No automation can reach them; they need a passcode read to them over the phone via Family Passcodes → Reset passcode, which shows you the code on screen. Worth knowing: for someone with no email, the code you read out is temporary, and they'll be shown a different permanent one after they sign in — so tell them to write down the second one.
August 26, 2026
- One passcode now works on the Walk of the Week site too — walk.ratterman.family is a separate site on a separate database, and it used to have one shared passcode that everyone typed. It now asks each person for their own. For anyone who's in the family directory, that's the same passcode they use here — one passcode, one place it's stored, nothing to keep in sync. The two walkers who aren't family (Mark Mollica, Dennis Smith) get a passcode issued by the walk site instead, and have no record here at all.
- The walk site cannot read anything about the family — It has no copy of the roster, no access to this database, and no share of the sign-in cookie. It asks one question over a new endpoint (
POST /api/walk-verify) — "is this passcode right for this person?" — and gets back yes or no plus a display name. No email, no household, no birthdays, and deliberately not admin status: being an admin here and being a walk organizer are different jobs. It is also never issued a session, so it cannot act as anyone on this site. Someone who completely owned the walk site would gain no way in here — only the ability to guess passcodes at five tries per person per fifteen minutes. - Why not just share the sign-in cookie — That was the original plan and it was wrong twice over. This site's cookie is host-only, so widening it to cover both sites would hand the walk site the credential that unlocks the whole directory on every single request. And the signing method is symmetric — the same key that verifies a session here can create one, so the walk site could have minted admin sessions for this site. The question-and-answer endpoint has neither problem.
- Lockout counters are now shared between the two doors — Failed attempts are counted once per person, whichever site they happen on (moved into
functions/_login-attempts.js, used by both/api/loginand/api/walk-verify). If they were counted separately, the walk endpoint would be an unlimited guessing machine against family passcodes that never trips the lockout here. The trade-off is deliberate: fumbling your passcode on the walk site can lock you out here for 15 minutes, which is correct — it's one passcode, so it gets one lockout. - Found while doing this: Vinnie Boryla and Mike Ratterman have no passcode at all — Neither has ever been issued one, and both of their old shared-password sessions expired months ago (Vinnie's around June 17, Mike's around June 3). They are locked out of this site today, four days before the August 30 rotation would have forced it anyway. Both have an email on file, so "Reset passcode" on the Family Passcodes tool will reach them.
- Corrected some wrong wording about passcodes — Several comments and one line of the reset email said people would "set" or "pick their own" passcode. They never do — the site generates every passcode, and always has. What the flag actually distinguishes is a temporary admin-issued code from a permanent one, not who chose it.
August 15, 2026 (Family Passcodes admin tool)
- New "Shared-Password Session" column — Raised after you asked whether someone who logged in weeks ago with the shared password gets in without a passcode. Answer: yes, sessions are independent 60-day cookies unrelated to passcode status. For anyone with no passcode at all, this column now shows whether their last login still works and until when: "Never logged in," "Expired <date>" (they're already forced to a real login), or "Expires <date>" (amber inside 7 days, green otherwise). Anyone who already has a passcode shows "—."
- A bug was caught before it shipped — The first version of that column had a JavaScript ordering mistake that would have silently broken the whole page for every admin — showing only the first 2 of 93 people on every fresh visit, with no error message. It only worked once you'd already interacted with the page (e.g. typed in the filter), which is exactly the kind of failure a code read alone wouldn't catch. Found by testing an actual cold page load in a browser instead of trusting the diff, then fixed and re-verified all five states individually before this shipped.
- Each device is its own session, not "whichever was most recent" — There's no way to look up "all of someone's active sessions" — every login mints its own independent 60-day cookie, and an earlier login on another device stays valid on its own even after a newer one happens elsewhere. The column shows the latest of however many a person has, i.e. the last date any of their devices stops working without a passcode.
- New "with an email" / "without an email" filters — Two more checkboxes next to the existing passcode filters. Each pair is exclusive with itself, but the two pairs combine, so you can now show exactly "no passcode + no email" or "has passcode + has email," etc. Verified against real data: "no passcode + no email" is 29 people, "has passcode + has email" is 19 — both cross-checked against an independent count, not just eyeballed.
- Everyone with a passcode currently has an email too — but that's not guaranteed — Checked directly against production: right now, all 19 people who've set a passcode also have an email on file. That's true of today's data, not something the system requires — someone with no email could still get a temporary code shown to you on-screen, set their own permanent one after signing in, and end up with a passcode but no email. The filters handle that correctly if it happens; it just hasn't yet.
August 15, 2026
- Sign-in now shows your full name, not just a nickname — On the sign-in page, typing your name used to sometimes show a result that didn't match what you typed — for example, typing "Nicholas" would find the right person, but the suggestion only showed "Nick." If that made it look like your name search didn't work, it now shows both: "Nicholas (Nick) Ratterman." You can still type either your full name or your nickname — both find you.
- Raised after a real login difficulty — You asked for this after a family member had trouble signing in. The search (
functions/api/people-search.js) had actually already been matching correctly on first name, last name, and nickname all along — the bug was purely in what got displayed back: the suggestion list only ever rendered the nickname, so someone who typed their legal first name (not knowing, or not thinking of, their nickname) saw a name on screen that didn't match what they'd typed. It now showsFirst (Nickname) Lastwhenever the two differ; anyone without a nickname, or whose nickname equals their first name, is unaffected. Verified against the live search API and against the rendered login page in a local preview. - Changes are now tested locally before they're pushed live — Claude now has a working local copy of the site (it existed already from earlier work, it just wasn't being used this way) plus a one-command automated check (
npm test) that boots a throwaway local copy of the site and verifies six things: no page is silently broken, no JavaScript file has the character-encoding bug that's bitten this site before (it once made every button on a page silently stop working, with no error shown), and the sign-in/security checks are actually enforcing what they're supposed to — for example, that a page requiring sign-in actually rejects someone who isn't signed in. It prints a plain pass/fail, so a failure is obvious without having to read code. This doesn't change anything about how the site behaves for you or the family — it's a safety check that runs before a change goes live, not a new feature. Confirmed it actually catches problems: temporarily broke one of the sign-in checks on purpose, confirmed the test caught it and explained exactly what was wrong, then fixed it back and confirmed it passed again. - Why this now — You asked about testing changes before they reach the live site, and whether that matched what a professional developer would actually do for a project this size. The answer: yes, roughly — a lightweight version of it, sized to a small family site rather than the heavier setup (full automated test suites, CI pipelines) a larger commercial project would carry.
August 10, 2026
- Household addresses — suggested corrections, never auto-applied — When adding or editing a household's address on the Edit page, if what's typed doesn't match the family's address conventions (standardized street abbreviations, "#" for units, ALL CAPS directions, no stray punctuation), a box now appears underneath showing a suggested correction, with "Use this" or "Keep as typed" — nothing changes unless you click one. This is deliberate: some real street names (e.g. one literally named "South Lane") would otherwise get mangled by the automatic rules, so a person always has the final say. State now auto-capitalizes as you type, and Postal Code now requires the full ZIP+4 format to save. A full audit of all 35 households currently on file found them already 100% compliant with the conventions — this only affects what gets entered going forward, since anyone signed in (not just admins) can add or edit a household and nothing previously checked the formatting at all.
- Reviewing a pending edit now shows only what actually changed — Previously, when a family member submitted an edit for your approval, the review screen showed their entire record — every field, even ones they never touched — as if it were part of the proposed change. It now shows only the fields genuinely being changed, so a one-word edit shows one row instead of their whole profile. Also retroactively cleaned up the one edit that was already sitting in the queue (Janet Layne's nickname change) so it displays the same way.
July 2026
July 25, 2026
- Family Passcodes — added an "Only those with a passcode" filter — Mirrors the existing "Only those without a passcode" checkbox. The two are mutually exclusive — checking one automatically unchecks the other — so you can't accidentally filter the list down to nothing.
- Family Passcodes — corrected the page's notice text — It previously mentioned "a one-time email sign-in link," which no longer applies now that magic-link login is hibernated, and implied an email on file was required to set a personal passcode, which was never true. The notice now also makes clear that passcodes are always system-generated — nobody types their own value, they just generate and adopt a new one.
July 24, 2026
- Sign-Up Sheets — invite lists are now private, and only the Organizer can add people to them — Two related tightenings, not shown to regular members. First, a sheet's invite list, item claims, and details are now only visible to its Organizer and the people actually invited to it — previously every signed-in family member could see every sheet, current or past, whether or not they were invited (e.g. a surprise party's guest list wasn't actually a secret from anyone who checked). Second, the "+ Add yourself to this list" self-add option is gone — only the Organizer (or an admin) can add someone to a sheet now; before, anyone could add themselves to any sheet regardless of whether the Organizer meant to invite them. As always, admins can see and do everything on every sheet, the same as before. Verified locally against several test accounts: Organizer add-invite works, a non-Organizer invitee is blocked (403) from adding others, an uninvited person sees zero sheets and is blocked even hitting the API directly, an invitee still sees their own sheet, and an admin retains full visibility and control.
- Your own passcode is coming to you — you don't need to do anything — The old shared family password stops working on August 30, 2026. If you haven't set up your own passcode yet, we'll email you one automatically two weeks beforehand, on August 16. You don't have to sign in first to get it, and you don't have to do anything when it arrives — just keep it. The next time you sign in, use that passcode instead of the old family password, and you'll be given a new personal passcode to keep. It comes from family@ratterman.family with the subject "Your Ratterman.Family passcode" — if you don't see it, please check your spam or junk folder, and look in any "Other" or "Focused Inbox" tab if your email has one.
- A clearer message if you try the old family password after August 30 — Previously, typing the retired family password just said "Incorrect passcode," and five tries would lock you out for 15 minutes even though that password could never work again. Now it explains that the family password has been retired, tells you where to find your own passcode, and no longer counts those attempts against you — so you can't get locked out over a password that no longer exists.
- The lockout gap this fixes — The July 16 plan said the August 30 deadline was informational and the shared password would keep working until you rotated it manually. That had a hole: sessions last 60 days and are completely independent of passcode status. Someone whose last real sign-in was in late June has their session expire in late August — before the rotation — with no personal passcode and no way to ask for one. Waiting for people to sign in and be prompted never reaches them, which is why the mailout goes out unprompted.
- Both steps are now automated, and both need one-time setup from you — Two new scheduled GitHub Actions workflows: the passcode mailout on August 16 and the
SITE_PASSWORDrotation on August 30. Cloudflare Pages Functions can't run cron jobs, so GitHub Actions calls the site over HTTPS. You must set a newMIGRATION_JOB_KEYsecret in two places — once on Cloudflare and once in GitHub — or the mailout will fail. Seedocs/shared-password-retirement.mdfor the exact commands. - Rotating the secret alone would have silently done nothing — A Cloudflare Pages secret change does not affect the deployment that's already running; it only applies to deployments made afterward. A workflow that just wrote the new
SITE_PASSWORDwould have reported success on August 30 while the old family password kept working indefinitely, with nothing visibly broken to tip you off. The rotation workflow now redeploys the site immediately after writing the secret, then checks the site is actually back up. - Run the verify-only test before August 30 — The rotation workflow has a manual verify-only mode that writes and deletes a throwaway secret purely to prove the Cloudflare API token is allowed to write project settings, not just deploy. That permission has never been exercised — the deploy workflow only deploys — and discovering it's missing on August 30 with the family locked out is exactly what this avoids. Please run it once from the Actions tab.
- 11 people have no passcode and no email address — and they're not all children — 26 living family members have neither. The assumption was that these were all young kids covered by a parent's sign-in; that's true for 15 of them. The other 11 are 13 or older, including a 74-year-old first-generation member and six adults between 18 and 35. Nothing automated can reach them — there's no address to send to. They do not block the rotation (your call), but they'll each lose access on August 30 unless you collect an email address or hand them a passcode directly. The new report emails you and Nick the list, oldest first.
- "Delivered" does not mean "they read it" — The report also lists everyone who was emailed a passcode but still hasn't set their own, which is the real follow-up list. Resend reporting "delivered" only means their mail server accepted the message — Outlook accepted Amy's magic-link email and then filtered it out of sight. Only
passcode_set_atproves a human actually got a code and used it. The report can optionally ask Resend what happened to each message, which does catch hard bounces from stale addresses. - Safety rails on the mailout — It works in batches (hashing costs ~12ms of CPU per person, so ~50 at once would strain a single request) and can be resumed. If an email fails to send, the passcode is rolled back so nobody is left holding a code that never arrived, and that person is reported for retry. Nobody is ever emailed twice. There's a dry-run mode that lists exactly who would be contacted without sending anything, and a single-person mode so you can prove the whole path works on one willing volunteer before ~50 irreversible emails go out — worth doing.
- Both workflows are year-gated and should be deleted afterward — GitHub cron has no "run once," so
0 14 30 8 *would fire every August 30 forever. A guard step makes any non-2026 scheduled run do nothing. Once the migration is confirmed, delete both workflow files and thepasscode_migration_logtable.
July 16, 2026
- New way to sign in — your own passcode or a one-time email link — You can now sign in with your own personal passcode or a one-time link emailed to you, instead of the shared family password. On the sign-in page, type your name and your passcode, or use "Email me a sign-in link" to get a link that signs you in with one click (it works once and expires after 15 minutes). The first time you sign in, you'll be given a personal passcode to save — save it in your phone or browser's password manager so you don't have to remember it. During the switch-over the old shared family password still works until you've set up your own, so no one gets locked out. Your sign-in still lasts 60 days on each device. The sign-in page will remind you if you're still using the old shared password — it stops working on August 30, 2026, so sign in once before then to get your own passcode.
- Migration deadline is not enforced automatically — The August 30, 2026 date shown on the login page is informational only, and the reminder itself disappears automatically the day after (so it won't linger claiming a past deadline). But that's cosmetic — the shared
SITE_PASSWORDitself keeps working until you manually rotate it to a random string once you're satisfied everyone's migrated. Check the Family Passcodes admin tool to see who still hasn't set their own passcode before you do. - New — Family Passcodes admin tool — Admin Tools has a new Family Passcodes card. It lists every family member with whether they've set their own passcode, whether an email is on file, whether they're holding a temporary code, and whether they're currently locked out. You can reset anyone's passcode from here — it generates a fresh temporary code, emails it to them (or shows it to you to pass along if they have no email on file), and forces them to choose their own passcode the next time they sign in.
- Roster no longer leaks on the login page — The old login flow showed a dropdown of every family member's name to anyone who reached the page. The name field is now type-ahead and returns nothing until at least 3 characters are typed, and only ever returns names (no contact info), so the full roster is never exposed.
- Per-person lockout on failed sign-ins — Five failed passcode attempts lock that person out for 15 minutes (tracked per person via new
failed_login_count/locked_untilcolumns), on top of Cloudflare's existing edge rate-limit on/api/login. A correct passcode or magic-link sign-in clears the lock. Magic-link requests always return the same generic response whether or not the email is on file, so they can't be used to discover which addresses are registered. - Under the hood — Per-person passcodes are stored as PBKDF2-SHA256 hashes in the existing
password_hashcolumn (now used for everyone, not just admins); passcodes are system-generated 8-character codes (XXX-YYYY, ambiguous glyphs excluded). Magic links are single-use 15-minute tokens in a newlogin_tokenstable. The sharedSITE_PASSWORDkeeps working during a 45-day migration window and stops working per-person once they set their own passcode; existing admins were backfilled so they are never prompted to reset. New endpoints:set-passcode,admin/reset-passcode,admin/passcode-status,people-search,request-magic-link,magic-login. After the migration window, rotatingSITE_PASSWORDto a random string completes the cutover.
July 15, 2026
- Sign-Up Sheets — rename a category or change its quantity — The Organizer of a sign-up sheet (and admins) can now click the pencil (✎) next to a category's name to rename it or change how many are needed, without having to delete and re-add it. Leave the quantity blank to make it unlimited.
July 4, 2026
- New — a User Manual — There's a new User Manual item in the top menu with a plain-language, step-by-step guide to the whole site: viewing the Family List, exploring the charts on Fun with Data!, printing and saving lists and contact cards from Reports, using and creating Sign-Up Sheets, looking someone up, editing a family member's information, and keeping up with What's New. It has pictures throughout, and a button at the top to print it or save it as a PDF.
July 3, 2026
- Sign-Up Sheets — templates now carry over invitees — When you use another event as a template for a new sign-up sheet, the people who were invited to that event are now automatically checked on the new one too (categories were already copied over). You can still add or remove anyone before saving.
- Sign-Up Sheets — invitee list now sorted oldest to youngest — The list of invitees on a sign-up sheet now appears in age order, oldest first. For a couple, the older person's age is used.
- Date of Birth is now required — When adding or editing a family member on the Edit page, Date of Birth must now be filled in.
- Database: date_of_birth is now NOT NULL — Rebuilt the
peopletable (SQLite requires a full rebuild to add a column constraint) after confirming no hard foreign-key references and taking a freshwrangler d1 exportbackup. The shared "GuestRatt" guest account (GUEST-001) had no birthdate on file and received an obviously-fake placeholder (1900-01-01) since it's already hidden from every list/report. Also correctedschema.sql, which had drifted from the live table and was missing theis_admin,password_hash,include_in_list, andis_guestcolumns entirely. - Fixed: GuestRatt could appear in four admin-only views —
/api/dataonly hides guest accounts from non-admins; admins always got the unfiltered list, and four pages weren't filtering it out on top of that: Reports' Custom Report member picker, the Dashboard's population/age stats, Sign-Up Sheets' "add a family member" dropdown, and Family Member Look-Up search. Regular (non-admin) members were never able to see it anywhere — this only affected what an admin could see. All four now excludeis_guestrows. It's still expected to appear on the Edit page's People directory, since that's where you manage its password.
July 2, 2026
- Site Audit Notes page corrected —
audit.htmlhad a few stale numbers left over from the original June 14 QA pass (it said 11 HTML files / 9 authenticated pages / 0 hardcoded colors — all since changed by later work). Updated the counts and replaced the absolute "zero hardcoded colors" claim with an accurate description of the current policy (token-based everywhere except one print-popup window that can't reachtheme.css). No functional change — this is a documentation correction only.
July 2, 2026
- Pop-up windows are easier to use with a keyboard — Pop-up windows across the site (the Edit dialogs and the Sign-Up Sheet dialogs, plus the admin Send Group Email → Sent Emails detail window) now close on the Esc key, move focus into the window on open and back to where you were on close, and expose
role="dialog"/aria-modal/aria-labelledbyso screen readers announce them correctly. Lightweight treatment — no focus-trap.
July 2, 2026
- Sign-Up Sheets — apostrophe in a contribution broke its edit button (fixed) — The per-claim ✎ (edit) button interpolated the description into an inline
onclickcall-string.esc()had already turned'into'(so the trailing.replace(/'/g,…)was a dead no-op), and the browser then decoded'back to'inside the attribute — producing invalid JS, so the button threw and did nothing for any description containing an apostrophe (e.g. "Mac 'n cheese"). The description is now carried in adata-descattribute and read viaelement.dataset, so user text never becomes part of a JS call-string. - Sign-Up Sheets — interactive controls moved to event delegation — Every dynamically-generated
onclick/onchangeinsignups.js(edit/delete event, request/approve/reject deletion, add/remove invite, add/delete category, add/edit/delete claim, attendee count, use-as-template, and the category-builder row remove) was converted todata-action+ delegated listeners, matching the pattern already used for the hub navigation. No behavior change; the static modal-button handlers insignups.htmlwere left as-is.
July 2, 2026
- Family Member Look-Up — sign-out badge restored —
lookup.jsnever calledRFAPI.mountUserBadge(), so the Look-Up page had no "Signed in as… · Sign out" badge and<body>never got the.is-non-adminclass — which also meant the Admin Tools nav link showed to every member on that page (a dead-end; the server still bounced non-admins). Added the mount call. - Records & Activity — toast notifications fixed — The local
toastalias inadmin-records.jspassed its arguments toRFAPI.toast(msg, kind, duration)in the wrong order (3000as kind, the type as duration). Success toasts rendered unstyled and error toasts vanished almost immediately (duration resolved toNaN). Restored correct coloring and the intended 3000 ms duration.
July 2, 2026
- Sign-Up Sheets — menu-driven navigation — The main page is now a hub of three choices (Current Events / Past Events / New Event) rendered via client-side view-switching in
signups.js. Current/Past show one-line lists (Organizer · date[+time] · title) that drill into the full sheet via the existingrenderEvent; Past opens read-only. The standalonesignups-past.htmlpage was deleted (its role moved into the hub's Past view). The adminsignups-pending-deletion.htmlpage is unchanged. - Sign-Up Sheets — permission corrections — The event creator (Organizer) can now edit/delete any claim on their sheet (
event-claims/[id].jscanEditnow allows the event'screated_by_id, not just admin/claim-owner). Invitees can remove themselves (event-invites/[id].jsDELETE now permits self-removal when the actor is inperson_ids, with an expired-event guard); a couple row removes both people. Admin-everywhere and invitee-own-line behavior were already correct. - Sign-Up Sheets — "Delete This Sheet" label + auto Organizer — Non-admin Organizer's button relabeled from "Request Deletion" to "Delete This Sheet" (same request→approval flow, same emails). The editable Organizer field was removed from the New Event form; organizer name is auto-set to the creator's nickname/first name and is omitted from edit PATCHes so it stays immutable. Existing events keep their stored organizer name.
- Sign-Up Sheets — fixed category display order — Category columns are sorted at display time (
sortedCategoriesinrenderGrid) to a canonical order: Entrée, Appetizers, Salads, Sides, Fruit, Desserts, Rolls / Bread, then custom names in creation order, then "Other" last. Storage/entry order is unchanged. The suggestions datalist was trimmed to those eight ("Rolls" → "Rolls / Bread"; Beverages/Condiments/Paper goods/Chairs/Tables/Ice removed). "Past Lists" wording changed to "Past Events" throughout the live UI. - Sign-Up Sheets — templating refinements — The New Event choice + picker heading are now "Use Another Event as a Template," and
openTemplatePickerlists all events (current + past, newest first) instead of past only. The per-sheet "Use as Template" button was removed fromrenderEvent's header (theuseAsTemplatefunction stays, reached only via the picker).
July 1, 2026
- Birthdays & Anniversaries — anniversaries now supported — The Edit page's Spouse/Partner section now has a "Marriage / Partnership Date" field, shared by both spouses since it lives on their one relationship record. Once a date is on file, the couple's anniversary automatically appears on the Birthdays & Anniversaries report — including marriages that ended in death (e.g. Nan & Pop), which are still commemorated each year. Populated initial dates for 23 of 24 current couples plus Nan & Pop from the family's historical records via direct database update (not through Edit, so these initial entries won't appear in Records & Activity). Two DePaulo marriages have no known date and were left blank.
- Sign-Up Sheets — guided New Event creation — "+ New Event" now opens a 3-way choice (Start from Scratch / Use a Past List as Template / Cancel) instead of one dense form. The template picker lists past events by Organizer, Date, Title, and Location. The New Event form gained searchable Individual and Couple Invitee checklists (Colorado households, age 16+, deceased members excluded, nickname-first display, bidirectional mutual exclusion so a couple and its two individuals can't both be checked, nobody checked by default, with Check all/Clear all links). Invite lists are now built entirely from what the Organizer checks — the previous fully-automatic server-side generation (which also had no deceased-member exclusion) is gone. Also fixed a bug where a partnered person never got a standalone checkbox in the Individuals list at all — meaning mutual exclusion silently never triggered — which also affected the "add a family member" dropdown on an event card; it now correctly offers both the individual and the couple option for a partnered person, with no state/age restriction.
- Sign-Up Sheets — deletion now requires Organizer or admin, non-admin requests go through review — Only the event's Organizer or an admin can delete a sheet now (previously delete was admin-only with no button shown to Organizers at all). An admin's delete stays immediate. A non-admin Organizer sees "Request Deletion" instead, which emails you (as admin) and the Organizer, then hides the sheet everywhere for everyone until you act. New column:
events.deletion_requested_at(migration2026-07-events-pending-deletion.sql). - New admin page: Lists Pending Deletion — Admin Tools → Lists Pending Deletion shows every sheet with a pending deletion request, read-only, with Approve Deletion (permanently removes it) and Keep Sign-Up Sheet (restores it, clears the flag) buttons. The Organizer is emailed the outcome either way. Backed by
GET /api/events/pending-deletionand newPOST /api/events/:idactionsrequest_deletion/approve_deletion/reject_deletion, all audit-logged. - Sign-Up Sheets — Event Name capitalization can be overridden — The Event Name field auto-capitalizes to Headline Case on blur only until the Organizer or an admin edits it further (e.g. "Cinco De Julio" → "Cinco de Julio," since "de" is Spanish for "of"); after that the field is left exactly as typed. Editing an existing event's name never auto-recapitalizes it, so a previously-corrected name can't get silently mangled again.
June 2026
June 30, 2026
- Send Group Email — Sent Emails log — The Send Group Email tool now has a "Sent Emails" tab listing every group email previously sent, with date, subject, sender, and recipient/sent/failed counts. Click "View" on any entry to see the full message body and complete recipient list.
June 22, 2026
- vCard name format — All vCard downloads (Family List Address Book, Custom Report, Member Look-Up) now show a person's nickname as their contact name when they have one, instead of their formal first name.
- Custom Report vCard — fixed missing contacts — The "Download .vcf" button on the Custom Report tab previously only showed the first selected person when opened in some contacts apps (including Windows). Fixed.
June 19, 2026
- Reports — Custom Report vCard download — The Create a Custom Report tab now has a Download .vcf button alongside View & Print and Download PDF. After selecting members, click it to download just those people as a contact file ready to import into any contacts app.
- Reports — Address Book download — A new Address Book card on the Family List tab of the Reports page lets any member download all living family members as a single
.vcffile, ready to import into iPhone, Android, Outlook, or any contacts app. Sorted alphabetically; deceased members excluded. - Activity — IP address and location tracking — Every login and page view is now logged with the visitor's IP address, city, state, country, and ISP. The Recent Logins table now shows IP, Location, and ISP columns; Recent Views shows IP and Location. Only new activity going forward is captured — older entries show "—". Find this under Admin Tools → Records & Activity → Activity.
- Guest account (GuestRatt) — You can now share the site with someone outside the family. Give them the shared site password and tell them to type GuestRatt at the name prompt — exactly as written, it is case-sensitive and will not appear in the login suggestions. Guests can browse all family data but cannot submit edits, sign up for sign-up sheets, or download PDF reports. The account is invisible everywhere on the site — not shown in the family list, reports, dashboard, look-up, or any dropdowns. You can manage the account from the Edit page.
June 18, 2026
- Fun with Data! — corrections — A heading on the generation composition chart has been corrected, and a confusing subtitle has been removed. On narrow phone screens, the Births per Decade chart now scrolls horizontally so all decades are visible.
June 16, 2026
- Family Member Look-Up — Download vCard — Every contact card on the Look-Up page now has a Download vCard button. Click it to download a
.vcffile with that person's name, address, phone numbers, email, and date of birth — ready to import into your iPhone, Android, Outlook, or any contacts app. - Reports — Create a Custom Report — The Reports page now has tabs, including a new Create a Custom Report tab. Build your own directory by selecting whole clans — which checks everyone in that clan so you can uncheck any you don't want — and/or picking individual family members, then choose which columns to show (address, cell phone, email, date of birth — names are always included). Your custom list keeps the same order and household grouping as the full Family List, and you can view, print, or download it as a PDF.
- Add-person requests now require approval — If a family member tries to add a new person to the site, the submission is now held in Pending Edits for your review. You receive an email notification and can approve, edit-then-approve (opens the Add Person form pre-filled with their proposed data so you can correct it before saving), or reject it. Previously, there was no server-side block and no notification.
- Include in family list — admin toggle — A new "Include in family list?" field is now in every person's edit modal (visible to admins only). Set it to Yes to include a step-child or other non-bloodline, non-spouse person on the family list and in reports. The person appears in non-bold (married-in) style. This setting is never applied automatically — an admin must set it per person.
June 15, 2026
- Sign-Up Sheets — add yourself — Any family member not already on a sign-up sheet can now add themselves with a single button click. Their name is added to the list so they can then sign up for any open slot.
- Sign-up sheet delete restricted to admins — Previously the server would allow a sheet's creator to delete it via a direct API call even though the Delete button was only shown to admins. The server now enforces admin-only deletion to match what the site shows.
- Admin privilege escalation blocked — A non-admin could previously craft a request to submit a pending edit that included an admin flag, which an admin might approve without noticing. The admin flag is now excluded from the pending-edit system entirely and can only be changed by an admin directly through the Edit page.
- What's New — Admin Updates page — This page. A new admin-only changelog under Admin Tools shows all site changes, with admin-only items highlighted in red so they are easy to spot.
June 14, 2026
- Age on Family Member Look-Up — Living members with a known date of birth now show their current age to one decimal point (e.g., "69.5 years old as of June 14, 2026") above their date of birth on the result card.
- Show/hide password — Every password field on the site now has an eye icon button so you can reveal or hide what you are typing while signing in or changing your password.
- Nicknames in all dropdowns — Every family member selection dropdown across the site now shows each person's nickname if they have one.
- Login accepts nickname or first name — Members with a nickname can sign in using either their nickname or their formal first name.
- Dark mode — All pages now respond correctly when a device is set to dark mode, with a consistent color scheme throughout.
- Mobile navigation — On smaller phone screens, the navigation menu now wraps cleanly instead of running off the edge of the screen.
- Records & Activity moved to Admin Tools — Pending edit requests, the recent-changes log, and the family activity summary are no longer on the Edit page. They now live under Admin Tools → Records & Activity, keeping the Edit page cleaner and those tools out of sight of regular members.
- Sortable tables on the Edit page — The People and Households tables can now be sorted by clicking any column header. Click once to sort; click again to reverse. Hold Shift and click a second column to sort on two fields at once (e.g., Branch first, then Generation within each branch).
- Site Audit Notes — A summary of the June 2026 quality review of the site's code is available under Admin Tools → Site Audit Notes.
- Activity and history locked to admins — The Recent Changes and Activity data feeds now enforce admin-only access on the server, so a regular member cannot retrieve that data even by making a direct request outside the normal site pages.
June 13, 2026
- Family Member Look-Up — A new search tool where any member can type a name and instantly see that person's contact card, including phone numbers, email, date of birth, and a clickable link to their address in Google Maps.
- Sign-Up Sheets — member list — The dropdown when adding someone to an event now shows a member's nickname (if they have one), and no longer includes deceased members.
- Phone number formatting — Hyphens are now added automatically as you type a phone number (XXX-XXX-XXXX), and numbers with fewer than 10 digits are not accepted.
- Admin preview mode — You can now switch to a "family member view" to see exactly what the site looks like to a regular member — no admin tools, no pending-edit buttons, nothing admin-specific. A banner at the top lets you switch back with one click. Find the option in your user badge (top right).
- Edit request confirmation email — The automatic email sent to a family member after they submit an edit request now includes a note telling them how long to expect before hearing back. This reduces follow-up questions to you.
June 12, 2026
- Sign-Up Sheets — A new section where any family member can create a sign-up sheet for an event (holiday gatherings, potlucks, etc.), and everyone can claim a slot. Creators can edit their own sheets. Past events are stored and viewable separately.
- Birthdays & Anniversaries print — Improved layout so the full list fits on one page, including on iPhones. A reminder now prompts users to select Legal-size paper for the best result.
- Group Email — You can now send an email to the whole family or to a targeted group (e.g., all Colorado members, all adults) directly from the site. Find it under Admin Tools → Send Group Email.
- Admin Tools hub — All administrator functions are now gathered in one place under "Admin Tools" in the navigation. Regular members see the link but are redirected away if they try to access any page under it.
- Household delete — safety check — When you delete a household, the confirmation dialog now shows how many people are currently listed at that address, so you can see at a glance whether anyone will be left without a home address before you confirm.
June 11, 2026
- Reports page — A new page with two printable/downloadable documents: the full Family List and the Birthdays & Anniversaries calendar. Both can be downloaded as PDF files or printed directly from the browser.
- Submit update requests — You can now submit a request to update your information on the site. Look for the "Suggest an Edit" button on the Edit page.
- Clickable contact info — Phone numbers and email addresses on the Family List are now clickable links.
- Edit request workflow — When a family member submits an update request, you receive an email notification. You can then review the proposed change, approve it as-is, edit it before approving, or reject it — all from the Records & Activity page. The member receives an email at each step.
June 1, 2026
- Undo recent changes — From the Recent Changes list in Records & Activity, you can undo any individual edit that was made in the past 30 days with a single click.
- Write access restricted to admins — Regular family members can no longer make direct changes to any record on the site. They can only submit edit requests for your review. This prevents accidental or unauthorized changes to family data.