@paubox/tracking
v0.3.0
Published
HIPAA-compliant first-party analytics snippet for Paubox products
Downloads
362
Readme
@paubox/tracking
HIPAA-compliant first-party analytics for Paubox products.
This repo ships two things:
@paubox/tracking— a TypeScript snippet library (ESM + CJS) that instruments Next.js pages with page views, click events, time-on-page, and login events.paubox-next-integration/— ready-to-copy files forpaubox-next: the ingest API route, database schema, PII scrubber, rate limiter, and the CSM Administrator analytics dashboard.
Why first-party?
Third-party analytics tools cannot receive PHI under HIPAA without a signed BAA and rigorous data-handling controls. Paubox Dashboard pages may contain PHI in URL paths. This system keeps all data inside Paubox-owned infrastructure: an encrypted AWS RDS PostgreSQL instance with AES-256 at rest and TLS 1.3 in transit.
Repository layout
paubox-tracking/
├── src/ # @paubox/tracking library source
│ ├── index.ts # public exports
│ ├── types.ts # shared TypeScript interfaces
│ ├── tracker.ts # event queue + flush logic
│ ├── session.ts # anon_id, session_id, session count
│ ├── page-view.ts # Next.js route-change listener
│ ├── click-tracker.ts # document-level delegated click listener
│ ├── time-on-page.ts # Page Visibility API timer
│ ├── login-meta.ts # login success/failure helpers
│ └── PauboxAnalyticsProvider.tsx # React provider component
│
└── paubox-next-integration/ # Files to copy into paubox-next
├── migrations/
│ └── 001_analytics_events.sql
├── src/
│ ├── components/PauboxAnalytics/index.tsx
│ ├── lib/analytics/ # db, scrub, bot-filter, rate-limit, queries
│ ├── pages/api/analytics/event.ts
│ ├── pages/api/admin/analytics/
│ └── views/Admin/Analytics/
├── routePolicy.patch.ts
└── sidebarOptions.patch.tsGetting started
Prerequisites
- Node.js 18+
- npm 9+
Install
npm installBuild the library
npm run build # outputs dist/ (ESM + CJS + .d.ts)
npm run dev # watch modeTest
npm testLint
npm run lintType-check
npm run typecheckUsing the library in paubox-next
1. Install the package
Until published to a registry, install as a local path dependency:
# from paubox-next directory
npm install ../paubox-tracking2. Add the provider to _app.tsx
import { PauboxAnalytics } from 'components/PauboxAnalytics';
// Inside the provider tree, after Auth0Provider and Core:
<PauboxAnalytics>
{children}
</PauboxAnalytics>PauboxAnalytics reads user.sub from useAuth0() and customer.id from useCustomer(), then passes them to the tracker automatically.
3. Instrument click targets
Add data-pb-track to any element you want to capture clicks on:
<button data-pb-track="send_email_btn">Send</button>
<a data-pb-track="nav_compose" href="/compose">Compose</a>Clicks on elements without this attribute are silently ignored.
4. Copy integration files
Copy the contents of paubox-next-integration/ into the corresponding paths in paubox-next. Apply the two small edits described in routePolicy.patch.ts and sidebarOptions.patch.ts.
5. Run the database migration
psql $ANALYTICS_DATABASE_URL -f paubox-next-integration/migrations/001_analytics_events.sql6. Set environment variables
# .env.local in paubox-next
ANALYTICS_DATABASE_URL=postgresql://user:pass@host/analytics?sslmode=verify-fullData collected
| Category | What is stored |
|---|---|
| Page views | URL path (no query string, no hash), surface, timestamp |
| Time on page | Total duration ms, visible (tab-active) ms |
| Clicks | data-pb-track label, element tag, href path |
| Sessions | Session count per user, session ID per browser session |
| Login events | Success/failure, Auth0 error code on failure |
| Login metadata | City, region, country (IP-derived at ingest); browser, OS, device type (UA-derived at ingest) |
| Identity | Auth0 sub (opaque string) — never email, name, or picture |
| Org context | Paubox customer.id (integer) |
Never stored: full URLs, query strings, email addresses, names, profile data, mouse positions, screen recordings.
Security & HIPAA notes
- Encryption at rest: AES-256 via AWS RDS storage encryption (KMS customer-managed key)
- Encryption in transit: TLS 1.2 minimum; connection string requires
sslmode=verify-full - PII scrubbing: ingest route scans
page_pathandpropertiesfor email, SSN, and credit card patterns and redacts before storage - Bot filtering:
isbotpackage drops known crawler User-Agents before any DB write - Rate limiting: 60 events/minute per IP sliding window; always responds 204 (never reveals limit state)
- Access control: analytics data is readable only by
super_adminusers via the CSM Administrator dashboard
License
Apache 2.0 — see LICENSE.
