Skip to content
scroodgePublic

About

Baby journal app. Flutter + Immich + Supabase. Self-hosted photos, cross-platform (Android/iOS).

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

51 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

  • Self-hosted — photos in your Immich, data in your Supabase
  • Family sharing — invite household members, share children and entries
  • EXIF magic — date and location auto-filled from photo metadata
  • AI descriptions — generate journal text from photos (OpenAI, Gemini, Claude, or DeepSeek with on-device labels); see docs/ai-providers.md
  • Offline-ready — cached journal list when offline
  • Batch import — add many photos at once

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.

  • Backend: Supabase (auth, Postgres) — journal entries and children profiles.
  • Media: Immich — all photos/videos are uploaded to the user's own Immich instance; only asset IDs are stored in Supabase.
  • Offline: Hive cache for journal list when offline; pull-to-refresh to sync when back online.

Tech stack

  • Flutter (Dart)
  • Supabase (auth, PostgREST)
  • Immich (self-hosted photo server; REST API)
  • Hive (local cache)
  • image_picker, file_picker, exif, geocoding, cached_network_image, share_plus, path_provider
  • AI (optional): user API keys for OpenAI, Gemini, Claude, DeepSeek; http for API calls; google_mlkit_image_labeling for DeepSeek path (on-device labels → text prompt)

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

  • lib/core/: config (Supabase URL/key), ImmichClient/ImmichService/ImmichStorage, photo_metadata (EXIF date/GPS→place), ai_provider_storage (API keys + selected provider), ai_vision_service (Vision / DeepSeek text), on_device_image_labels (ML Kit labels for DeepSeek on Android/iOS).
  • lib/data/: Child, JournalEntry, JournalEntryAsset; JournalRepository (Supabase CRUD), ChildrenRepository; JournalCache (Hive).
  • lib/features/auth/: AuthGuard, LoginScreen, SignUpScreen.
  • lib/features/journal/: JournalListScreen, JournalEntryScreen.
  • lib/features/children/: ChildrenListScreen, ChildEditScreen.
  • lib/features/import/: BatchImportScreen.
  • lib/features/settings/: SettingsScreen, AiProviderSettingsScreen.

Routes

  • / — journal list (guarded)
  • /login — login
  • /signup — signup
  • /settings — settings
  • /settings-ai-providers — AI provider API keys and default provider
  • /children — children list
  • /import — batch import

Environment

  • SUPABASE_URL, SUPABASE_ANON_KEY — from .env or --dart-define-from-file=.env.

Setup

Prerequisites

  • Flutter SDK (stable)
  • Android Studio / Xcode for running on device or simulator
  • Supabase project (free tier is enough)
  • Your own Immich instance or public Immich server

Environment

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

  • SUPABASE_URL — your Supabase project URL (e.g. https://xxxx.supabase.co)
  • SUPABASE_ANON_KEY — Supabase anonymous (public) key

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

  • lib/ — Flutter app
    • main.dart — entry, Supabase init, Hive cache init
    • core/ — config, Immich client, secure storage, AI provider storage & vision service, on-device image labels (ML Kit)
    • data/ — models, Supabase repository, local cache (Hive)
    • features/ — auth, journal list/detail, settings, AI provider settings, batch import
  • docs/ — full_schema.sql (apply once in SQL Editor), backend.md (schema, API), ai-providers.md, immich-api.md, edge-function-setup.md

Legal URLs (App Store / Google Play)

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

About

Baby journal app. Flutter + Immich + Supabase. Self-hosted photos, cross-platform (Android/iOS).

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages