d866d32336
Admin can now enter CalDAV URL, Apple-ID and app-specific password directly in Settings; credentials are tested live before saving and stored in sync_config (take precedence over .env); disconnect clears DB-stored credentials without server restart. Auto-sync interval (15 min, configurable via SYNC_INTERVAL_MINUTES) was already in place. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7.9 KiB
7.9 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
Added
- Calendar: recurring events are now expanded in GET /api/v1/calendar — all occurrences within the requested date window are returned as virtual instances; duration is preserved; instances are marked with is_recurring_instance=1 and shown with a ↻ icon in the agenda view; /upcoming also expands recurring events within a 90-day window
- Budget: recurring entries auto-generate instances for each viewed month; instances deleted by the user are skipped permanently via
budget_recurrence_skippedtable; generated instances are marked with ↩ in the transaction list - Budget: month-over-month comparison in summary cards — each card (Einnahmen, Ausgaben, Saldo) shows a trend line (▲/▼ + delta amount vs. previous month); previous month summary is fetched in parallel with current month
- Meals: drag & drop between slots and days using Pointer Events (touch + mouse); ghost element follows pointer; drop on occupied slot swaps meals; reduced-motion: no ghost animation, interaction still works
- Settings: Apple CalDAV credentials form (URL, Apple-ID, app-specific password) with live connection test; admin can connect and disconnect via UI without restarting the server; DB-stored credentials take precedence over .env vars; auto-sync runs every 15 min (configurable via SYNC_INTERVAL_MINUTES)
[0.2.1] - 2026-03-30
Fixed
- Accumulating click listeners on
#notes-grid: listener is now registered once inrender()via event delegation instead of re-registered in everyrenderGrid()call - Accumulating anonymous
documentclick listener in dashboard FAB:initFab()now accepts an AbortSignal;render()aborts the previous signal before creating a new one, eliminating listener leaks across navigation cycles - Add
btnError()shake feedback to notes.js save error handler for consistency with other modules - Calendar event popup
closePopuplistener now checkspopup.isConnectedto self-remove correctly after navigation without a click
Added
- CSS alias
.form-labelalongside.labelto cover usage innotes.jsandsettings.jswithout requiring a mass-rename - Tests for
wireBlurValidation,btnSuccess, andbtnError(12 cases) intest-modal-utils.js
[0.2.0] - 2026-03-30
Changed
- Directional slide-x page transitions (forward = right, backward = left) with race condition guard
- PWA install prompt delayed until 2 user interactions; dismiss window reduced from 30 to 7 days; interaction counter resets on dismiss
- Unified card padding to 16px (
--space-4) across tasks, contacts, budget, and meals modules
Added
- Staggered fade-in animation for list items on page load across all modules (tasks, shopping, meals, contacts, budget, notes, calendar agenda)
- Unified empty states using shared
.empty-stateclass across all modules (replaces per-module CSS) stagger()andvibrate()UX utilities inpublic/utils/ux.jswith full test coverage- Proportional opacity on swipe-reveal action areas in tasks (already implemented, confirmed)
- FAB colors tied to per-module accent tokens via CSS custom properties
scrollIntoViewfor focused inputs when virtual keyboard opens in modals (300ms delay)- Consistent vibration feedback via
vibrate()utility across tasks, shopping, contacts, budget, and notes - Bottom sheet modal on mobile (< 768px) with drag handle, slide-in animation, and swipe-to-close
- Enter-key navigation between form fields in modals; Enter on last field triggers submit
- Blur-triggered inline validation for required fields with error/success border states
wireBlurValidation(),btnSuccess(), andbtnError()exported frommodal.js- Submit button checkmark-success (700ms) and shake-error feedback animations
0.1.0 - 2026-03-29
Initial release of Oikos — a self-hosted family planner for 2–6 person households. Runs as a Docker container behind Nginx with SSL, no cloud dependency.
Added
- Dashboard with time-of-day greeting, urgent tasks, upcoming events, today's meals, pinned notes, and weather widget (OpenWeatherMap integration with 3–5 day forecast scaling by screen size)
- Task management with categories, priorities, due dates, subtasks (max 2 levels), list and Kanban views, swipe gestures on mobile (swipe left = toggle done, swipe right = edit), and recurring tasks via iCal RRULE
- Shopping lists with multiple named lists, supermarket-aisle sorting, autocomplete from history, optimistic checkbox toggle, and bulk-clear of checked items
- Weekly meal planner with breakfast/lunch/dinner/snack grid (Mon–Sun), ingredient tracking per meal, and one-click transfer of ingredients to shopping lists
- Calendar with month, week, day, and agenda views, multi-day event support, color-coded entries, and family member assignment
- Google Calendar sync via OAuth 2.0 with incremental sync tokens and Apple CalDAV sync via tsdav, both bidirectional
- Pinboard (notes) with color-coded sticky notes, pin-to-top, Markdown formatting toolbar (bold, italic, lists, headings, code, links), and automatic text contrast based on background color
- Contacts directory with category filtering (doctor, emergency, trades, etc.), full-text search, and direct tel:/mailto:/maps: links
- Budget tracker with income/expense logging, monthly navigation, category breakdown bar charts (pure CSS), and CSV export
- Settings page for password change, calendar sync status, and family member management
- Authentication with session-based login (bcrypt, httpOnly/secure/sameSite cookies, 7-day TTL), admin-only user creation, and rate-limited login (5 attempts/min with 15-min lockout)
- CSRF protection using Double Submit Cookie pattern with timing-safe comparison
- Progressive Web App with app-shell caching (service worker with stale-while-revalidate for static assets, network-first for navigation, network-only for API), custom install prompt for Android and iOS, dynamic theme-color per module, safe area inset handling, and offline fallback
- Responsive design with mobile bottom navigation (swipeable pages with dot indicator), collapsible sidebar on tablet, and full sidebar on desktop
- Dark mode with system preference detection and manual toggle, warm-tinted neutral color scale
- Design system with CSS custom properties (tokens for colors, spacing, typography, shadows, radii, z-indices), module-specific accent colors, and consistent component patterns
- Accessibility improvements: skip link, sr-only headings on all pages, aria-hidden decorative icons, aria-label on icon-only buttons, token-based touch targets (44–48px), 12px minimum font size, and prefers-reduced-motion support
- Docker deployment with docker-compose, optional SQLCipher encryption (AES-256), and nginx.conf example
- Setup script (
node setup.js) for initial admin account creation with LAN-reachable URL display - Input validation middleware with centralized rules (string length, date/time format, enum, color) across all API routes
- Content Security Policy via Helmet with strict CSP, self-hosted Lucide Icons (no CDN at runtime)
- Lazy loading with per-page ES module imports cached in memory, Cache-Control headers (immutable for assets, must-revalidate for code), and service worker update notification
Security
- Fail-fast on missing
SESSION_SECRETin production - Rate limiting on login endpoint and global API limiter (300 req/min/IP)
- No user data cached by service worker (API requests are network-only)
- Hardened
.gitignoreand.dockerignoreto prevent accidental secret or binary leakage