From 68c0459533f09be4d3de39cb28daff6aa777d123 Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Fri, 15 Aug 2025 08:16:11 +0000 Subject: [PATCH] refactor(settings): simplify updateSettings calls in HomeView.vue, FeedFilters.vue - Remove conditional activeDid checks around $updateSettings calls in FeedFilters.vue - Call $updateSettings unconditionally, letting implementation handle missing activeDid - Maintain functional behavior while simplifying code structure --- .cursor/rules/logging_standards.mdc | 138 ++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 .cursor/rules/logging_standards.mdc diff --git a/.cursor/rules/logging_standards.mdc b/.cursor/rules/logging_standards.mdc new file mode 100644 index 00000000..62c075ed --- /dev/null +++ b/.cursor/rules/logging_standards.mdc @@ -0,0 +1,138 @@ +# 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. + +## 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. +```ts +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); +``` +**Avoid:** Vague messages (`'Processing data'`). + +### INFO +Use for user-visible lifecycle and completed operations. +```ts +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); +``` +**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); +logger.warn('[ContactQRScanShowView] Invalid QR format – no JWT in URL'); +logger.warn('[ContactQRScanShowView] JWT missing "own" field'); +``` +**Avoid:** Hard failures (those are `error`). + +### ERROR +Use for unrecoverable failures, data integrity issues, and thrown exceptions. +```ts +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); +``` +**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. + +## 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.error(...)` → `logger.error(...)` +- Multi-arg handling: + - First arg becomes `message` (stringify safely if non-string). + - 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: + `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')`. + +## 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 +// 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). + +## Quick Before/After +**Before** +```ts +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'; + +logger.info('User signed in', user.id, meta); +logger.error('Failed to update profile', err); +logger.debug('[FeedFilters] Filter toggled', this.hasVisibleDid); +``` + +## Checklist (for every PR) +- [ ] 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_