# Insight

> Create and manage analytics insights and queries

The Insight resource allows you to create and manage analytics insights for tracking events, funnels, retention, and other metrics in PostHog.

## Example Usage

### Basic Trends Insight

```typescript
import * as posthog from "pulumi-posthog";

const pageviews = new posthog.Insight("pageviews", {
    name: "Pageview Trends",
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "$pageview",
            name: "Pageviews",
        }],
        dateRange: {
            date_from: "-30d",
        },
    }),
});
```

### Signup Tracking

```typescript
const signups = new posthog.Insight("signups", {
    name: "User Signups",
    description: "Track new user registrations",
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "user_signed_up",
            name: "User Signed Up",
        }],
        dateRange: {
            date_from: "-30d",
        },
    }),
});
```

### Retention Analysis

```typescript
const retention = new posthog.Insight("retention", {
    name: "User Retention",
    description: "Track how many users return after signup",
    queryJson: JSON.stringify({
        kind: "RetentionQuery",
        retentionFilter: {
            targetEntity: {
                id: "user_signed_up",
                type: "events",
            },
            returningEntity: {
                id: "$pageview",
                type: "events",
            },
        },
        dateRange: {
            date_from: "-90d",
        },
    }),
});
```

### Insight on Dashboard

```typescript
const dashboardInsight = new posthog.Insight("dashboard-metric", {
    name: "Key Metric",
    dashboardIds: [12345], // Add to specific dashboard
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "purchase_completed",
        }],
        dateRange: { date_from: "-7d" },
    }),
});
```

### Insight with Tags

```typescript
const taggedInsight = new posthog.Insight("tagged-insight", {
    name: "Mobile App Sessions",
    tags: ["mobile", "engagement", "daily"],
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "app_session_start",
        }],
        dateRange: { date_from: "-30d" },
    }),
});
```

### Funnel Analysis

```typescript
const funnel = new posthog.Insight("conversion-funnel", {
    name: "Signup to Purchase Funnel",
    description: "Track user journey from signup to first purchase",
    queryJson: JSON.stringify({
        kind: "FunnelsQuery",
        series: [
            {
                kind: "EventsNode",
                event: "user_signed_up",
                name: "Signed Up",
            },
            {
                kind: "EventsNode",
                event: "added_to_cart",
                name: "Added to Cart",
            },
            {
                kind: "EventsNode",
                event: "purchase_completed",
                name: "Purchased",
            },
        ],
        dateRange: {
            date_from: "-30d",
        },
    }),
});
```

## Resource Properties

### Required Arguments

- `queryJson` (string): Raw JSON serialized query payload accepted by PostHog (e.g., `InsightVizNode` with a `TrendsQuery`)

### Optional Arguments

- `name` (string): Insight name
- `description` (string): Insight description
- `dashboardIds` (number[]): List of dashboard IDs to add the insight to
- `createInFolder` (string): Folder where the insight is created
- `tags` (string[]): List of tags to apply to the insight
- `deleted` (boolean): Whether the insight is deleted (soft delete)
- `derivedName` (string): Insight derived name (auto-generated by PostHog when name is not set)

### Attributes

- `insightId`: Numeric insight ID
- `name`: Insight name
- `derivedName`: Auto-generated insight name

## Query Types

PostHog supports several query types:

### TrendsQuery

Track event volumes over time:

```typescript
queryJson: JSON.stringify({
    kind: "TrendsQuery",
    series: [{
        kind: "EventsNode",
        event: "event_name",
    }],
    dateRange: { date_from: "-30d" },
})
```

### FunnelsQuery

Analyze conversion funnels:

```typescript
queryJson: JSON.stringify({
    kind: "FunnelsQuery",
    series: [
        { kind: "EventsNode", event: "step_1" },
        { kind: "EventsNode", event: "step_2" },
        { kind: "EventsNode", event: "step_3" },
    ],
    dateRange: { date_from: "-30d" },
})
```

### RetentionQuery

Measure user retention:

```typescript
queryJson: JSON.stringify({
    kind: "RetentionQuery",
    retentionFilter: {
        targetEntity: { id: "signup", type: "events" },
        returningEntity: { id: "$pageview", type: "events" },
    },
    dateRange: { date_from: "-90d" },
})
```

## Best Practices

### 1. Use Descriptive Names

```typescript
// ✅ Good
const insight = new posthog.Insight("user-engagement", {
    name: "Daily Active Users - Last 30 Days",
    description: "Number of unique users who performed any action",
});

// ❌ Avoid
const insight = new posthog.Insight("insight1", {
    name: "Insight 1",
});
```

### 2. Add to Relevant Dashboards

```typescript
const insight = new posthog.Insight("key-metric", {
    name: "Revenue Trend",
    dashboardIds: [123, 456], // Add to multiple dashboards
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{ kind: "EventsNode", event: "purchase" }],
        dateRange: { date_from: "-30d" },
    }),
});
```

### 3. Use Tags for Organization

```typescript
const insight = new posthog.Insight("mobile-metric", {
    name: "Mobile App Launches",
    tags: ["mobile", "engagement", "ios", "android"],
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{ kind: "EventsNode", event: "app_launched" }],
        dateRange: { date_from: "-7d" },
    }),
});
```

## Common Use Cases

### User Engagement Tracking

```typescript
const engagement = new posthog.Insight("engagement", {
    name: "Daily Active Users",
    description: "Unique users per day",
    tags: ["engagement", "daily"],
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "$pageview",
            math: "dau", // Daily active users
        }],
        dateRange: { date_from: "-30d" },
    }),
});
```

### Feature Adoption

```typescript
const adoption = new posthog.Insight("feature-adoption", {
    name: "New Feature Usage",
    description: "Track adoption of newly released feature",
    tags: ["product", "feature"],
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "new_feature_used",
        }],
        dateRange: { date_from: "-90d" },
    }),
});
```

### Conversion Tracking

```typescript
const conversion = new posthog.Insight("conversion", {
    name: "Signup to Trial Conversion",
    description: "Users who start trial after signing up",
    queryJson: JSON.stringify({
        kind: "FunnelsQuery",
        series: [
            { kind: "EventsNode", event: "user_signed_up" },
            { kind: "EventsNode", event: "trial_started" },
        ],
        dateRange: { date_from: "-30d" },
    }),
});
```

## Troubleshooting

### Invalid Query JSON

**Issue**: Error creating insight with invalid query

**Solution**:
- Ensure `queryJson` is a valid JSON string
- Use `JSON.stringify()` to convert objects to JSON strings
- Validate query structure matches PostHog's query schema

```typescript
// ✅ Correct - use JSON.stringify()
queryJson: JSON.stringify({
    kind: "TrendsQuery",
    series: [{ kind: "EventsNode", event: "$pageview" }],
})

// ❌ Incorrect - queryJson must be a string, not an object
queryJson: { kind: "TrendsQuery" } // This will fail
```

### Insight Not Showing Data

**Issue**: Insight created but shows no data

**Solution**:
- Verify the event name exists in PostHog
- Check the date range includes data
- Confirm events are being captured

### Dashboard Assignment Fails

**Issue**: Cannot add insight to dashboard

**Solution**:
- Use numeric dashboard IDs (from PostHog)
- Ensure dashboard exists before creating insight
- Verify you have access to the dashboard

## Additional Resources

- [Dashboard Resource](/pulumi-any-terraform/providers/posthog/dashboard)
- [PostHog Insights Documentation](https://posthog.com/docs/user-guides/insights)
- [PostHog Query Types](https://posthog.com/docs/product-analytics/insights)
- [Configuration](/pulumi-any-terraform/providers/posthog/configuration)
