* fix: clean up dangling FK references before deleting a user
Resolves FOREIGN KEY constraint failed (500) on DELETE /api/admin/users/:id
and DELETE /api/auth/me when the target user had rows in trip_members.invited_by,
share_tokens.created_by, budget_items.paid_by_user_id, journeys.user_id,
journey_entries.author_id, journey_contributors.user_id, or
journey_share_tokens.created_by — none of which had ON DELETE clauses.
Introduces deleteUserCompletely() in userCleanupService.ts which wraps all
cleanup and the final DELETE FROM users in a single transaction. Both
adminService.deleteUser and authService.deleteAccount now call it instead of
the bare DELETE. Tests ADMIN-005b and AUTH-040 cover all reference types
including notification sender/recipient and notice dismissals.
* test: extend FK deletion tests to cover journeys, files, and photos
ADMIN-005b and AUTH-040 now also seed and assert:
- owned journey with entries (cascade-deleted via journeys.user_id cleanup)
- trip_files.uploaded_by (SET NULL — file survives, attribution cleared)
- trek_photos.owner_id (SET NULL — photo record survives, owner cleared)
- trip_photos.user_id (CASCADE — photo association removed)
* test: extend user deletion tests to cover all FK relationships
ADMIN-005b and AUTH-040 now seed and assert every user FK relationship:
CASCADE (row deleted): trips, trip_members, tags, mcp_tokens, oauth_tokens,
oauth_consents, vacay_plans, vacay_plan_members, bucket_list,
visited_countries, visited_regions, packing_templates, invite_tokens,
collab_notes, settings, password_reset_tokens, notification_channel_preferences
SET NULL (row survives, column nulled): categories, todo_items.assigned_user_id,
packing_bags, audit_log
Caught and fixed: notification_preferences was dropped in migration 72;
correct table is notification_channel_preferences.
* fix: preserve URL hash and OIDC redirect target through login flow
- Include location.hash in redirect param at all three producer sites
(ProtectedRoute, axios 401 interceptor, OAuthAuthorizePage) so
hash fragments survive the login bounce
- Stash redirectTarget in sessionStorage before any OIDC provider
redirect and restore it after the code exchange, since the IdP
strips the original ?redirect= param during the roundtrip
- Clear sessionStorage on OIDC error to avoid stale state
- Add tests covering sessionStorage stash on mount, navigate to saved
redirect after OIDC exchange, fallback to /dashboard, and cleanup
on error
* fix: use day position instead of ID for accommodation date range clamping
Math.min/Math.max over raw day IDs breaks the start/end picker when a
trip's day IDs are non-monotonic relative to day_number (normal after
repeated generateDays extend/shrink cycles). Replaced with findIndex
lookups so clamping is always based on positional order.
Closes#889
* fix: normalize env var comparisons to be case-insensitive
All NODE_ENV, DEMO_MODE, OIDC_ONLY, FORCE_HTTPS, COOKIE_SECURE, and
ALLOW_INTERNAL_NETWORK checks now use .toLowerCase() so values like
'Production' or 'True' behave identically to their lowercase forms.
Also adds APP_VERSION to the startup banner.
* fix: delete surplus days when shortening a trip
When shrinking a trip's date range, surplus days are now deleted along
with their assignments, notes, and accommodations (cascade). Places
remain in the trip pool; reservations keep their day reference nulled
by the existing ON DELETE SET NULL constraint (issue #909).
Updates TRIP-SVC-011 to reflect the new behaviour; adds TRIP-SVC-016
as a regression test for the empty-day case.
* fix: auto-backup retention deletes itself and manual backups on Docker
Two bugs in cleanupOldBackups:
1. Filter was .endsWith('.zip') — swept manual backup-*.zip files too.
Now restricted to auto-backup-* prefix.
2. Age was derived from stat.birthtimeMs, which is 0 on overlayfs
(Docker default), making every backup appear epoch-old and get
deleted immediately. Age is now parsed from the filename timestamp
and falls back to mtimeMs (reliable on overlayfs).
Also converts inline require('./services/auditLog') calls to a static
import throughout scheduler.ts, and adds 8 unit tests covering the
fixed retention logic including the overlayfs regression case.
* test: update TRIP-024 to match delete behavior on trip shrink
* feat: add bypass-branch-check label to skip branch enforcement
- Add wiki/Install-Proxmox.md with full install/update/log instructions
- Add Proxmox VE section to wiki/Updating.md
- Add Install: Proxmox VE (LXC) to wiki/_Sidebar.md
- Add "Proxmox Community Script" option to bug report install dropdown
- Exclude GitHub meta files from triggering Docker CI workflow
Moves the 91 MB product-tour GIF out of the repo entirely. Standard
clones and CI checkouts no longer pull it — even LFS-aware clients
previously downloaded the blob on checkout, which made `git pull`
noticeably slower for everyone.
The file now lives as a release asset on a separate repo and is
referenced from README via its GitHub Fastly-backed download URL.
Removes the LFS tracking entry from .gitattributes.
- Animated TREK logo (light + dark variants) via <picture> + prefers-color-scheme
- 60-second product tour GIF (91MB, 1100x619, 10fps) stored via Git LFS so
standard clones don't pull it by default
- 9 feature tiles as composite SVG grids: 3x3 on desktop, 2x4 on mobile
- 8 fresh screenshots captured from dev.pakulat.org
- Feature details folded into a collapsible 2-column table
- Environment variables moved behind a collapsible
- Roadmap badge added next to Live Demo / Docker / Discord
- Removed redundant Community section and footer
Adds the complete TREK documentation wiki covering installation,
trip planning, admin panel, MCP/AI integration, addons, and operations.
Also fixes encrypt-at-rest gaps: mapbox_access_token, Synology
credentials, per-user webhook/ntfy tokens, and photo passphrases
are now rotated by migrate-encryption.ts and stored encrypted via
settingsService.
- Add concurrency groups to both workflows to prevent parallel version-bump races
- Defer git tag push to merge job so orphan tags can't exist without a live image
- Pin build/merge jobs to the SHA captured in version-bump to prevent TOCTOU
- Guard auto-finalize in docker.yml against cross-major prereleases (requires bump=major + confirm_major=MAJOR)
- Add STABLE fallback to 0.0.0 for fresh repos with no stable tag
- Fix cleanup sort to extract numeric N via awk instead of fragile sort -t. -k4 -n
- Add 5-minute in-memory cache to checkVersion to avoid GitHub API rate limits
- Type GitHubPanel releases state; remove any cast on filter
- Quote all $VERSION/$MAJOR_TAG vars in imagetools create calls
- Remove stale mauriceboe/nomad tags from docker-dev.yml
- Fix APP_VERSION empty string fallback (?? -> ||)
- Fix compareVersions to handle -pre.N suffixes correctly
- Use highest existing N instead of tag count to avoid collision after cleanup
- Add cleanup step to keep only last 5 prerelease tags per base version
- Add docker-dev.yml: prerelease CI for dev branch with minor/major bump
inputs; auto-continues in-flight major line via existing pre tags;
publishes floating major-pre Docker tag (e.g. 2-pre)
- Rewrite docker.yml version-bump: tag-based versioning, manual bump
inputs (auto/patch/minor/major), major guarded by confirm_major=MAJOR,
auto-finalizes in-flight prereleases; publishes floating major tag (e.g. 2)
- Inject APP_VERSION build-arg through Dockerfile so the running container
knows its real version instead of reading package.json
- Server reads APP_VERSION env in authService/adminService; exposes
is_prerelease in app config and update-check response; prerelease builds
compare against GitHub prerelease releases rather than latest stable
- Client stores isPrerelease from config; navbar shows amber version badge
on prerelease builds (left of dark-mode toggle); GitHubPanel filters out
prerelease releases unless the running build is itself a prerelease
- Add PR template with description, type of change, and contributing checklist
- Enforce target branch: label + comment + 24h auto-close for PRs targeting main
- Flag bad issue titles: label + comment + 24h auto-close instead of instant close
- Redirect feature requests to Discussions (instant close, unchanged)
- Add two scheduled workflows to close stale labeled issues and PRs after 24h
- Update CONTRIBUTING.md with tests and branch up-to-date requirements
npm audit fix exits non-zero when vulnerabilities require breaking-change
upgrades (esbuild/vite, vite-plugin-pwa), blocking CI with no actionable fix.
Run frontend tests in parallel with backend tests on every PR.
Rename the server artifact to backend-coverage and upload client
coverage as frontend-coverage.
- No dates → tomorrow to tomorrow+7d
- Start only → end = start+7d
- End only → start = end-7d
- Both provided → unchanged
fix(ci): include client/package-lock.json in version bump commit
* add test suite, mostly covers integration testing, tests are only backend side
* workflow runs the correct script
* workflow runs the correct script
* workflow runs the correct script
* unit tests incoming
* Fix multer silent rejections and error handler info leak
- Revert cb(null, false) to cb(new Error(...)) in auth.ts, collab.ts,
and files.ts so invalid uploads return an error instead of silently
dropping the file
- Error handler in app.ts now always returns 500 / "Internal server
error" instead of forwarding err.message to the client
* Use statusCode consistently for multer errors and error handler
- Error handler in app.ts reads err.statusCode to forward the correct
HTTP status while keeping the response body generic