Add share metadata and a real product social card so OpenSEO links render with a stronger preview. Sync the landing site and app shell favicons with the shared Every App icon set.
* refactor: move lighthouse audits to dataforseo (#43)
* refactor: move lighthouse audits to dataforseo
* chore: remove obsolete audit settings modal
* refactor: rename psi flows to lighthouse
* save
* refactor: simplify audit lighthouse storage flow
* fix: separate lighthouse metrics from actionable audits
* refactor: remove redundant audit project inputs
* feat: redesign lighthouse issues screen with score gauges and table layout
Replace flat score cards with circular SVG gauges, condense metrics into
a compact grid, and switch issue list from cards to an expandable table
with fixed column widths.
* test: harden lighthouse regression coverage
* fix: restore project-scoped audit inputs
* refactor: simplify lighthouse payload handling
* refactor: inline lighthouse server handlers
* refactor: share audit workflow types
* refactor: simplify lighthouse payload flows
* save
* refactor: drop project pagespeed api key
* fix: restore lighthouse issues loading with resilient project context
* fix: restore audit issues back navigation
* refactor: simplify project context and lighthouse error handling
* fix: tolerate DataForSEO lighthouse payload drift
* refactor: route audit lighthouse through dataforseo client
---------
* refactor: move DataForSEO response cache from KV to R2
KV TTL-based expiry is imprecise for cache freshness. Switch to R2 with
soft TTL via custom metadata (expiresAt) and a 7-day lifecycle rule for
cleanup. Cache objects live under the `dataforseo-cache/` prefix,
separate from durable audit payloads in `site-audit/`.
* refactor: use Workers crypto for R2 cache keys
Keep the cache helper aligned with the Cloudflare runtime and avoid pulling Worker bindings into Vitest. Also clarify that R2 lifecycle cleanup is optional but recommended to control storage growth.
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add email verification and password reset for hosted auth
Add email-based sign-up verification and password reset flows using
Better Auth and Loops transactional emails. New routes for
/verify-email, /reset-password, and /forgot-password. Sign-up now
redirects to verify-email page instead of showing inline state.
* refactor: use TanStack Form standard schema validation for auth forms
Pass Zod schemas directly to `validators.onSubmit` instead of manually
calling safeParse and reducing over issues. TanStack Form v1.25+ with
Zod v4 handles field-level error extraction automatically.
* refactor: use form.isSubmitSuccessful instead of manual state
Replace `submittedEmail` state in forgot-password and `isComplete`
state in reset-password with TanStack Form's built-in
`isSubmitSuccessful` flag, removing the need for useState in both.
* fix: formatting and lint fixes for ci:check
Fix prettier formatting, replace unsafe type assertions with
Reflect.get for Cloudflare env access.
* fix auth copy and verification redirect
* refactor: derive auth route page copy from state
* refactor: rename delegated auth user table
* feat: scaffold hosted better auth setup
* feat: add hosted auth flows
* refactor: scope project access to organizations
* fix: harden hosted auth entry points
* fix: stabilize org backfills and auth state
* refactor: simplify hosted organization setup
* fix: restore hosted auth signup flow
* fix: preserve hosted workspace access
* fix: preserve hosted auth redirects
* Improve hosted auth UX: auto-redirect to sign-up, hide header on auth pages, add form placeholders, and trust portless dev origins
- Auto-redirect unauthenticated users to /sign-up in hosted mode
- Hide top nav on /sign-in and /sign-up for a cleaner auth experience
- Add input placeholders across sign-in and sign-up forms
- Make name field optional on sign-up (falls back to email username)
- Update copy: remove 'hosted' from user-facing text, rename link to 'Create account'
- Trust *.open-seo.localhost:1355 in dev mode to fix Better Auth origin rejection with portless worktrees
* Simplify hosted auth flow and remove standalone PSI
Use TanStack Form for sign-in and sign-up, make hosted unauthenticated handling redirect-focused, and inline auth route errors. Remove the leftover standalone PSI route, services, and table so PSI only exists within site audits.
* Align project auth with Better Auth organizations
* Make server function auth middleware global
* Reduce auth server function boilerplate
* delete migrations
* fix regenerated migration data backfills
* Simplify hosted auth flow and project audit scoping
* Use active project context for audit actions
* Allow hosted session project updates
* Let agent dev server inherit auth mode
* Match hosted header to gateway account menu
* Scope project session updates to active project
* Inline authenticated server function setup
* Polish header project and account controls
* restore auth generate script
* Use explicit project access in server functions
Make project-scoped server functions take projectId input and enforce ownership through shared middleware instead of session-backed current project state. Document the tradeoffs in an ADR so future changes can follow the same boundary.
* fix ci dependency detection for auth tooling
* Harden project auth in server middleware
Authorize projectId automatically in authenticated server middleware and add a requireProject guard for project-scoped handlers. This makes the auth boundary harder to bypass and removes ad hoc non-null assertions from server functions.
* Inline project id input schemas
Remove tiny shared projectId schema helpers where they were adding indirection without reducing real complexity. Keep project-scoped validation explicit at each server function boundary.
* Skip hosted backlinks access checks
* Simplify auth mode helpers
* Avoid rerunning auth server middleware
* Simplify server function scoping ADR
* Fix backlinks project scoping in hosted auth
* Refine auth route foundations
* Simplify ensure user auth resolution
Split auth-mode context resolvers into focused modules so the middleware reads as request orchestration instead of implementation details. Reuse a shared ensured-user context type across server middleware.
* Simplify hosted organization bootstrap
Use Better Auth to own hosted organization creation and membership so hosted auth only needs to resolve a default active organization. Keep delegated-mode compatibility records isolated in a separate helper.
* Clarify hosted auth and backlinks behavior
Document the hosted AUTH_MODE deploy contract and explain why hosted deployments skip manual backlinks verification. This makes the platform-managed behavior explicit in the code paths that differ from self-serve mode.
* Document hosted org creation callback
Explain why auth.ts injects createOrganization into the hosted org helper. This makes the dependency direction explicit and avoids future import cycles while keeping the helper reusable.
* Fix CI check failures
* Fix nav link prop forwarding
* save
* fix: cap per-user audit capacity
Block new audits before a user exceeds the temporary 100k audit footprint cap. Surface a clear delete-old-audits message in the audit launch UI.
* fix: reserve audit capacity with Drizzle
* chore: prepare 0.0.2 release notes
* docs: add release notes workflow
* fix: cap per-user audit capacity
Block new audits before a user exceeds the temporary 100k audit footprint cap. Surface a clear delete-old-audits message in the audit launch UI.
* fix: reserve audit capacity with Drizzle
* chore: prepare 0.0.2 release notes
* chore: add published Docker image workflow and self-host image flow
* fix: align Docker publish and build paths
Use the canonical GHCR image name and correct Dockerfile path references so CI publishing and documented local builds work as expected.
* fix: restore Docker self-host runtime defaults
Use the full Node base image and expose Compose env vars to the Cloudflare Vite runtime so local self-hosting keeps auth bindings and outbound HTTPS working.
* refactor: simplify keyword source selection flow
* fix: improve stacked keyword page layout
* fix: keep SERP tied to searched keyword
Stop silently falling back SERP lookups to related keywords and show a keyword-specific empty message so missing coverage is explicit to users.
* refactor: extract keyword controller and switch SERP to live
Move keyword research orchestration out of the route, call DataForSEO organic live SERP, and harden response normalization with runtime validation for safer typed handling.
* refactor: split keyword research page state into focused hooks
* fix: aggregate auto keyword fallback and reuse cached results
* scope keyword metrics to projectId
* refactor: modularize SEO routes and harden parsing for CI checks
* refactor: adopt zod json codecs at parse boundaries
* refactor: adopt papaparse, tldts, and zod error enums
* refactor: reorganize client and server feature layout
Group keyword UI/controller files and server repositories/services by feature while keeping serverFunctions as the stable API surface. This improves navigation and maintainability without changing runtime behavior.
* refactor: move PSI business logic into service layer
Keep serverFunctions/psi as thin transport handlers by delegating orchestration, export shaping, and source resolution to PsiAuditService. This aligns PSI with the existing service-first backend pattern without changing endpoint behavior.
* refactor: enforce 350/120 size limits across modules
* move self host
* fix: show dynamic range for search trends
Replace the static 'Past 12 months' subtitle with a computed range from the actual plotted trend points so the UI reflects data lag correctly.
* fix: bind audit workflow writes to workflow instance
* chore: make ci checks pass
* add DataForSEO key setup guard and onboarding help
Detect missing DataForSEO credentials at app load so users get a clear setup path before running SEO workflows.
* fix api key setup warning visibility and help docs
Make the setup warning fail-safe when status checks error, switch the top notice to DaisyUI alert styling, and add Cloudflare dashboard secret instructions to the help page.
* fix README formatting for CI
* fix seo api key status fallback behavior
* harden DataForSEO setup status checks and modal UX
Gate API key status behind authenticated middleware and improve the setup modal’s keyboard/accessibility behavior, with a clearer fallback notice when status checks fail.
* refine setup UX and local env docs
Hide the API key setup modal on the setup guide route to avoid a self-blocking flow, and clarify README local configuration for DATAFORSEO_API_KEY format.
* Enforce safe TypeScript assertions and validate runtime payloads
* Fix CI knip config and floating promise lint
* Validate DataForSEO payloads with Zod schemas
Replace weak object guards with endpoint-level schema parsing so invalid API shapes fail fast instead of being silently filtered. Align downstream keyword mapping with the stricter validated payload contracts.
* chore: bump @every-app/sdk to 0.1.14 for deploy install
* Add selfhosting to Cloudflare file
* Revise Cloudflare deployment instructions in README
Updated instructions for Cloudflare deployment and setup.
* docs: streamline self-hosting docs and split Cloudflare guide
* save
* remove Every App SDK and add auth modes for Cloudflare Access and local_noauth
* align local dev auth defaults and normalize Access team domain
* Apply suggestions from code review
* restore local drizzle D1 URL helper
* save
* fix auth error mapping and document self-hosting setup
* Tweak readme
* improve auth config error UI and remove manifest link
* fix team domain config validation and docs anchor