Commit Graph

33 Commits

Author SHA1 Message Date
Alexander 530308033b fix(build): disable prerender crawl so build stops OOMing
`/hikes` is `prerender = true` and carries the global nav, so the
prerender crawler followed those links and tried to statically render
the whole dynamic, DB-/ML-backed app. SvelteKit prerenders inside a
heap-capped worker_threads worker, so this exhausted its heap
(ERR_WORKER_OUT_OF_MEMORY) and failed the build.

- svelte.config.js: prerender.crawl = false. The intended static set is
  fully described by `prerender = true` (/hikes) + the /errors/[status]
  EntryGenerator, so crawling is unneeded. Add a defensive
  handleHttpError that ignores /hikes/*/images/* 404s (those binaries
  live in hikes-assets/, served by nginx/dev-middleware, not /static).
- hooks.server.ts: skip init when `building` so builds don't connect to
  Mongo, start the payment scheduler, or warm the romcal cache.
- hikes/[slug]: set `prerender = false`, enforcing the intent its
  comment already stated.

Version 1.86.1 -> 1.86.2.
2026-05-24 15:41:39 +02:00
Alexander f3d16d5187 feat(hikes): route-builder, overview map + cards, SAC-coloured pipeline
Build pipeline (scripts/build-hikes.ts) parses per-hike GPX, encodes
images via sharp, reverse-geocodes the centroid against Swisstopo and
emits a typed manifest under src/lib/data/hikes.generated.ts (gitignored).
Track JSON + image binaries live outside /static; served in dev by a
small hike-images plugin in vite.config.ts, in prod by nginx (private/
images proxied through Node + X-Accel-Redirect for auth-gating).

/hikes overview: full-bleed Swisstopo hero map (HikesOverviewMap) sits
under the sticky nav, drawing one polyline per route coloured by SAC
tier (T1 yellow Wegweiser, T2/T3 white-red-white, T4-T6 white-blue-
white). Click navigates, hover thickens + tooltips. Layer toggle,
recenter, GPS controls mirror the detail map (minus images toggle).
Cards drop the trail SVG, gain a per-route icon + SAC marker
pictogram on the cover, altitude range, season label, and "Neu" badge
for recently-published hikes. Filter bar + totals strip recompute over
the currently-visible set.

/hikes/[slug]: hero map with elevation profile, photo strip with map
sync, scroll-position pin, GPX download, SAC marker stats + min/max
altitude + season.

Route-builder (/hikes/route-builder): client-side draft persisted to
localStorage, EXIF-driven image placement, snap-to-route via BRouter
(OSRM + linear fallback) and Swisstopo profile.json elevation
enrichment that handles degenerate same-coord segments via the height
endpoint.

Filter init switched from a script-time snapshot of data.hikes (which
sporadically returned a one-hike subset during dev hydration and
locked the page to that single hike) to a post-mount \$effect.

Content under src/content/hikes/ intentionally not included (WIP).
2026-05-18 21:13:00 +02:00
Alexander 4623d7a1f7 feat(seo): noindex hook, recipe self-canonical, list-page metadata
CI / update (push) Successful in 37s
Add X-Robots-Tag noindex,nofollow handler in hooks.server.ts for /api,
/login, /logout, /register, /settings, /tasks, /fitness, /cospend,
/expenses, and the recipe admin/edit/add/search/favorites/to-try paths.
Header-based so the rule lives in one place and covers JSON responses.

Recipe detail pages now emit a self-canonical pointing at the bare slug —
the layout helper deliberately skipped detail pages, leaving query-param
variants (?multiplier=2, ?utm=…) as duplicate URLs in Google's index.

Per-page Seo on list pages so each ranks for its category-level query:
- Apologetik contra/pro indices now use localized heading + lede instead
  of hardcoded English descriptions
- Calendar month view title includes month + rite ("April 2026 ·
  Liturgical Calendar (Vetus Ordo) — Bocken")
- Recipe /category, /tag, /icon, /season hub + detail pages get
  descriptions via new *_meta_description and *_meta_prefix i18n keys
  (added in both DE and EN locales)
2026-05-02 22:23:15 +02:00
Alexander ecbd24d7a4 feat(seo): per-route html lang, QAPage/Breadcrumb/Event/WebSite schemas, sitemap lastmod
Set <html lang> from URL prefix via handle hook (was hardcoded "en" despite
mostly German content). Add Person + WebSite + SearchAction graph to root
layout — enables Google sitelinks search box and clusters identity across
git.bocken.org and github.com/AlexBocken via sameAs.

Build apologetikJsonLd.ts: contra args now emit QAPage with one suggestedAnswer
per voiced archetype, citations as CreativeWork. Build breadcrumbJsonLd.ts and
wire BreadcrumbList into recipe detail, contra args, prayer detail, and
calendar day. Calendar day also emits Event schema.

Sitemap now reads recipes directly from MongoDB to populate <lastmod> from
dateModified; static URLs use server-startup ISO date. English recipe URLs
only emitted when translation status is approved.
2026-05-02 21:48:05 +02:00
Alexander d8abcbf74b refactor(hooks): move server bootstrap into ServerInit hook
Module-level top-level await for db/scheduler init and the cache
warmup IIFE move into the canonical export const init hook. Same
ordering and non-blocking semantics; makes the lifecycle explicit
and works on environments without top-level await.
2026-04-30 19:07:42 +02:00
Alexander 2b1a415ab6 perf(faith): warm liturgical cache + fix 1962 rendering
CI / update (push) Successful in 3m59s
Pre-compute romcal year maps on server boot for current + next civil year
across en/de/la in each rite's default diocese, non-blocking so startup is
unaffected.

Also fixes several 1962-rite rendering bugs: commemorations previously
leaked 1969-shape ids (e.g. andrew_apostle) next to proper 1962 sancti;
station church names came through unresolved because RomcalConfig's
internal i18next has no bundle loaded; season names arrived as raw keys
(advent.season) for the same reason. All three now resolve locally via
the shipped 1962 bundle with Latin as fallback. ClassIV ferias get a
small dot on the grid.
2026-04-21 08:04:20 +02:00
Alexander 9093e0fe51 perf: add Server-Timing, split fitness bundle, tighten DB queries
- Add `timing` handle in hooks.server.ts emitting Server-Timing headers
  and expose `locals.timing.mark/measure` for per-load instrumentation.
- Drop dead `getEnrichedExerciseById` fallback in fitness detail page —
  server load already 404s via errorWithVerse, so the client no longer
  pulls exercisedb-raw.json (~760KB) into the detail bundle.
- Add `{ createdBy: 1, nextExecutionDate: -1 }` index on RecurringPayment
  for user-scoped list queries.
- Narrow populate projections in cospend/debts (title/date/category on
  userSplits, _id only on allRelatedSplits) to cut payload + hydration.
- Parallelize today's sessions + WorkoutSchedule lookup in the nutrition
  page load via Promise.all; add `.lean()` + `.select('templateId')` to
  the lastScheduled query.
2026-04-21 07:37:10 +02:00
Alexander ad154bf914 fix(errors): surface Bible verses on section error pages
SvelteKit's handleError hook is skipped for expected `error()` throws,
so verses set there never reached `$page.error` for server-thrown 404s
and auth denials. Introduce `errorWithVerse()` in `$lib/server/errorQuote`
that fetches a random verse first, then throws `error(status, body)`
with `{ message, bibleQuote, lang }`, making the quote available in
every `SectionError`. Convert all page load throws (catchalls, layout
validators, calendar, prayers, recipes, fitness, cospend, admin) and
hooks.server auth gates to the helper. Add `src/error.html` as a
branded last-resort fallback.
2026-04-20 22:39:39 +02:00
Alexander 9af36b0c14 feat: add EN/DE internationalization to cospend section
Move cospend routes to parameterized [cospendRoot=cospendRoot] supporting
both /cospend (DE) and /expenses (EN). Add cospendI18n.ts with 100+
translation keys covering all pages, components, categories, frequency
descriptions, and error messages. Translate BarChart legend, ImageUpload,
UsersList, SplitMethodSelector, DebtBreakdown, EnhancedBalance, and
PaymentModal. Update LanguageSelector and hooks.server.ts for /expenses.
2026-04-08 15:46:01 +02:00
Alexander e92fc1cc25 feat: shareable shopping list links with token-based guest access
- Generate temporary share links (default 24h) that allow unauthenticated
  users to view and edit the shopping list
- Share token management modal: create, copy, delete, and adjust TTL
- Token auth bypasses hooks middleware for /cospend/list routes only
- Guest users see only the Liste nav item, other cospend tabs are hidden
- All list API endpoints accept ?token= query param as alternative auth
- MongoDB TTL index auto-expires tokens
2026-04-08 09:04:58 +02:00
Alexander 81c70df78e tasks: shared task board with sticker rewards, difficulty levels, and calendar
Complete household task management system behind task_users auth group:
- Task CRUD with recurring schedules, assignees, tags, and optional difficulty
- Blobcat SVG sticker rewards on completion, rarity weighted by difficulty
- Sticker collection page with calendar view and progress tracking
- Redesigned cards with left accent urgency strip, assignee PFP, round check button
- Weekday-based due date labels for tasks within 7 days
- Tasks link added to homepage LinksGrid
2026-04-02 07:32:55 +02:00
Alexander f8daf7f295 fix: cache auth session on locals to prevent cookies.set after response
The authorization hook already calls locals.auth() which can set cookies.
Layout server loads calling auth() again caused a race where cookies.set()
fired after the response started streaming. Now the hook stashes the session
on locals.session and all layouts reuse it.
2026-03-20 16:28:31 +01:00
Alexander fa3c40d6de fitness: require authentication for all fitness routes 2026-03-20 06:53:06 +01:00
Alexander 19e46b2b3a fix: replace any types with proper types across codebase
Replace ~100 `any` usages with proper types: use existing interfaces
(RecipeModelType, BriefRecipeType, IPayment, etc.), Record<string, unknown>
for dynamic objects, unknown for catch clauses with proper narrowing,
and inline types for callbacks. Remaining `any` types are in Svelte
components and cases where mongoose document mutation requires casts.
2026-03-02 20:15:08 +01:00
Alexander d2ac67fb44 fix: resolve all 1008 svelte-check type errors across codebase
Add type annotations, JSDoc types, null checks, and proper generics
to eliminate all svelte-check errors. Key changes include:
- Type $state(null) variables to avoid 'never' inference
- Add JSDoc typedefs for plain <script> components
- Fix mongoose model typing with Model<any> to avoid union complexity
- Add App.Error/App.PageState interfaces in app.d.ts
- Fix tuple types to array types in types.ts
- Type catch block errors and API handler params
- Add null safety for DOM queries and optional chaining
- Add standard line-clamp property alongside -webkit- prefix
2026-03-02 08:40:18 +01:00
Alexander 134b3deaa4 add Douay-Rheims Bible to the project for english bible references 2026-02-11 10:15:54 +01:00
Alexander c2a25941db chore: update @auth/sveltekit to v1.11.1 and remove direct @auth/core dependency
Updated authentication packages to latest versions for security fixes:
- @auth/sveltekit: 1.10.0 → 1.11.1 (includes nodemailer security fix)
- @auth/core: removed from devDependencies (transitively pulled as 0.41.1)

Changed imports to use @auth/sveltekit/providers instead of @auth/core/providers
and removed unused imports from hooks.server.ts.
2026-01-10 17:49:51 +01:00
Alexander 7a44ffefb4 feat: enhance rosary with interactive Bible citations and improved mystery selection
- Add clickable Bible reference buttons that open modal with full verses
- Create BibleModal component with backdrop blur and styled close button
- Implement build-time data fetching for Bible texts while maintaining reactivity
- Redesign mystery selector with responsive grid (3-in-row/4-in-row/2×2)
- Add "Heutige" badge to indicate today's auto-selected mystery
- Reposition luminous mysteries toggle below mystery selector
- Integrate Bible reference and counter buttons side-by-side
- Restructure Bible API under /api/glaube/bibel/ for better organization
2025-12-16 15:45:40 +01:00
Alexander b233c55ee6 fix: implement persistent MongoDB connections and resolve race conditions
- Replace connect/disconnect pattern with persistent connection pool
- Add explicit database initialization on server startup
- Remove all dbDisconnect() calls from API endpoints to prevent race conditions
- Fix MongoNotConnectedError when scheduler runs concurrently with API requests
- Add connection pooling with proper MongoDB driver options
- Add safety check for recipes array in favorites utility
2025-09-14 19:53:55 +02:00
Alexander 9c50a60853 fix: use event.fetch instead of global fetch for server-side requests
Updated both hooks.server.ts and bible-quote API to properly use event.fetch
for relative URLs in server-side code, following SvelteKit best practices.
2025-09-12 23:17:18 +02:00
Alexander 498d156a9d error page: prettier + random bible verse 2025-09-12 23:11:57 +02:00
Alexander 96f8dce88c error page: prettier + random bible verse 2025-09-12 22:49:32 +02:00
Alexander eea126c099 cospend: require group membership for access 2025-09-12 22:27:21 +02:00
Alexander eedfd3ecec Add comprehensive recurring payments system with scheduling
- Add RecurringPayment model with flexible scheduling options
- Implement node-cron based scheduler for payment processing
- Create API endpoints for CRUD operations on recurring payments
- Add recurring payments management UI with create/edit forms
- Integrate scheduler initialization in hooks.server.ts
- Enhance payments/add form with progressive enhancement
- Add recurring payments button to main dashboard
- Improve server-side rendering for better performance
2025-09-12 12:41:18 +02:00
Alexander 3a2737c3b1 Implement proper page redirects for protected routes
- Update hooks.server.ts to preserve original URL when redirecting to login
- Use callbackUrl parameter to maintain user's intended destination
- Preserve both pathname and search parameters in redirect flow
- Leverage OIDC standard callback URL support built into Auth.js
- Users now land exactly where they intended after authentication
- Works for /rezepte/add, /rezepte/edit/[name], and any future protected routes
2025-08-31 22:04:27 +02:00
Alexander fb8394adfe Update @auth/sveltekit to latest stable version 1.10.0
- Upgraded @auth/sveltekit from 0.14.0 to 1.10.0
- Updated session API from event.locals.getSession() to event.locals.auth()
- Fixed TypeScript definitions for new auth API in app.d.ts
- Updated layout server load functions to use LayoutServerLoad type
- Fixed session callbacks with proper token type casting
- Switched to generic OIDC provider config to resolve issuer validation issues
- All auth functionality now working with latest Auth.js version
2025-08-31 21:45:14 +02:00
Alexander 04fecbeb0e remove unnecesarry deps since moving to authjs 2024-02-19 23:17:16 +01:00
Alexander b138e56633 OIDC can check for groups now to properly secure users 2024-02-15 04:10:06 +01:00
Alexander ac5786355c re-protect client paths 2024-02-15 03:13:49 +01:00
Alexander e7ed39dc51 initial OIDC setup 2024-02-14 16:07:55 +01:00
Alexander c541fcc7a1 user displayed in navbar with option to logout 2023-07-19 14:52:50 +02:00
Alexander a6b8685f91 First fully working user management, move to layout groups 2023-07-18 14:18:52 +02:00
Alexander c14b174a42 cleaner login and registration 2023-07-18 12:05:30 +02:00