Project summary · Last updated May 2026 · Current build v6.7 · All modules stable · Trial launch imminent
A feature-complete family management web app for chores, trades, tokens and rewards. Built entirely in vanilla HTML, CSS and JavaScript — no framework, no build step, no npm dependencies. Google Sheets serves as the database via a Cloudflare Worker proxy. The app is deployed on Cloudflare Pages behind Zero Trust access control, with a separate public-facing documentation site.
Designed initially for a single family as a cost-efficient proof of concept, with an architecture that can evolve to serve multiple families. Built solo over approximately 14 days (est. ~101 hours) with AI assistance throughout design, engineering and testing.
Four distinct layers, each with a clear responsibility. The app HTML never communicates with Google Sheets directly — all data access is mediated by the Cloudflare Worker.
The app's security model evolved significantly during development. The initial version had the Google service account private key embedded in the client HTML — readable by any authenticated user via browser DevTools. A three-tier hardening plan was identified and fully implemented in v6.0–v6.3, resulting in a defence-in-depth architecture where no sensitive credential is ever accessible client-side.
The Zero Trust layer was already in place and provides strong perimeter protection. The three tiers add security within that perimeter.
Content-Security-Policy — restricts resource originsX-Frame-Options: DENY — prevents clickjacking via iframe embeddingX-Content-Type-Options: nosniff — prevents MIME type sniffingReferrer-Policy: no-referrer — prevents URL leakage in referrer headersThe Super Admin role is scoped to platform administration only. A Super Admin can see that a family exists, its name and member count — but cannot access any family content: no chores, no trades, no rewards, no member personal data. This is a deliberate privacy boundary enforced at the application level.
Google Sheets is functional at current scale but is not a production-grade database for multi-family use. The planned D1 migration replaces Sheets with Cloudflare's serverless SQLite, keeping all data within the Cloudflare ecosystem. Because the Worker already mediates all data access, this migration requires no changes to the app HTML — only the Worker's data layer changes.
The UI is built on a consistent CSS custom property token system. Every colour, radius, spacing unit and typography size is defined as a variable — this is what makes dark mode possible without per-component rewrites. All design was AI-generated and iterated through the development process. Future plan is a dedicated UI polish sprint.
fh_theme in localStorage. Persists across sessions on the same device. Reads and applies on page load before render to prevent flash.prefers-color-scheme media query checked on first load. If no saved preference exists, the app automatically matches the device OS setting.[data-theme="dark"] attribute on documentElement. Covers all badge variants, action buttons, inputs, select dropdowns, banners, trade cards and reward elements. Components using CSS variables adapt automatically.isDark() used where inline styles (e.g. reward banners) need programmatic colour selection. Keeps dark-mode logic consistent across both CSS and JS-rendered elements.Testing is primarily manual and role-based, supported by a dedicated test environment at test.nyefome.uk backed by a separate Sheets database. Every build is validated across all four roles before promotion to production. The two-environment gate is the primary quality control mechanism.
Given the single-file, no-framework architecture, there is no unit test runner or CI pipeline. Test coverage is behavioural — each feature is validated end-to-end through the UI as a real user would use it. This approach was chosen for speed of iteration during the initial build phase.
Three distinct environments serve different purposes. All three share the same codebase but point to different Sheets databases and API endpoints. Promotion always flows in one direction: test → production. The guide is environment-independent — it covers the app generally and is not tied to a specific build.
These limitations are the result of deliberate early-stage trade-offs — choosing speed of delivery and zero cost over architectural perfection. Each one has a known resolution path. The app works correctly within these constraints at current scale, and the architecture is designed to evolve without requiring a rewrite.
Terms used throughout the app, this document and the user guide.
localStorage persistence via fh_theme key. System prefers-color-scheme auto-detected on first load. 45 dark-override selectors covering badges, buttons, inputs, banners, trade cards. isDark() helper for JS-rendered inline styles. Version bumped from v6.6.apiCall() function replaces direct sheets.googleapis.com calls. getGToken/importPK removed.Current phase — Trial launch
Near term
Medium term
Completed security roadmap
Key data model notes
Open backlog
Resolved backlog
Reference files