MyKid

English • Русский • Беларуская

MyKid

MyKid

Journal for your child's life

Photos, videos, moments — stored in your Immich. Journal syncs via Supabase.

Screenshots • Features • Quick Start • Setup • License

Platform Flutter License


Screenshots

Select child Timeline empty Timeline with entry

Suggestions Add entry modal Entry view New entry form


Features

Quick Start

flutter pub get
flutter run --dart-define-from-file=.env

See Setup for Supabase and Immich configuration.


Project Description (for AI / LLM context)

This section provides a full technical and functional overview for AI assistants working with the codebase.

What the app does

MyKid is a Flutter (Dart) mobile app for parents to keep a journal of their child’s life. Each journal entry can contain: date, text description, place (location), photos/videos (stored as references to Immich assets), and an optional link to a child profile.

Tech stack

Data model

Children (children table): id, user_id, name, date_of_birth, immich_album_id (optional; album created in Immich for this child).

Journal entries (journal_entries table): id, user_id, date, text, assets (JSONB array of {immichAssetId, caption?}), child_id (optional FK to children), location (optional text), created_at, updated_at.

RLS: users can access only their own rows.

Features (current)

  1. Auth
    • Supabase Auth (email/password). AuthGuard redirects to LoginScreen if not authenticated.
    • Login, signup, sign out. Session persists.
  2. Journal list (JournalListScreen, route /)
    • Lists all entries (from Supabase), ordered by date descending.
    • Pull-to-refresh; on network error falls back to Hive cache.
    • FAB: create entry via modal: From camera From gallery Empty entry.
    • From camera: take photo → upload to Immich → open new entry with today’s date, no location.
    • From gallery: pick one photo → read EXIF (date, GPS → reverse geocode for place) → upload to Immich → open new entry with inferred date/location.
    • Empty entry: open new entry with today, no assets.
    • AppBar: batch import button, settings button.
    • Tap entry → open JournalEntryScreen.
  3. Journal entry (JournalEntryScreen)
    • View mode (default for existing entries): large photo preview, swipe between photos, tap photo → fullscreen with Share/Back. Edit button to switch to edit mode.
    • Edit mode: date picker, child selector (ChoiceChips), place field, description text, photo grid. Add photos (camera/gallery) → upload to Immich → add to entry; optionally add to selected child’s Immich album.
    • Generate description: button sends first photo to selected AI provider (OpenAI/Gemini/Claude vision, or DeepSeek via on-device ML Kit labels + text API) and fills description field. Configure in Settings → AI providers.
    • When child is selected and photos are added, app creates Immich album “MyKid: {name}” for the child (if needed) and adds assets to it.
    • Save creates/updates entry in Supabase. Delete: optionally remove photos from child’s Immich album.
    • New entries open in edit mode; existing ones open in view mode.
  4. Children (Settings → Manage children, route /children)
    • List, add, edit, delete child profiles (name, date of birth).
    • Children used in journal entries to link entries to a child and to organize photos in Immich albums per child.
    • Age displayed as “X лет Y мес Z дн” (Russian) or similar.
  5. Batch import (route /import)
    • Pick multiple photos/videos (FilePicker) → upload all to Immich → create one journal entry with all assets.
    • Opens JournalEntryScreen in create mode.
  6. Settings (route /settings)
    • AI providers (route /settings-ai-providers): API keys for OpenAI, Gemini, Claude, DeepSeek; select default provider for “Generate description” in journal entries.
    • Immich: server URL and API key; Test connection (saves on success).
    • Link to Manage children, Family invites.
    • Legal: Privacy Policy, Terms of Use, Support, Open Source Licenses (App Store / Google Play compliance).
    • Account: Export my data (GDPR), Delete account, Sign out.

Key modules

Routes

Environment


Setup

Prerequisites

Environment

Create a .env or use --dart-define so the app can reach Supabase. Do not commit real keys.

Example .env.example:

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key

The app also supports loading these from a config file or build-time defines; see lib/core/config.dart.

Backend (Supabase)

  1. Create a project at supabase.com.
  2. Apply the schema: in Supabase Dashboard → SQL Editor run docs/full_schema.sql.
  3. In Supabase Dashboard → Authentication → enable Email (or other providers you want).

Table journal_entries and API are described in docs/backend.md.

Immich

In the app: Settings → Immich: set your Immich server URL and API key (create the key in your Immich instance). All photo/video uploads and thumbnails use this connection.

AI descriptions (optional)

To use “Generate description” in journal entries, go to Settings → AI providers: add one or more API keys (OpenAI, Gemini, Claude, DeepSeek) and select the default provider. Keys are stored only on device. See docs/ai-providers.md for details and how DeepSeek uses on-device labels.

Run

Copy .env.example to .env, fill in your Supabase URL and anon key, then:

flutter pub get
flutter run --dart-define-from-file=.env

Or pass defines explicitly:

flutter run --dart-define=SUPABASE_URL=https://your-project.supabase.co --dart-define=SUPABASE_ANON_KEY=your-anon-key

(Use an Android device/emulator first; iOS requires a Mac and proper signing. If the ios/ folder is incomplete, run flutter create . to regenerate platform files; camera/photo usage descriptions are already in ios/Runner/Info.plist.)

Offline

When the app cannot reach Supabase, the journal list falls back to the last cached entries (Hive). After going back online, pull-to-refresh to sync again.

Project structure

For store compliance, the app includes links to Privacy Policy, Terms of Use, Support, Account Deletion, and Data Export. Configure in .env:

PRIVACY_POLICY_URL=https://scroodge.github.io/MyKid/privacy.html
TERMS_OF_SERVICE_URL=https://scroodge.github.io/MyKid/terms.html
SUPPORT_URL=mailto:scroodgemac@gmail.com
ACCOUNT_DELETION_URL=mailto:scroodgemac@gmail.com?subject=Account%20Deletion%20Request
DATA_EXPORT_URL=mailto:scroodgemac@gmail.com?subject=Data%20Export%20Request
SOURCE_CODE_URL=https://github.com/scroodge/MyKid
SPONSOR_URL=https://github.com/sponsors/scroodge

Or use --dart-define=PRIVACY_POLICY_URL=... etc. when building.

Self-service account deletion

The app calls the delete-account Edge Function, which removes the user and cascades to children, journal entries, household data. Deploy:

supabase functions deploy delete-account

Open Source Licenses

Regenerate lib/oss_licenses.dart after changing pubspec.yaml dependencies:

dart run dart_pubspec_licenses:generate

Contributors

Thanks to everyone who contributes to MyKid. See CONTRIBUTING.md for how to get involved.

Support development

If you find MyKid useful, consider supporting its development:

License

MIT License