Louis Whittington df06dcc0d7 Enhance person editing functionality and birthday reminders
- Added a modal for editing person details, including name, role, favorite color, birthday, and description.
- Implemented visibility toggling for PIN input based on role selection, ensuring security for Head of Household.
- Introduced birthday reminder functionality in the calendar, generating events for upcoming birthdays with appropriate notifications.
- Updated calendar and settings UI to accommodate new features, improving user experience and data management.
2026-03-31 18:08:22 -05:00
2026-03-30 14:53:13 -05:00
2026-03-30 21:05:12 -05:00
2026-03-30 14:53:13 -05:00
2026-03-30 14:53:13 -05:00
2026-03-30 19:08:26 -05:00
2026-03-30 14:53:13 -05:00

Family Hub

A centralized family organization system with tabs for chores, groceries, meal planning, family currency, and settings.

Features

  • Tabbed interface for chores, groceries, meals, combined Calendar (Family Hub agenda plus optional Google embed), currency, and family settings (profiles, stores, preferences)
  • Optional banking mode in the Currency tab: per-person checking, savings, and charity accounts with transfer rules and HoH controls
  • Banking safeguards and reporting: irreversible transfers into charity, immutable transaction reversals, and monthly statements (JSON/CSV)
  • JSON-based data storage under data/
  • Daily automated exports (scripts/daily_export.php and export.php?type=…)
  • Mobile-friendly interface

Setup

  1. Clone this repository to your web server.
  2. Configure the environment
    • With a browser, open the app URL (for example http://your-server/familyHub/). If .env is missing, you are redirected to install.php, which builds .env from env.example.
    • Alternatively, copy env.example to .env and edit .env by hand.
    • See Environment variables below for where to get each value.
  3. Ensure proper permissions on the data directory (and that the web server can create or write JSON files there).
  4. Set up the daily cron job for exports (see scripts/daily_export.php). It writes one JSON file per type into exports/ (for example chores, groceries, meals, meal_plans, expenses, stores, grocery_lists, grocery_catalog, bank_transactions). From the command line, the script exits with an error if .env is missing; complete browser setup first or copy env.example manually.
  5. Access the hub at http://your-local-ip/familyHub/ (adjust path and host to match your deployment).

Google Cloud prerequisites (OAuth + APIs)

Most Google-related values come from Google Cloud Console.

  1. Create or select a project.
  2. Open APIs & Services → Library, then enable any APIs you rely on (for example Google Calendar API and Google Drive API if you use those integrations).
  3. Open APIs & Services → OAuth consent screen and complete it for your use case (Internal for Workspace-only, External for broader testing; test users may be required until published).
  4. Open APIs & Services → Credentials → Create credentials → OAuth client ID. Choose Web application if your app uses a browser redirect.
  5. Under Authorized redirect URIs, add the exact URL you will put in GOOGLE_REDIRECT_URI in .env (scheme, host, path, no trailing slash unless your app uses one).

Use the official Google Cloud OAuth documentation for details if anything in the console changes.

Environment variables

Values are defined in env.example. The install wizard reads that file only; use this section to learn where to obtain each value.

Google API credentials

Variable What it is Where to find it
GOOGLE_CLIENT_ID Public OAuth 2.0 client ID for your app Google Cloud Console → APIs & Services → Credentials. Open your OAuth 2.0 Client ID (Web application). Copy Client ID.
GOOGLE_CLIENT_SECRET Secret for the same OAuth client Same credential row. Copy Client secret (treat it like a password; never commit it).
GOOGLE_REDIRECT_URI URL Google redirects to after OAuth Must match exactly one of Authorized redirect URIs on that OAuth client. Set it to your real callback URL (e.g. https://yourdomain.com/family-hub/auth/google/callback). Use the same scheme and path your server exposes.

Google Calendar

The Calendar tab embeds your family calendar in the hub using these values (HTTPS Google Calendar URLs only; optional iframe src is extracted from pasted HTML).

Variable What it is Where to find it
GOOGLE_CALENDAR_ID ID of the calendar to target (APIs, sharing, embeds) Google Calendar → hover the calendar in the sidebar → Settings and sharing → scroll to Integrate calendarCalendar ID (often an email or ...@group.calendar.google.com). If GOOGLE_CALENDAR_EMBED_CODE is unset, the tab builds a standard embed URL from this ID.
GOOGLE_CALENDAR_EMBED_CODE Embed URL or full iframe HTML from Google Same Settings and sharing page → Integrate calendar → copy the embed code (iframe) or the https://calendar.google.com/... URL from the src attribute. Prefer this when you want Googles chosen view options.

Google Drive

Variable What it is Where to find it
GOOGLE_DRIVE_FOLDER_ID Folder used as export or attachment root Google Drive → open the folder in the browser. The URL looks like https://drive.google.com/drive/folders/THIS_PART_IS_THE_ID — copy THIS_PART_IS_THE_ID.

Application settings

Variable What it is Where to find it
APP_ENV Logical environment name Your choice (e.g. development, staging, production). Used for app behavior toggles if the code checks it.
APP_DEBUG Verbose errors / debug mode true or false (strings as in env.example). Only use true on trusted local or staging servers.
APP_URL Base URL of this app Same origin users use in the browser (e.g. https://example.com/family-hub), no trailing path beyond the app root unless your deployment requires it. Should align with GOOGLE_REDIRECT_URI host/path where applicable.

Export settings

Variable What it is Where to find it
EXPORT_FREQUENCY How often exports are expected to run Your choice (e.g. daily). Match how you schedule scripts/daily_export.php in cron.
EXPORT_RETENTION_DAYS How long to keep export files (interpreted by app logic) Integer number of days (e.g. 30).

MCP / AI automation (optional)

These enable machine-to-machine access to the same JSON APIs the browser uses. When MCP_API_TOKEN is non-empty, API requests may send Authorization: Bearer <MCP_API_TOKEN>; the app then treats the request as the Head of household identified by MCP_ACTOR_PERSON_ID (PIN-verified semantics), without a browser session.

Variable What it is Where to find it
MCP_API_TOKEN Shared secret for automation (Cursor MCP, scripts, etc.) Generate locally (treat like a password). Example: openssl rand -hex 32. Paste into .env. Never commit the real value. If left empty, Bearer impersonation is disabled and only normal browser sessions work.
MCP_ACTOR_PERSON_ID Which person the token impersonates Open data/people.json (after setup) and copy the id field for your Head of household profile. Must match a person whose role is head_of_household. Wrong or non-head IDs are ignored and the token will not authenticate.

Security: The token grants the same power as a logged-in, HoH-verified session (create chores, manage people, grocery data, etc.). Use HTTPS in production. Rotate the token by changing .env and restarting anything that caches env.

Cursor MCP: The MCP server is plain PHP (no Node): mcp/familyhub/server.php. Register it in Cursor Settings → MCP with the absolute path to PHP and the script, and set environment variables FAMILYHUB_BASE_URL (your hubs …/api URL, e.g. http://localhost/family-hub/api) and FAMILYHUB_MCP_TOKEN (same value as MCP_API_TOKEN). Tools exposed: familyhub_health, familyhub_get_snapshot, familyhub_calendar_events, familyhub_post_api (allowlisted POST endpoints only).

Example mcp.json server entry (adjust paths and env):

{
  "mcpServers": {
    "familyhub": {
      "command": "php",
      "args": ["/full/path/to/familyHub/mcp/familyhub/server.php"],
      "env": {
        "FAMILYHUB_BASE_URL": "http://localhost/family-hub/api",
        "FAMILYHUB_MCP_TOKEN": "paste-the-same-secret-as-MCP_API_TOKEN"
      }
    }
  }
}

Calendar preferences (family settings)

These are not in .env; they live in data/family_settings.json and are edited under Family settings → Calendar and dates.

Key / UI Purpose Notes
Family timezone US IANA zone (e.g. America/Denver) Dropdown of US zones only. Drives today and date ranges on the Calendar tab agenda. Options are the standard PHP US timezone identifiers (e.g. America/*, Pacific/Honolulu).
Enable two-way Google Calendar sync Opt-in for future OAuth sync with Google Default off. When off, the Calendar tab uses the Google embed from .env (if set) and the local agenda only—no merge API. When on, the app may show sync messaging; full OAuth is not required for the embed.
Monthly bill reminders calendar_bill_days JSON array of { "dayOfMonth": 131, "title": "Rent" }. Shown on the agenda on that calendar day each month.

API: GET api/calendar_events.php?from=YYYY-MM-DD&to=YYYY-MM-DD returns { success, events, rangeStart, rangeEnd, today } for the signed-in profile (same session rules as other APIs). Omit from/to to use the default two-week window from today in the family timezone.

Banking mode (optional)

Enable this in Family settings → Chore economy → Banking system.

  • Accounts per person
    • checking_balance: primary spendable chore income balance.
    • savings_balance: earns the configured monthly rate, compounded daily via lazy apply when balances are read/written.
    • charity_pending_balance: funds committed to charity and not transferable back out.
    • charity_donated_total: historical amount already logged as donated by HoH.
  • Income routing
    • Approved chore payouts and HoH manual credits flow through checking.
    • Optional auto split sends a percent of each incoming credit to savings and charity.
    • Optional round-up rule moves each income credits fractional remainder to either savings or charity.
  • Permissions
    • Any active person can move their own funds between checking/savings/charity, but cannot transfer out of charity.
    • Verified HoH can add checking credits/debits, log charity outflows, and reverse transactions with immutable compensating entries.
  • Donation goals
    • Per-person monthly donation goals with progress based on current-month charity outflow totals.
  • Statements
    • GET api/bank_statement.php?month=YYYY-MM&format=json|csv[&person_id=...]
    • Non-HoH users can fetch only their own statement; verified HoH can request any person.

NFC chore submission (HoH)

NFC support uses per-chore tokens plus per-person submitter tokens so a scan can submit as a specific person and credit that person after HoH approval.

Family settings for NFC

In Family settings → Chore economy:

  • NFC base URL override (nfc_base_url): optional app base URL used when generating NFC links. Leave blank to auto-detect from the current request.
  • NFC scan cooldown seconds (nfc_scan_cooldown_seconds): optional soft replay dampener (0-600 seconds).
  • Show NFC confirmation page after scan (nfc_show_confirmation): when off, NFC scans redirect directly to chores.
  • Emergency NFC actions:
    • Disable all chore NFC links
    • Rotate all person NFC submitter tokens

HoH setup checklist (per chore)

  1. Open Chores as a verified Head of household.
  2. For a chore, optionally enable Allow anyone to complete this chore.
  3. Click Generate NFC links.
  4. Copy each person-specific URL and write it to that persons NFC card/tag (NDEF URI).
  5. Label tags physically (name + chore).
  6. Test scan once per person.

NFC URL format

Generated links use:

/api/chore_submit_nfc.php?id=<chore_id>&token=<chore_token>&person_token=<person_token>

  • token identifies the chore NFC token.
  • person_token identifies who is submitting (credit recipient on approval).

Completion and credit rules

  • Assignee-only chore (anyone_can_complete = false): only assignees may submit, even with valid person tokens.
  • Anyone-can-complete chore (anyone_can_complete = true): any valid person token holder may submit.
  • Credit is always applied only on HoH approval (not at scan time), to the submitted_by person on the pending submission.

Troubleshooting

  • Invalid chore token: regenerate chore NFC links and rewrite tags.
  • Invalid submitter token: rotate that person token and regenerate links.
  • Already pending review: wait for HoH approve/reject.
  • Chore inactive: reactivate/update chore before scanning again.
  • Lost/shared card: rotate token(s) or disable chore NFC immediately.

Security notes

  • NFC links are bearer-style secrets. Anyone with a valid URL can submit as that URLs person token.
  • Use HTTPS in production and rotate tokens on loss/suspected leakage.
  • Keep HoH approval enabled as the payout gate.

Directory Structure

familyHub/
├── api/                  # JSON endpoints (chores, groceries, meals, people, settings, expenses, banking, calendar_events, NFC helpers, …)
├── assets/               # Static assets
│   ├── css/              # CSS files
│   │   └── style.css
│   ├── js/               # JavaScript files
│   │   └── main.js
│   └── img/              # Images
├── config/               # Configuration files
│   ├── config.php
│   └── env.php           # Loads .env
├── data/                 # JSON data storage (not tracked in git)
│   ├── chores.json       # Chores, assignments, submissions, reviews
│   ├── people.json       # Profiles, roles, PIN hashes, currency balances
│   ├── family_settings.json   # Currency labels, US timezone, week start, calendar merge flag, bill reminders, etc.
│   ├── expenses.json     # Head-of-household expense log
│   ├── bank_transactions.json # Banking ledger (credits, debits, transfers, outflows, reversals)
│   ├── stores.json       # Grocery store definitions
│   ├── grocery_lists.json     # Per-store shopping lines
│   ├── grocery_catalog.json   # Deduped catalog / recurring metadata
│   ├── groceries.json    # Legacy single-file groceries; migrated when detected
│   ├── meals.json        # Meal library (titles, tags, ingredients, shopping items)
│   └── meal_plans.json   # Active weekly plan: `weekStart` (Monday YYYY-MM-DD) and `slots` 06 × breakfast/lunch/dinner → meal id or empty
├── includes/             # PHP includes (db, persona, tab helpers, `api_bootstrap.php`, …)
│   ├── header.php
│   ├── footer.php
│   ├── db.php            # JSON file I/O (flock)
│   └── utils.php         # Shared helpers
├── exports/              # Export output (not tracked in git)
├── scripts/              # Cron / CLI helpers
│   └── daily_export.php
├── mcp/familyhub/      # Optional MCP stdio server (PHP only): `server.php`
├── tabs/                 # Tab views included by `index.php`
│   ├── chores.php
│   ├── groceries.php
│   ├── meals.php
│   ├── calendar.php
│   ├── currency.php
│   └── settings.php
├── env.example           # Environment template (parsed by install.php)
├── install.php           # Web wizard to create .env when missing
├── .gitignore
├── .cursor/              # Cursor editor configuration and rules
├── readme.md
├── index.php             # Main entry point
├── AGENTS.md             # Agent / contributor notes
└── export.php            # `?type=` JSON export (same types as daily script)
Description
No description provided
Readme 2.6 MiB
Languages
PHP 82.7%
JavaScript 11.2%
CSS 6.1%