safeeyes
간단하고 아름다운 휴식 알림으로 눈 피로 보호
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
Kova - personal health and productivity app
README 전체를 불러오는 중입니다.
README 전문 보기 ↗One HTML file (the app) plus a small server, both on Netlify's free plan, with sign-in, the database and push notifications on Firebase's free Spark plan. Nothing here needs a credit card.
index.html - the whole app. Built from index.html plus the modules in src/
(python3 src/inject_p07.py index.html puts them in; edit the module, not the copy inside the page).functions/ - the server: every /api route, publishing, the wellness agent, reminders, payments.netlify/functions/ - three small files that run functions/ on Netlify.privacy.html - the privacy policy (also shown inside the app).build/site.mjs - npm run build writes dist/, the folder Netlify publishes: the same page
minified (about 420 KB compressed instead of 880 KB), Work OS and the study tools (32 screens) split
into a file that loads after the first screen, and only the files the site serves.SETUP.md - every key, where to get it and where it goes. ROUTES.md - every server route, which
file implements it and where the app calls it (generated; CI keeps it true).native/ - the iPhone and Android app (Capacitor). See native/README.md.Why not Firebase Cloud Functions: since 2020 they need the paid Blaze plan, and since February 2026 so does Firebase Storage. Blaze has a free tier but needs a card and has no spending cap. Netlify's free plan stops (the site pauses until next month) instead of charging, so there is never a surprise bill.
Everything in the app persists through a small set of localStorage keys. That is the real
storage boundary, so the sync layer sits there rather than inside each pillar. One
interception point means Fuel, Workout, Sleep, Vitals, Work OS and Studio all sync at once,
and there is no second copy of any value to drift out of step.
| Module | What it does |
|---|---|
KovaCloud | Mirrors all 21 tracked storage keys to Realtime Database under users/{uid}/store. Offline-first. |
KovaMedia | Files (form-check video, food photos, machine scans, avatars, docs) to /api/media/upload in 3 MB parts, kept in Netlify Blobs. Wired at 5 capture points. |
KovaAnalytics | One track() into both Firebase Analytics and gtag. |
KovaCloudAuth | Email/password, Google, anonymous guest, password reset. |
Ordering matters: writes go to localStorage first and always succeed; the cloud copy is
best-effort and catches up. A failed network call can never lose a logged set or a logged meal.
Conflicts are last-write-wins per key, using a timestamp stored beside the value. Per key rather than per field, because these keys hold independent documents — the food log does not overlap the sleep history. A field-level merge would be inventing precision we cannot honour.
The security rules are the only thing protecting the data. Until they are deployed the database is world-readable, regardless of what the app code does.
npm install -g firebase-tools
firebase login
firebase deploy --only database
Then in the Firebase console:
KOVA_FB_VAPID near the top of index.html (it is public). Without it, reminders on the website only
show while Kova is open.netlify.toml sets everything; there is no build step.여기까지가 README 앞부분입니다. 나머지는 원문에서 읽을 수 있습니다. README 전문 보기 ↗