You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
4.9 KiB
176 lines
4.9 KiB
# Agent Contract — TimeSafari Logging (Unified, MANDATORY)
|
|
|
|
**Author**: Matthew Raymer
|
|
**Date**: 2025-08-19
|
|
**Status**: 🎯 **ACTIVE** - Mandatory logging standards
|
|
|
|
## Overview
|
|
|
|
This document defines unified logging standards for the TimeSafari project,
|
|
ensuring consistent, rest-parameter logging style using the project logger.
|
|
No `console.*` methods are allowed in production code.
|
|
|
|
## Scope and Goals
|
|
|
|
**Scope**: Applies to all diffs and generated code in this workspace unless
|
|
explicitly exempted below.
|
|
|
|
**Goal**: One consistent, rest-parameter logging style using the project
|
|
logger; no `console.*` in production code.
|
|
|
|
## Non‑Negotiables (DO THIS)
|
|
|
|
- You **MUST** use the project logger; **DO NOT** use any `console.*`
|
|
|
|
methods.
|
|
|
|
- Import exactly as:
|
|
|
|
- `import { logger } from '@/utils/logger'`
|
|
|
|
- If `@` alias is unavailable, compute the correct relative path (do not
|
|
|
|
fail).
|
|
|
|
- Call signatures use **rest parameters**: `logger.info(message, ...args)`
|
|
|
|
- Prefer primitives/IDs and small objects in `...args`; **never build a
|
|
|
|
throwaway object** just to "wrap context".
|
|
|
|
- Production defaults: Web = `warn+`, Electron = `error`, Dev/Capacitor =
|
|
|
|
`info+` (override via `VITE_LOG_LEVEL`).
|
|
|
|
- **Database persistence**: `info|warn|error` are persisted; `debug` is not.
|
|
|
|
Use `logger.toDb(msg, level?)` for DB-only.
|
|
|
|
## Available Logger API (Authoritative)
|
|
|
|
- `logger.debug(message, ...args)` — verbose internals, timings, input/output
|
|
|
|
shapes
|
|
|
|
- `logger.log(message, ...args)` — synonym of `info` for general info
|
|
|
|
- `logger.info(message, ...args)` — lifecycle, state changes, success paths
|
|
|
|
- `logger.warn(message, ...args)` — recoverable issues, retries, degraded mode
|
|
|
|
- `logger.error(message, ...args)` — failures, thrown exceptions, aborts
|
|
|
|
- `logger.toDb(message, level?)` — DB-only entry (default level = `info`)
|
|
|
|
- `logger.toConsoleAndDb(message, isError)` — console + DB (use sparingly)
|
|
|
|
- `logger.withContext(componentName)` — returns a scoped logger
|
|
|
|
## Level Guidelines (Use These Heuristics)
|
|
|
|
### DEBUG
|
|
|
|
Use for method entry/exit, computed values, filters, loops, retries, and
|
|
external call payload sizes.
|
|
|
|
### INFO
|
|
|
|
Use for user-visible lifecycle and completed operations.
|
|
|
|
### WARN
|
|
|
|
Use for recoverable issues, fallbacks, unexpected-but-handled conditions.
|
|
|
|
### ERROR
|
|
|
|
Use for unrecoverable failures, data integrity issues, and thrown
|
|
exceptions.
|
|
|
|
## Context Hygiene (Consistent, Minimal, Helpful)
|
|
|
|
- **Component context**: Prefer scoped logger.
|
|
|
|
- **Emojis**: Optional and minimal for visual scanning.
|
|
|
|
- **Sensitive data**: Never log secrets (tokens, keys, passwords) or
|
|
payloads >10KB. Prefer IDs over objects; redact/hash when needed.
|
|
|
|
## DB Logging Rules
|
|
|
|
- `debug` **never** persists automatically.
|
|
|
|
- `info|warn|error` persist automatically.
|
|
|
|
- For DB-only events (no console), call `logger.toDb('Message',
|
|
'info'|'warn'|'error')`.
|
|
|
|
## Exceptions (Tightly Scoped)
|
|
|
|
Allowed paths (still prefer logger):
|
|
|
|
- `**/*.test.*`, `**/*.spec.*`
|
|
|
|
- `scripts/dev/**`, `scripts/migrate/**`
|
|
|
|
To intentionally keep `console.*`, add a pragma on the previous line:
|
|
|
|
```typescript
|
|
|
|
// cursor:allow-console reason="short justification"
|
|
console.log('temporary output');
|
|
|
|
```
|
|
|
|
## CI & Diff Enforcement
|
|
|
|
- Do not introduce `console.*` anywhere outside allowed, pragma'd spots.
|
|
|
|
- If an import is missing, insert it and resolve alias/relative path
|
|
correctly.
|
|
|
|
- Enforce rest-parameter call shape in reviews; replace object-wrapped
|
|
context.
|
|
|
|
- Ensure environment log level rules remain intact (`VITE_LOG_LEVEL`
|
|
respected).
|
|
|
|
---
|
|
|
|
**See also**:
|
|
`.cursor/rules/development/logging_migration.mdc` for migration patterns and examples.
|
|
|
|
**Status**: Active and enforced
|
|
**Priority**: Critical
|
|
**Estimated Effort**: Ongoing reference
|
|
**Dependencies**: TimeSafari logger utility
|
|
**Stakeholders**: Development team, Code review team
|
|
|
|
## Model Implementation Checklist
|
|
|
|
### Before Adding Logging
|
|
|
|
- [ ] **Logger Import**: Import logger as `import { logger } from
|
|
'@/utils/logger'`
|
|
- [ ] **Log Level Selection**: Determine appropriate log level
|
|
(debug/info/warn/error)
|
|
- [ ] **Context Planning**: Plan what context information to include
|
|
- [ ] **Sensitive Data Review**: Identify any sensitive data that needs redaction
|
|
|
|
### During Logging Implementation
|
|
|
|
- [ ] **Rest Parameters**: Use `logger.info(message, ...args)` format, not object
|
|
wrapping
|
|
- [ ] **Context Addition**: Include relevant IDs, primitives, or small objects in
|
|
args
|
|
- [ ] **Level Appropriateness**: Use correct log level for the situation
|
|
- [ ] **Scoped Logger**: Use `logger.withContext(componentName)` for
|
|
component-specific logging
|
|
|
|
### After Logging Implementation
|
|
|
|
- [ ] **Console Check**: Ensure no `console.*` methods are used (unless in
|
|
allowed paths)
|
|
- [ ] **Performance Review**: Verify logging doesn't impact performance
|
|
- [ ] **DB Persistence**: Use `logger.toDb()` for database-only logging if needed
|
|
- [ ] **Environment Compliance**: Respect `VITE_LOG_LEVEL` environment
|
|
variable
|
|
|