Handoff: CreatorTrack workspace-scoping batch + University app, BUILT (awaiting review/merge)¶
Date: 2026-07-09. Built by Fable coordinator over Sonnet workers, isolated slot.
Branch¶
feat/workspace-scoping-university, 15 commits, worktree ~/forge-suite-wt/feat/workspace-scoping-university, dev server http://100.97.43.104:3064 (DB clone ct_feat_workspace_scoping_university). NOT merged, NOT deployed. Worktree clean, tsc clean, dev compiles.
What shipped on the branch¶
- Workspace app allowlist (new primitive):
AppDef.allowWorkspaceSlugs+isAppAllowedInWorkspace()inlib/apps.ts; enforced in AppLibrary,/api/apps/installPOST (403),resolveInstalled(sidebar drop-off), page gates. Applies to everyone including owner (unlike per-memberblocked_apps). Slugs: personal=justin(ws 67), Gus The Bass=gus-the-bass(ws 85). - CRM rename: catalog
salesentry now "CRM", iconpeople. Note:SalesClient.tsxh1 still says "Sales CRM"; system appcrm= "Personal Contacts" (no collision). - Calendar per-workspace Google connections:
app.api_connectionsrows withworkspace_id; newwsgoogle:<id>source key; admin-gated (owner/admin) connect/disconnect in CalendarSettingsModal, HMAC state carries workspaceId, re-verified at callback. Members auto-inherit the shared calendar. Personal path + gtasks sync untouched. - Social analytics: owner YouTube-token fallback now scoped to owner's personal workspace only;
gus-the-bassshows empty state + per-workspace connect path. To light up: connect Gus channel in /gus-the-bass/settings API Connections (zero api_connections rows exist for ws 85). - Campaigns: brands + rollups scoped by workspace; Gus The Bass sees ONLY gusthebass.com + Gus Outdoor Co brands; personal keeps all 6.
- Link-in-Bio: allowlisted to justin + gus-the-bass (page, API, sidebar); stale chooser fixed (router.refresh after mutations); verified via curl incl. 403 in gus-outdoor-co workspace.
- Business Manager: allowlisted same; new
lib/business-company-scope.tsmaps workspace to ERPNext companies; gus-the-bass =["Gus Outdoor Co", "Gus The Bass"](latter pending ERPNext creation, tolerated); applied server-side to companies/invoices/mutations. - CreatorTrack University (new app): id
university, all workspaces; schema courses/modules/lessons/quizzes/lesson_progress/lesson_notes (RLS, idempotent migrations + seed); catalog/course/lesson UI, YouTube embeds, link-out fallback (bluprintuniversity.com blocks framing, so those are link lessons), embedded notes panel (nodes doc + tags), quiz scoring plumbing. Seeded: Blueprint University (6 lessons), Colin & Samir (4), MrBeast (empty starter). - CRM overhaul design doc:
docs/crm-overhaul-design.mdon the branch; brand-deal pipeline mapped onto existing crm./campaigns./nodes primitives, phased plan. - CRM overhaul PHASE 1 (built, same session): deals as
app.nodescollection rows (lib/crm-deals.ts), 5-stage brand-deal pipeline (Outbound Pitching, Negotiation, In Contract, Content Production, Awaiting Payment, +Paid/Lost), deliverable fields (contract value, platform, format, usage-rights window, deadlines, live link), new Pipeline kanban tab in SalesClient with drag-to-move + right-pane editor, crm-scoped join tablescrm.deal_companies/crm.deal_contacts(deliberate deviation: did NOT widen sharedapp.collection_relations, documented in migration header). Legacycrm.deals/old Deals tab untouched. "Sales CRM" literals swept. Commits 5ae0fad, 513429b, 890932e, 60ca29a. Deferred to phase 2+: deadline task auto-creation, log-entry block type, timeline aggregation, legacy backfill/cutover.
Round 2 (same session, same branch, commits through eeb8a76/020b1ef; branch now 26 commits)¶
- University install bug FIXED: root cause was a missing bare-route redirect shim
app/(suite)/university/page.tsx(sidebar links to/universityunprefixed; every route app needs the shim). Followup idea: lint asserting every route-app AppDef has a matching shim. - University icon: new greyscale
gradcapglyph in components/ui/icons.tsx. - University v2: in-app AppSidebar with Courses / Quizzes / Notes / CreatorPedia / Progress segments;
university.comments(module+lesson threads),university.quiz_attempts(persisted per-user scores, retake upserts), cross-member Progress leaderboard; course/module cards with image_url+bio hotlinked (og:image, i.ytimg.com thumbnails, NO files under public/); youtube-nocookie embeds; channel lessons render in-app video grid via channel RSS (no API key); CreatorPedia seeded with 4 starter entries (nodes docs, workspace-shared). - CRM restyle: eeb8a76 matches Tasks/Projects app-sidebar pattern, Add company/contact buttons aligned to shared button variants. Screenshots delivered in session.
- v2 followups: course-level hero images null (module cards only), module bios missing when first lesson is YouTube (noembed backfill possible), consider syncing AppDef tagline for University.
- Click-through App Library + sidebar per workspace (allowlist verified by curl, not browser).
- University lesson view: notes panel + quiz UX.
- Calendar workspace-connect flow (OAuth leg untested in dev; verified via injected connection row).
Round 3, University v3 (same branch, commits dfeb44a..eaeb0fe; branch now 35 commits)¶
- Blueprint full curriculum: 7 chapters, 21 lessons, real titles + Bunny CDN thumbnails; videos are Bunny Stream (iframe.mediadelivery.net, library 348727), confirmed freely iframe-embeddable, playing in-app. Public site, no auth gate. Cols added: lessons.provider, lessons.thumbnail_url.
- Learning: university.lesson_transcripts side table + lessons.summary; transcripts ingested for N9gSO66oC6U (MrBeast/NYT attention-economy interview, 8.1k words) + z0N1iaitiCc (Creator Support); authored summaries below player; first real quizzes (transcript-grounded, verified 6/6 scoring path); collapsible transcript panel; Mark-complete checkbox on lesson view + rows feeding Progress.
- Catalog v3: 4 new courses (Film Booth, Think Media, Ali Abdaal, vidIQ; Creator Science dropped, channel hides videos tab from yt-dlp), MrBeast filled with 3 case-study lessons, all 7 courses have hotlinked thumbnails (26 remote images verified 200), real durations via yt-dlp, hero + rich-card landing redesign.
- v3 followups: Blueprint/Bunny lessons have no transcripts yet; no summary edit UI; Colin & Samir durations unfilled; N9gSO66oC6U is an NYT-channel video (worker flagged; seeded as instructed).
Round 4, University v4 (same branch, now 40 commits)¶
- Bunny 403 root-caused: vz-*.b-cdn.net referrer-allowlists bluprintuniversity.com. Videos DO play in-app (inner player requests carry the Bunny iframe host as referrer); iframe + RemoteThumb img now use referrerPolicy=no-referrer, which also fixed all 26 thumbnails (proven 403 -> 200 in-browser). If Justin still sees a video 403, capture the failing request URL + Referer from devtools.
- Link-outs: always-visible "Watch on Bluprint University" / "Watch on YouTube" under every player.
- AI quiz generator: lesson/module/course scope; sources transcripts (on-demand yt-dlp ingest persists new transcripts), falls back to title/summary for Bunny lessons ("light" quizzes); LLM via existing resolveProviderForUser plumbing; options shuffled to kill position bias; module/course quizzes anchor to first lesson (overwrites its lesson quiz; add module_id/course_id cols if distinct storage wanted).
- AI tab: sidebar segment, SSE-streamed grounded chat over catalog+summaries+transcripts+own notes; declines out-of-scope questions (verified both paths).
- Note: dev user's chat_ai.agent temporarily set to self-hosted Copper provider because justin-haiku subscription agent was 429-rate-limited during verification; revisit before relying on default provider in dev.
Known gaps / followups¶
- Gus YouTube analytics needs Justin to connect the channel (owner/admin, in-workspace).
- Campaigns still owner-gated (
isPersonalAppsOwner); membership-based access is a bigger refactor, deliberately deferred. Gus rollups zero until sync runs for ws 85. - No quiz questions seeded; no manual module/lesson curation UI yet (seed script only).
- "Sales CRM" literal strings sweep (SalesClient h1, chat tool descriptions).
- Prod deploy does NOT run migrations: apply university migrations to lifeos manually at deploy time.
URL: https://mkdocs.justinsforge.com/memory/handoffs/creatortrack-workspace-scoping-university-2026-07-09/