آلفانا/مستندات

معرفی

آلفانا یک SDK رهگیری رفتار کاربران برای اپلیکیشن‌های React، Next.js و Vanilla JS است. تمام داده‌ها — ناوبری، زمان حضور، نقشه حرارتی و لاگ‌ها — بدون کوکی و بدون شخص ثالث جمع‌آوری می‌شوند.

🗺️
نقشه حرارتی

رکورد کلیک، موس و اسکرول با نمونه‌برداری قابل تنظیم.

⏱️
زمان حضور

اندازه‌گیری دقیق time-on-page به ازای هر مسیر.

🧭
ناوبری SPA

ردیابی خودکار pushState و popstate بدون نیاز به کد اضافه.

📸
اسکرین‌شات

ارسال full-page screenshot هر ۵ دقیقه برای heatmap overlay.

🪵
لاگ خطا

جمع‌آوری console.error، onerror و unhandledrejection.

🔒
حریم خصوصی

بدون کوکی، بدون ذخیره IP، سازگار با GDPR.

نصب

پکیج را با هر package manager که استفاده می‌کنید نصب کنید:

bash
# npm
npm install alphana-sdk

# pnpm
pnpm add alphana-sdk

# yarn
yarn add alphana-sdk

# bun
bun add alphana-sdk

React / Vite

UserTrackerProvider را یک بار دور کل اپ بپیچید، معمولاً در main.tsx.

tsx
// main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { UserTrackerProvider } from 'alphana-sdk/react';
import App from './App';

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <UserTrackerProvider
      config={{
        appId: import.meta.env.VITE_TRACKER_APP_ID,
        secretKey: import.meta.env.VITE_TRACKER_SECRET,
      }}
    >
      <App />
    </UserTrackerProvider>
  </StrictMode>
);
bash
# .env.local
VITE_TRACKER_APP_ID=your_app_id_here
VITE_TRACKER_SECRET=your_secret_key_here

Next.js App Router

چون UserTrackerProvider از hooks استفاده می‌کند، باید در یک Client Component باشد.

گام ۱ — ساخت Providers component

tsx
// app/providers.tsx
'use client';
import { UserTrackerProvider } from 'alphana-sdk/react';
import type { ReactNode } from 'react';

export function Providers({ children }: { children: ReactNode }) {
  return (
    <UserTrackerProvider
      config={{
        appId: process.env.NEXT_PUBLIC_TRACKER_APP_ID!,
        secretKey: process.env.NEXT_PUBLIC_TRACKER_SECRET!,
      }}
    >
      {children}
    </UserTrackerProvider>
  );
}

گام ۲ — استفاده در layout.tsx

tsx
// app/layout.tsx
import { Providers } from './providers';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="fa" dir="rtl">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

گام ۳ — متغیرهای محیطی

bash
# .env.local
NEXT_PUBLIC_TRACKER_APP_ID=your_app_id_here
NEXT_PUBLIC_TRACKER_SECRET=your_secret_key_here

Vanilla JS / TS

بدون هیچ فریم‌وری — فقط یک instance از UserTracker بسازید و init() صدا بزنید.

ts
import { UserTracker } from 'alphana-sdk';

const tracker = new UserTracker({
  appId: 'YOUR_APP_ID',
  secretKey: 'YOUR_SECRET_KEY',
});

// یک بار در شروع برنامه فراخوانی کنید
tracker.init();

// هنگام logout یا unmount
tracker.destroy();

تنظیمات کامل

تمام گزینه‌های قابل پاس دادن به TrackerConfig:

نامنوعتوضیح
appIdاجباریstringشناسه اپ از داشبورد آلفانا.
secretKeyاجباریstringکلید مخفی SDK — به عنوان Bearer token ارسال می‌شود.
endpointstringآدرس API. فقط در خودمیزبانی تغییر دهید. پیش‌فرض: https://api.alphana.ir/api/events
trackNavigationbooleanردیابی تغییر مسیر SPA. پیش‌فرض: true
trackHeatmapbooleanجمع‌آوری داده موس/کلیک/اسکرول. پیش‌فرض: true
trackTimebooleanاندازه‌گیری زمان حضور در هر صفحه. پیش‌فرض: true
trackLogsbooleanگرفتن console.error و window.onerror. پیش‌فرض: true
trackSnapshotsbooleanارسال اسکرین‌شات صفحه هر ۵ دقیقه. نیاز به `html2canvas`. پیش‌فرض: true
snapshotIntervalMsnumber (ms)فاصله زمانی بین اسکرین‌شات‌ها. پیش‌فرض: 300000 (۵ دقیقه)
mouseSampleRatenumber (0–1)درصد نمونه‌برداری رویداد موس. پیش‌فرض: 0.3
maxHeatmapPointsnumberحداکثر نقاط heatmap در حافظه. پیش‌فرض: 2000
batchSizenumberاندازه batch قبل از flush خودکار. پیش‌فرض: 20
flushIntervalnumber (ms)فاصله flush خودکار به میلی‌ثانیه. پیش‌فرض: 5000
onEvent(event) => voidcallback برای هر رویداد emit‌شده.

خودمیزبانی

تمام کد بک‌اند، داشبورد، و این landing page در GitHub موجود است. برای راه‌اندازی:

گام ۱ — Clone و تنظیم متغیرها

bash
git clone https://github.com/teokamalipour/alphana-sdk.git
cd alphana-sdk
cp .env.example .env
# سپس .env را با مقادیر واقعی ویرایش کنید

گام ۲ — اجرا با Docker Compose

bash
docker compose up -d

این دستور MongoDB، بک‌اند NestJS و داشبورد React را راه‌اندازی می‌کند.

گام ۳ — تغییر endpoint در SDK

ts
new UserTracker({
  appId: 'YOUR_APP_ID',
  secretKey: 'YOUR_SECRET_KEY',
  // آدرس سرور خودتان را اینجا بگذارید
  endpoint: 'https://your-server.com/api/events',
})

React Hooks

وقتی از alphana-sdk/react استفاده می‌کنید این hooks در دسترس هستند:

Hookخروجیتوضیح
useTracker()UserTrackerدسترسی به instance اصلی tracker.
usePageView()PageView | nullداده pageview صفحه جاری.
usePageViews()PageView[]تمام pageview های session جاری.
useHeatmapData()HeatmapPoint[]نقاط heatmap صفحه جاری.
useTimeSpent()number (s)زمان حضور در صفحه جاری (ثانیه).
useFeatureFlags()Record<string, boolean>تمام فلگ‌های ارزیابی‌شده برای کاربر جاری. با هر بار identify() به‌روز می‌شود.
useFeatureFlagEnabled(key)booleantrue اگر فلگ مشخص‌شده برای کاربر جاری فعال باشد، در غیر این‌صورت false.

مثال

tsx
import { useTracker, useTimeSpent, useHeatmapData } from 'alphana-sdk/react';

export function DebugPanel() {
  const tracker   = useTracker();
  const timeSpent = useTimeSpent();   // ثانیه
  const points    = useHeatmapData(); // HeatmapPoint[]

  return (
    <div>
      <p>زمان حضور: {timeSpent}s</p>
      <p>نقاط heatmap: {points.length}</p>
      <button onClick={() => tracker.flush()}>ارسال فوری</button>
    </div>
  );
}

فیچر فلگ — معرفی

فیچر فلگ (Feature Flag) به شما امکان می‌دهد بدون دیپلوی مجدد، قابلیت‌های مختلف را برای کاربران مختلف فعال یا غیرفعال کنید. SDK آلفانا این قابلیت را به صورت built-in ارائه می‌دهد.

🚀
بدون دیپلوی

فلگ را از داشبورد تغییر دهید — تغییر بلافاصله برای کاربران اعمال می‌شود.

🎯
هدف‌گیری دقیق

فلگ را بر اساس email، plan، country یا هر property دیگری هدف‌گیری کنید.

🔄
real-time

بعد از identify() فلگ‌ها بلافاصله دوباره ارزیابی می‌شوند.

🛡️
kill switch

یک قابلیت مشکل‌دار را فوری غیرفعال کنید بدون نیاز به rollback.

پلن موردنیاز: فیچر فلگ فقط در پلن‌های حرفه‌ای، اقتصادی و ویژه در دسترس است.

ساخت فلگ در داشبورد

در داشبورد به بخش فیچر فلگ‌ها بروید و روی فلگ جدید کلیک کنید.

فیلدتوضیح
keyشناسه ماشینی فلگ — فقط حروف کوچک انگلیسی، اعداد، خط‌تیره یا زیرخط. مثال: new-checkout
descriptionتوضیح اختیاری برای یادآوری هدف فلگ.
فعال/غیرفعالوضعیت کلی فلگ. اگر غیرفعال باشد برای هیچ کاربری true نمی‌شود.
شرط‌های هدف‌گیریاختیاری. اگر تعریف شود، همه شرط‌ها باید برقرار باشند (AND). بدون شرط یعنی برای همه فعال است.

استفاده در SDK

React Hooks

ساده‌ترین روش — از hooks اختصاصی استفاده کنید:

tsx
import {
  useFeatureFlagEnabled,
  useFeatureFlags,
} from 'alphana-sdk/react';

// بررسی یک فلگ خاص
function CheckoutButton() {
  const showNewCheckout = useFeatureFlagEnabled('new-checkout');

  if (showNewCheckout) {
    return <NewCheckout />;
  }
  return <OldCheckout />;
}

// دریافت همه فلگ‌ها
function DebugFlags() {
  const flags = useFeatureFlags();
  // { 'new-checkout': true, 'promo-banner': false, ... }
  return <pre>{JSON.stringify(flags, null, 2)}</pre>;
}

شناسایی کاربر

برای استفاده از شرط‌های هدف‌گیری (مثل email یا plan)، ابتدا کاربر را شناسایی کنید:

tsx
import { useTracker } from 'alphana-sdk/react';

function AuthWrapper({ user }) {
  const tracker = useTracker();

  useEffect(() => {
    if (user && tracker) {
      // properties به عنوان شرط‌های هدف‌گیری استفاده می‌شوند
      tracker.identify({
        email: user.email,
        plan: user.plan,       // 'free' | 'pro' | ...
        country: user.country, // 'IR' | 'US' | ...
      });
    }
  }, [user, tracker]);

  return <>{children}</>;
}

Vanilla JS

ts
const tracker = new UserTracker({
  appId: 'YOUR_APP_ID',
  secretKey: 'YOUR_SECRET_KEY',
}).init();

// شناسایی کاربر
tracker.identify({ email: 'user@example.com', plan: 'pro' });

// بررسی فلگ
if (tracker.isFeatureEnabled('new-checkout')) {
  showNewCheckout();
}

// گوش دادن به تغییرات فلگ
const unsub = tracker.onFlagsChange((flags) => {
  console.log('flags updated:', flags);
});

// دریافت همه فلگ‌ها
const allFlags = tracker.getFlags();
// { 'new-checkout': true, 'promo-banner': false }

شرط‌های هدف‌گیری

هر فلگ می‌تواند یک یا چند شرط داشته باشد. تمام شرط‌ها باید برقرار باشند (AND). اگر شرطی تعریف نشود، فلگ برای همه فعال است.

operatorتوضیحمثال
equalsمقدار دقیقاً برابر باشد (case-insensitive)email equals user@example.com
containsمقدار شامل رشته مشخص‌شده باشدemail contains @mycompany.com
is_inمقدار در لیست جداشده با کاما باشدplan is_in pro,economy,special
نکته: شرط‌ها روی userProperties که از طریق tracker.identify({...}) ارسال می‌کنید ارزیابی می‌شوند. اگر identify() فراخوانی نشده باشد، تمام شرط‌ها به عنوان عدم تطابق در نظر گرفته می‌شوند.

پلن‌های پشتیبانی‌کننده

فیچر فلگ یک قابلیت premium است و فقط در پلن‌های زیر در دسترس است:

پلنفیچر فلگ
رایگان✗ غیرفعال
پایه✗ غیرفعال
حرفه‌ای✓ فعال
اقتصادی✓ فعال
ویژه✓ فعال

Tracker API

متدهای عمومی روی instance UserTracker:

متدتوضیح
init()شروع ردیابی. در SSR no-op است. مقدار this را برمی‌گرداند.
destroy()توقف تمام event listenerها و timerها و ارسال رویدادهای باقی‌مانده.
flush()ارسال فوری تمام رویدادها از صف.
trackPageView(path?)ثبت دستی یک pageview برای مسیر مشخص (یا مسیر جاری).
subscribe(fn)اضافه کردن subscriber. تابع unsubscribe را برمی‌گرداند.
getSession()اطلاعات session جاری.
getPageViews()تمام pageviewهای session جاری.
getHeatmapData(path?)نقاط heatmap برای یک مسیر یا تمام مسیرها.
ts
import { UserTracker } from 'alphana-sdk';

const tracker = new UserTracker({ appId: 'id', secretKey: 'key' });

// گوش دادن به رویدادها
تراکر‌مستقیم آغاز کنید
const unsubscribe = tracker.subscribe((event) => {
  console.log(event.type, event);
});

tracker.init();

// هر جا که نیاز به ارسال فوری دارید
tracker.flush();

// لغو اشتراک
// unsubscribe();