Revert AutoScroll and Headline components to their original JS
requestAnimationFrame implementations. Keep the WASM-based AutoScroll
as an alternative at util/wasm/AutoScroll.vue.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Port AutoScroll and Headline scroll logic from Vue/JS to Rust compiled
to WASM via wasm-pack. Add multi-stage Docker build for WASM compilation,
Vite WASM plugins, and top-level await for WASM init. Enable Hasura
service in docker-compose. Move bookmarks from a separate route to an
inline sidebar component on the home page. Fix ToggleHeader click
propagation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Deleted handle_activity.go, handle_favorites.go, handle_post.go, and
handle_user.go — all logic already exists in schema.resolvers.go.
Removed corresponding REST routes from main.go. Moved UserCredentials
struct (used by Login handler) into handle_auth.go.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a Docker healthcheck to the backend service (polling GET / every 30s)
and the willfarrell/autoheal container to automatically restart any unhealthy containers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auth-protected CRUD for personal info (LinkedIn, GitHub, etc.) and
experience entries, stored in the database so nothing sensitive is in
the public repo. Displayed as a categorized panel on the Job Applications page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Lazy-load create forms (Post, Activity, Favorite, Rowing) directly
into their corresponding home components with an admin-only toggle
button, replacing the need to navigate to the admin page.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace hardcoded bookmarks in the frontend with a GORM-backed Bookmark
model exposed through GraphQL query and admin-only create/delete mutations.
Frontend groups bookmarks by category dynamically from the store.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pass the requested URI as ?redirect= when nginx denies access, so the
login page can forward the user to their intended destination on success.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add /admin/login route for Login.vue as a standalone page
- Add requiresAdmin guard to /admin route
- Update auth guard redirect to /admin/login with redirect query param
- Update nginx @auth_denied to redirect to /admin/login
- Remove Login component from Admin.vue; drop v-if auth checks (guard handles access)
- Remove stale view files from old views/ structure (moved in prior commit)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move shrines and bookmarks under home/, landing and 404 into own
subdirectories, and retire Notes.vue (served by external service).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add DefaultLayout and CVLayout with nested routing
- Job applications is now a standalone page at /cv/jobs with a back link
- Remove JobApplications embed from CV.vue
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Full CRUD GraphQL API for tracking job applications with status workflow.
Frontend component in CV view, hidden from print. Login now redirects to
intended route after auth via query param.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When the access token is missing or expired, the handler now falls back
to the refresh token, verifies the user is still admin via DB lookup,
and issues fresh cookies in the subrequest response.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ValidateAdmin endpoint that checks JWT admin claim for use as an
nginx auth_request subrequest. Widen cookie path from backend endpoint
to "/" so the access_token is sent on all paths. Extend access token
lifetime from 24h to 7 days. Disable hasura service by default via
Docker profile.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Gin's trusted proxies list is hardcoded to 172.28.0.0/16, but Docker was
assigning the bridge network whatever subnet was free, so c.ClientIP()
often returned nginx's container IP instead of the real client.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merges both files and adds full endpoint reference, .env variable table,
setup guides (Spotify, Certbot, Obsidian/Quartz, Icecast), deprecated
endpoint notes, and updated architecture with all services.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Since app.ini is gitignored, the container needs to create it at
runtime. The entrypoint copies the template on first start, then
Gitea's env var overrides handle secrets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Runtime config (app.ini) should not be tracked since secrets are
injected via env vars in docker-compose. The template remains as
source of truth. INTERNAL_TOKEN is removed from the template as
it is set exclusively via GITEA__security__INTERNAL_TOKEN env var.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Strip hardcoded secrets from gitea/config/app.ini (already injected
via GITEA__ env vars) and commit it to git. Add download.sh to fetch
the act_runner binary on demand instead of syncing it. Everything else
(searxng settings, certbot certs, runner registration, Spotify tokens)
is generated at runtime.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove unused uptime-kuma and wallabag services from docker-compose,
nginx configs, and vite proxy. Use BASE_URL env var in searxng
settings template instead of hardcoded URL.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Untrack .runner (contains registration token), act_runner binary, and nohup.out
- Add gitea-runner sensitive files to .gitignore
- Auto-register runner from env var if .runner is missing
- Switch deploy workflow git pull from HTTP to SSH
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>