Project
Two Tails
An iPhone and iPad app for one household: shared lists, Google Calendar, workouts, and one screen for what today needs. List and workout edits save on the device first, then sync between members.
In development · Not on the App Store yet
Visit the Two Tails websiteWhat This Demonstrates
The gap between saving an edit on one phone and sharing it with the household: the app says so when it is offline, uploads are waiting, or a change could not be saved or shared.
The App
- Today
- One screen for what is due, today's events and classes, and the day's workout. Fixed rules flag overlaps. A next-7-days view shows light days and moves an item only after you confirm.
- Shared Lists
- Keep groceries, chores, and errands in checklists the household can edit. Items can have due dates, notes, links, and repeat schedules. Shopping lists group by store section.
- Calendar
- Each member connects their own Google account and picks one calendar to view, create, and edit events. Google Calendar tokens and events stay on that device and in Google, with one exception: a class marked attended becomes a workout the household can see, with its title, times, and event id.
- Workouts and Apple Health
- Record sets, reps, weight, time, or distance, and see what you did last time while logging the next one. Connecting Apple Health is optional and read-only. It brings in workouts, daily steps, and each workout's active energy and average heart rate.
An Edit Should Not Wait for Wi-Fi
Lists and workouts save on the device first. Pending changes stay queued until the server accepts them. If the server rejects one as invalid, it leaves the queue and stays only on that device. A status line stays quiet while all is well and appears when the device is offline, uploads are waiting, or a change could not be saved or shared.
How It Is Built
Save on the Device
- Native SwiftUI app
- Full local copy of household records
An edit does not wait for a network connection.
Queue the Change
- Pending changes kept on the device
- Retry after a connection failure
The status line stays quiet while all is well. It appears when the device is offline, uploads are waiting, or a change could not be shared.
Sync the Household
- Production backend on AWS
- Signed-in household members
- Lists, workouts, and imported health data
Push pending changes, then pull the household change feed. The server checks membership on every request and merges field by field. Calendar events take a separate path through Google.
What the Household Sees
- Everyone in a household can see all fitness and health data that any member brings into Two Tails, including imported Apple Health data.
- Anyone who joins later can also see the lists and workouts from before they joined.
- The app says so before someone joins a household or connects Apple Health.
The product website holds its privacy policy, health data policy, and support information.
Current Limits
- Two Tails is not on the App Store, so there is no public download yet. The website and the production backend are live; the app is not released.
- Automated checks run on simulators and a local backend. They do not show how the app behaves on a physical iPhone or iPad, or with live Google, Apple Health, and notification services.
- Physical-device testing is a separate step and is still open. Apple Health import has not run on a device yet.
- Live sign-in and the production backend have no recorded end-to-end run from a device yet.
The app source is private; the files below build this portfolio page.
Inside the Build
The files that do the work, the choices behind them, and excerpts taken from the source each time the site builds.
Key Files
apps/portfolio/src/pages/TwoTails.tsx
The portfolio page, product link, household visibility, and current limits
apps/portfolio/src/content/two-tails.ts
Workflow descriptions, the sync diagram, and the visibility and limits text
apps/portfolio/src/content/projects.ts
Discovery through the project library and search
docs/specs/two-tails.md
The source record for the statements on this page
Decisions
Saving lists and workouts on the device first
Over waiting for the server before saving an edit: household tasks still need to work without a connection.
A separate Google Calendar connection on each device
Over copying calendar events into household sync: the server never receives Google Calendar tokens or calendar events; a class marked attended crosses over only as a workout.
A next-7-days plan built from fixed rules
Over adding a generated note to the plan: the generated note failed its evaluation, so the plan was built without it.
The Household Sync Flow
apps/portfolio/src/content/two-tails.ts · line 27 · TypeScript
export const twoTailsArchitecture: FlowStage[] = [
{
stage: 'Save on the Device',
parts: ['Native SwiftUI app', 'Full local copy of household records'],
note: 'An edit does not wait for a network connection.',
},
{
stage: 'Queue the Change',
parts: ['Pending changes kept on the device', 'Retry after a connection failure'],
note: 'The status line stays quiet while all is well. It appears when the device is offline, uploads are waiting, or a change could not be shared.',
},
{
stage: 'Sync the Household',
parts: ['Production backend on AWS', 'Signed-in household members', 'Lists, workouts, and imported health data'],
note: 'Push pending changes, then pull the household change feed. The server checks membership on every request and merges field by field. Calendar events take a separate path through Google.',
},
];Explore Next
Run a weekly delivery review in a sandbox that never leaves your browser.