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/views/coaching.stxmodified+11-2
Changes to resources/views/coaching.stx
@@ -2,14 +2,21 @@
22@section('content')
33<script server>
44import { coachingHubStyles } from '~/resources/data/coaching'
5import { coachingOrigin } from '~/resources/functions/coaching-source'
5import { coachingOrigin, loadBrand } from '~/resources/functions/coaching-source'
66
77// The home, race-entry and next-loop sheets are each suffixed with their own
88// page scope, so none of their rules could ever match here. This page's own
99// rules are coaching-page.css, loaded by this route alone; the storefront and
1010// module index it carries are styled by the surface sheet, which the eight
1111// module routes load too.
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: coachingHubStyles, preconnect: [coachingOrigin()] }
12/* The embed, and the connection warmed for it, only when the brand has
13 published something. The branded subscription return lands on this page
14 with its receipt hint and the element is what passes that back to HQ - but
15 an unpublished brand has no subscriptions, so there is no receipt to carry
16 and no reason to load a remote script to frame a 404. */
17const hubBrand = await loadBrand()
18const hubLive = (hubBrand?.modules.length ?? 0) > 0
19const 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: coachingHubStyles, ...(hubLive ? { preconnect: [coachingOrigin()] } : {}) }
1320const canonicalPath = '/coaching'
1421</script>
1522<div class="coaching-page">
@@ -96,7 +103,9 @@ const canonicalPath = '/coaching'
96103 <CoachingOffers />
97104 <CoachingIndex />
98105 </div>
106 @if(hubLive)
99107 <div class="coaching-portal"><CoachingPortal /></div>
108 @endif
100109 </section>
101110
102111 <section id="coaches" class="coaching-coaches">
tests/coaching-views.test.tsmodified+33-0
Changes to tests/coaching-views.test.ts
@@ -216,3 +216,36 @@ describe('what a tier says it is', () => {
216216 expect([...plans.matchAll(/sample price/g)]).toHaveLength(1)
217217 })
218218})
219
220describe('the coaching hub', () => {
221 async function hub(): Promise<string> {
222 const path = resolve('resources/views/coaching.stx')
223 return processDirectives(await Bun.file(path).text(), {}, path, {
224 enabled: true,
225 cache: false,
226 componentsDir: resolve('resources/components'),
227 layoutsDir: resolve('resources/layouts'),
228 partialsDir: resolve('resources/partials'),
229 }, new Set())
230 }
231
232 it('embeds the portal and warms the connection when something is published', async () => {
233 stubHq()
234 const html = await hub()
235
236 expect(html).toContain('<hq-coaching')
237 expect(html).toContain('rel="preconnect"')
238 })
239
240 it('loads no remote script when there is nothing to show', async () => {
241 // No published brand means no subscriptions, so no receipt can arrive
242 // here either, and the element has nothing left to do.
243 stubHq(null)
244 const html = await hub()
245
246 expect(html).not.toContain('<hq-coaching')
247 expect(html).not.toContain('hq-coaching.js')
248 expect(html).not.toContain('rel="preconnect"')
249 expect(html).toContain('Nothing is open yet')
250 })
251})