- Paste-to-embed: pasting an image into the markdown editor uploads it and
inserts  at the cursor. Unlike gallery attachments these aren't
tied to a journal_entry (the entry may not exist yet while composing), so
they're stored per-user under app/media/journal/{user_id}/pasted/ with no
DB row, served through an ownership-scoped route, and never cleaned up
automatically when an entry is deleted -- an accepted tradeoff at this
app's personal scale.
- The markdown sanitizer was stripping all <img> tags (not on the bleach
allowlist), which would have silently deleted every pasted image on save;
added img/src/alt/title while keeping event-handler attributes blocked.
- Cap embedded image width in both the editor pane and the rendered preview
so a large pasted photo can't overflow its card.
- Fix real data loss risk found while testing this: docker-compose.yml had
no volume for app/media, so every container recreate during a deploy wiped
uploaded photos, and deploy_sftp.py was syncing app/media/ (runtime user
data, not source) into the remote build context. Added the volume mount
and excluded media/ from the sync script. Recovered and relocated the
real attachments that had already landed in the wrong place on the NAS
during earlier deploys this session.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- rebrand from 습관 트래커 to 해빗랩 across templates, manifest, service worker
- add HTTPS redirect middleware for reverse-proxied deployments
- add public landing page (/) and privacy policy page with real data
handling disclosures
- add in-app account deletion (Apple review requirement)
- add Android TWA Digital Asset Links support (/.well-known/assetlinks.json)
- add SFTP deployment script for the Synology-hosted server
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add offline.html served by the service worker when a never-visited route
is requested without network. Disable rubber-band overscroll bounce and
gray tap highlights so standalone mode feels less like a webview. Split
theme-color by prefers-color-scheme so the iOS status bar matches dark
mode, and add a proper 180x180 apple-touch-icon instead of downscaling
the 192px icon.
FastAPI + SQLAlchemy/Alembic + MariaDB backend with Jinja2/htmx/Alpine
server-rendered frontend. Multi-user via Google OAuth, daily habit
tracking, monthly/weekly history views, Web Push reminders via
APScheduler, and PWA support (manifest, service worker, offline caching).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>