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

# Using Naite

> Debugging with Naite

This covers effective debugging methods using Naite.

## What is Naite?

Naite is Sonamu's test-dedicated logging system that collects and analyzes all logs generated during test execution.

**Key features:**

* Log isolation per test
* Key-value based log storage
* Powerful query capabilities
* Visualization with Naite Viewer

## Basic Usage

### 1. Recording Logs

```typescript theme={null}
import { Naite } from "sonamu";

describe("User API", () => {
  test("create user", async () => {
    const email = "test@example.com";

    // Record log
    Naite.t("user.create.input", { email });

    const user = await UserModel.create({ email });

    Naite.t("user.create.output", { userId: user.id });

    expect(user.email).toBe(email);
  });
});
```

### 2. Retrieving Logs

When a test fails, you can check the logs to identify the problem:

```typescript theme={null}
test("debugging example", async () => {
  try {
    const result = await complexOperation();
    expect(result).toBe(expectedValue);
  } catch (error) {
    // Check logs on failure
    const logs = Naite.getAll();
    console.log("Test logs:", logs);
    throw error;
  }
});
```

## Debugging Patterns

### API Request/Response Tracking

```typescript theme={null}
test("API call tracking", async () => {
  const params = { page: 1, limit: 10 };

  // Record request
  Naite.t("api.request", {
    method: "findMany",
    params,
  });

  const users = await UserModel.findMany(params);

  // Record response
  Naite.t("api.response", {
    count: users.length,
    firstUser: users[0],
  });

  expect(users.length).toBeGreaterThan(0);
});
```

### Database Query Tracking

```typescript theme={null}
test("query tracking", async () => {
  const userId = 1;

  // Before query
  Naite.t("db.query.before", { userId });

  const user = await UserModel.findById(userId);

  // After query
  Naite.t("db.query.after", {
    found: !!user,
    data: user,
  });

  expect(user).toBeDefined();
});
```

### Business Logic Flow Tracking

```typescript theme={null}
test("order process tracking", async () => {
  const orderId = 1;

  Naite.t("order.process.start", { orderId });

  // 1. Get order
  const order = await OrderModel.findById(orderId);
  Naite.t("order.found", { status: order.status });

  // 2. Process payment
  const payment = await processPayment(order);
  Naite.t("payment.processed", {
    paymentId: payment.id,
    amount: payment.amount,
  });

  // 3. Update order status
  await OrderModel.updateStatus(orderId, "paid");
  Naite.t("order.status.updated", { newStatus: "paid" });

  Naite.t("order.process.complete", { orderId });
});
```

## Log Key Naming Conventions

Designing keys with a hierarchical structure makes querying easier later:

```typescript theme={null}
// Good key naming
Naite.t("user.create.input", data);
Naite.t("user.create.validation", result);
Naite.t("user.create.output", user);

// Domain separation
Naite.t("order.payment.start", params);
Naite.t("order.payment.complete", result);

// Bad key naming
Naite.t("data1", data);
Naite.t("result", result);
Naite.t("test", value);
```

**Recommended pattern:**

```
{domain}.{action}.{stage}
Example: user.create.input, order.payment.complete
```

## Conditional Logging

Activate logging only when debugging is needed:

```typescript theme={null}
const DEBUG = process.env.DEBUG === "true";

test("conditional logging", async () => {
  if (DEBUG) {
    Naite.t("debug.start", { timestamp: Date.now() });
  }

  const result = await someOperation();

  if (DEBUG) {
    Naite.t("debug.result", result);
  }

  expect(result).toBeDefined();
});
```

## Using Naite in Models

You can log with Naite in business logic:

```typescript theme={null}
class UserModelClass extends BaseModelClass {
  @api()
  async createUser(name: string, email: string) {
    // Record log with Naite.t()
    Naite.t("user.input", { name, email });

    const user = await this.save({ name, email });

    Naite.t("user.created", user);

    return user;
  }
}
```

Check in tests:

```typescript theme={null}
test("verify Naite logs", async () => {
  await UserModel.createUser("Alice", "alice@example.com");

  // Extract first data with .first()
  const input = Naite.get("user.input").first();
  const created = Naite.get("user.created").first();

  expect(input.name).toBe("Alice");
  expect(created.id).toBeDefined();
});
```

## Log Queries

Naite provides powerful query capabilities:

```typescript theme={null}
test("log queries", async () => {
  // Perform multiple operations
  await createUsers();
  await processOrders();

  // Query by specific key
  const userLogs = Naite.get("user").result();

  // Query by pattern (wildcard supported)
  const createLogs = Naite.get("*.create.*").result();

  // All logs
  const allLogs = Naite.getAll();

  console.log("User logs:", userLogs);
  console.log("Create logs:", createLogs);
  console.log("All logs:", allLogs);
});
```

### NaiteQuery Methods

`Naite.get()` returns a `NaiteQuery` object:

```typescript theme={null}
test("NaiteQuery methods", async () => {
  Naite.t("test.data", { value: 1 });
  Naite.t("test.data", { value: 2 });
  Naite.t("test.data", { value: 3 });

  // First data
  const first = Naite.get("test.data").first();
  console.log(first); // { value: 1 }

  // Last data
  const last = Naite.get("test.data").last();
  console.log(last); // { value: 3 }

  // All data as array
  const all = Naite.get("test.data").result();
  console.log(all); // [{ value: 1 }, { value: 2 }, { value: 3 }]
});
```

## Using Naite Viewer

Visualize logs with Naite Viewer after running tests:

```bash theme={null}
# Run tests
pnpm test

# Run Naite Viewer
pnpm naite:view
```

**Viewer features:**

* Filter logs by test
* Key-based search
* Timeline view
* Export logs

## Debugging Workflow

### 1. When Tests Fail

```typescript theme={null}
test("failing test", async () => {
  // Add sufficient logs
  Naite.t("test.start", { timestamp: Date.now() });

  try {
    const result = await problematicFunction();
    Naite.t("test.result", result);
    expect(result).toBe(expectedValue);
  } catch (error) {
    // Output all logs on error
    console.log("=== Naite Logs ===");
    console.log(JSON.stringify(Naite.getAll(), null, 2));
    throw error;
  }
});
```

### 2. Log Analysis

```typescript theme={null}
afterEach(() => {
  // Summarize logs after test
  const allLogs = Naite.getAll();
  const errorKeys = Object.keys(allLogs).filter(
    (key) => key.includes("error") || key.includes("fail"),
  );

  if (errorKeys.length > 0) {
    const errorLogs = errorKeys.map((key) => ({ key, data: allLogs[key] }));
    console.log("Warning - Error logs:", errorLogs);
  }
});
```

### 3. Reproducing Specific Scenarios

```typescript theme={null}
test("bug reproduction", async () => {
  // Reproduce the scenario where the bug occurred
  Naite.t("bug.reproduction.start", {
    scenario: "Delete user immediately after creation",
  });

  const user = await UserModel.create({ email: "test@example.com" });
  Naite.t("bug.user.created", user);

  await UserModel.del(user.id);
  Naite.t("bug.user.deleted", { userId: user.id });

  // Attempt to retrieve again
  const deletedUser = await UserModel.findById(user.id);
  Naite.t("bug.user.found", { found: !!deletedUser });

  expect(deletedUser).toBeNull();
});
```

## Performance Debugging

Add timestamps to logs for performance analysis:

```typescript theme={null}
test("performance measurement", async () => {
  const start = Date.now();
  Naite.t("perf.start", { timestamp: start });

  // Heavy operation
  const result = await heavyOperation();

  const end = Date.now();
  Naite.t("perf.end", {
    timestamp: end,
    duration: end - start,
    result,
  });

  // Verify performance criteria
  expect(end - start).toBeLessThan(1000); // Within 1 second
});
```

## Cautions

### 1. Do Not Use in Production Code

```typescript theme={null}
// Do not use Naite in production code
class UserModelClass extends BaseModelClass {
  async createUser() {
    Naite.t("user.create", data); // Bad - Test only!
    return this.save(data);
  }
}
```

### 2. Be Careful with Sensitive Information

```typescript theme={null}
test("logging cautions", async () => {
  // Do not log sensitive information like passwords
  Naite.t("user.create", {
    email,
    password, // Bad
  });

  // Exclude sensitive information
  Naite.t("user.create", {
    email,
    hasPassword: !!password, // Good
  });
});
```

### 3. Avoid Excessive Logging

```typescript theme={null}
// Excessive logging inside loops
for (let i = 0; i < 1000; i++) {
  Naite.t(`item.${i}`, data); // Bad - Too many
}

// Summary logging
Naite.t("items.processed", {
  count: 1000,
  sample: items.slice(0, 3), // Good - Sample only
});
```

## Related Documentation

* [What is Naite](/en/testing/naite/what-is-naite)
* [Recording Logs](/en/testing/naite/recording-logs)
* [Querying Logs](/en/testing/naite/querying-logs)
* [Naite Viewer](/en/testing/naite/naite-viewer)
* [Debugging Tests](/en/testing/naite/debugging-tests)
