ReviewOS

also looking at this

stacks/lastsoulultra

LSU's own coaching surface, and what auditing the site turned up

#12
Merged glennmichael123 wants to merge claude/last-soul-ultra-web-6e0718 into main
86 files +3943 -1190

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

resources/data/coaching.tsmodified+2-0
Changes to resources/data/coaching.ts
@@ -128,6 +128,8 @@ export interface CoachingPageMeta {
128128 description: string
129129 styles: string[]
130130 noindex?: boolean
131 /** Origins this page will open a connection to. Read by the head partial. */
132 preconnect?: string[]
131133}
132134
133135/**
resources/functions/coaching-source.tsmodified+20-1
Changes to resources/functions/coaching-source.ts
@@ -1,6 +1,7 @@
11import type { CoachingBrand } from './coaching-brand'
22import coaching from '../../config/coaching'
3import { coachingModule } from '../data/coaching'
3import type { CoachingPageMeta } from '../data/coaching'
4import { coachingModule, coachingPage } from '../data/coaching'
45import { parseBrand } from './coaching-brand'
56
67/**
@@ -131,3 +132,21 @@ export function forgetBrand(): void {
131132 cache.clear()
132133 inFlight.clear()
133134}
135
136/**
137 * Head metadata for a module route, with a preconnect when the page is going
138 * to load HQ's element.
139 *
140 * The browser opens DNS, TCP and TLS to hq.training before the parser reaches
141 * the module script in the body, which is the one request this page's content
142 * waits on. It is only promised when the brand publishes this module: a
143 * preconnect to an origin the page never calls is a socket held open for
144 * nothing, and with no brand published these pages frame nothing at all.
145 */
146export async function coachingPageMeta(slug: string): Promise<CoachingPageMeta> {
147 const page = coachingPage(slug)
148 const brand = await loadBrand()
149 if (!brand?.modules.includes(slug))
150 return page
151 return { ...page, preconnect: [coachingOrigin()] }
152}
resources/partials/head.stxmodified+7-0
Changes to resources/partials/head.stx
@@ -8,6 +8,9 @@ const card = shareCard(pagePath)
88// Not on a noindex page: nothing indexes it, so the graph is bytes a reader
99// pays for and no crawler reads.
1010const graph = metaPage.noindex ? '' : structuredDataJson(pagePath, metaPage.title)
11// Origins the page says it will open a connection to, warmed before the
12// parser reaches the element that needs them.
13const warm = Array.isArray(metaPage.preconnect) ? metaPage.preconnect : []
1114</script>
1215<meta charset="utf-8">
1316<meta name="viewport" content="width=device-width, initial-scale=1">
@@ -33,6 +36,10 @@ const graph = metaPage.noindex ? '' : structuredDataJson(pagePath, metaPage.titl
3336<meta name="twitter:image:alt" content="">
3437<link rel="icon" href="/assets/lsu/images/favicon.png" type="image/png">
3538<link rel="apple-touch-icon" href="/assets/lsu/images/apple-touch-icon.png">
39@foreach(warm as origin)
40<link rel="dns-prefetch" href="">
41<link rel="preconnect" href="" crossorigin>
42@endforeach
3643<link rel="preload" href="/assets/lsu/fonts/anton-400-latin.woff2" as="font" type="font/woff2" crossorigin>
3744<link rel="preload" href="/assets/lsu/fonts/barlow-400-latin.woff2" as="font" type="font/woff2" crossorigin>
3845@foreach(metaPage.styles as sheet)
resources/views/coaching.stxmodified+2-1
Changes to resources/views/coaching.stx
@@ -2,13 +2,14 @@
22@section('content')
33<script server>
44import { coachingStyles } from '~/resources/data/coaching'
5import { coachingOrigin } from '~/resources/functions/coaching-source'
56
67// The home, race-entry and next-loop sheets are each suffixed with their own
78// page scope, so none of their rules could ever match here. This page's own
89// rules live in the site-wide stx-site.css that the head always loads; the
910// storefront and module index it now carries are styled by the surface sheet,
1011// which the eight module routes load too.
11const currentPage = { title: 'Coaching - Last Soul Ultra', description: 'Send a voice message after your run and an AI rebuilds next week around what you said, inside a coach\'s method.', styles: coachingStyles }
12const currentPage = { title: 'Coaching - Last Soul Ultra', description: 'Send a voice message after your run and an AI rebuilds next week around what you said, inside a coach\'s method.', styles: coachingStyles, preconnect: [coachingOrigin()] }
1213const canonicalPath = '/coaching'
1314</script>
1415<div class="coaching-page">
resources/views/coaching/account.stxmodified+3-2
Changes to resources/views/coaching/account.stx
@@ -1,8 +1,9 @@
11@extends('layouts/LSU')
22@section('content')
33<script server>
4import { coachingPage, modulePath } from '~/resources/data/coaching'
5const currentPage = coachingPage('account')
4import { modulePath } from '~/resources/data/coaching'
5import { coachingPageMeta } from '~/resources/functions/coaching-source'
6const currentPage = await coachingPageMeta('account')
67const canonicalPath = modulePath('account')
78</script>
89<CoachingModule slug="account" />
resources/views/coaching/calendar.stxmodified+3-2
Changes to resources/views/coaching/calendar.stx
@@ -1,8 +1,9 @@
11@extends('layouts/LSU')
22@section('content')
33<script server>
4import { coachingPage, modulePath } from '~/resources/data/coaching'
5const currentPage = coachingPage('calendar')
4import { modulePath } from '~/resources/data/coaching'
5import { coachingPageMeta } from '~/resources/functions/coaching-source'
6const currentPage = await coachingPageMeta('calendar')
67const canonicalPath = modulePath('calendar')
78</script>
89<CoachingModule slug="calendar" />
resources/views/coaching/feedback.stxmodified+3-2
Changes to resources/views/coaching/feedback.stx
@@ -1,8 +1,9 @@
11@extends('layouts/LSU')
22@section('content')
33<script server>
4import { coachingPage, modulePath } from '~/resources/data/coaching'
5const currentPage = coachingPage('feedback')
4import { modulePath } from '~/resources/data/coaching'
5import { coachingPageMeta } from '~/resources/functions/coaching-source'
6const currentPage = await coachingPageMeta('feedback')
67const canonicalPath = modulePath('feedback')
78</script>
89<CoachingModule slug="feedback" />
resources/views/coaching/health.stxmodified+3-2
Changes to resources/views/coaching/health.stx
@@ -1,8 +1,9 @@
11@extends('layouts/LSU')
22@section('content')
33<script server>
4import { coachingPage, modulePath } from '~/resources/data/coaching'
5const currentPage = coachingPage('health')
4import { modulePath } from '~/resources/data/coaching'
5import { coachingPageMeta } from '~/resources/functions/coaching-source'
6const currentPage = await coachingPageMeta('health')
67const canonicalPath = modulePath('health')
78</script>
89<CoachingModule slug="health" />
resources/views/coaching/library.stxmodified+3-2
Changes to resources/views/coaching/library.stx
@@ -1,8 +1,9 @@
11@extends('layouts/LSU')
22@section('content')
33<script server>
4import { coachingPage, modulePath } from '~/resources/data/coaching'
5const currentPage = coachingPage('library')
4import { modulePath } from '~/resources/data/coaching'
5import { coachingPageMeta } from '~/resources/functions/coaching-source'
6const currentPage = await coachingPageMeta('library')
67const canonicalPath = modulePath('library')
78</script>
89<CoachingModule slug="library" />
resources/views/coaching/messages.stxmodified+3-2
Changes to resources/views/coaching/messages.stx
@@ -1,8 +1,9 @@
11@extends('layouts/LSU')
22@section('content')
33<script server>
4import { coachingPage, modulePath } from '~/resources/data/coaching'
5const currentPage = coachingPage('messages')
4import { modulePath } from '~/resources/data/coaching'
5import { coachingPageMeta } from '~/resources/functions/coaching-source'
6const currentPage = await coachingPageMeta('messages')
67const canonicalPath = modulePath('messages')
78</script>
89<CoachingModule slug="messages" />
resources/views/coaching/plans.stxmodified+3-2
Changes to resources/views/coaching/plans.stx
@@ -1,8 +1,9 @@
11@extends('layouts/LSU')
22@section('content')
33<script server>
4import { coachingPage, modulePath } from '~/resources/data/coaching'
5const currentPage = coachingPage('plans')
4import { modulePath } from '~/resources/data/coaching'
5import { coachingPageMeta } from '~/resources/functions/coaching-source'
6const currentPage = await coachingPageMeta('plans')
67const canonicalPath = modulePath('plans')
78</script>
89<CoachingModule slug="plans" />
resources/views/coaching/progress.stxmodified+3-2
Changes to resources/views/coaching/progress.stx
@@ -1,8 +1,9 @@
11@extends('layouts/LSU')
22@section('content')
33<script server>
4import { coachingPage, modulePath } from '~/resources/data/coaching'
5const currentPage = coachingPage('progress')
4import { modulePath } from '~/resources/data/coaching'
5import { coachingPageMeta } from '~/resources/functions/coaching-source'
6const currentPage = await coachingPageMeta('progress')
67const canonicalPath = modulePath('progress')
78</script>
89<CoachingModule slug="progress" />
tests/coaching-views.test.tsmodified+28-1
Changes to tests/coaching-views.test.ts
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
22import { resolve } from 'node:path'
33import { processDirectives } from '@stacksjs/stx'
44import { coachingModules } from '../resources/data/coaching'
5import { forgetBrand } from '../resources/functions/coaching-source'
5import { coachingOrigin, forgetBrand } from '../resources/functions/coaching-source'
66
77/**
88 * The eight module routes, rendered the way the site renders them.
@@ -169,3 +169,30 @@ describe('getting back out of a module', () => {
169169 expect(plans).toContain('href="/coaching"')
170170 })
171171})
172
173describe('warming the connection to HQ', () => {
174 it('promises it on a module the brand publishes', async () => {
175 stubHq()
176 const html = await render('calendar')
177
178 expect(html).toContain(`<link rel="preconnect" href="${coachingOrigin()}" crossorigin>`)
179 expect(html).toContain(`<link rel="dns-prefetch" href="${coachingOrigin()}">`)
180 })
181
182 it('promises nothing on a page that will not call HQ', async () => {
183 // With nothing published the module frames nothing, so a held-open
184 // socket would be a connection made for no request.
185 stubHq(null)
186 const html = await render('calendar')
187
188 expect(html).not.toContain('rel="preconnect"')
189 expect(html).not.toContain('rel="dns-prefetch"')
190 })
191
192 it('warms it before the element that needs it', async () => {
193 stubHq()
194 const html = await render('calendar')
195
196 expect(html.indexOf('rel="preconnect"')).toBeLessThan(html.indexOf('hq-coaching.js'))
197 })
198})