@@ -565,7 +565,133 @@ Both SDKs use shared HTTP client libraries:
565565
566566---
567567
568- ## 9. Database Schema
568+ ## 9. loom-web Tracking Patterns
569+
570+ The loom-web application uses helper functions to ensure consistent event naming and properties across all tracked interactions.
571+
572+ ### 9.1 Tracking Helper Functions
573+
574+ Import from ` $lib/analytics ` :
575+
576+ ``` typescript
577+ import {
578+ capture ,
579+ trackLinkClick ,
580+ trackButtonClick ,
581+ trackFormSubmit ,
582+ trackModalOpen ,
583+ trackModalClose ,
584+ trackFilterChange ,
585+ trackAction
586+ } from ' $lib/analytics' ;
587+ ```
588+
589+ ### 9.2 Function Signatures
590+
591+ | Function | Parameters | Event Name |
592+ | ----------| ------------| ------------|
593+ | ` trackLinkClick ` | ` linkName: string, href: string, properties? ` | ` link_clicked ` |
594+ | ` trackButtonClick ` | ` buttonName: string, properties? ` | ` button_clicked ` |
595+ | ` trackFormSubmit ` | ` formName: string, properties? ` | ` form_submitted ` |
596+ | ` trackModalOpen ` | ` modalName: string, properties? ` | ` modal_opened ` |
597+ | ` trackModalClose ` | ` modalName: string, properties? ` | ` modal_closed ` |
598+ | ` trackFilterChange ` | ` filterName: string, value: unknown, properties? ` | ` filter_changed ` |
599+ | ` trackAction ` | ` action: string, resourceType: string, resourceId: string, properties? ` | ` action_performed ` |
600+
601+ ### 9.3 Usage Examples
602+
603+ ** Link tracking:**
604+ ``` svelte
605+ <a href="/threads" onclick={() => trackLinkClick('nav_threads', '/threads')}>
606+ Threads
607+ </a>
608+ ```
609+
610+ ** Button tracking:**
611+ ``` svelte
612+ <button onclick={() => { trackButtonClick('create_weaver'); handleCreate(); }}>
613+ New Weaver
614+ </button>
615+ ```
616+
617+ ** Modal tracking:**
618+ ``` svelte
619+ <script>
620+ function openDeleteModal(weaver: Weaver) {
621+ trackModalOpen('delete_weaver', { weaver_id: weaver.id });
622+ deleteModal = weaver;
623+ }
624+
625+ function closeDeleteModal() {
626+ trackModalClose('delete_weaver');
627+ deleteModal = null;
628+ }
629+ </script>
630+ ```
631+
632+ ** Filter tracking:**
633+ ``` svelte
634+ <select onchange={(e) => {
635+ const value = e.currentTarget.value;
636+ trackFilterChange('org_filter', value);
637+ selectedOrg = value;
638+ }}>
639+ ```
640+
641+ ** Action tracking:**
642+ ``` svelte
643+ <button onclick={() => {
644+ trackAction('resolve', 'issue', issue.id);
645+ handleResolve();
646+ }}>
647+ Resolve
648+ </button>
649+ ```
650+
651+ ** Form tracking:**
652+ ``` svelte
653+ <form onsubmit={(e) => {
654+ trackFormSubmit('create_monitor', { org_id: selectedOrg });
655+ handleSubmit(e);
656+ }}>
657+ ```
658+
659+ ### 9.4 Event Property Conventions
660+
661+ | Property | Description | Example |
662+ | ----------| -------------| ---------|
663+ | ` link_name ` | Descriptive link identifier | ` 'project_card' ` , ` 'back_button' ` |
664+ | ` href ` | Destination URL | ` '/crashes/proj-123' ` |
665+ | ` button_name ` | Descriptive button identifier | ` 'create_weaver' ` , ` 'delete_monitor' ` |
666+ | ` form_name ` | Form identifier | ` 'create_org' ` , ` 'profile_settings' ` |
667+ | ` modal_name ` | Modal identifier | ` 'delete_confirmation' ` , ` 'logs_viewer' ` |
668+ | ` filter_name ` | Filter identifier | ` 'status' ` , ` 'time_range' ` , ` 'org' ` |
669+ | ` filter_value ` | Selected filter value | ` 'active' ` , ` '7d' ` , ` 'org-123' ` |
670+ | ` action ` | Action performed | ` 'resolve' ` , ` 'delete' ` , ` 'pause' ` |
671+ | ` resource_type ` | Type of resource | ` 'issue' ` , ` 'monitor' ` , ` 'weaver' ` |
672+ | ` resource_id ` | Resource identifier | ` 'issue-abc' ` , ` 'mon-xyz' ` |
673+
674+ ### 9.5 Navigation Tracking
675+
676+ Navigation paths are automatically tracked via the ` nav_clicked ` event in the app layout:
677+
678+ ``` svelte
679+ <script>
680+ function trackNavClick(item: string, path: string) {
681+ capture('nav_clicked', { item, path });
682+ }
683+ </script>
684+
685+ <nav>
686+ <a href="/threads" onclick={() => trackNavClick('threads', '/threads')}>
687+ Threads
688+ </a>
689+ </nav>
690+ ```
691+
692+ ---
693+
694+ ## 10. Database Schema
569695
570696### 9.1 Migration: ` XXX_analytics.sql `
571697
@@ -652,16 +778,16 @@ CREATE INDEX idx_analytics_api_keys_key_hash ON analytics_api_keys(key_hash);
652778
653779---
654780
655- ## 10 . API Key Management
781+ ## 11 . API Key Management
656782
657- ### 10 .1 Key Types
783+ ### 11 .1 Key Types
658784
659785| Type | Prefix | Use Case | Capabilities |
660786| ------| --------| ----------| --------------|
661787| Write | ` loom_analytics_write_ ` | Client-side, public | Capture, identify, alias |
662788| ReadWrite | ` loom_analytics_rw_ ` | Server-side, secret | All write + query/export |
663789
664- ### 10 .2 Key Format
790+ ### 11 .2 Key Format
665791
666792```
667793loom_analytics_{type}_{random}
@@ -671,7 +797,7 @@ loom_analytics_write_7a3b9f2e1c4d8a5b6e0f3c2d1a4b5c6d7e8f9a0b
671797loom_analytics_rw_8b4c0g3f2d5e9a6c7f1g4d3e2b5a6c7d8e9f0a1b
672798```
673799
674- ### 10 .3 Authentication
800+ ### 11 .3 Authentication
675801
676802SDK requests include:
677803
@@ -688,9 +814,9 @@ Server validates:
688814
689815---
690816
691- ## 11 . Configuration
817+ ## 12 . Configuration
692818
693- ### 11 .1 Environment Variables
819+ ### 12 .1 Environment Variables
694820
695821| Variable | Type | Description | Default |
696822| ----------| ------| -------------| ---------|
@@ -701,7 +827,7 @@ Server validates:
701827
702828---
703829
704- ## 12 . Audit Events
830+ ## 13 . Audit Events
705831
706832Analytics operations logged via ` loom-server-audit ` :
707833
@@ -714,17 +840,17 @@ Analytics operations logged via `loom-server-audit`:
714840
715841---
716842
717- ## 13 . Permissions
843+ ## 14 . Permissions
718844
719- ### 13 .1 API Key Management
845+ ### 14 .1 API Key Management
720846
721847| Action | Org Admin | Org Member | Super Admin |
722848| --------| -----------| ------------| -------------|
723849| List API keys | ✓ | ✗ | ✓ (all) |
724850| Create API key | ✓ | ✗ | ✓ |
725851| Revoke API key | ✓ | ✗ | ✓ |
726852
727- ### 13 .2 Query Access
853+ ### 14 .2 Query Access
728854
729855| Action | Write Key | ReadWrite Key |
730856| --------| -----------| ---------------|
@@ -736,9 +862,9 @@ Analytics operations logged via `loom-server-audit`:
736862
737863---
738864
739- ## 14 . Security Considerations
865+ ## 15 . Security Considerations
740866
741- ### 14 .1 IP Address Handling
867+ ### 15 .1 IP Address Handling
742868
743869IP addresses are sensitive data. Use ` loom-secret::Secret ` :
744870
@@ -756,14 +882,14 @@ This ensures:
756882- Explicit ` .expose() ` required to access
757883- Serialization can be controlled
758884
759- ### 14 .2 Write Key Safety
885+ ### 15 .2 Write Key Safety
760886
761887Write-only keys are safe for client-side because:
762888- Cannot read any data back
763889- Cannot query other users
764890- Scoped to single org
765891
766- ### 14 .3 Event Validation
892+ ### 15 .3 Event Validation
767893
768894Validate incoming events:
769895- ` event_name ` : Max 200 chars, alphanumeric + underscore + ` $ ` prefix
@@ -772,7 +898,7 @@ Validate incoming events:
772898
773899---
774900
775- ## 15 . Rust Dependencies
901+ ## 16 . Rust Dependencies
776902
777903``` toml
778904# loom-analytics-core
0 commit comments