From cdf5fbdfc63839880616cb73fb628b8ac7a66656 Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Mon, 18 Aug 2025 12:16:07 +0000 Subject: [PATCH] chore: fixing formatting --- .cursor/rules/logging_standards.mdc | 195 ++++++++++++++++++++-------- 1 file changed, 141 insertions(+), 54 deletions(-) diff --git a/.cursor/rules/logging_standards.mdc b/.cursor/rules/logging_standards.mdc index 62c075ed..729f9a4d 100644 --- a/.cursor/rules/logging_standards.mdc +++ b/.cursor/rules/logging_standards.mdc @@ -1,21 +1,48 @@ +--- +globs: *.vue,*.ts,*.tsx +alwaysApply: false +--- # Agent Contract โ€” TimeSafari Logging (Unified, MANDATORY) -**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. +**Author**: Matthew Raymer +**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) -- 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 {{ logger }} from '@/utils/logger'` - - If `@` alias is unavailable, compute the correct relative path (do not fail). + - `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. +- 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.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 @@ -24,103 +51,157 @@ - `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. -```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] Current filter settings', settings.filterFeedByVisible, settings.filterFeedByNearby, settings.searchBoxes?.length ?? 0); -logger.debug('[FeedFilters] Toggling nearby filter', this.isNearby, this.settingChanged, this.activeDid); +logger.debug('[HomeView] Current filter settings', + 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 + Use for user-visible lifecycle and completed operations. -```ts + +```typescript logger.info('[StartView] Component mounted', process.env.VITE_PLATFORM); logger.info('[StartView] User selected new seed generation'); -logger.info('[SearchAreaView] Search box stored', searchBox.name, searchBox.bbox); -logger.info('[ContactQRScanShowView] Contact registration OK', contact.did); +logger.info('[SearchAreaView] Search box stored', + 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 + 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] JWT missing "own" field'); ``` -**Avoid:** Hard failures (those are `error`). + +**Avoid**: Hard failures (those are `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('[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) -- **Component context:** Prefer scoped logger. - ```ts - const log = logger.withContext('UserService'); - log.info('User created', userId); - log.error('Failed to create user', error); - ``` - 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. + +- **Component context**: Prefer scoped logger. + +```typescript +const log = logger.withContext('UserService'); +log.info('User created', userId); +log.error('Failed to create user', error); +``` + +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) + - Exact transforms: - `console.debug(...)` โ†’ `logger.debug(...)` - - `console.log(...)` โ†’ `logger.log(...)` (or `logger.info(...)` when clearly stateful) - - `console.info(...)` โ†’ `logger.info(...)` - - `console.warn(...)` โ†’ `logger.warn(...)` + - `console.log(...)` โ†’ `logger.log(...)` (or `logger.info(...)` when + clearly stateful) + - `console.info(...)` โ†’ `logger.info(...)` + - `console.warn(...)` โ†’ `logger.warn(...)` - `console.error(...)` โ†’ `logger.error(...)` + - Multi-arg handling: - 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)` + - Sole `Error`: - `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)` ## 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')`. +- 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: -```ts + +```typescript // cursor:allow-console reason="short justification" console.log('temporary output'); ``` + Without the pragma, rewrite to `logger.*`. ## 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). + +- 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). ## Quick Before/After -**Before** -```ts + +### **Before** + +```typescript console.log('User signed in', user.id, meta); console.error('Failed to update profile', err); console.info('Filter toggled', this.hasVisibleDid); ``` -**After** -```ts -import {{ logger }} from '@/utils/logger'; + +### **After** + +```typescript +import { logger } from '@/utils/logger'; logger.info('User signed in', user.id, meta); logger.error('Failed to update profile', err); @@ -128,11 +209,17 @@ logger.debug('[FeedFilters] Filter toggled', this.hasVisibleDid); ``` ## 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` - [ ] Rest-parameter call shape (`message, ...args`) - [ ] Right level chosen (debug/info/warn/error) - [ ] No secrets / oversized payloads / throwaway context objects - [ ] 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