12 KiB
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)
- JSON-based data storage under
data/ - Daily automated exports (
scripts/daily_export.phpandexport.php?type=…) - Mobile-friendly interface
Setup
- Clone this repository to your web server.
- Configure the environment
- With a browser, open the app URL (for example
http://your-server/familyHub/). If.envis missing, you are redirected toinstall.php, which builds.envfromenv.example. - Alternatively, copy
env.exampleto.envand edit.envby hand. - See Environment variables below for where to get each value.
- With a browser, open the app URL (for example
- Ensure proper permissions on the
datadirectory (and that the web server can create or write JSON files there). - Set up the daily cron job for exports (see
scripts/daily_export.php). It writes one JSON file per type intoexports/(for examplechores,groceries,meals,meal_plans,expenses,stores,grocery_lists,grocery_catalog). From the command line, the script exits with an error if.envis missing; complete browser setup first or copyenv.examplemanually. - 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.
- Create or select a project.
- 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).
- 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).
- Open APIs & Services → Credentials → Create credentials → OAuth client ID. Choose Web application if your app uses a browser redirect.
- Under Authorized redirect URIs, add the exact URL you will put in
GOOGLE_REDIRECT_URIin.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 calendar → Calendar 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 Google’s 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 hub’s …/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": 1–31, "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.
Directory Structure
familyHub/
├── api/ # JSON POST endpoints (chores, groceries, meals, people, settings, expenses, calendar_events, …)
├── 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
│ ├── 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` 0–6 × 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)