Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion PROJECT_STATUS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# swe-interview-prep — PROJECT_STATUS

Last updated: 2026-08-14
Last updated: 2026-08-15

## Why/What

Expand Down Expand Up @@ -116,6 +116,7 @@ External: LeetCode API (import), multi-provider LLM APIs
- CI-enforced Fleet code-health ratchets across coverage, dead code, complexity, duplication, cycles, dependency advisories, suppression markers, documentation, builds, bundle size, and repository hygiene.
- Fleet Ultracite lint baseline for core TypeScript, React, and Vitest code with a clean 345-file check.
- Cloudflare Pages static frontend + Pages Functions backend in production architecture.
- **Core Web Vitals on the public root:** the generated curriculum summary is the initial-response shell and the LCP element on `/`, held until the lazy destination route commits, with its styles pinned against the asynchronously loaded stylesheet. Production five-run measurement: mobile-mid p75 LCP 1.22 s and CLS 0.010, desktop 656 ms and CLS 0.002, performance score 100 on both.
- Cloudflare D1 persistence for problems, notes, chats, and authenticated progress.
- Google One Tap auth with httpOnly JWT cookie issuance.
- R2-backed Go WASM interpreter for in-browser code execution path.
Expand Down
9 changes: 8 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ErrorBoundary } from './components/ErrorBoundary';
import Layout from './components/Layout';
import { SaaSMakerFeedback } from './components/saasmaker-feedback';
import { useAuth } from './contexts/AuthContext';
import { trackReturned, trackSignup } from './lib/analytics';
import { trackPageView, trackReturned, trackSignup } from './lib/analytics';
import { focusedRoute } from './lib/focusedRoute';
import { loadLocal, STORE_KEYS } from './lib/userStore';

Expand Down Expand Up @@ -184,6 +184,13 @@ export default function App() {
}
}, []);

// Manually track page_view on every route change. PostHog's built-in
// capture_pageview is disabled (see foundry-monitoring.ts) so we can attach
// the project_id property to every page view.
useEffect(() => {
trackPageView();
}, [location.pathname]);

/**
* Nobody is asked to sign in to use this.
*
Expand Down
19 changes: 13 additions & 6 deletions src/lib/analytics.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/**
* Owner-facing analytics — the fixed 4-event taxonomy.
* Owner-facing analytics — the fixed 5-event taxonomy.
*
* EVERY fleet project emits exactly these four events — `signup`, `activated`,
* `core_action`, `returned` — so a single PostHog project can build one
* cross-fleet funnel (signup -> activated -> core_action) and a D1/D7
* retention insight, with no custom dashboard.
* EVERY fleet project emits exactly these five events — `signup`, `activated`,
* `core_action`, `returned`, `page_view` — so a single PostHog project can
* build one cross-fleet funnel (signup -> activated -> core_action) and a
* D1/D7 retention insight, with no custom dashboard.
*
* Every event carries a `project_id` property. This is what makes per-app and
* cross-fleet views possible from one PostHog login.
Expand Down Expand Up @@ -47,7 +47,7 @@ export type SystemsLabStage =

/**
* The fixed taxonomy. Do NOT add events here — the whole point is that all
* fleet projects emit the same four. Product-specific detail goes in
* fleet projects emit the same five. Product-specific detail goes in
* `CoreAction` (or as extra properties), never as a new top-level event name.
*/
interface AnalyticsEventMap {
Expand All @@ -59,6 +59,8 @@ interface AnalyticsEventMap {
core_action: { project_id: typeof PROJECT; action: CoreAction };
/** A return session by a user with prior activity. */
returned: { project_id: typeof PROJECT };
/** A page view, tracked manually on route change with the project_id. */
page_view: { project_id: typeof PROJECT };
}

export function trackEvent(event: string, properties: Record<string, unknown> = {}): void {
Expand Down Expand Up @@ -127,3 +129,8 @@ export function trackSystemsLabAction(
export function trackReturned(): void {
emit('returned', {});
}

/** Fire on each route change to record a page view with the project_id. */
export function trackPageView(): void {
emit('page_view', {});
}
Loading