Open-WebUI's SvelteKit frontend hardcodes asset/API paths at build time,
so subpath hosting under /openwebui/ produced 404s on /_app/... assets.
Move it to its own subdomain so it can run at root.
- certbot: request cert with chat.${DOMAIN} as a third SAN via --expand
- nginx (prod): drop /openwebui blocks; add chat.${DOMAIN} HTTP redirect
+ HTTPS server with the existing admin auth gate
- nginx (dev): drop /openwebui blocks (no chat.localhost in dev)
- compose: WEBUI_URL points to https://chat.${DOMAIN}
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Drop the Crown and Anchor entry and rework Profile, Key Strengths,
Experience and Additional so the copy reads more like something I'd
actually write rather than polished boilerplate.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Rework the apprenticeship-specific profile into a general electrical
apprenticeship pitch, folding in the useful framing from Why Electrical,
and tighten experience and Additional copy.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Rewrite email_imap.go to use a minimal hand-rolled IMAP client instead of go-imap/go-message,
for better compatibility with Outlook's non-standard responses
- Consolidate and simplify CVLayout.vue CSS overrides
- Bump vite from 7.1.11 to 7.3.2
- Move SEED_DB env var from nginx to backend in dev compose
- Add /app/src/wasm volume exclusion in dev compose
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move Query/Mutation field declarations from the monolithic schema.graphql
into each domain's .graphql file using extend type, so gqlgen places
resolvers in the matching *.resolvers.go files. Extract helper functions
into *_helpers.go files to prevent gqlgen from commenting them out.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use Docker's embedded DNS resolver (127.0.0.11) with nginx variables in
proxy_pass directives so upstream hostnames are re-resolved at runtime
instead of being cached forever at startup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
go-imap/v2's strict wire parser rejects Outlook's non-standard IMAP
login responses. v1 is more lenient and handles these gracefully.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Background poller fetches emails via IMAP or Microsoft Graph API,
classifies them with Claude Haiku, and creates/updates JobApplication
records automatically. Includes manual sync endpoint and OAuth callback.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>