Browse Source

chore: fixing formatting

build-web-serve-test
Matthew Raymer 4 days ago
parent
commit
cdf5fbdfc6
  1. 193
      .cursor/rules/logging_standards.mdc

193
.cursor/rules/logging_standards.mdc

@ -1,21 +1,48 @@
---
globs: *.vue,*.ts,*.tsx
alwaysApply: false
---
# Agent Contract — TimeSafari Logging (Unified, MANDATORY) # Agent Contract — TimeSafari Logging (Unified, MANDATORY)
**Scope:** Applies to all diffs and generated code in this workspace unless explicitly exempted below. **Author**: Matthew Raymer
**Goal:** One consistent, rest-parameter logging style using the project logger; no `console.*` in production code. **Date**: 2025-08-15
**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) ## Non‑Negotiables (DO THIS)
- You **MUST** use the project logger; **DO NOT** use any `console.*` methods.
- You **MUST** use the project logger; **DO NOT** use any `console.*`
methods.
- Import exactly as: - Import exactly as:
- `import {{ logger }} from '@/utils/logger'` - `import { logger } from '@/utils/logger'`
- If `@` alias is unavailable, compute the correct relative path (do not fail). - If `@` alias is unavailable, compute the correct relative path (do not
fail).
- Call signatures use **rest parameters**: `logger.info(message, ...args)` - 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”. - Prefer primitives/IDs and small objects in `...args`; **never build a
- Production defaults: Web = `warn+`, Electron = `error`, Dev/Capacitor = `info+` (override via `VITE_LOG_LEVEL`). throwaway object** just to "wrap context".
- **Database persistence:** `info|warn|error` are persisted; `debug` is not. Use `logger.toDb(msg, level?)` for DB-only. - 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) ## 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.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.info(message, ...args)` — lifecycle, state changes, success paths
- `logger.warn(message, ...args)` — recoverable issues, retries, degraded mode - `logger.warn(message, ...args)` — recoverable issues, retries, degraded mode
- `logger.error(message, ...args)` — failures, thrown exceptions, aborts - `logger.error(message, ...args)` — failures, thrown exceptions, aborts
@ -24,103 +51,157 @@
- `logger.withContext(componentName)` — returns a scoped logger - `logger.withContext(componentName)` — returns a scoped logger
## Level Guidelines (Use These Heuristics) ## Level Guidelines (Use These Heuristics)
### DEBUG ### DEBUG
Use for method entry/exit, computed values, filters, loops, retries, and external call payload sizes.
```ts Use for method entry/exit, computed values, filters, loops, retries, and
external call payload sizes.
```typescript
logger.debug('[HomeView] reloadFeedOnChange() called'); logger.debug('[HomeView] reloadFeedOnChange() called');
logger.debug('[HomeView] Current filter settings', settings.filterFeedByVisible, settings.filterFeedByNearby, settings.searchBoxes?.length ?? 0); logger.debug('[HomeView] Current filter settings',
logger.debug('[FeedFilters] Toggling nearby filter', this.isNearby, this.settingChanged, this.activeDid); settings.filterFeedByVisible,
settings.filterFeedByNearby,
settings.searchBoxes?.length ?? 0);
logger.debug('[FeedFilters] Toggling nearby filter',
this.isNearby, this.settingChanged, this.activeDid);
``` ```
**Avoid:** Vague messages (`'Processing data'`).
**Avoid**: Vague messages (`'Processing data'`).
### INFO ### INFO
Use for user-visible lifecycle and completed operations. Use for user-visible lifecycle and completed operations.
```ts
```typescript
logger.info('[StartView] Component mounted', process.env.VITE_PLATFORM); logger.info('[StartView] Component mounted', process.env.VITE_PLATFORM);
logger.info('[StartView] User selected new seed generation'); logger.info('[StartView] User selected new seed generation');
logger.info('[SearchAreaView] Search box stored', searchBox.name, searchBox.bbox); logger.info('[SearchAreaView] Search box stored',
logger.info('[ContactQRScanShowView] Contact registration OK', contact.did); searchBox.name, searchBox.bbox);
logger.info('[ContactQRScanShowView] Contact registration OK',
contact.did);
``` ```
**Avoid:** Diagnostic details that belong in `debug`.
**Avoid**: Diagnostic details that belong in `debug`.
### WARN ### WARN
Use for recoverable issues, fallbacks, unexpected-but-handled conditions. Use for recoverable issues, fallbacks, unexpected-but-handled conditions.
```ts
logger.warn('[ContactQRScanShowView] Invalid scan result – no value', resultType); ```typescript
logger.warn('[ContactQRScanShowView] Invalid scan result – no value',
resultType);
logger.warn('[ContactQRScanShowView] Invalid QR format – no JWT in URL'); logger.warn('[ContactQRScanShowView] Invalid QR format – no JWT in URL');
logger.warn('[ContactQRScanShowView] JWT missing "own" field'); logger.warn('[ContactQRScanShowView] JWT missing "own" field');
``` ```
**Avoid:** Hard failures (those are `error`).
**Avoid**: Hard failures (those are `error`).
### ERROR ### ERROR
Use for unrecoverable failures, data integrity issues, and thrown exceptions.
```ts Use for unrecoverable failures, data integrity issues, and thrown
exceptions.
```typescript
logger.error('[HomeView Settings] initializeIdentity() failed', err); logger.error('[HomeView Settings] initializeIdentity() failed', err);
logger.error('[StartView] Failed to load initialization data', error); logger.error('[StartView] Failed to load initialization data', error);
logger.error('[ContactQRScanShowView] Error processing contact QR', error, rawValue); logger.error('[ContactQRScanShowView] Error processing contact QR',
error, rawValue);
``` ```
**Avoid:** Expected user cancels (use `info`/`debug`).
**Avoid**: Expected user cancels (use `info`/`debug`).
## Context Hygiene (Consistent, Minimal, Helpful) ## Context Hygiene (Consistent, Minimal, Helpful)
- **Component context:** Prefer scoped logger.
```ts - **Component context**: Prefer scoped logger.
const log = logger.withContext('UserService');
log.info('User created', userId); ```typescript
log.error('Failed to create user', error); const log = logger.withContext('UserService');
``` log.info('User created', userId);
If not using `withContext`, prefix message with `[ComponentName]`. log.error('Failed to create user', error);
- **Emojis:** Optional and minimal for visual scanning. Recommended set: ```
- Start/finish: 🚀 / ✅ • Retry/loop: 🔄 • External call: 📡 • Data/metrics: 📊 • Inspection: 🔍
- **Sensitive data:** Never log secrets (tokens, keys, passwords) or payloads >10KB. Prefer IDs over objects; redact/hash when needed. If not using `withContext`, prefix message with `[ComponentName]`.
- **Emojis**: Optional and minimal for visual scanning. Recommended set:
- Start/finish: 🚀 / ✅
- Retry/loop: 🔄
- External call: 📡
- Data/metrics: 📊
- Inspection: 🔍
- **Sensitive data**: Never log secrets (tokens, keys, passwords) or
payloads >10KB. Prefer IDs over objects; redact/hash when needed.
## Migration — Auto‑Rewrites (Apply Every Time) ## Migration — Auto‑Rewrites (Apply Every Time)
- Exact transforms: - Exact transforms:
- `console.debug(...)` → `logger.debug(...)` - `console.debug(...)` → `logger.debug(...)`
- `console.log(...)` → `logger.log(...)` (or `logger.info(...)` when clearly stateful) - `console.log(...)` → `logger.log(...)` (or `logger.info(...)` when
- `console.info(...)` → `logger.info(...)` clearly stateful)
- `console.warn(...)` → `logger.warn(...)` - `console.info(...)` → `logger.info(...)`
- `console.warn(...)` → `logger.warn(...)`
- `console.error(...)` → `logger.error(...)` - `console.error(...)` → `logger.error(...)`
- Multi-arg handling: - Multi-arg handling:
- First arg becomes `message` (stringify safely if non-string). - First arg becomes `message` (stringify safely if non-string).
- Remaining args map 1:1 to `...args`: - Remaining args map 1:1 to `...args`:
`console.info(msg, a, b)` → `logger.info(String(msg), a, b)` `console.info(msg, a, b)` → `logger.info(String(msg), a, b)`
- Sole `Error`: - Sole `Error`:
- `console.error(err)` → `logger.error(err.message, err)` - `console.error(err)` → `logger.error(err.message, err)`
- **Object-wrapping cleanup:** Replace `{{ userId, meta }}` wrappers with separate args:
- **Object-wrapping cleanup**: Replace `{{ userId, meta }}` wrappers with
separate args:
`logger.info('User signed in', userId, meta)` `logger.info('User signed in', userId, meta)`
## DB Logging Rules ## DB Logging Rules
- `debug` **never** persists automatically. - `debug` **never** persists automatically.
- `info|warn|error` persist automatically. - `info|warn|error` persist automatically.
- For DB-only events (no console), call `logger.toDb('Message', 'info'|'warn'|'error')`. - For DB-only events (no console), call `logger.toDb('Message',
'info'|'warn'|'error')`.
## Exceptions (Tightly Scoped) ## Exceptions (Tightly Scoped)
Allowed paths (still prefer logger): Allowed paths (still prefer logger):
- `**/*.test.*`, `**/*.spec.*` - `**/*.test.*`, `**/*.spec.*`
- `scripts/dev/**`, `scripts/migrate/**` - `scripts/dev/**`, `scripts/migrate/**`
To intentionally keep `console.*`, add a pragma on the previous line: To intentionally keep `console.*`, add a pragma on the previous line:
```ts
```typescript
// cursor:allow-console reason="short justification" // cursor:allow-console reason="short justification"
console.log('temporary output'); console.log('temporary output');
``` ```
Without the pragma, rewrite to `logger.*`. Without the pragma, rewrite to `logger.*`.
## CI & Diff Enforcement ## 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. - Do not introduce `console.*` anywhere outside allowed, pragma'd spots.
- Enforce rest-parameter call shape in reviews; replace object-wrapped context. - If an import is missing, insert it and resolve alias/relative path
- Ensure environment log level rules remain intact (`VITE_LOG_LEVEL` respected). correctly.
- Enforce rest-parameter call shape in reviews; replace object-wrapped
context.
- Ensure environment log level rules remain intact (`VITE_LOG_LEVEL`
respected).
## Quick Before/After ## Quick Before/After
**Before**
```ts ### **Before**
```typescript
console.log('User signed in', user.id, meta); console.log('User signed in', user.id, meta);
console.error('Failed to update profile', err); console.error('Failed to update profile', err);
console.info('Filter toggled', this.hasVisibleDid); console.info('Filter toggled', this.hasVisibleDid);
``` ```
**After**
```ts ### **After**
import {{ logger }} from '@/utils/logger';
```typescript
import { logger } from '@/utils/logger';
logger.info('User signed in', user.id, meta); logger.info('User signed in', user.id, meta);
logger.error('Failed to update profile', err); logger.error('Failed to update profile', err);
@ -128,11 +209,17 @@ logger.debug('[FeedFilters] Filter toggled', this.hasVisibleDid);
``` ```
## Checklist (for every PR) ## Checklist (for every PR)
- [ ] No `console.*` (or properly pragma’d in the allowed locations)
- [ ] No `console.*` (or properly pragma'd in the allowed locations)
- [ ] Correct import path for `logger` - [ ] Correct import path for `logger`
- [ ] Rest-parameter call shape (`message, ...args`) - [ ] Rest-parameter call shape (`message, ...args`)
- [ ] Right level chosen (debug/info/warn/error) - [ ] Right level chosen (debug/info/warn/error)
- [ ] No secrets / oversized payloads / throwaway context objects - [ ] No secrets / oversized payloads / throwaway context objects
- [ ] Component context provided (scoped logger or `[Component]` prefix) - [ ] Component context provided (scoped logger or `[Component]` prefix)
_Unified on: 2025-08-15 08:11:46Z_ ---
**Status**: Active and enforced
**Last Updated**: 2025-08-15 08:11:46Z
**Version**: 1.0
**Maintainer**: Matthew Raymer

Loading…
Cancel
Save