Commit Graph

385 Commits

Author SHA1 Message Date
fd68efdb78 nook bug reporting handler 2026-09-01 17:44:20 -04:00
1ee61d8fe4 remove "The Nook" in license key phrasing 2026-08-28 14:15:40 -04:00
6c024342ba fixed privacy routing 2026-08-28 13:16:28 -04:00
9860213760 remove - Michael 2026-08-27 23:29:01 -04:00
cb584f8b68 license resend, license pretified 2026-08-27 23:03:33 -04:00
8c5fe25c2b fix email trigger 2026-08-27 20:42:17 -04:00
22f40b2284 favicons 2026-08-27 14:18:12 -04:00
b10a81068d nook icon 2026-08-27 13:38:19 -04:00
6d3315c71f fix nook subdomain routing 2026-08-27 13:06:41 -04:00
20944bf46e update nook brand color 2026-08-27 11:58:54 -04:00
a161c96b05 nook: surface per-license maxDevices in activate + status responses 2026-08-27 09:26:14 -04:00
082e503d4f nook: per-license device caps + grant CLI for free licenses 2026-08-27 09:16:31 -04:00
0031055315 nook: fix idempotent reactivation SQL bind (row object -> id) 2026-08-27 08:55:51 -04:00
e4a9be4899 prep for the nook 2026-08-26 17:41:57 -04:00
898c891bd5 chore: remediate pygienium audit findings
Dead code: 77 verified-unused exports, files (BackArrow, MenuBars,
cookies.ts, db/create.ts, schemas/comment.ts, security-headers.ts) and
12 unused dependencies removed
Comments: ~370 RESTATE comments stripped across 53 files; 2 verbose
blocks tightened; dead commented-out config removed
Complexity: bulkUpsert extracted into 11 per-entity helpers (CCN 156->~10);
login formHandler split into 3 submitters (CCN 63->~5); account page render
split into 8 section components (CCN 40); updatePost SQL builder rebuilt;
assert*Owned consolidated behind generic assertOwnedBy
Defensive guards: 4 redundant rethrow/nullish guards removed
2026-08-11 13:36:18 -04:00
33ca9213f2 fix: root /downloads button fix, subdomain footer fix 2026-07-28 14:25:15 -04:00
34db684fe1 subdomain footer 2026-07-27 16:34:32 -04:00
2f1b5f35c6 fix: color and blog fixes, favicon pointers 2026-07-27 15:47:59 -04:00
44b6e7595c fix: subdomain routing fixed, favicon bundles 2026-07-27 14:01:50 -04:00
5ddbfbc429 fix: subdomain capture 2026-07-26 09:53:20 -04:00
ad5221dc35 fix: stop toggle from triggering overflow 2026-07-24 22:32:01 -04:00
5eecb8e7d1 fix: correct DarkModeToggle sig 2026-07-24 22:28:25 -04:00
c66cd6d456 nav color fixes, cache busting 2026-07-24 15:26:36 -04:00
4b663c014a feat: (lineage) quest event json 2026-07-24 08:56:35 -04:00
9e285570e1 feat:lineage compat, nessa made more similar 2026-07-24 07:40:58 -04:00
a876cee6ec fix: drop redis env 2026-07-23 23:06:11 -04:00
84e4c2203e meta: further task ref cleanup 2026-07-23 22:53:40 -04:00
f2fc6a5d1a meta: task ref cleanup 2026-07-23 21:54:52 -04:00
8e33af43a5 fix: product subdomain cleanup 2026-07-23 20:52:49 -04:00
e7b32d6566 Merge branch 'per-subdomain-contact-pages' (task 09)
# Conflicts:
#	src/routes/contact.tsx
2026-07-23 17:08:54 -04:00
e55a28d249 Merge branch 'downloads-and-deletion-flows' (task 11)
# Conflicts:
#	src/routes/privacy-policy/life-and-lineage.tsx
2026-07-23 17:08:06 -04:00
7fb38f37a0 Merge branch 'inputhalo-landing-page' 2026-07-23 14:53:36 -04:00
06c39b8813 feat: add InputHalo landing page with DMG download flow
Add a marketing landing page for inputhalo.freno.me with a hero section
(theme-aware app icon, glitch title, tagline), feature highlights, and a
download section offering a macOS DMG via the tRPC signed-S3 URL endpoint
plus an App Store link.

Extract the download orchestration into a pure, side-effect-free helper
(query/performInputHaloDownload) so the asset-name and redirect contract is
unit-tested in isolation, mirroring the existing site-aware page-head /
nav-config split. Include dark and default app-icon exports in the public
folder.
2026-07-23 14:32:06 -04:00
59d129b46b feat: add product-aware deletion emails and subdomain deletion/downloads routes
- Extend DeletionForm with product discriminator and configurable cooldown cookie
- Extract env-free deletion email helpers into deletion-email.ts with Lineage/Nessa branding
- Make misc.sendDeletionRequestEmail mutation product-aware (subject, html content, cookie)
- Replace legacy /deletion/life-and-lineage page with 308 redirect to lineage subdomain
- Add Lineage and Nessa subdomain deletion route modules with shared content components
- Add Lineage downloads route modules with shared content
- Update privacy policy deletion link to lineage subdomain
2026-07-23 12:32:14 -04:00
d5794f6e34 Merge branch 'privacy-policy-consolidation' 2026-07-23 12:25:54 -04:00
a7ad581ed2 feat(contact): extract shared ContactForm and add per-subdomain contact pages
Refactor the monolithic main-site contact page into a reusable
<ContactForm> component that encapsulates the Turnstile widget, cooldown
timer, email-verification flow, and tRPC submission. The main
/contact route becomes a thin wrapper that supplies the site-specific
disclaimer subline and Life-and-Lineage FAQ accordion (now exported as
<LineageContactQuestions> for reuse).

Add per-subdomain contact routes (gaze, inputhalo, lineage, nessa) that
render the shared component, with site-aware subject prefix, recipient,
heading, and PageHead metadata derived via useSite() from CONTACT_CONTEXT.

Introduce src/lib/contact-config.ts (with tests) centralizing the contact
recipient/sender addresses and subject building. The misc.sendContactRequest
mutation accepts an optional subjectPrefix (defaulting to "freno.me") so
inbound call sites continue emitting byte-identical legacy subjects, while
subdomain submissions route distinct subjects (e.g. "[Gaze] Contact Request")
to the same inbox.
2026-07-23 12:25:13 -04:00
6a8c8b7662 feat(privacy): migrate privacy policies to product subdomains
Consolidate privacy policies per-subdomain:
- Migrate Gaze and Life and Lineage privacy policies verbatim from the
  legacy /privacy-policy/* routes to their subdomain paths
  (gaze.freno.me/privacy, lineage.freno.me/privacy), and replace the old
  routes with 308 permanent redirects to preserve SEO equity and stable
  link resolution.
- Add net-new privacy policies for the InputHalo and Nessa subdomains.
- Update the contact page link to point at the Lineage subdomain privacy
  policy.
2026-07-23 12:22:33 -04:00
5705c5add7 Merge branch 'gaze-landing-page' 2026-07-23 12:19:22 -04:00
f2ff75e6df feat(gaze): add Gaze subdomain landing page with direct download
Move the Gaze marketing home from the legacy /marketing/gaze route to
a dedicated gaze subdomain landing page (src/routes/gaze). The new page
adds a richer hero, feature highlights, and a direct .dmg download flow
that resolves a signed S3 URL via the tRPC downloads.getDownloadUrl
endpoint.

Extract the download-resolution logic into a shared, testable
downloadAsset helper (src/lib/download-asset) so current and future
subdomain landing pages (InputHalo, Lineage, …) share one code path.
The helper is pure over an injected DownloadApi + redirect sink, keeping
it unit-testable without importing solid-js / CSRF cookie code.

Replace the old marketing/gaze route with a permanent 308 redirect to
https://gaze.freno.me so existing inbound links keep resolving to the
canonical home.

Add unit tests covering the tRPC call shape, redirect sink, and error
handling.
2026-07-23 12:15:04 -04:00
bc907fb990 Merge branch 'lineage-landing-page-migration' 2026-07-23 12:07:29 -04:00
0356bdcaad refactor(lineage): migrate life-and-lineage to lineage subdomain redirect
Move the marketing landing page content to the new  route group
served at , and convert the legacy
 route into a 308 permanent
redirect to the new subdomain.

- Add  hosting the migrated marketing page.
- Extract shared landing content and the redirect target into
  , with unit tests asserting the
  redirect destination.
2026-07-23 11:55:48 -04:00
dbf47f3170 feat(nessa): add branded landing page with site-aware metadata
Add the Nessa subdomain landing page served at nessa.freno.me/.

- index.tsx: hero, feature highlights, CTA band, and footer themed via
  useSite() brandColor and useDarkMode(); deliberately avoids freno.me
  web-auth UI (Nessa uses Clerk) and uses a non-fabricated 'Coming soon'
  CTA since there's no app-store presence yet.
- meta.ts: deterministic PageHeadProps (title, description, OG) as a pure
  module mirroring the page-head-meta testability pattern; feature copy is
  derived from real nessaCommunityRouter capabilities (clubs, challenges,
  social.feed, events).
- meta.test.ts: resolves metadata over SITE_CONFIG.nessa + pathname '/' to
  assert title suffix composition, canonical, OG image fallback, and
  description content.
2026-07-23 11:42:25 -04:00
d42cfc106b feat(nav): site-aware layout and navigation refinements
- Extract shared SubdomainNavList used by both subdomain bars
- Add branded Typewriter header to MainLeftBarContent
- Update BACK_TO_FRENO label to 'back to freno.me'
2026-07-23 11:14:58 -04:00
650b216dbc feat(Bars): add site-aware layout and navigation with subdomain nav config
Refactor LeftBar/RightBarContent into main-site and subdomain variants.
Subdomain sites render a simplified, brand-colored shell iterating a new
pure nav-config module (NAV_CONFIG), with a "back to freno.me" affordance
and inline SVG icon resolver. The main site retains its bespoke bars
(Recent Posts, auth-aware nav, admin links, widgets) unchanged.

Add nav-config.ts as an import-free, unit-testable module defining the
per-site link sets (with external/href/auth-gating/icon contract), plus
filterNavByAuth helper and BACK_TO_FRENO link.
2026-07-23 10:38:53 -04:00
d82f31990d Merge branch 'site-aware-pagehead-and-canonical' 2026-07-23 10:13:23 -04:00
741a6e26a3 feat(PageHead): make page metadata site-aware with auto-derived canonical URLs
Extract pure resolvePageHeadMeta helper that derives title suffix,
canonical URL, and OpenGraph fallbacks from the active site config and
router pathname. PageHead now reads useSite() + useLocation() to
render per-subdomain metadata (e.g. " | Nessa", canonical on
nessa.freno.me) instead of hardcoding " | Michael Freno".

- Always emit a canonical link (explicit override wins; otherwise
  https://<site.domain><pathname>)
- Default og:image to the site ogDefaultImage when not provided
- Add unit tests covering all five sites, canonical derivation, and
  OpenGraph fallback behavior
2026-07-23 10:09:10 -04:00
e9aa987b94 feat: generate per-subdomain sitemaps based on Host header
Refactor sitemap.xml route to read the Host header, determine the active
site, and produce a sitemap scoped to that site's routes with canonical
URLs. Extracts route definitions and XML generation into shared modules.
2026-07-23 09:46:28 -04:00
8ae42d32bd Merge branch 'subdomain-routing-and-site-context' 2026-07-23 09:20:49 -04:00
92890ce259 feat: add subdomain-based site context with SSR resolution
Resolve the active site from the request Host header on the server and
expose it through a SiteContext provider so the app can vary rendering
per subdomain. Serialize the resolved site into the document shell
(data-site attribute + window.__SITE__) so client hydration matches the
server render. Add host-based Vercel rewrites mapping each subdomain to
its site root, and include unit tests for the site resolution logic.
2026-07-23 09:18:55 -04:00
72d1cfaf3f more nessa prep 2026-07-23 08:43:40 -04:00