Skip to content

feat: add login, register, create pack and create topic capture events#44

Merged
mehdiasadli merged 1 commit into
mainfrom
feat/posthog-events
May 7, 2026
Merged

feat: add login, register, create pack and create topic capture events#44
mehdiasadli merged 1 commit into
mainfrom
feat/posthog-events

Conversation

@mehdiasadli
Copy link
Copy Markdown
Contributor

@mehdiasadli mehdiasadli commented May 7, 2026

Summary by CodeRabbit

  • Chores
    • Enhanced event capture across form submissions for pack creation, topic creation, login, and registration flows.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
xamsa-web Ready Ready Preview, Comment May 7, 2026 5:28am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This pull request introduces analytics event capture to user-submitted forms. A new useCapture hook wraps PostHog analytics with browser-safety guards, and four form components (create pack, create topic, login, register) now emit structured event data on submission before executing their existing submission logic.

Changes

Analytics Event Capture Integration

Layer / File(s) Summary
Hook Foundation
apps/web/src/hooks/use-capture.ts
New useCapture hook exports a capture function that forwards event name and typed properties to PostHog, guarded by browser runtime, PostHog availability, and event name checks.
Creation Forms
apps/web/src/components/create-pack-form.tsx, apps/web/src/components/create-topic-form.tsx
CreatePackForm emits packs_create_attempt with name, language, visibility, allowOthersHost, and withTsual; CreateTopicForm emits topics_create_attempt with name, description, and pack ID. Both hook imports and event calls are added to submit handlers before mutation execution.
Auth Forms
apps/web/src/components/login-form.tsx, apps/web/src/components/register-form.tsx
LoginForm emits login_attempt with email, provider type, and optional callbackURL; RegisterForm emits register_attempt with email, provider, callbackURL, name, and username. Both integrate useCapture at component initialization and call capture before auth service invocation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

📊 A rabbit tracks the form submissions clear,
With PostHog events captured, data sincere,
Four forms now whisper their analytics tales,
Through useCapture's safe and guarded trails,
Events flow freely when the browser prevails! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main changes: adding capture events for login, register, create pack, and create topic forms.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/posthog-events

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the size:m label May 7, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/web/src/components/create-topic-form.tsx (1)

212-216: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Create and Go path skips analytics capture.

Line 214–216 submits via createTopic(...) without capture(...), so topics_create_attempt is only emitted from the default submit button path.

Suggested fix
+	const trackTopicCreateAttempt = (values: CreateTopicFormFieldValues) => {
+		capture("topics_create_attempt", {
+			name: values.name,
+			description: values.description,
+			pack: packSlug,
+		});
+	};

 	const onSubmit = form.handleSubmit((values) => {
-		capture("topics_create_attempt", {
-			name: values.name,
-			description: values.description,
-			pack: packSlug,
-		});
+		trackTopicCreateAttempt(values);

 		createNavigationModeRef.current = "continue";
 		createTopic({ ...values, pack: packSlug });
 	}, onFormValidationError);

 	const submitForCreate = (mode: "continue" | "go") => {
 		createNavigationModeRef.current = mode;
 		void form.handleSubmit((values) => {
+			trackTopicCreateAttempt(values);
 			createTopic({ ...values, pack: packSlug });
 		}, onFormValidationError)();
 	};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/create-topic-form.tsx` around lines 212 - 216,
submitForCreate currently calls createTopic directly inside form.handleSubmit,
so the analytics event topics_create_attempt isn't emitted for the "go" path;
update the submitForCreate handler to call the analytics capture(...) with the
same payload (including pack: packSlug) before invoking createTopic (or wrap
createTopic call inside capture's callback if your capture utility expects a
callback), referencing submitForCreate, createNavigationModeRef,
form.handleSubmit, and createTopic to locate the code; ensure the capture call
runs for both "continue" and "go" modes so analytics are always emitted.
🧹 Nitpick comments (1)
apps/web/src/hooks/use-capture.ts (1)

1-1: ⚡ Quick win

Avoid file-wide lint suppression here.

Line 1 disables a rule for the whole file, but there is no any usage in this hook. Narrow or remove the ignore to avoid masking future type issues.

Suggested cleanup
-/** biome-ignore-all lint/suspicious/noExplicitAny: any is used to capture any props */
 import { usePostHog } from "posthog-js/react";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/hooks/use-capture.ts` at line 1, The file-wide lint suppression
at the top of use-capture.ts is unnecessary and masks future typing issues;
remove the biome-ignore-all comment and, if a specific `any` usage later needs
suppression, add a narrow inline suppression only at that statement (e.g.,
adjacent to the offending variable or parameter in the useCapture hook) so the
rest of the file remains checked by the rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/components/create-topic-form.tsx`:
- Around line 202-206: The telemetry call is sending raw free-text fields (name,
description) which may contain PII; change the capture("topics_create_attempt",
...) payload so it no longer includes verbatim text from values.name or
values.description — instead send non-identifying metadata (e.g., name_present:
boolean, name_length: number, description_present: boolean, description_length:
number) or stable irreversible hashes (e.g., sha256 of the value) if you need
deduplication, and keep packSlug as-is; update the code around the capture call
in create-topic-form.tsx to compute and send only these redacted/hashed fields
(or presence/length flags) rather than raw strings.

In `@apps/web/src/components/login-form.tsx`:
- Around line 39-43: The analytics capture call in login-form.tsx currently
sends raw PII (values.email and callbackURL); change the payload in the
capture("login_attempt", ...) invocation to avoid transmitting raw email or full
callback URL by sending non-PII fields instead — include provider, a boolean
like redirect_present = Boolean(callbackURL), and either email_domain =
values.email.split("@")[1] or a hashed email identifier if you must correlate
users, and ensure callbackURL is not sent or is reduced to domain-only; update
the capture call site accordingly.

In `@apps/web/src/components/register-form.tsx`:
- Around line 73-79: The telemetry call emitting PII is the
capture("register_attempt", ...) invocation; change the payload to remove direct
identifiers (email, name, username, full callbackURL) and instead send
non-identifying metadata — e.g., email domain (extract domain from
values.email), a deterministic but non-reversible username fingerprint (e.g.,
hashed or truncated length), and a redacted callback host (extract hostname only
or boolean indicating presence of callback) — so update the capture call in
register-form.tsx to replace email, name, username, and callbackURL with these
non-identifying fields.

---

Outside diff comments:
In `@apps/web/src/components/create-topic-form.tsx`:
- Around line 212-216: submitForCreate currently calls createTopic directly
inside form.handleSubmit, so the analytics event topics_create_attempt isn't
emitted for the "go" path; update the submitForCreate handler to call the
analytics capture(...) with the same payload (including pack: packSlug) before
invoking createTopic (or wrap createTopic call inside capture's callback if your
capture utility expects a callback), referencing submitForCreate,
createNavigationModeRef, form.handleSubmit, and createTopic to locate the code;
ensure the capture call runs for both "continue" and "go" modes so analytics are
always emitted.

---

Nitpick comments:
In `@apps/web/src/hooks/use-capture.ts`:
- Line 1: The file-wide lint suppression at the top of use-capture.ts is
unnecessary and masks future typing issues; remove the biome-ignore-all comment
and, if a specific `any` usage later needs suppression, add a narrow inline
suppression only at that statement (e.g., adjacent to the offending variable or
parameter in the useCapture hook) so the rest of the file remains checked by the
rule.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 20062501-821e-4d0e-aaa4-0b4aef9fbfe3

📥 Commits

Reviewing files that changed from the base of the PR and between 8d2f903 and e5de3df.

📒 Files selected for processing (5)
  • apps/web/src/components/create-pack-form.tsx
  • apps/web/src/components/create-topic-form.tsx
  • apps/web/src/components/login-form.tsx
  • apps/web/src/components/register-form.tsx
  • apps/web/src/hooks/use-capture.ts

Comment on lines +202 to +206
capture("topics_create_attempt", {
name: values.name,
description: values.description,
pack: packSlug,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid sending raw free-text fields to analytics.

Line 203–204 sends name and description verbatim. These fields can contain sensitive or personal data and create unnecessary privacy/compliance risk in telemetry.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/create-topic-form.tsx` around lines 202 - 206, The
telemetry call is sending raw free-text fields (name, description) which may
contain PII; change the capture("topics_create_attempt", ...) payload so it no
longer includes verbatim text from values.name or values.description — instead
send non-identifying metadata (e.g., name_present: boolean, name_length: number,
description_present: boolean, description_length: number) or stable irreversible
hashes (e.g., sha256 of the value) if you need deduplication, and keep packSlug
as-is; update the code around the capture call in create-topic-form.tsx to
compute and send only these redacted/hashed fields (or presence/length flags)
rather than raw strings.

Comment on lines +39 to +43
capture("login_attempt", {
email: values.email,
provider: "credentials",
callbackURL: callbackURL || undefined,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Do not emit raw email/callback URL in analytics events.

Line 40 and Line 42 include directly identifying/sensitive values. Prefer non-PII properties (e.g., provider, redirect-present boolean, domain-level or hashed identifier if truly needed).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/login-form.tsx` around lines 39 - 43, The analytics
capture call in login-form.tsx currently sends raw PII (values.email and
callbackURL); change the payload in the capture("login_attempt", ...) invocation
to avoid transmitting raw email or full callback URL by sending non-PII fields
instead — include provider, a boolean like redirect_present =
Boolean(callbackURL), and either email_domain = values.email.split("@")[1] or a
hashed email identifier if you must correlate users, and ensure callbackURL is
not sent or is reduced to domain-only; update the capture call site accordingly.

Comment on lines +73 to +79
capture("register_attempt", {
email: values.email,
provider: "credentials",
callbackURL: callbackURL || undefined,
name: values.name,
username: values.username,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Registration telemetry currently includes direct identifiers.

Line 74, Line 77, and Line 78 emit PII (email, name, username), and Line 76 emits URL data that may carry sensitive query params. Please reduce this to non-identifying metadata.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/register-form.tsx` around lines 73 - 79, The
telemetry call emitting PII is the capture("register_attempt", ...) invocation;
change the payload to remove direct identifiers (email, name, username, full
callbackURL) and instead send non-identifying metadata — e.g., email domain
(extract domain from values.email), a deterministic but non-reversible username
fingerprint (e.g., hashed or truncated length), and a redacted callback host
(extract hostname only or boolean indicating presence of callback) — so update
the capture call in register-form.tsx to replace email, name, username, and
callbackURL with these non-identifying fields.

@mehdiasadli mehdiasadli merged commit d980d0b into main May 7, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant