> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aiola.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Setup Health

> Scan a local workspace for broken Analytics and App Logs integrations and apply the supported fixes.

Setup Health finds integration mistakes that stop or degrade data collection and points to the affected file and line. Findings remain visible until a fresh scan confirms the integration is working.

## Where it appears

| Surface                  | Label and behavior                                                                                  |
| ------------------------ | --------------------------------------------------------------------------------------------------- |
| Workspace home           | **Needs attention** section with every finding and a **Check again** button                         |
| Workspace sidebar        | Collapsible **Needs attention** card with the finding count, **Check again**, and **Open settings** |
| **Settings → Analytics** | Warning banner for Analytics findings with **Check again**                                          |
| **Settings → App Logs**  | Warning banner for App Logs findings with **Check again**                                           |

Central pages do not run or show the scan. Each surface shares the same in-memory state for the active workspace.

## Findings

| Finding ID                   | Severity  | Exact title                      | Exact detail                                                                                                                                                 | Meaning                                                                                                                                                                   |
| ---------------------------- | --------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `analytics-missing`          | `warning` | Analytics tracker is missing     | Add the Aiola tracker to your app so analytics can be collected.                                                                                             | Analytics is enabled for the workspace, but no supported tracker tag or programmatic tracker configuration was found.                                                     |
| `analytics-site-id-mismatch` | `error`   | Analytics site ID does not match | The tracker is configured for a different Aiola site.                                                                                                        | A literal `data-site-id` differs from the tracking ID assigned to this workspace. Dynamic IDs are not treated as mismatches.                                              |
| `analytics-proxy-collector`  | `error`   | Analytics collector is proxied   | The proxy hides the visitor, so country and city are lost. The tracker now posts directly to [https://aiola.app/api/collect](https://aiola.app/api/collect). | A non-Aiola `data-host-url`, rewrite, redirect, route, or proxy sends collector traffic through another server. This check is skipped for `aiola.app` and its subdomains. |
| `logger-outdated`            | `warning` | App Logs SDK is outdated         | `Update @aiolaapp/logger from v{current} to v{latest}.`                                                                                                      | A workspace package lists `@aiolaapp/logger`, and its installed or locked semantic version is older than npm's latest version.                                            |
| `logger-legacy-endpoint`     | `error`   | App Logs uses a legacy endpoint  | The logger is configured with an old hardcoded ingest URL.                                                                                                   | Source contains an endpoint option or `AIOLA_ENDPOINT...` value using `app.aiola.com` or `/functions/v1/app-logs-ingest`.                                                 |

The scan only checks Analytics when an `analytics_sites` row exists for the signed-in user and workspace name. It only checks App Logs when a project key exists and `logs_enabled` is not `false`.

## Fixes

| Finding                  | Button                | Action                                                                                                                                                                            |
| ------------------------ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Missing tracker          | **Fix with agent**    | Starts an agent thread with the exact tracker tag and asks it to add the tag to the correct app shell without unrelated changes. **Copy snippet** copies the tag instead.         |
| Site ID mismatch         | **Fix with agent**    | Starts an agent thread with the assigned tracking ID and the corrected tracker tag.                                                                                               |
| Proxied collector        | **Fix with agent**    | Asks the agent to remove the collector rewrite/proxy and `data-host-url`, while retaining the `cdn.aiola.app/analytics.js` script. A proxy for the script file itself may remain. |
| Legacy App Logs endpoint | **Fix with agent**    | Asks the agent to use `https://aiola.app/api/app-logs-ingest` or remove the endpoint option so the SDK default is used.                                                           |
| Outdated App Logs SDK    | `Update to v<latest>` | Runs the detected package manager in the package directory: npm uses `install @aiolaapp/logger@latest`; pnpm, yarn, and bun use `add @aiolaapp/logger@latest`. It then rescans.   |

The automatic update accepts package managers `npm`, `pnpm`, `yarn`, and `bun`, runs for at most 300,000 ms, and returns the last 40 output lines. The package directory must resolve inside the workspace and contain a `package.json` whose dependencies or dev dependencies list `@aiolaapp/logger`.

## Why findings cannot be dismissed

Setup Health has no dismiss action. Previous stored dismissals under `aiola:setup-health-dismissed:v1` are removed because hiding a required correction leaves the integration broken. A finding clears only when **Check again**, an automatic post-update scan, or a later workspace scan no longer detects it.

## Scan endpoint

```text theme={null}
GET /api/workspace/setup-health?workspaceId=<workspace-id>
GET /api/workspace/setup-health?workspaceId=<workspace-id>&force=1
Aiola session required
```

The successful response always has HTTP `200` and this shape:

```json theme={null}
{
  "ok": true,
  "workspaceId": "workspace-id",
  "checkedAt": "2026-09-19T12:00:00.000Z",
  "analytics": {
    "enabled": true,
    "status": "ok",
    "trackingId": "site-id",
    "domain": "example.com"
  },
  "appLogs": {
    "enabled": true,
    "status": "issue",
    "current": "1.0.0",
    "latest": "1.1.0",
    "packageDir": "."
  },
  "findings": []
}
```

`analytics.status` and `appLogs.status` are `ok`, `issue`, or `skipped`. Authentication failure, missing user, an ineligible plan, an unavailable workspace, SSH runtime, or missing local root returns a successful `skipped` result with no findings rather than an error response.

## Cache and force refresh

| Layer                           | Behavior                                                                                                              |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Renderer                        | Runs once per workspace per app process when the workspace is first opened. It does not poll on focus or an interval. |
| Server workspace scan           | Cached by workspace ID for 1 hour.                                                                                    |
| npm latest version              | Cached for 1 hour. The registry request has a 5,000 ms timeout.                                                       |
| **Check now** / **Check again** | Sends `force=1`, bypasses the workspace cache, and clears the npm-latest cache before scanning.                       |
| Successful logger update        | Deletes the workspace cache, clears npm-latest cache, and forces a new scan.                                          |

The disk scan considers at most 6,000 files, skips files over 512 KiB, stops at 48 MiB total content, and uses a maximum fallback directory depth of 8. It excludes dependencies, build output, Git data, tests, fixtures, and the bundled `analytics.js` file.

## Access gating

| Requirement | Required value                                                                               |
| ----------- | -------------------------------------------------------------------------------------------- |
| Workspace   | A local workspace with `rootPath`; `runtime: "ssh"` is skipped                               |
| Account     | `subscription_tier` is `pro_monthly` or `pro_yearly`, or `trial_ends_at` is in the future    |
| Session     | A signed-in Aiola user is required to resolve the workspace's Analytics site and project key |
| Scope       | The scan is disabled while the current route starts with `/central`                          |

GUI Lifetime access alone does not satisfy this scan's plan gate.

## Logger update endpoint

```text theme={null}
POST /api/workspace/setup-health/update-logger
Content-Type: application/json
Aiola session required
```

<ParamField path="workspaceId" type="string" required />

<ParamField path="packageDir" type="string" required>
  A directory inside the workspace containing a `package.json` that lists `@aiolaapp/logger`.
</ParamField>

```json theme={null}
{
  "workspaceId": "workspace-id",
  "packageDir": "."
}
```

| Status | Trigger                                                                                                                                         |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `200`  | Update command completed; inspect `success`, `current`, `latest`, `stillOutdated`, and `output`.                                                |
| `400`  | Invalid/SSH workspace, missing package directory, directory outside the workspace, missing `package.json`, or `@aiolaapp/logger` is not listed. |
