feat: new public website

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-12-02 09:17:49 +01:00
parent e2536774b0
commit ac4429d6d9
206 changed files with 18415 additions and 12433 deletions

View File

@@ -12,7 +12,7 @@ A **device ID** is a unique identifier generated for each device/browser combina
- **Origin** (project ID)
- **Salt** (a rotating secret key)
```typescript:packages/common/server/profileId.ts
```typescript
export function generateDeviceId({
salt,
ua,
@@ -31,7 +31,7 @@ The salt used for device ID generation rotates **daily at midnight** (UTC). This
- Device IDs reset each day for privacy purposes
- The system maintains both the current and previous day's salt to handle events that may arrive slightly after midnight
```typescript:apps/worker/src/jobs/cron.salt.ts
```typescript
// Salt rotation happens daily at midnight (pattern: '0 0 * * *')
```
@@ -45,7 +45,7 @@ A **session** represents a continuous period of user activity. Sessions are used
Sessions have a **30-minute timeout**. If no events are received for 30 minutes, the session automatically ends. Each new event resets this 30-minute timer.
```typescript:apps/worker/src/utils/session-handler.ts
```typescript
export const SESSION_TIMEOUT = 1000 * 60 * 30; // 30 minutes
```
@@ -59,7 +59,7 @@ Sessions are **only created for client events**, not server events. This means:
Additionally, sessions are **not created for events older than 15 minutes**. This prevents historical data imports from creating artificial sessions.
```typescript:apps/worker/src/jobs/events.incoming-event.ts
```typescript
// Sessions are not created if:
// 1. The event is from a server (uaInfo.isServer === true)
// 2. The timestamp is from the past (isTimestampFromThePast === true)
@@ -81,7 +81,7 @@ This means:
- Once you identify a user (by providing a profile ID), all their events will be associated with that profile
- The same user can be tracked across multiple devices by using the same profile ID
```typescript:packages/db/src/services/event.service.ts
```typescript
// If no profileId is provided, it defaults to deviceId
if (!payload.profileId && payload.deviceId) {
payload.profileId = payload.deviceId;
@@ -116,7 +116,7 @@ Server events:
- Are attached to existing sessions if available
- Are useful for backend tracking without session management
```typescript:packages/common/server/parser-user-agent.ts
```typescript
// Server events are detected by patterns like "Go-http-client/1.0"
function isServer(res: UAParser.IResult) {
if (SINGLE_NAME_VERSION_REGEX.test(res.ua)) {
@@ -128,7 +128,7 @@ function isServer(res: UAParser.IResult) {
The distinction is made in the event processing pipeline:
```typescript:apps/worker/src/jobs/events.incoming-event.ts
```typescript
const uaInfo = parseUserAgent(userAgent, properties);
// Only client events create sessions
@@ -158,7 +158,7 @@ The system validates timestamps to prevent abuse and ensure data quality:
1. **Future timestamps**: If a timestamp is more than **1 minute in the future**, the server timestamp is used instead
2. **Past timestamps**: If a timestamp is older than **15 minutes**, it's marked as `isTimestampFromThePast: true`
```typescript:apps/api/src/controllers/track.controller.ts
```typescript
// Timestamp validation logic
const ONE_MINUTE_MS = 60 * 1000;
const FIFTEEN_MINUTES_MS = 15 * ONE_MINUTE_MS;
@@ -177,7 +177,7 @@ const isTimestampFromThePast =
**Important**: Events with timestamps older than 15 minutes (`isTimestampFromThePast: true`) will **not create new sessions**. This prevents historical data imports from creating artificial sessions in your analytics.
```typescript:apps/worker/src/jobs/events.incoming-event.ts
```typescript
// Events from the past don't create sessions
if (uaInfo.isServer || isTimestampFromThePast) {
// Attach to existing session or track without session

View File

@@ -13,7 +13,7 @@ import WebSdkConfig from '@/components/web-sdk-config.mdx';
<Steps>
### Step 1: Install
```bash
```npm
npm install @openpanel/sdk
```

View File

@@ -12,7 +12,7 @@ The OpenPanel Kotlin SDK allows you to track user behavior in your Kotlin applic
## Installation
<Callout type="warn">
This package is not yet published. So you cannot install it with `gradle` yet.
This package is not yet published. So you cannot install it with `` yet.
</Callout>
<Steps>
@@ -20,7 +20,7 @@ This package is not yet published. So you cannot install it with `gradle` yet.
Add the OpenPanel SDK to your project's dependencies:
```gradle
```
dependencies {
implementation 'dev.openpanel:openpanel:0.0.1'
}

View File

@@ -17,7 +17,7 @@ import CommonSdkConfig from '@/components/common-sdk-config.mdx';
We're dependent on `expo-application` for `buildNumber`, `versionNumber` (and `referrer` on android) and `expo-constants` to get the `user-agent`.
```bash
```npm
npm install @openpanel/react-native
npx expo install expo-application expo-constants
```

View File

@@ -133,7 +133,7 @@ window.op('init', {
<Steps>
#### Step 1: Install the SDK
```bash
```npm
npm install @openpanel/web
```
@@ -186,7 +186,7 @@ declare global {
<Steps>
##### Step 1: Install the SDK
```bash
```npm
npm install @openpanel/web
```

View File

@@ -13,7 +13,7 @@ import WebSdkConfig from '@/components/web-sdk-config.mdx';
<Steps>
### Step 1: Install
```bash
```npm
npm install @openpanel/web
```