back

analytics

Plan, implement, or audit analytics, error monitoring, health checks, dashboards, and reporting. Use when designing events, consent-aware tracking, incident visibility, or observability.

Category
analytics
Package
analytics/SKILL.md
License
MIT
Author
@tushaarmehtaa
Tags
analyticsposthoggoogle-analyticssentryhealth-checkdashboard

Install

Swipe for more runtimes.

Codex

Skills directory: ~/.codex/skills

available to install

Install globally

$npx skills add tushaarmehtaa/tushar-skills --skill analytics -g -a codex -y

Invoke

$analytics or /skills

You can also describe the task naturally; runtimes may select the skill from its description.

Required access

project filesterminal commandsnetwork access

local coding agent required

This skill requires project files, terminal commands, and network access. Uploading it to a chat app does not provide equivalent execution.

ChatGPT Skills

This workflow needs a local coding environment or capabilities that a chat-only Skills upload does not provide.

Why local agent required →

Instructions

Source: SKILL.md

Analytics

Build the smallest measurement system that answers explicit product or operational questions. Preserve existing providers and schemas unless a migration is part of the request.

Workflow

  1. Inspect the framework, router/runtime, deployment target, auth model, existing analytics and monitoring packages, environment-variable examples, privacy controls, and current event calls.
  2. Define the decisions the data must support: acquisition, activation, retention, adoption, revenue, reliability, or incident response. For every metric, record its unit, eligible population and exclusions, numerator/event, denominator, cohort anchor where relevant, observation window, maturity/censoring rule, timezone, owner, and decision threshold. Record event names, required properties, identity rules, retention needs, and sensitive fields to exclude.
  3. Separate four concerns before choosing tools:
    • traffic analytics;
    • product analytics and experimentation;
    • errors, traces, and logs;
    • liveness, readiness, and business reporting.
  4. Reuse an installed provider. If none exists, recommend the minimum stack and explain the tradeoff. Ask only for unresolved choices that materially affect implementation, such as consent requirements, data residency, provider preference, or whether a database dependency belongs in readiness checks. Never ask the user to paste secrets into chat; scaffold names in .env.example and let the user set values in the deployment environment.
  5. Create or update a measurement plan before adding calls. Use stable event names, typed properties, server-side capture for authoritative outcomes, and a documented anonymous-to-authenticated identity transition.
  6. Implement only the selected paths:
    • Read PostHog before changing PostHog browser/server setup, identity, page views, or events.
    • Read Sentry before changing Sentry initialization, boundaries, logging, replay, tracing, or source maps.
    • Read health endpoints before adding liveness/readiness routes or uptime monitoring.
  7. When an internal dashboard is requested, implement it as an authenticated product surface, not a public health endpoint. Use server-owned aggregate queries; define freshness and caching; reconcile each tile to its metric contract; enforce role/tenant access; suppress or coarsen small sensitive groups; and cover loading, empty, stale, partial, and error states. Keep operational status separate from product metrics even when they share a page.
  8. Apply privacy controls before capture: minimize properties, exclude credentials/payment data/content by default, avoid URLs or query strings that contain personal data, honor applicable consent/opt-out rules, and review replay masking and log scrubbing.
  9. Preserve secrets and deployment boundaries. Public ingestion tokens may be exposed only when the provider defines them as public; source-map tokens, service-role keys, and personal API keys stay server-side and out of logs and git.

Verification

Verify only systems actually implemented:

  • Trigger a known page view and typed product event; confirm exact names/properties in the provider.
  • Test anonymous activity, sign-in identification, account switching, and logout reset without merging the wrong people.
  • Trigger a controlled client and server error; record event IDs, verify redaction, environment/release tags, and resolved source maps, then remove the test path.
  • Test liveness independently from dependencies. Test readiness with a forced dependency failure, a short timeout, and the expected non-2xx response.
  • For dashboards, test authorization and tenant boundaries, reconcile aggregate queries to source fixtures, verify timezone/window/maturity behavior, and render loading, empty, stale, partial, error, and populated states.
  • Run the project’s lint/type/test/build commands and test in the target runtime when serverless or edge behavior matters.
  • Record anything that requires dashboard access or production credentials as manual setup, not as verified.

Output

Report:

  • questions the system now answers and the event/monitoring plan;
  • metric contracts for activation, retention, or other implemented measures;
  • providers reused, added, or deliberately omitted;
  • files and environment-variable names changed;
  • dashboard routes/components, aggregate queries, access policy, freshness, and rendered states when applicable;
  • privacy, consent, identity, sampling, and retention decisions;
  • verification performed with event IDs or observed responses;
  • dashboard, DNS, token, alerting, and production checks still required.

Bundled references

3 files · 229 lines

references/health-endpoint.md

source ↗

Health endpoints

Read this reference when the selected observability plan needs liveness, readiness, or external uptime monitoring.

Contents

Choose the signal

  • Liveness answers whether the process can serve. Keep it cheap and independent of downstream services.
  • Readiness answers whether this instance can perform essential work. Probe only critical dependencies, use short timeouts, and return a non-2xx response when unavailable.
  • Business checks belong in synthetic monitoring, not a public health response.

Do not expose environment names, versions, connection details, exception text, row counts, or dependency topology publicly. In serverless runtimes, process uptime is instance-local and usually not a useful service metric.

Next.js pattern

// app/api/health/live/route.ts
export async function GET() {
  return Response.json(
    { status: 'ok', timestamp: new Date().toISOString() },
    { headers: { 'Cache-Control': 'no-store' } },
  );
}

For readiness, inject a project-specific dependency check rather than assuming a users table or creating a new service-role client on every request:

// app/api/health/ready/route.ts
import { checkDatabase } from '@/lib/health/check-database';

export async function GET() {
  const result = await checkDatabase({ timeoutMs: 1_500 });
  return Response.json(
    { status: result.ok ? 'ok' : 'unavailable' },
    {
      status: result.ok ? 200 : 503,
      headers: { 'Cache-Control': 'no-store' },
    },
  );
}

Reuse the application’s server-only database client. The check should be bounded, non-mutating, and inexpensive. Protect readiness with network policy or a monitoring token if exposing dependency status creates risk.

FastAPI pattern

from datetime import datetime, timezone
from fastapi import Response

@app.get('/health/live')
async def live():
    return {
        'status': 'ok',
        'timestamp': datetime.now(timezone.utc).isoformat(),
    }

@app.get('/health/ready')
async def ready(response: Response):
    ok = await check_database(timeout_seconds=1.5)
    response.status_code = 200 if ok else 503
    return {'status': 'ok' if ok else 'unavailable'}

Verification

  • Liveness returns quickly while a downstream dependency is unavailable.
  • Readiness returns 200 normally and 503 under a forced dependency failure or timeout.
  • Responses contain no sensitive internals and are not cached.
  • The external monitor uses the expected path, interval, regions, and alert contacts.
  • Record dashboard/monitor configuration as manual until actually observed.

references/posthog.md

source ↗

PostHog implementation

Read this reference before changing PostHog browser/server setup, identity, page views, feature flags, or events. Check the installed posthog-js/posthog-node versions and current PostHog documentation before copying API options.

Contents

Plan events and privacy

Define stable event names and required properties before installation. Avoid credentials, payment data, message/content bodies, raw prompts, unrestricted URLs/query strings, and unnecessary personal data. Email addresses are personal data; capture them only when justified by the product’s privacy/consent policy. Configure opt-out/consent, retention, replay masking, and region before production.

Initialize

Use the framework pattern recommended for the installed version. In current Next.js versions, prefer PostHog’s current App Router guidance and do not add manual page-view capture until checking whether the selected defaults already capture navigation.

'use client';

import posthog from 'posthog-js';
import { PostHogProvider as Provider } from 'posthog-js/react';

if (typeof window !== 'undefined' && process.env.NEXT_PUBLIC_POSTHOG_KEY) {
  posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
    api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
    person_profiles: 'identified_only',
    // Set capture_pageview explicitly only when the installed-version plan requires it.
  });
}

export function PostHogProvider({ children }: { children: React.ReactNode }) {
  return <Provider client={posthog}>{children}</Provider>;
}

The browser project token is designed for ingestion; do not confuse it with a personal API key. Keep personal keys and management API credentials server-only.

Identity

Use the stable internal application user ID as distinct_id. Identify only after authoritative authentication, reset on logout, and test account switching and impersonation.

posthog.identify(user.id, {
  // Include personal properties only when approved by the measurement/privacy plan.
  plan: user.plan,
});

posthog.reset();

Do not identify from untrusted query/body fields. Define how anonymous pre-login activity merges and how deletion/opt-out requests are handled.

Typed capture

type ProductEvent =
  | { event: 'project_created'; properties: { projectId: string } }
  | { event: 'generation_completed'; properties: { generationId: string; latencyMs: number } };

export function captureProductEvent(value: ProductEvent) {
  posthog.capture(value.event, value.properties);
}

Capture authoritative outcomes on the server when a browser event could be blocked, forged, or duplicated.

Server capture

Create one reusable server client per runtime pattern, pass the stable user ID, and ensure queued events are flushed according to the host lifecycle. Do not force flushAt: 1 without measuring latency/cost. Serverless and edge runtimes may require explicit shutdown/flush handling from current SDK documentation.

Verification

  • Confirm exactly one expected page-view event per navigation strategy.
  • Confirm typed custom events and property shapes.
  • Test anonymous-to-authenticated merge, logout reset, and account switching.
  • Confirm development/test traffic is separated or disabled.
  • Inspect a real event for accidental personal/sensitive properties.
  • For server capture, confirm delivery before the runtime exits and verify duplicate-request behavior.

references/sentry.md

source ↗

Sentry implementation

Read this reference before changing Sentry initialization, source maps, boundaries, structured errors, replay, or tracing. Use the installed SDK’s current wizard/manual setup and review every generated file.

Contents

Install and configure

For Next.js, the current Sentry wizard may generate instrumentation files, client initialization, global-error, and withSentryConfig. Run it only when dependency installation and generated changes are in scope, then inspect the diff and adapt it to the detected Next.js/Sentry versions.

Keep DSNs where the SDK expects them. Keep source-map auth tokens and organization/project management credentials server-side and out of the application bundle.

Privacy and sampling

Choose trace/replay sampling from traffic, incident needs, and budget rather than hard-coding 10%. Before enabling replay or request data capture:

  • mask text and block sensitive media/DOM regions;
  • scrub authorization, cookies, tokens, payment fields, prompts, and message bodies;
  • set user identity only when allowed by policy;
  • honor consent and regional requirements;
  • tag environment and release consistently.

Error-triggered replay can still collect personal data; it is not automatically safe because normal session replay sampling is zero.

Boundaries and logging

Use framework error files/boundaries for user recovery and capture unexpected exceptions once. Avoid duplicate capture in nested boundaries. Preserve a safe user-facing message and a retry/reset path.

import * as Sentry from '@sentry/nextjs';

export function captureAppError(
  error: unknown,
  context: { action?: string; requestId?: string; metadata?: Record<string, unknown> } = {},
) {
  const normalized = error instanceof Error ? error : new Error(String(error));
  Sentry.withScope((scope) => {
    if (context.action) scope.setTag('action', context.action);
    if (context.requestId) scope.setTag('request_id', context.requestId);
    if (context.metadata) scope.setExtras(context.metadata);
    Sentry.captureException(normalized);
  });
}

Metadata must be allow-listed and scrubbed. Do not attach entire request bodies or user objects.

Source maps

Upload source maps during the production build using the provider’s supported integration. Do not expose source-map tokens at runtime. Verify with a real event/release, because a successful build alone does not prove frames resolve.

Verification

  • Trigger controlled client and server errors and record their event IDs.
  • Confirm each error is captured once with correct environment/release tags.
  • Inspect payloads/replay for redaction and masking.
  • Confirm the boundary recovery/reset path works.
  • Verify source frames resolve to authored code, then remove the test path.
  • Exercise tracing only at the configured sampling behavior and confirm cost-sensitive data is not attached.