Skip to content

Conversation

@sid597
Copy link
Collaborator

@sid597 sid597 commented Dec 27, 2024

Initially
This will likely evolve over time, but initially basic usage would be good:

For the following we have to configure the dashboard, based on what we are collecting in the PII we would be able to query for some and maybe not for others.

  • total unique users
  • total unique graphs
  • daily active users
  • daily active graphs

Note: we'll have to be careful with Personally Identifiable Information.

Going forward
Then for some interesting usage stats, things like:

  • new Discourse Node Type created (Question, Evidence, etc)
  • new Discourse Node created (An individual instance of a Discourse Node Type)
  • Discourse Relation created
  • Instantiated Discourse Relation
  • canvas created
  • canvas node created
  • canvas relation created
  • discourse context viewed
  • query builder page created/viewed
  • query builder block created/fired
  • query drawer opened
  • query drawer query created/viewed
  • canvas drawer opened
  • discourse graph exported
  • query block results shared
  • query block view types used
  • kanban specifically

At a high level, if it's a feature we are investing time into, we should have some insight into it.

Eventually, creating user-funnels from emerging patterns could inform new features, dev paths for new plugins, ux optimizations, etc.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Integrated PostHog analytics into various components for enhanced user interaction tracking.
    • Added functionality to log events for actions such as creating discourse nodes, viewing queries, and rendering components.
    • Enhanced tracking for user interactions in the query drawer, canvas, and results view.
    • Improved loading state management with a new debounce hook for a smoother user experience.
  • Chores

    • Updated project dependencies to include posthog-js version ^1.203.2.

@vercel
Copy link

vercel bot commented Dec 27, 2024

@sid597 is attempting to deploy a commit to the Discourse Graphs Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 27, 2024

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This pull request integrates PostHog analytics into the Roam project. It adds the posthog-js library as a dependency in the package.json file and implements an initialization function in the index.ts file. Various components and utility functions are updated to log user interactions, such as fetching discourse context results, creating nodes, and rendering queries, thereby enhancing the project's tracking capabilities.

Changes

File Change Summary
apps/roam/package.json Added posthog-js dependency with version ^1.203.2
apps/roam/src/index.ts Introduced initPostHog() function to configure PostHog analytics
apps/roam/src/components/DiscourseContext.tsx Added event tracking for fetching discourse context results and introduced useDebounce hook
apps/roam/src/components/DiscourseNodeMenu.tsx Added event tracking for creating new discourse node types
apps/roam/src/components/ExportDiscourseContext.tsx Added event tracking for discourse graph export button clicks
apps/roam/src/components/QueryBuilder.tsx Added event tracking for rendering query blocks and pages
apps/roam/src/components/QueryDrawer.tsx Added event tracking for viewing saved queries and creating new queries
apps/roam/src/components/ResultsView/ResultsView.tsx Added event tracking for view mode changes and export actions
apps/roam/src/components/ResultsView/views/Kanban.tsx Added event tracking for Kanban board creation
apps/roam/src/components/canvas/CanvasDrawer.tsx Added event tracking for opening the canvas drawer
apps/roam/src/components/canvas/Tldraw.tsx Added event tracking for various actions within the Tldraw canvas
apps/roam/src/utils/createDiscourseNode.ts Added event tracking for discourse node creation
apps/roam/src/utils/triplesToBlocks.ts Added event tracking for new relations created
apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx Added event tracking for new relation creation in config panel

Possibly related PRs

  • Posthog web analytics in website #28: Integrates PostHog web analytics into the website, which is directly related to the addition of the posthog-js dependency and the new analytics functionalities introduced in the main PR.
  • Finish integrating Discourse Graph mode #38: Although this PR primarily focuses on removing the discourseGraphsMode.ts file, it involves changes to the index.ts file where the new posthog-js functionality could be relevant, as it may affect how analytics are integrated into the discourse graph features.

Suggested reviewers

  • mdroidian

Poem

🐰 In the garden of code, we take a leap,
With PostHog's help, our insights we reap.
Events captured, like carrots in a row,
Analytics bloom, watch our metrics grow!
A rabbit's delight in each data-filled hop,
Tracking our journey, we never will stop! 📊


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sid597 sid597 marked this pull request as draft December 27, 2024 10:46
@vercel
Copy link

vercel bot commented Dec 27, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
discourse-graph ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 3, 2025 4:54pm

Copy link
Contributor

@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: 1

🧹 Nitpick comments (1)
apps/roam/src/index.ts (1)

55-55: Consider delaying analytics initialization until explicit user interaction.

Currently, analytics is initialized immediately at extension load. If you want to respect user privacy preferences or application performance, consider deferring initialization until the user grants consent or after a user action indicates engagement.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e6eabc and 3c91265.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • apps/roam/package.json (1 hunks)
  • apps/roam/src/index.ts (1 hunks)
🔇 Additional comments (2)
apps/roam/src/index.ts (1)

45-50: Verify compliance with data privacy and consent policies.

PostHog initialization may gather user analytics data, potentially including PII. Ensure compliance with your privacy requirements and any relevant regulations (e.g., GDPR) by anonymizing user data or prompting for user consent.

apps/roam/package.json (1)

32-32: Ensure the newly added dependency is safely updated and secure.

When introducing posthog-js, confirm you’re using the recommended or latest stable version. Additionally, run security scanners (like npm audit) to verify no newly introduced vulnerabilities.

✅ Verification successful

posthog-js appears secure, but other dependencies need attention

The version of posthog-js (1.203.2) is recent and doesn't show any known vulnerabilities. However, the npm audit revealed several other security concerns in the project's dependencies that should be addressed:

  • High severity vulnerabilities:

    • cross-spawn: ReDoS vulnerability
    • d3-color: ReDoS vulnerability
    • semver: ReDoS vulnerability
    • ws: DoS vulnerability when handling requests with many headers
  • Moderate severity vulnerabilities:

    • axios: CSRF vulnerability
    • follow-redirects: URL parsing and header handling issues
    • nanoid: Predictable results with non-integer values

Recommended actions:

  • Run npm audit fix to address issues that don't require breaking changes
  • Carefully review and test after running npm audit fix --force for issues requiring breaking changes
  • Consider updating these dependencies individually with proper testing to maintain stability
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for known vulnerabilities in `posthog-js` using npm audit
npm audit --omit dev

Length of output: 2887

@sid597 sid597 self-assigned this Dec 27, 2024
@sid597 sid597 linked an issue Dec 27, 2024 that may be closed by this pull request
@sid597
Copy link
Collaborator Author

sid597 commented Dec 27, 2024

Took too many hours to figure out the properties, and how to turn them off, turns out we can see everything and cutomise many things in the ui itself.

@sid597
Copy link
Collaborator Author

sid597 commented Dec 27, 2024

added capture event for query drawer but could not test them in resultsgraph because the page is not present. Tested other events

@mdroidian
Copy link
Contributor

mdroidian commented Dec 27, 2024

So I think the deploy task is failing due Repository Forks not having access to GitHub org secrets. I believe this is intentional [1, 2].

A couple possible solutions:

  1. instead of forking, clone the repo directly
  2. add the secret to your forked repo (you can snag it from Vercel)

#1 would probably be better long term, as you wouldn't need to add more secrets over time

@sid597
Copy link
Collaborator Author

sid597 commented Dec 30, 2024

will do so after this pr is done

@sid597
Copy link
Collaborator Author

sid597 commented Dec 30, 2024

@mdroidian how is "Instantiated Discourse Relation" different from "Discourse Relation created"?

@sid597 sid597 marked this pull request as ready for review December 30, 2024 17:18
Copy link
Contributor

@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: 1

🧹 Nitpick comments (13)
apps/roam/src/components/canvas/CanvasDrawer.tsx (1)

165-166: Monitor frequency of "canvas_drawer_opened"
Capturing the event here makes sense. Just ensure that repeated toggling of the drawer does not flood analytics with excessive events.

apps/roam/src/components/QueryBuilder.tsx (1)

194-200: Capture usage carefully
Logging "query_block_rendered" is useful for measuring usage. Double-check there’s no risk of overcounting if the block re-renders often due to state changes or React lifecycle events.

apps/roam/src/components/QueryDrawer.tsx (2)

24-24: Initialize PostHog and handle edge cases.

Be sure to confirm that PostHog is initialized before capturing analytics events throughout this file, in case the user’s environment blocks analytics or PostHog initialization fails.


297-301: Ensure minimal overhead for frequent captures.

Calling posthog.capture every time a new query is created is likely acceptable. Just confirm that frequent calls do not degrade performance, especially if your code is in a tight loop or called repeatedly by user interactions.

apps/roam/src/components/DiscourseContext.tsx (1)

30-30: Validate PostHog initialization.

Similarly to other files, ensure that PostHog is initialized before usage to prevent potential runtime errors if PostHog fails to load or is blocked by the user.

apps/roam/src/components/ExportDiscourseContext.tsx (1)

28-28: Prevent raw usage of PostHog.

As with other files, ensure that the PostHog dependency is properly guarded in case of blocked requests or missing credentials. A quick fallback can help avoid unhandled promise rejections if network connectivity fails.

apps/roam/src/components/ResultsView/views/Kanban.tsx (2)

25-25: Ensure consistent import ordering.
While importing posthog is valid, you might consider grouping analytics imports (like posthog) together, distinct from React imports and utility imports, for clarity.


283-284: Avoid repetitive event captures if component re-renders frequently.
The posthog.capture("kanban_created", { page: page }) call could fire repeatedly if Kanban re-renders. Consider using a ref or a check (e.g., useEffect or a once-like guard) to ensure the event fires only when genuinely creating the Kanban rather than on every render.

+ useEffect(() => {
+   posthog.capture("kanban_created", { page });
+ }, []);
apps/roam/src/components/canvas/Tldraw.tsx (1)

730-734: Refine naming for capture events.
"Canvas node created" is a clear event name, but ensure a consistent naming format across the codebase (e.g., snake_case, kebab-case, or PascalCase). Unified naming can help analytics queries remain consistent.

apps/roam/src/components/ResultsView/ResultsView.tsx (3)

42-42: Use environment variables for analytics.
In a production environment, consider loading posthog keys or config from environment variables or a secure source; do not commit them to version control if possible.


555-560: Event naming consistency.
"query_view_type_changed" might align better with your other event naming patterns if kept parallel, such as "Query View Type Changed." Keep a consistent naming across your analytics calls.


902-910: Consider one unified function for column view updates and analytics capture.
You might wrap onItemSelect with a single function that captures analytics first and then calls onViewChange. This helps avoid duplication and ensures analytics are always captured.

onItemSelect={(m) => {
+  logColumnViewChange(m, mode, parentUid);
   onViewChange({ mode: m, column, value }, i);
}}
apps/roam/src/index.ts (1)

29-31: Group initialization logs under debug conditions.
Consider wrapping console.log("PostHog initialized"); with a debug or environment check if you prefer separation between dev and production logs.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c91265 and d27e272.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (13)
  • apps/roam/package.json (1 hunks)
  • apps/roam/src/components/DiscourseContext.tsx (2 hunks)
  • apps/roam/src/components/DiscourseNodeMenu.tsx (2 hunks)
  • apps/roam/src/components/ExportDiscourseContext.tsx (2 hunks)
  • apps/roam/src/components/QueryBuilder.tsx (3 hunks)
  • apps/roam/src/components/QueryDrawer.tsx (5 hunks)
  • apps/roam/src/components/ResultsView/ResultsView.tsx (4 hunks)
  • apps/roam/src/components/ResultsView/views/Kanban.tsx (2 hunks)
  • apps/roam/src/components/canvas/CanvasDrawer.tsx (2 hunks)
  • apps/roam/src/components/canvas/Tldraw.tsx (4 hunks)
  • apps/roam/src/index.ts (1 hunks)
  • apps/roam/src/utils/createDiscourseNode.ts (2 hunks)
  • apps/roam/src/utils/triplesToBlocks.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/roam/package.json
🔇 Additional comments (20)
apps/roam/src/utils/triplesToBlocks.ts (1)

3-3: Ensure minimal analytics overhead
This import of posthog is appropriate for analytics, but verify that the overhead is kept minimal if this function is frequently invoked.

apps/roam/src/utils/createDiscourseNode.ts (2)

15-15: Confirm minimal import
posthog import is consistent with the rest of the analytics changes. Ensure the library does not negatively impact function performance.


32-36: Flag potential PII
The properties text, configPageUid, and newPageUid might contain identifying information. Confirm that these fields cannot store personal data. If they can, anonymize or redact them prior to invoking posthog.capture.

apps/roam/src/components/canvas/CanvasDrawer.tsx (1)

12-12: Check for consistent dependency usage
The import aligns well with existing usage; no immediate issues found.

apps/roam/src/components/QueryBuilder.tsx (2)

26-26: Streamline analytics usage
posthog import is consistent with other files.


216-219: Validate event triggers
Confirm that posthog.capture("query_builder_page_rendered") only fires once per page render, to avoid spamming analytics data.

apps/roam/src/components/DiscourseNodeMenu.tsx (2)

28-28: Consider error handling or fallback for PostHog initialization.

You’re adding the PostHog import here, which is good. However, ensure that posthog is properly initialized within your app before usage to prevent potential runtime errors. If network connectivity to PostHog fails, consider adding a safeguard to avoid throwing unhandled exceptions.


70-74: Confirm that no PII is inadvertently logged.

This new posthog.capture("new_discourse_node_type_created") event includes both nodeType and text. If text can contain user-generated content or sensitive data, ensure it does not violate PII or security requirements.

apps/roam/src/components/QueryDrawer.tsx (3)

59-62: Check event naming consistency.

"query_drawer_view_saved_query" is descriptive, but confirm that naming is consistent across your analytics events for easier data querying. Also verify that no PII or user-specific IDs are included here without anonymization.


375-379: Event usage clarity.

"query_drawer_opened" is triggered once the drawer loads. This looks fine. Consider capturing additional context if needed (e.g., user roles or environment data) — but be mindful about exposing PII.


393-400: Verify correctness of run flow and blockUid usage.

Capturing "query_drawer_rendered" when rendering the overlay is consistent with your analytics approach. However, ensure that blockUid is the correct, non-sensitive identifier. If it’s user-specific, consider anonymizing or hashing it.

apps/roam/src/components/DiscourseContext.tsx (1)

348-350: Confirm event property compliance with PII policy.

posthog.capture("show_discourse_context_result", { uid: uid }) logs a raw uid. If there is a chance this could be user-related PII, consider hashing or anonymizing this value to comply with privacy guidelines.

apps/roam/src/components/ExportDiscourseContext.tsx (1)

557-561: Check for potential PII in export analytics.

Logging "discourse_graph_export_button_clicked" with the current degreesIn and degreesOut is fine, but confirm that no user or page-specific data is included inadvertently. If user data needs to be included, consider hashing or removing sensitive details.

apps/roam/src/components/canvas/Tldraw.tsx (3)

61-61: Double-check environment variable usage for analytics.
Storing keys in code is sometimes unavoidable, but if there's a chance to place it in environment variables for more security, please do so.


600-602: Caution with storing user data.
You're passing potentially user-generated data (triples) to posthog.capture("Canvas Relations Created", {...}). Ensure that any PII within these data structures is sanitized to comply with privacy standards.


851-853: Conditionally log "Canvas-mounted" event.
When the app re-initializes or re-renders, this event might be repeatedly captured. Add checks or gating logic so it only fires once.

apps/roam/src/components/ResultsView/ResultsView.tsx (1)

1046-1051: Guard the export event.
You capture an event when the user clicks "Share Data." If the user cancels or never proceeds with the actual export, we might record misleading analytics. Consider capturing again upon successful export completion or clarifying the event name to "Export Initiated."

apps/roam/src/index.ts (3)

27-28: Revisit API key handling to prevent exposure.
This key is most likely sensitive. If possible, retrieve it from environment variables or a secure store. Committing the key to the repo can pose security risks.


32-51: Ensure you truly need these denied properties.
While this is explicitly disallowing certain default properties, confirm that these are indeed the right set for your privacy rules and that no further sensitive fields slip through, especially if your data shape changes.


57-57: Check for race conditions or call order concerns.
By calling initPostHog() before many other steps, you might capture early events. Verify that analytics calls from other modules happen only after PostHog is truly initialized.

Copy link
Contributor

@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

🔭 Outside diff range comments (2)
apps/roam/src/components/canvas/Tldraw.tsx (2)

Line range hint 764-770: Improve error handling and user feedback

The error handling could be improved in several ways:

  1. Error messages like "Shape not found" could be more user-friendly
  2. Error handling is scattered across different handlers
  3. Missing React Error Boundary for graceful fallbacks

Consider implementing a centralized error handling utility:

// errorUtils.ts
export const handleCanvasError = (error: Error | string, context?: string) => {
  const message = typeof error === 'string' ? error : error.message;
  renderToast({
    id: "tldraw-error",
    intent: "warning",
    content: `${context ? `${context}: ` : ''}${message}`,
  });
};

// Usage in component
if (!shape) {
  return handleCanvasError("Unable to locate the requested shape on canvas", "Navigation Error");
}

Also, consider adding an Error Boundary:

class CanvasErrorBoundary extends React.Component {
  componentDidCatch(error: Error) {
    handleCanvasError(error, "Canvas Error");
  }
  
  render() {
    return this.props.children;
  }
}

Also applies to: 776-783


Line range hint 919-947: Enhance accessibility support

The canvas implementation lacks proper accessibility features:

  1. Missing ARIA labels and roles
  2. Limited keyboard navigation support
  3. No screen reader considerations

Add proper accessibility support:

 <div
   className={`z-10 h-full w-full overflow-hidden rounded-md border border-gray-300 bg-white ${
     maximized ? "absolute inset-0" : "relative"
   }`}
   id={`roamjs-tldraw-canvas-container`}
   ref={containerRef}
+  role="application"
+  aria-label="Discourse Graph Canvas"
   tabIndex={-1}
+  aria-describedby="canvas-instructions"
 >
+  <div id="canvas-instructions" className="sr-only">
+    Use arrow keys to navigate the canvas. Press Space to pan, and Shift+Space to zoom.
+  </div>

Consider adding keyboard shortcuts help:

const KEYBOARD_SHORTCUTS = {
  pan: 'Space',
  zoom: 'Shift + Space',
  select: 'S',
  // ... add more shortcuts
};

const KeyboardHelp = () => (
  <div role="dialog" aria-label="Keyboard shortcuts">
    {Object.entries(KEYBOARD_SHORTCUTS).map(([action, key]) => (
      <div key={action}>
        <kbd>{key}</kbd>: {action}
      </div>
    ))}
  </div>
);
🧹 Nitpick comments (4)
apps/roam/src/components/canvas/Tldraw.tsx (2)

Line range hint 764-897: Optimize performance in event handlers

The event handlers contain complex logic that could impact performance:

  1. Complex calculations in event handlers
  2. Nested conditions increasing cognitive complexity
  3. Multiple DOM manipulations

Consider these optimizations:

  1. Extract complex logic into separate functions:
const handleShapeInteraction = (e: TLPointerEvent, shape: TLShape) => {
  if (!isValidForInteraction(e, shape)) return;
  
  if (e.shiftKey) {
    handleShiftKeyInteraction(shape);
  } else if (e.ctrlKey || e.metaKey) {
    handleCtrlKeyInteraction(shape);
  }
};

const isValidForInteraction = (e: TLPointerEvent, shape: TLShape) => {
  const validModifier = e.shiftKey || e.ctrlKey || e.metaKey;
  return validModifier && !app.selectedIds.length && shape?.props.uid;
};
  1. Debounce frequent operations:
const debouncedCenterOnPoint = debounce(
  (x: number, y: number) => {
    app.centerOnPoint(x, y, { duration: 500, easing: (t) => t * t });
  },
  100
);

Line range hint 4-4: Address remaining code quality issues

Several improvements could enhance code maintainability:

  1. TODO comment needs addressing
  2. CSS should be extracted to a separate file
  3. Magic numbers should be constants

Consider these improvements:

  1. Extract CSS to a separate file:
// styles/canvas.css
.canvas-container {
  z-index: 10;
  height: 100%;
  width: 100%;
  overflow: hidden;
  border-radius: 0.375rem;
  border: 1px solid #d1d5db;
  background-color: white;
}

// Import in component
import './styles/canvas.css';
  1. Extract magic numbers:
const CONSTANTS = {
  ANIMATION_DURATION: 500,
  DEFAULT_HEIGHT: '70vh',
  Z_INDEX: 10,
} as const;

Would you like me to help implement these improvements or create GitHub issues to track them?

Also applies to: 919-947

apps/roam/src/components/QueryDrawer.tsx (2)

24-24: Consider centralizing analytics logic

Instead of importing PostHog directly in components, consider creating a centralized analytics service to manage all tracking events. This would:

  • Ensure consistent event naming and properties
  • Make it easier to manage PII filtering
  • Simplify future analytics changes

Create an analytics service like this:

// services/analytics.ts
import posthog from 'posthog-js';

export const Analytics = {
  queryDrawer: {
    viewSavedQuery: (queryUid: string, isSavedToPage: boolean) => {
      posthog.capture('Query drawer: view saved query', {
        queryUid,
        isSavedToPage,
      });
    },
    // ... other events
  },
};

Line range hint 375-391: Enhance analytics context for drawer opening

The current implementation only tracks a static source. Consider:

  1. Adding more context about where the drawer was opened from
  2. Including the trigger action (e.g., button click, keyboard shortcut)
-export const openQueryDrawer = (onloadArgs: OnloadArgs) => {
+export const openQueryDrawer = (onloadArgs: OnloadArgs, context?: { source: string; trigger: string }) => {
   posthog.capture("Query drawer: opened", {
-    source: "drawer_open",
+    source: context?.source || "drawer_open",
+    trigger: context?.trigger || "unknown",
   });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d27e272 and c21cc0b.

📒 Files selected for processing (12)
  • apps/roam/src/components/DiscourseContext.tsx (2 hunks)
  • apps/roam/src/components/DiscourseNodeMenu.tsx (2 hunks)
  • apps/roam/src/components/ExportDiscourseContext.tsx (2 hunks)
  • apps/roam/src/components/QueryBuilder.tsx (3 hunks)
  • apps/roam/src/components/QueryDrawer.tsx (5 hunks)
  • apps/roam/src/components/ResultsView/ResultsView.tsx (4 hunks)
  • apps/roam/src/components/ResultsView/views/Kanban.tsx (2 hunks)
  • apps/roam/src/components/canvas/CanvasDrawer.tsx (2 hunks)
  • apps/roam/src/components/canvas/Tldraw.tsx (4 hunks)
  • apps/roam/src/index.ts (1 hunks)
  • apps/roam/src/utils/createDiscourseNode.ts (2 hunks)
  • apps/roam/src/utils/triplesToBlocks.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
  • apps/roam/src/index.ts
  • apps/roam/src/utils/createDiscourseNode.ts
  • apps/roam/src/components/DiscourseNodeMenu.tsx
  • apps/roam/src/components/canvas/CanvasDrawer.tsx
  • apps/roam/src/utils/triplesToBlocks.ts
  • apps/roam/src/components/ExportDiscourseContext.tsx
  • apps/roam/src/components/ResultsView/views/Kanban.tsx
  • apps/roam/src/components/DiscourseContext.tsx
  • apps/roam/src/components/QueryBuilder.tsx
  • apps/roam/src/components/ResultsView/ResultsView.tsx
🔇 Additional comments (1)
apps/roam/src/components/QueryDrawer.tsx (1)

59-62: Verify PII handling in analytics events

The queryUid being tracked could potentially contain sensitive information. Consider:

  1. Verifying if queryUid contains or could contain PII
  2. Implementing a sanitization function for analytics properties

Run this script to check for potential PII in query UIDs:

✅ Verification successful

Based on the analysis of the code, I can now provide a final response:

queryUid is a safe identifier, not containing PII

The queryUid used in analytics is a Roam page identifier that is:

  1. Generated from a fixed page title pattern discourse-graph/queries/${target}
  2. Used to reference saved queries in a structured format
  3. Not containing any user-input or personal information

The analytics event captures:

  • queryUid: A system-generated page identifier
  • isSavedToPage: A boolean flag

The rationale for this verification:

  1. The code shows that queryUids are generated from a fixed page path pattern using getPageUidByPageTitle("discourse-graph/queries/${target}")
  2. Saved queries are stored in a structured format with system-generated identifiers
  3. The implementation shows no user data or personal information being incorporated into the uid generation process
  4. The analytics event is using these system identifiers to track feature usage, not user data
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential PII patterns in query UIDs
# Look for email-like patterns or personally identifiable text in queries

rg -A 3 'queryUid.*' | rg -i 'email|name|address|phone|ssn|social|security'

Length of output: 77


Script:

#!/bin/bash
# Let's first understand how queryUid is generated/used
ast-grep --pattern 'queryUid'

Length of output: 272


Script:

#!/bin/bash
# Let's also check for any uid generation patterns
rg -A 5 'uid.*=' 

Length of output: 65555


Script:

#!/bin/bash
# Check the type definition of the uid
fd "types?.ts" --exec rg -A 3 "interface.*Query"

Length of output: 50


Script:

#!/bin/bash
# Let's check how queryUid is generated in the context of saved queries
rg -B 3 -A 3 "queryUid.*=" 

Length of output: 727


Script:

#!/bin/bash
# Check for any PII-related patterns in the query implementation
rg -A 5 "Query.*{" 

Length of output: 100


Script:

#!/bin/bash
# Check how the uid is used in the analytics context
rg -A 3 "posthog.*capture.*uid"

Length of output: 33


Script:

#!/bin/bash
# Let's check how queries are saved and what they contain
rg -A 5 'discourse-graph/queries'

Length of output: 2137


Script:

#!/bash
# Check the implementation around saved queries
ast-grep --pattern 'function.*Query'

Length of output: 38


Script:

#!/bin/bash
# Check for any sensitive data patterns in query-related code
rg -A 5 "saved.*query" -i

Length of output: 6825

Copy link
Contributor

@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: 0

🧹 Nitpick comments (1)
apps/roam/src/components/canvas/Tldraw.tsx (1)

600-602: LGTM!

The "Canvas Relations: Created" event captures appropriate non-PII data. Consider adding more metrics like relationCount for better analytics insights.

 posthog.capture("Canvas Relations: Created", {
   relation: relationLabel,
+  relationCount: newTriples.length,
 });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc71f80 and e680135.

📒 Files selected for processing (4)
  • apps/roam/src/components/canvas/DiscourseNodeUtil.tsx (2 hunks)
  • apps/roam/src/components/canvas/Tldraw.tsx (3 hunks)
  • apps/roam/src/components/settings/QueryPagesPanel.tsx (2 hunks)
  • apps/roam/src/utils/createDiscourseNode.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/roam/src/utils/createDiscourseNode.ts
🔇 Additional comments (6)
apps/roam/src/components/canvas/Tldraw.tsx (2)

61-61: LGTM!

The PostHog analytics import is correctly placed at the top of the file.


846-848: ⚠️ Potential issue

Review PII handling in analytics event

The "Canvas: mounted" event captures the title parameter which could potentially contain PII. Consider capturing non-PII metrics instead.

 posthog.capture("Canvas: mounted", {
-  title: title,
+  hasTitle: !!title,
+  titleLength: title.length,
 });

Likely invalid or redundant comment.

apps/roam/src/components/settings/QueryPagesPanel.tsx (2)

2-2: Ensure event naming consistency and watch for PII.

Importing posthog here seems fine, though be mindful of event naming consistency across the codebase. Also confirm that value does not contain sensitive or personally identifiable data.


50-50: Safeguard user data in analytics properties.

Capturing the “newType” property is useful. However, confirm that this property isn’t storing user-specific or private info that might qualify as PII.

apps/roam/src/components/canvas/DiscourseNodeUtil.tsx (2)

29-29: Validate import usage.

Importing posthog looks correct. Be sure it’s properly initialized elsewhere before capturing events to avoid uninitialized analytics calls.


390-395: Avoid inadvertently capturing PII in “text” property.

Although logging uid, text, and action is valuable, verify that text does not contain any user-identifying details if the user or block data can be considered sensitive. Consider sanitizing or hashing the content before capturing if it is at risk of exposing PII.

Would you like help creating a sanitization utility for these analytics events?

@mdroidian
Copy link
Contributor

@sid597 my OCD required me to rename the capture events 😅

Just pull these changes in before doing the final edits.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (2)
apps/roam/src/components/canvas/Tldraw.tsx (1)

846-848: Add error handling for analytics calls

The analytics events should be wrapped in try-catch blocks to gracefully handle potential failures.

Apply this diff to add error handling:

-posthog.capture("Canvas: Mounted", {
-  title: title,
-});
+try {
+  posthog.capture("Canvas: Mounted", {
+    hasTitle: !!title,
+  });
+} catch (error) {
+  console.error("Failed to capture analytics event:", error);
+}
apps/roam/src/components/ResultsView/ResultsView.tsx (1)

42-42: Consider centralizing PostHog initialization and error handling.

The PostHog import suggests direct usage. Consider creating a wrapper service to centralize analytics initialization, error handling, and PII protection.

Create an analytics service that provides:

  1. Centralized error handling
  2. Standardized event naming
  3. Consistent PII protection
  4. Type safety for events and properties

Example implementation:

// services/analytics.ts
import posthog from 'posthog-js';

type AnalyticsEvent = {
  results_view_layout_changed: {
    pageUidHash: string | null;
    oldLayout: string;
    newLayout: string;
  };
  // ... other events
};

export const analytics = {
  track<T extends keyof AnalyticsEvent>(
    event: T,
    properties: AnalyticsEvent[T]
  ) {
    try {
      posthog.capture(event, properties);
    } catch (error) {
      console.error(`Failed to capture analytics event ${event}:`, error);
    }
  },
  
  hashPageUid(uid: string | null): string | null {
    return uid ? window.btoa(uid).slice(0, 10) : null;
  }
};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e680135 and 740aa87.

📒 Files selected for processing (12)
  • apps/roam/src/components/DiscourseContext.tsx (2 hunks)
  • apps/roam/src/components/DiscourseNodeMenu.tsx (2 hunks)
  • apps/roam/src/components/ExportDiscourseContext.tsx (2 hunks)
  • apps/roam/src/components/QueryBuilder.tsx (3 hunks)
  • apps/roam/src/components/QueryDrawer.tsx (6 hunks)
  • apps/roam/src/components/ResultsView/ResultsView.tsx (4 hunks)
  • apps/roam/src/components/canvas/CanvasDrawer.tsx (2 hunks)
  • apps/roam/src/components/canvas/DiscourseNodeUtil.tsx (2 hunks)
  • apps/roam/src/components/canvas/Tldraw.tsx (3 hunks)
  • apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx (2 hunks)
  • apps/roam/src/components/settings/QueryPagesPanel.tsx (2 hunks)
  • apps/roam/src/utils/createDiscourseNode.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
  • apps/roam/src/utils/createDiscourseNode.ts
  • apps/roam/src/components/ExportDiscourseContext.tsx
  • apps/roam/src/components/canvas/DiscourseNodeUtil.tsx
  • apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx
  • apps/roam/src/components/canvas/CanvasDrawer.tsx
  • apps/roam/src/components/DiscourseNodeMenu.tsx
  • apps/roam/src/components/DiscourseContext.tsx
  • apps/roam/src/components/settings/QueryPagesPanel.tsx
  • apps/roam/src/components/QueryDrawer.tsx
  • apps/roam/src/components/QueryBuilder.tsx
🔇 Additional comments (5)
apps/roam/src/components/canvas/Tldraw.tsx (2)

600-602: Review analytics event data for PII exposure

The analytics event "Canvas Relation: Created" captures the relation label which could potentially contain sensitive information.

Apply this diff to minimize PII exposure:

 posthog.capture("Canvas Relation: Created", {
-  relation: relationLabel,
+  hasRelation: !!relationLabel,
 });

61-61: Verify PostHog initialization

The PostHog import is present, but we should verify its proper initialization.

✅ Verification successful

PostHog is properly initialized in the codebase

PostHog is correctly initialized in both the website and roam applications:

  • In apps/roam/src/index.ts, PostHog is initialized with a specific project key and configuration
  • The import in apps/roam/src/components/canvas/Tldraw.tsx is valid as it's used within the same application where PostHog is initialized
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for PostHog initialization in the codebase

# Look for PostHog initialization
rg -A 5 "posthog\.init"

# Check for environment variables or configuration related to PostHog
rg -l "POSTHOG|posthog" --type yaml --type json

Length of output: 858

apps/roam/src/components/ResultsView/ResultsView.tsx (3)

902-913: 🛠️ Refactor suggestion

Improve analytics implementation for column view changes.

The analytics event for column view changes needs similar improvements.

Apply this diff:

-posthog.capture("Results View: Column View Changed", {
-  pageUid: parentUid,
-  oldMode: mode,
-  newMode: m,
-});
+try {
+  posthog.capture("results_view_column_changed", {
+    pageUidHash: parentUid ? window.btoa(parentUid).slice(0, 10) : null,
+    oldMode: mode,
+    newMode: m,
+  });
+} catch (error) {
+  console.error("Failed to capture analytics event:", error);
+}

Likely invalid or redundant comment.


555-560: 🛠️ Refactor suggestion

Add error handling and protect PII in analytics event.

The analytics event for layout changes needs improvements in error handling and PII protection.

Apply this diff to improve the implementation:

-posthog.capture("Results View: Layout Changed", {
-  pageUid: parentUid,
-  oldLayout: layoutMode,
-  newLayout: l.id,
-});
+try {
+  posthog.capture("results_view_layout_changed", {
+    pageUidHash: parentUid ? window.btoa(parentUid).slice(0, 10) : null,
+    oldLayout: layoutMode,
+    newLayout: l.id,
+  });
+} catch (error) {
+  console.error("Failed to capture analytics event:", error);
+}

Changes made:

  1. Added error handling for analytics calls
  2. Protected PII by hashing the pageUid
  3. Standardized event name to snake_case

Likely invalid or redundant comment.


1049-1054: 🛠️ Refactor suggestion

Enhance analytics for share data events.

The share data analytics event needs improvements in error handling, PII protection, and additional metadata.

Apply this diff:

-posthog.capture("Results View: Share Data Clicked", {
-  parentUid: parentUid,
-  resultCount: results.length,
-  columnCount: columns.length,
-  layout: layoutMode,
-});
+try {
+  posthog.capture("results_view_share_clicked", {
+    pageUidHash: parentUid ? window.btoa(parentUid).slice(0, 10) : null,
+    resultCount: results.length,
+    columnCount: columns.length,
+    layout: layoutMode,
+    hasFilters: columnFilters.length > 0,
+    hasSort: activeSort.length > 0,
+  });
+} catch (error) {
+  console.error("Failed to capture analytics event:", error);
+}

Changes made:

  1. Added error handling
  2. Protected PII
  3. Standardized event name
  4. Added relevant metadata about filters and sorting

Likely invalid or redundant comment.

@sid597
Copy link
Collaborator Author

sid597 commented Jan 3, 2025

@mdroidian ready for review

@mdroidian
Copy link
Contributor

image

@sid597 shutdown() doesn't exist in the posthog definition. Is it required for frontend React? Or just Nodejs?

I have removed it, but if it is required, let me know.

@mdroidian mdroidian merged commit 6326417 into DiscourseGraphs:main Jan 5, 2025
1 of 3 checks passed
Copy link
Contributor

@mdroidian mdroidian left a comment

Choose a reason for hiding this comment

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

🔥

@sid597
Copy link
Collaborator Author

sid597 commented Jan 5, 2025

good catch my bad, its not required in React only nodejs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

Add Analytics

2 participants