- Delete root social-preview.png (identical copy of docs/social-preview.png,
only the docs/ version is referenced in README)
- Consolidate BACKLOG.md: all 10 entries were completed, compress into a
reference table and clear the active section for future use
- Delete prompt-i18n.md (untracked, i18n fully shipped in v0.5.0)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Dockerfile used node:20-slim but the project requires Node >=22
(--experimental-sqlite in tests, CI matrix). package.json had a
duplicate engines block where the second (>=20.0.0) silently
overwrote the correct first one (>=22.0.0).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cookies were sent without Secure flag outside of production (NODE_ENV check).
New logic: secure=true by default; set SESSION_SECURE=false in .env to
allow HTTP explicitly (local dev without reverse proxy). Affects session
cookie, CSRF cookie in login handler, and CSRF middleware.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rate-limit SPA fallback route (missing rate limiting on fs access)
- Add csrfMiddleware to all state-changing auth routes (logout, create
user, change password, delete user) — previously bypassed global CSRF
middleware due to router registration order
- Fix incomplete vCard escaping: escape backslashes before other special
characters to prevent injection via contact fields
- Restrict CI GITHUB_TOKEN to contents: read (least privilege)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Internal Claude Code working documents (plans, specs) are not relevant
for contributors. Remove tracked files and add to .gitignore.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add social-preview.png to version control (referenced in README but untracked)
- Update README: test count 146+ → 162 across 9 suites
- Add engines.node >=22.0.0 to package.json (required for --experimental-sqlite)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Files that kept their original names after content replacement were served
from GitHub's CDN cache. Rename with -2 suffix to force fresh delivery.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cleanup() set dragging = null, then onUp accessed dragging.slot,
.mealId, .sourceDate, .sourceType on the now-null reference.
Fix: destructure all needed values before calling cleanup().
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
External image requests to openweathermap.org fail silently in Chrome
Android PWA standalone mode. Icons are now proxied via
GET /api/v1/weather/icon/:code, making them same-origin — cacheable by
the service worker and free of CORS/CSP issues.
Tightened CSP: removed openweathermap.org from imgSrc (no longer needed).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Icons were cached with immutable/30-day headers, so Chrome Android kept
serving the old placeholder even after new icons were deployed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add id field and display_override to manifest.json for reliable
Chrome Android PWA recognition
- Serve manifest.json with application/manifest+json MIME type
- Add /i18n.js and locale files to SW app shell cache (were missing)
- Bump SW cache version to v21
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Android was showing only a blue circle because maskable icons had no
visible content after the adaptive icon mask was applied. All icons now
use the actual Oikos house logo from docs/logo.svg. Maskable variants
use full-bleed background with logo within the 80% safe zone.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The locale JSON files use nested structure (e.g. {"nav":{"tasks":"…"}}),
but t() did a flat lookup, always falling back to the raw key string.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace all hardcoded German strings in router.js (navItems labels,
aria-labels, skip-link, error/toast messages) with t() calls. Add a
locale-changed event listener that re-renders sidebar and bottom-nav
items on language switch.
Replace hardcoded German strings in modal.js and oikos-install-prompt.js
with t() calls; wire locale-changed event listener for live re-render on
locale switch.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extracts all German UI strings from public/pages/, public/components/,
and public/router.js into 482 i18n keys organized by module prefix.
English translations added for all keys.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Discussions links for questions at top and bottom of CONTRIBUTING.md.
Update security reporting to reference GitHub Private Vulnerability Reporting.
Customize Discussions #2 welcome post with project-specific content.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Delete orphaned Python screenshot generators, social-preview template,
and duplicate icon files in public/assets/ (superseded by public/icons/).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Geometric house icon on blue gradient rounded square (SVG).
Replaces shields.io badge placeholder in README hero section.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restructure README with compelling hero section, "Why Oikos?" philosophy
section, two-column feature grid, tablet screenshot gallery, and streamlined
quick start. Add GitHub Private Vulnerability Reporting link to SECURITY.md.
Include social preview HTML template for GitHub social card generation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>