Browse Source

Merge branch 'master' into fix-deep-link

fix-deep-link
Trent Larson 2 days ago
parent
commit
3aaea9c829
  1. 10
      .cursor/rules/adr_template.mdc
  2. 282
      .cursor/rules/app/architectural_decision_record.mdc
  3. 413
      .cursor/rules/app/timesafari.mdc
  4. 49
      .cursor/rules/asset_configuration.mdc
  5. 96
      .cursor/rules/base_context.mdc
  6. 47
      .cursor/rules/database/absurd-sql.mdc
  7. 5
      .cursor/rules/database/legacy_dexie.mdc
  8. 55
      .cursor/rules/development/type_safety_guide.mdc
  9. 8
      .cursor/rules/features/camera-implementation.mdc
  10. 81
      .cursor/rules/investigation_report_example.mdc
  11. 13
      .cursor/rules/logging_standards.mdc
  12. 4
      .cursor/rules/research_diagnostic.mdc
  13. 101
      .cursor/rules/software_development.mdc
  14. 329
      .cursor/rules/time.mdc
  15. 321
      .cursor/rules/workflow/version_control.mdc
  16. 182
      doc/debug-hook-guide.md
  17. 103
      scripts/git-hooks/README.md
  18. 86
      scripts/git-hooks/debug-checker.config
  19. 252
      scripts/git-hooks/pre-commit
  20. 171
      scripts/install-debug-hook.sh
  21. 117
      scripts/test-debug-hook.sh
  22. 6
      src/interfaces/common.ts
  23. 23
      src/services/ProfileService.ts
  24. 10
      src/views/AccountViewView.vue

10
.cursor/rules/adr_template.mdc

@ -2,14 +2,16 @@
## ADR-XXXX-YY-ZZ: [Short Title]
**Date:** YYYY-MM-DD
**Status:** [PROPOSED | ACCEPTED | REJECTED | DEPRECATED | SUPERSEDED]
**Deciders:** [List of decision makers]
**Date:** YYYY-MM-DD
**Status:** [PROPOSED | ACCEPTED | REJECTED | DEPRECATED | SUPERSEDED]
**Deciders:** [List of decision makers]
**Technical Story:** [Link to issue/PR if applicable]
## Context
[Describe the forces at play, including technological, political, social, and project local. These forces are probably in tension, and should be called out as such. The language in this section is value-neutral. It is simply describing facts.]
[Describe the forces at play, including technological, political, social, and
project local. These forces are probably in tension, and should be called out as
such. The language in this section is value-neutral. It is simply describing facts.]
## Decision

282
.cursor/rules/app/architectural_decision_record.mdc

@ -1,10 +1,13 @@
---
description:
globs:
alwaysApply: true
description: when you need to understand the system architecture or make changes that impact the system architecture
alwaysApply: false
---
# TimeSafari Cross-Platform Architecture Guide
**Author**: Matthew Raymer
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Architecture guidelines
## 1. Platform Support Matrix
| Feature | Web (PWA) | Capacitor (Mobile) | Electron (Desktop) |
@ -15,11 +18,10 @@ alwaysApply: true
| Camera Access | MediaDevices API | Capacitor Camera | Not Implemented |
| Platform Detection | Web APIs | Capacitor.isNativePlatform() | process.env checks |
---
## 2. Project Structure
### Core Directories
```
src/
├── components/ # Vue components
@ -38,14 +40,13 @@ src/
```
### Entry Points
- `main.ts` → Base entry
- `main.common.ts` → Shared init
- `main.capacitor.ts` → Mobile entry
- `main.electron.ts` → Electron entry
- `main.web.ts` → Web entry
---
## 3. Service Architecture
### Service Organization
@ -64,28 +65,30 @@ services/
```
### Factory Pattern
Use a **singleton factory** to select platform services via `process.env.VITE_PLATFORM`.
---
Use a **singleton factory** to select platform services via
`process.env.VITE_PLATFORM`.
## 4. Feature Guidelines
### QR Code Scanning
- Define `QRScannerService` interface.
- Implement platform-specific classes (`WebInlineQRScanner`, Capacitor, etc).
- Implement platform-specific classes (`WebInlineQRScanner`, Capacitor,
etc).
- Provide `addListener` and `onStream` hooks for composability.
### Deep Linking
- URL format: `timesafari://<route>[/<param>][?query=value]`
- Web: `router.beforeEach` → parse query
- Web: `router.beforeEach` → parse query
- Capacitor: `App.addListener("appUrlOpen", …)`
---
## 5. Build Process
- `vite.config.common.mts` → shared config
- Platform configs: `vite.config.web.mts`, `.capacitor.mts`, `.electron.mts`
- `vite.config.common.mts` → shared config
- Platform configs: `vite.config.web.mts`, `.capacitor.mts`,
`.electron.mts`
- Use `process.env.VITE_PLATFORM` for conditional loading.
```bash
@ -94,78 +97,255 @@ npm run build:capacitor
npm run build:electron
```
---
## 6. Testing Strategy
- **Unit tests** for services.
- **Playwright** for Web + Capacitor:
- `playwright.config-local.ts` includes web + Pixel 5.
- **Electron tests**: add `spectron` or Playwright-Electron.
- **Playwright** for Web + Capacitor:
- `playwright.config-local.ts` includes web + Pixel 5.
- **Electron tests**: add `spectron` or Playwright-Electron.
- Mark tests with platform tags:
```ts
test.skip(!process.env.MOBILE_TEST, "Mobile-only test");
```
> 🔗 **Human Hook:** Before merging new tests, hold a short sync (≤15 min) with QA to align on coverage and flaky test risks.
---
> 🔗 **Human Hook:** Before merging new tests, hold a short sync (≤15
> min) with QA to align on coverage and flaky test risks.
## 7. Error Handling
- Global Vue error handler → logs with component name.
- Platform-specific wrappers log API errors with platform prefix (`[Capacitor API Error]`, etc).
- Global Vue error handler → logs with component name.
- Platform-specific wrappers log API errors with platform prefix
(`[Capacitor API Error]`, etc).
- Use structured logging (not `console.log`).
---
## 8. Best Practices
- Keep platform code **isolated** in `platforms/`.
- Keep platform code **isolated** in `platforms/`.
- Always define a **shared interface** first.
- Use feature detection, not platform detection, when possible.
- Dependency injection for services → improves testability.
- Maintain **Competence Hooks** in PRs (2–3 prompts for dev discussion).
---
- Use feature detection, not platform detection, when possible.
- Dependency injection for services → improves testability.
- Maintain **Competence Hooks** in PRs (2–3 prompts for dev
discussion).
## 9. Dependency Management
- Key deps: `@capacitor/core`, `electron`, `vue`.
- Use conditional `import()` for platform-specific libs.
---
- Key deps: `@capacitor/core`, `electron`, `vue`.
- Use conditional `import()` for platform-specific libs.
## 10. Security Considerations
- **Permissions**: Always check + request gracefully.
- **Storage**: Secure storage for sensitive data; encrypt when possible.
- **Audits**: Schedule quarterly security reviews.
---
- **Permissions**: Always check + request gracefully.
- **Storage**: Secure storage for sensitive data; encrypt when possible.
- **Audits**: Schedule quarterly security reviews.
## 11. ADR Process
- All major architecture choices → log in `doc/adr/`.
- Use ADR template with Context, Decision, Consequences, Status.
- Link related ADRs in PR descriptions.
- All major architecture choices → log in `doc/adr/`.
- Use ADR template with Context, Decision, Consequences, Status.
- Link related ADRs in PR descriptions.
> 🔗 **Human Hook:** When proposing a new ADR, schedule a 30-min
> design sync for discussion, not just async review.
## 12. Collaboration Hooks
- **QR features**: Sync with Security before merging → permissions &
privacy.
- **New platform builds**: Demo in team meeting → confirm UX
differences.
- **Critical ADRs**: Present in guild or architecture review.
> 🔗 **Human Hook:** When proposing a new ADR, schedule a 30-min design sync for discussion, not just async review.
## Self-Check
- [ ] Does this feature implement a shared interface?
- [ ] Are fallbacks + errors handled gracefully?
- [ ] Have relevant ADRs been updated/linked?
- [ ] Did I add competence hooks or prompts for the team?
- [ ] Was human interaction (sync/review/demo) scheduled?
---
**Status**: Active architecture guidelines
**Priority**: High
**Estimated Effort**: Ongoing reference
**Dependencies**: Vue 3, Capacitor, Electron, Vite
**Stakeholders**: Development team, Architecture team
- [ ] Are fallbacks + errors handled gracefully?
- [ ] Have relevant ADRs been updated/linked?
- [ ] Did I add competence hooks or prompts for the team?
- [ ] Was human interaction (sync/review/demo) scheduled?
# TimeSafari Cross-Platform Architecture Guide
**Author**: Matthew Raymer
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Architecture guidelines
## 1. Platform Support Matrix
| Feature | Web (PWA) | Capacitor (Mobile) | Electron (Desktop) |
|---------|-----------|--------------------|-------------------|
| QR Code Scanning | WebInlineQRScanner | @capacitor-mlkit/barcode-scanning | Not Implemented |
| Deep Linking | URL Parameters | App URL Open Events | Not Implemented |
| File System | Limited (Browser API) | Capacitor Filesystem | Electron fs |
| Camera Access | MediaDevices API | Capacitor Camera | Not Implemented |
| Platform Detection | Web APIs | Capacitor.isNativePlatform() | process.env checks |
## 2. Project Structure
### Core Directories
```
src/
├── components/ # Vue components
├── services/ # Platform services and business logic
├── views/ # Page components
├── router/ # Vue router configuration
├── types/ # TypeScript type definitions
├── utils/ # Utility functions
├── lib/ # Core libraries
├── platforms/ # Platform-specific implementations
├── electron/ # Electron-specific code
├── constants/ # Application constants
├── db/ # Database related code
├── interfaces/ # TypeScript interfaces
└── assets/ # Static assets
```
### Entry Points
- `main.ts` → Base entry
- `main.common.ts` → Shared init
- `main.capacitor.ts` → Mobile entry
- `main.electron.ts` → Electron entry
- `main.web.ts` → Web entry
## 3. Service Architecture
### Service Organization
```tree
services/
├── QRScanner/
│ ├── WebInlineQRScanner.ts
│ └── interfaces.ts
├── platforms/
│ ├── WebPlatformService.ts
│ ├── CapacitorPlatformService.ts
│ └── ElectronPlatformService.ts
└── factory/
└── PlatformServiceFactory.ts
```
### Factory Pattern
Use a **singleton factory** to select platform services via
`process.env.VITE_PLATFORM`.
## 4. Feature Guidelines
### QR Code Scanning
- Define `QRScannerService` interface.
- Implement platform-specific classes (`WebInlineQRScanner`, Capacitor,
etc).
- Provide `addListener` and `onStream` hooks for composability.
### Deep Linking
- URL format: `timesafari://<route>[/<param>][?query=value]`
- Web: `router.beforeEach` → parse query
- Capacitor: `App.addListener("appUrlOpen", …)`
## 5. Build Process
- `vite.config.common.mts` → shared config
- Platform configs: `vite.config.web.mts`, `.capacitor.mts`,
`.electron.mts`
- Use `process.env.VITE_PLATFORM` for conditional loading.
```bash
npm run build:web
npm run build:capacitor
npm run build:electron
```
## 6. Testing Strategy
- **Unit tests** for services.
- **Playwright** for Web + Capacitor:
- `playwright.config-local.ts` includes web + Pixel 5.
- **Electron tests**: add `spectron` or Playwright-Electron.
- Mark tests with platform tags:
```ts
test.skip(!process.env.MOBILE_TEST, "Mobile-only test");
```
> 🔗 **Human Hook:** Before merging new tests, hold a short sync (≤15
> min) with QA to align on coverage and flaky test risks.
## 7. Error Handling
- Global Vue error handler → logs with component name.
- Platform-specific wrappers log API errors with platform prefix
(`[Capacitor API Error]`, etc).
- Use structured logging (not `console.log`).
## 8. Best Practices
- Keep platform code **isolated** in `platforms/`.
- Always define a **shared interface** first.
- Use feature detection, not platform detection, when possible.
- Dependency injection for services → improves testability.
- Maintain **Competence Hooks** in PRs (2–3 prompts for dev
discussion).
## 9. Dependency Management
- Key deps: `@capacitor/core`, `electron`, `vue`.
- Use conditional `import()` for platform-specific libs.
## 10. Security Considerations
- **Permissions**: Always check + request gracefully.
- **Storage**: Secure storage for sensitive data; encrypt when possible.
- **Audits**: Schedule quarterly security reviews.
## 11. ADR Process
- All major architecture choices → log in `doc/adr/`.
- Use ADR template with Context, Decision, Consequences, Status.
- Link related ADRs in PR descriptions.
> 🔗 **Human Hook:** When proposing a new ADR, schedule a 30-min
> design sync for discussion, not just async review.
## 12. Collaboration Hooks
- **QR features**: Sync with Security before merging → permissions & privacy.
- **New platform builds**: Demo in team meeting → confirm UX differences.
- **Critical ADRs**: Present in guild or architecture review.
- **QR features**: Sync with Security before merging → permissions &
privacy.
- **New platform builds**: Demo in team meeting → confirm UX
differences.
- **Critical ADRs**: Present in guild or architecture review.
## Self-Check
- [ ] Does this feature implement a shared interface?
- [ ] Are fallbacks + errors handled gracefully?
- [ ] Have relevant ADRs been updated/linked?
- [ ] Did I add competence hooks or prompts for the team?
- [ ] Was human interaction (sync/review/demo) scheduled?
---
# Self-Check
**Status**: Active architecture guidelines
**Priority**: High
**Estimated Effort**: Ongoing reference
**Dependencies**: Vue 3, Capacitor, Electron, Vite
**Stakeholders**: Development team, Architecture team
- [ ] Does this feature implement a shared interface?
- [ ] Are fallbacks + errors handled gracefully?
- [ ] Have relevant ADRs been updated/linked?
- [ ] Did I add competence hooks or prompts for the team?

413
.cursor/rules/app/timesafari.mdc

@ -1,316 +1,181 @@
---
description:
globs:
alwaysApply: true
---
# Time Safari Context
**Author**: Matthew Raymer
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Core application context
## Project Overview
Time Safari is an application designed to foster community building through gifts,
gratitude, and collaborative projects. The app should make it extremely easy and
intuitive for users of any age and capability to recognize contributions, build
trust networks, and organize collective action. It is built on services that
preserve privacy and data sovereignty.
Time Safari is an application designed to foster community building through
gifts, gratitude, and collaborative projects. The app makes it easy and
intuitive for users of any age and capability to recognize contributions,
build trust networks, and organize collective action. It is built on services
that preserve privacy and data sovereignty.
The ultimate goals of Time Safari are two-fold:
## Core Goals
1. **Connect** Make it easy, rewarding, and non-threatening for people to
connect with others who have similar interests, and to initiate activities
together. This helps people accomplish and learn from other individuals in
less-structured environments; moreover, it helps them discover who they want
to continue to support and with whom they want to maintain relationships.
1. **Connect**: Make it easy, rewarding, and non-threatening for people to
connect with others who have similar interests, and to initiate activities
together.
2. **Reveal** Widely advertise the great support and rewards that are being
given and accepted freely, especially non-monetary ones. Using visuals and text,
display the kind of impact that gifts are making in the lives of others. Also
show useful and engaging reports of project statistics and personal accomplishments.
2. **Reveal**: Widely advertise the great support and rewards that are being
given and accepted freely, especially non-monetary ones, showing the impact
gifts make in people's lives.
## Technical Foundation
## Core Approaches
### Architecture
Time Safari should help everyday users build meaningful connections and organize
collective efforts by:
- **Privacy-preserving claims architecture** via endorser.ch
- **Decentralized Identifiers (DIDs)**: User identities based on
public/private key pairs stored on devices
- **Cryptographic Verification**: All claims and confirmations are
cryptographically signed
- **User-Controlled Visibility**: Users explicitly control who can see their
identifiers and data
- **Cross-Platform**: Web (PWA), Mobile (Capacitor), Desktop (Electron)
1. **Recognizing Contributions**: Creating permanent, verifiable records of gifts
and contributions people give to each other and their communities.
### Current Database State
2. **Facilitating Collaboration**: Making it ridiculously easy for people to ask
for or propose help on projects and interests that matter to them.
- **Database**: SQLite via Absurd SQL (browser) and native SQLite
(mobile/desktop)
- **Legacy Support**: IndexedDB (Dexie) for backward compatibility
- **Status**: Modern database architecture fully implemented
3. **Building Trust Networks**: Enabling users to maintain their network and activity
visibility. Developing reputation through verified contributions and references,
which can be selectively shown to others outside the network.
### Core Technologies
4. **Preserving Privacy**: Ensuring personal identifiers are only shared with
explicitly authorized contacts, allowing private individuals including children
to participate safely.
- **Frontend**: Vue 3 + TypeScript + vue-facing-decorator
- **Styling**: TailwindCSS
- **Build**: Vite with platform-specific configs
- **Testing**: Playwright E2E, Jest unit tests
- **Database**: SQLite (Absurd SQL in browser), IndexedDB (legacy)
- **State**: Pinia stores
- **Platform Services**: Abstracted behind interfaces with factory pattern
5. **Engaging Content**: Displaying people's records in compelling stories, and
highlighting those projects that are lifting people's lives long-term, both in
physical support and in emotional-spiritual-creative thriving.
## Development Principles
### Code Organization
## Technical Foundation
- **Platform Services**: Abstract platform-specific code behind interfaces
- **Service Factory**: Use `PlatformServiceFactory` for platform selection
- **Type Safety**: Strict TypeScript, no `any` types, use type guards
- **Modern Architecture**: Use current platform service patterns
This application is built on a privacy-preserving claims architecture (via
endorser.ch) with these key characteristics:
### Architecture Patterns
- **Decentralized Identifiers (DIDs)**: User identities are based on public/private
key pairs stored on their devices
- **Cryptographic Verification**: All claims and confirmations are
cryptographically signed
- **User-Controlled Visibility**: Users explicitly control who can see their
identifiers and data
- **Merkle-Chained Claims**: Claims are cryptographically chained for verification
and integrity
- **Native and Web App**: Works on Capacitor (iOS, Android), Desktop (Electron
and CEFPython), and web browsers
- **Dependency Injection**: Services injected via mixins and factory pattern
- **Interface Segregation**: Small, focused interfaces over large ones
- **Composition over Inheritance**: Prefer mixins and composition
- **Single Responsibility**: Each component/service has one clear purpose
## User Journey
### Testing Strategy
The typical progression of usage follows these stages:
- **E2E**: Playwright for critical user journeys
- **Unit**: Jest with F.I.R.S.T. principles
- **Platform Coverage**: Web + Capacitor (Pixel 5) in CI
- **Quality Assurance**: Comprehensive testing and validation
1. **Gratitude & Recognition**: Users begin by expressing and recording gratitude
for gifts received, building a foundation of acknowledgment.
## Current Development Focus
2. **Project Proposals**: Users propose projects and ideas, reaching out to connect
with others who share similar interests.
### Active Development
3. **Action Triggers**: Offers of help serve as triggers and motivations to execute
proposed projects, moving from ideas to action.
- **Feature Development**: Build new functionality using modern platform
services
- **Performance Optimization**: Improve app performance and user experience
- **Platform Enhancement**: Leverage platform-specific capabilities
- **Code Quality**: Maintain high standards and best practices
## Context for LLM Development
### Development Metrics
When developing new functionality for Time Safari, consider these design principles:
- **Code Quality**: High standards maintained across all platforms
- **Performance**: Optimized for all target devices
- **Testing**: Comprehensive coverage maintained
- **User Experience**: Focus on intuitive, accessible interfaces
1. **Accessibility First**: Features should be usable by non-technical users with
minimal learning curve.
## Platform-Specific Considerations
2. **Privacy by Design**: All features must respect user privacy and data sovereignty.
### Web (PWA)
3. **Progressive Enhancement**: Core functionality should work across all devices,
with richer experiences where supported.
- **QR Scanning**: WebInlineQRScanner
- **Deep Linking**: URL parameters
- **File System**: Limited browser APIs
- **Build**: `npm run build:web` (development build)
4. **Voluntary Collaboration**: The system should enable but never coerce participation.
### Mobile (Capacitor)
5. **Trust Building**: Features should help build verifiable trust between users.
- **QR Scanning**: @capacitor-mlkit/barcode-scanning
- **Deep Linking**: App URL open events
- **File System**: Capacitor Filesystem
- **Build**: `npm run build:capacitor`
6. **Network Effects**: Consider how features scale as more users join the platform.
### Desktop (Electron)
7. **Low Resource Requirements**: The system should be lightweight enough to run
on inexpensive devices users already own.
- **File System**: Node.js fs
- **Build**: `npm run build:electron`
- **Distribution**: AppImage, DEB, DMG packages
## Use Cases to Support
## Development Workflow
### Build Commands
LLM development should focus on enhancing these key use cases:
```bash
# Web (development)
npm run build:web
1. **Community Building**: Tools that help people find others with shared
interests and values.
# Mobile
npm run build:capacitor
npm run build:native
2. **Project Coordination**: Features that make it easy to propose collaborative
projects and to submit suggestions and offers to existing ones.
# Desktop
npm run build:electron
npm run build:electron:appimage
npm run build:electron:deb
npm run build:electron:dmg
```
3. **Reputation Building**: Methods for users to showcase their contributions
and reliability, in contexts where they explicitly reveal that information.
### Testing Commands
4. **Governance Experimentation**: Features that facilitate decision-making and
collective governance.
```bash
# Web E2E
npm run test:web
## Constraints
When developing new features, be mindful of these constraints:
# Mobile
npm run test:mobile
npm run test:android
npm run test:ios
# Type checking
npm run type-check
npm run lint-fix
```
## Key Constraints
1. **Privacy First**: User identifiers remain private except when explicitly
shared
2. **Platform Compatibility**: Features must work across all target platforms
3. **Performance**: Must remain performant on older/simpler devices
4. **Modern Architecture**: New features should use current platform services
5. **Offline Capability**: Key functionality should work offline when feasible
## Use Cases to Support
1. **Community Building**: Tools for finding others with shared interests
2. **Project Coordination**: Easy proposal and collaboration on projects
3. **Reputation Building**: Showcasing contributions and reliability
4. **Governance**: Facilitating decision-making and collective governance
## Resources
- **Testing**: `docs/migration-testing/`
- **Architecture**: `docs/architecture-decisions.md`
- **Build Context**: `docs/build-modernization-context.md`
---
1. **Privacy Preservation**: User identifiers must remain private except when
explicitly shared.
## Status: Active application context
2. **Platform Limitations**: Features must work within the constraints of the target
app platforms, while aiming to leverage the best platform technology available.
3. **Endorser API Limitations**: Backend features are constrained by the endorser.ch
API capabilities.
4. **Performance on Low-End Devices**: The application should remain performant
on older/simpler devices.
5. **Offline-First When Possible**: Key functionality should work offline when feasible.
## Project Technologies
- Typescript using ES6 classes using vue-facing-decorator
- TailwindCSS
- Vite Build Tool
- Playwright E2E testing
- IndexDB
- Camera, Image uploads, QR Code reader, ...
## Mobile Features
- Deep Linking
- Local Notifications via a custom Capacitor plugin
## Project Architecture
- The application must work on web browser, PWA (Progressive Web Application),
desktop via Electron, and mobile via Capacitor
- Building for each platform is managed via Vite
## Core Development Principles
### DRY development
- **Code Reuse**
- Extract common functionality into utility functions
- Create reusable components for UI patterns
- Implement service classes for shared business logic
- Use mixins for cross-cutting concerns
- Leverage TypeScript interfaces for shared type definitions
- **Component Patterns**
- Create base components for common UI elements
- Implement higher-order components for shared behavior
- Use slot patterns for flexible component composition
- Create composable services for business logic
- Implement factory patterns for component creation
- **State Management**
- Centralize state in Pinia stores
- Use computed properties for derived state
- Implement shared state selectors
- Create reusable state mutations
- Use action creators for common operations
- **Error Handling**
- Implement centralized error handling
- Create reusable error components
- Use error boundary components
- Implement consistent error logging
- Create error type definitions
- **Type Definitions**
- Create shared interfaces for common data structures
- Use type aliases for complex types
- Implement generic types for reusable components
- Create utility types for common patterns
- Use discriminated unions for state management
- **API Integration**
- Create reusable API client classes
- Implement request/response interceptors
- Use consistent error handling patterns
- Create type-safe API endpoints
- Implement caching strategies
- **Platform Services**
- Abstract platform-specific code behind interfaces
- Create platform-agnostic service layers
- Implement feature detection
- Use dependency injection for services
- Create service factories
- **Testing**
- Create reusable test utilities
- Implement test factories
- Use shared test configurations
- Create reusable test helpers
- Implement consistent test patterns
- F.I.R.S.T. (for Unit Tests)
F – Fast
I – Independent
R – Repeatable
S – Self-validating
T – Timely
### SOLID Principles
- **Single Responsibility**: Each class/component should have only one reason to
change
- Components should focus on one specific feature (e.g., QR scanning, DID management)
- Services should handle one type of functionality (e.g., platform services,
crypto services)
- Utilities should provide focused helper functions
- **Open/Closed**: Software entities should be open for extension but closed for
modification
- Use interfaces for service definitions
- Implement plugin architecture for platform-specific features
- Allow component behavior extension through props and events
- **Liskov Substitution**: Objects should be replaceable with their subtypes
- Platform services should work consistently across web/mobile
- Authentication providers should be interchangeable
- Storage implementations should be swappable
- **Interface Segregation**: Clients shouldn't depend on interfaces they don't use
- Break down large service interfaces into smaller, focused ones
- Component props should be minimal and purposeful
- Event emissions should be specific and targeted
- **Dependency Inversion**: High-level modules shouldn't depend on low-level modules
- Use dependency injection for services
- Abstract platform-specific code behind interfaces
- Implement factory patterns for component creation
### Law of Demeter
- Components should only communicate with immediate dependencies
- Avoid chaining method calls (e.g., `this.service.getUser().getProfile().getName()`)
- Use mediator patterns for complex component interactions
- Implement facade patterns for subsystem access
- Keep component communication through defined events and props
### Composition over Inheritance
- Prefer building components through composition
- Use mixins for shared functionality
- Implement feature toggles through props
- Create higher-order components for common patterns
- Use service composition for complex features
### Interface Segregation
- Define clear interfaces for services
- Keep component APIs minimal and focused
- Split large interfaces into smaller, specific ones
- Use TypeScript interfaces for type definitions
- Implement role-based interfaces for different use cases
### Fail Fast
- Validate inputs early in the process
- Use TypeScript strict mode
- Implement comprehensive error handling
- Add runtime checks for critical operations
- Use assertions for development-time validation
### Principle of Least Astonishment
- Follow Vue.js conventions consistently
- Use familiar naming patterns
- Implement predictable component behaviors
- Maintain consistent error handling
- Keep UI interactions intuitive
### Information Hiding
- Encapsulate implementation details
- Use private class members
- Implement proper access modifiers
- Hide complex logic behind simple interfaces
- Use TypeScript's access modifiers effectively
### Single Source of Truth
- Use Pinia for state management
- Maintain one source for user data
- Centralize configuration management
- Use computed properties for derived state
- Implement proper state synchronization
### Principle of Least Privilege
- Implement proper access control
- Use minimal required permissions
- Follow privacy-by-design principles
- Restrict component access to necessary data
- Implement proper authentication/authorization
- **Priority**: Critical
- **Estimated Effort**: Ongoing reference
- **Dependencies**: Vue 3, TypeScript, SQLite, Capacitor, Electron
- **Stakeholders**: Development team, Product team

49
.cursor/rules/asset_configuration.mdc

@ -1,32 +1,61 @@
---
alwaysApply: true
description: when doing anything with capacitor assets
alwaysApply: false
---
# Asset Configuration Directive
*Scope: Assets Only (icons, splashes, image pipelines) — not overall build orchestration*
**Author**: Matthew Raymer
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Asset management guidelines
*Scope: Assets Only (icons, splashes, image pipelines) — not overall build
orchestration*
## Intent
- Version **asset configuration files** (optionally dev-time generated).
- **Do not** version platform asset outputs (Android/iOS/Electron); generate them **at build-time** with standard tools.
- **Do not** version platform asset outputs (Android/iOS/Electron); generate
them **at build-time** with standard tools.
- Keep existing per-platform build scripts unchanged.
## Source of Truth
- **Preferred (Capacitor default):** `resources/` as the single master source.
- **Alternative:** `assets/` is acceptable **only** if `capacitor-assets` is explicitly configured to read from it.
- **Never** maintain both `resources/` and `assets/` as parallel sources. Migrate and delete the redundant folder.
- **Alternative:** `assets/` is acceptable **only** if `capacitor-assets` is
explicitly configured to read from it.
- **Never** maintain both `resources/` and `assets/` as parallel sources.
Migrate and delete the redundant folder.
## Config Files
- Live under: `config/assets/` (committed).
- Examples:
- `config/assets/capacitor-assets.config.json` (or the path the tool expects)
- `config/assets/capacitor-assets.config.json` (or the path the tool
expects)
- `config/assets/android.assets.json`
- `config/assets/ios.assets.json`
- `config/assets/common.assets.yaml` (optional shared layer)
- **Dev-time generation allowed** for these configs; **build-time generation is forbidden**.
- **Dev-time generation allowed** for these configs; **build-time
generation is forbidden**.
## Build-Time Behavior
- Build generates platform assets (not configs) using the standard chain:
```bash
npm run build:capacitor # web build via Vite (.mts)
npx cap sync
```bash
npm run build:capacitor # web build via Vite (.mts)
npx cap sync
npx capacitor-assets generate # produces platform assets; not committed
# then platform-specific build steps
```
---
**Status**: Active asset management directive
**Priority**: Medium
**Estimated Effort**: Ongoing reference
**Dependencies**: capacitor-assets toolchain
**Stakeholders**: Development team, Build team
npx capacitor-assets generate # produces platform assets; not committed
# then platform-specific build steps

96
.cursor/rules/base_context.mdc

@ -1,3 +1,6 @@
---
alwaysApply: true
---
```json
{
"coaching_level": "standard",
@ -10,7 +13,12 @@
# Base Context — Human Competence First
**Author**: Matthew Raymer
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Core interaction guidelines
## Purpose
All interactions must *increase the human's competence over time* while
completing the task efficiently. The model may handle menial work and memory
extension, but must also promote learning, autonomy, and healthy work habits.
@ -21,57 +29,79 @@ machine-driven steps.
## Principles
1) Competence over convenience: finish the task *and* leave the human more
1. Competence over convenience: finish the task *and* leave the human more
capable next time.
2) Mentorship, not lectures: be concise, concrete, and immediately applicable.
3) Transparency: show assumptions, limits, and uncertainty; cite when non-obvious.
4) Optional scaffolding: include small, skimmable learning hooks that do not
2. Mentorship, not lectures: be concise, concrete, and immediately applicable.
3. Transparency: show assumptions, limits, and uncertainty; cite when
non-obvious.
4. Optional scaffolding: include small, skimmable learning hooks that do not
bloat output.
5) Time respect: default to **lean output**; offer opt-in depth via toggles.
6) Psychological safety: encourage, never condescend; no medical/clinical advice.
No censorship!
7) Reusability: structure outputs so they can be saved, searched, reused, and repurposed.
8) **Collaborative Bias**: Favor solutions that invite human review, discussion,
and iteration. When in doubt, ask "Who should this be shown to?" or "Which human
input would improve this?"
5. Time respect: default to **lean output**; offer opt-in depth via toggles.
6. Psychological safety: encourage, never condescend; no medical/clinical
advice. No censorship!
7. Reusability: structure outputs so they can be saved, searched, reused, and
repurposed.
8. **Collaborative Bias**: Favor solutions that invite human review,
discussion, and iteration. When in doubt, ask "Who should this be shown
to?" or "Which human input would improve this?"
## Toggle Definitions
### coaching_level
Determines the depth of learning support: `light` (short hooks), `standard`
(balanced), `deep` (detailed).
Determines the depth of learning support: `light` (short hooks),
`standard` (balanced), `deep` (detailed).
### socratic_max_questions
The number of clarifying questions the model may ask before proceeding.
If >0, questions should be targeted, minimal, and followed by reasonable assumptions if unanswered.
If >0, questions should be targeted, minimal, and followed by reasonable
assumptions if unanswered.
### verbosity
'terse' (just a sentence), `concise` (minimum commentary), `normal` (balanced explanation), or other project-defined levels.
'terse' (just a sentence), `concise` (minimum commentary), `normal`
(balanced explanation), or other project-defined levels.
### timebox_minutes
*integer or null* — When set to a positive integer (e.g., `5`), this acts as a **time budget** guiding the model to prioritize delivering the most essential parts of the task within that constraint.
*integer or null* — When set to a positive integer (e.g., `5`), this acts
as a **time budget** guiding the model to prioritize delivering the most
essential parts of the task within that constraint.
Behavior when set:
1. **Prioritize Core Output** — Deliver the minimum viable solution or result first.
2. **Limit Commentary** — Competence Hooks and Collaboration Hooks must be shorter than normal.
3. **Signal Skipped Depth** — Omitted details should be listed under *Deferred for depth*.
4. **Order by Value** — Start with blocking or high-value items, then proceed to nice-to-haves if budget allows.
If `null`, there is no timebox — the model can produce full-depth responses.
1. **Prioritize Core Output** — Deliver the minimum viable solution or
result first.
2. **Limit Commentary** — Competence Hooks and Collaboration Hooks must be
shorter than normal.
3. **Signal Skipped Depth** — Omitted details should be listed under
*Deferred for depth*.
4. **Order by Value** — Start with blocking or high-value items, then
proceed to nice-to-haves if budget allows.
If `null`, there is no timebox — the model can produce full-depth
responses.
### format_enforcement
`strict` (reject outputs with format drift) or `relaxed` (minor deviations acceptable).
`strict` (reject outputs with format drift) or `relaxed` (minor deviations
acceptable).
## Modes (select or combine)
- **Doer**: produce the artifact fast, minimal commentary.
- **Mentor**: add short "why/how" notes + next-step pointers.
- **Socratic**: ask up to N targeted questions when requirements are ambiguous.
- **Socratic**: ask up to N targeted questions when requirements are
ambiguous.
- **Pair-Programmer/Pair-Writer**: explain tradeoffs as you implement.
- **Facilitator**: structure output to be reviewable, commentable, and ready for group discussion.
- **Facilitator**: structure output to be reviewable, commentable, and
ready for group discussion.
Default: Doer + short Mentor notes.
## Competence & Collaboration Levers (keep lightweight)
- "Why this works" (≤3 bullets)
- "Common pitfalls" (≤3 bullets)
- "Next skill unlock" (1 tiny action or reading)
@ -79,6 +109,7 @@ Default: Doer + short Mentor notes.
- "Discussion prompts" (≤2 short questions for peers/stakeholders)
## Output Contract (apply to every deliverable)
- Clear **Objective** (1 line)
- **Result** (artifact/code/answer)
- **Use/Run** (how to apply/test)
@ -88,8 +119,10 @@ Default: Doer + short Mentor notes.
- **References** (if used; links or titles)
## Do-Not
- No filler, hedging, or moralizing.
- No medical/mental-health advice; keep "healthy habits" to general work practices.
- No medical/mental-health advice; keep "healthy habits" to general work
practices.
- No invented facts; mark uncertainty plainly.
- No censorship.
- Avoid outputs that bypass human review when such review is valuable.
@ -100,11 +133,22 @@ Default: Doer + short Mentor notes.
- **research_diagnostic.mdc**: For investigation and research workflows
## Self-Check (model, before responding)
- [ ] Task done *and* at least one competence lever included (≤120 words total).
- [ ] Task done *and* at least one competence lever included (≤120 words
total).
- [ ] At least one collaboration/discussion hook present.
- [ ] Output follows the **Output Contract** sections.
- [ ] Toggles respected; verbosity remains concise.
- [ ] Uncertainties/assumptions surfaced.
- [ ] No disallowed content.
---
**Status**: Active core guidelines
**Priority**: Critical
**Estimated Effort**: Ongoing reference
**Dependencies**: None (base ruleset)
**Stakeholders**: All AI interactions
- [ ] Uncertainties/assumptions surfaced.
- [ ] No disallowed content.

47
.cursor/rules/database/absurd-sql.mdc

@ -1,13 +1,23 @@
---
globs: **/db/databaseUtil.ts, **/interfaces/absurd-sql.d.ts, **/src/registerSQLWorker.js, **/services/AbsurdSqlDatabaseService.ts
globs: **/db/databaseUtil.ts, **/interfaces/absurd-sql.d.ts, **/src/registerSQLWorker.js, **/
services/AbsurdSqlDatabaseService.ts
alwaysApply: false
---
# Absurd SQL - Cursor Development Guide
**Author**: Matthew Raymer
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Database development guidelines
## Project Overview
Absurd SQL is a backend implementation for sql.js that enables persistent SQLite databases in the browser by using IndexedDB as a block storage system. This guide provides rules and best practices for developing with this project in Cursor.
Absurd SQL is a backend implementation for sql.js that enables persistent
SQLite databases in the browser by using IndexedDB as a block storage system.
This guide provides rules and best practices for developing with this project
in Cursor.
## Project Structure
```
absurd-sql/
├── src/ # Source code
@ -20,36 +30,45 @@ absurd-sql/
## Development Rules
### 1. Worker Thread Requirements
- All SQL operations MUST be performed in a worker thread
- Main thread should only handle worker initialization and communication
- Never block the main thread with database operations
### 2. Code Organization
- Keep worker code in separate files (e.g., `*.worker.js`)
- Use ES modules for imports/exports
- Follow the project's existing module structure
### 3. Required Headers
When developing locally or deploying, ensure these headers are set:
```
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
```
### 4. Browser Compatibility
- Primary target: Modern browsers with SharedArrayBuffer support
- Fallback mode: Safari (with limitations)
- Always test in both modes
### 5. Database Configuration
Recommended database settings:
```sql
PRAGMA journal_mode=MEMORY;
PRAGMA page_size=8192; -- Optional, but recommended
```
### 6. Development Workflow
1. Install dependencies:
```bash
yarn add @jlongster/sql.js absurd-sql
```
@ -60,17 +79,20 @@ PRAGMA page_size=8192; -- Optional, but recommended
- `yarn serve` - Start development server
### 7. Testing Guidelines
- Write tests for both SharedArrayBuffer and fallback modes
- Use Jest for testing
- Include performance benchmarks for critical operations
### 8. Performance Considerations
- Use bulk operations when possible
- Monitor read/write performance
- Consider using transactions for multiple operations
- Avoid unnecessary database connections
### 9. Error Handling
- Implement proper error handling for:
- Worker initialization failures
- Database connection issues
@ -78,18 +100,21 @@ PRAGMA page_size=8192; -- Optional, but recommended
- Storage quota exceeded scenarios
### 10. Security Best Practices
- Never expose database operations directly to the client
- Validate all SQL queries
- Implement proper access controls
- Handle sensitive data appropriately
### 11. Code Style
- Follow ESLint configuration
- Use async/await for asynchronous operations
- Document complex database operations
- Include comments for non-obvious optimizations
### 12. Debugging
- Use `jest-debug` for debugging tests
- Monitor IndexedDB usage in browser dev tools
- Check worker communication in console
@ -98,6 +123,7 @@ PRAGMA page_size=8192; -- Optional, but recommended
## Common Patterns
### Worker Initialization
```javascript
// Main thread
import { initBackend } from 'absurd-sql/dist/indexeddb-main-thread';
@ -109,6 +135,7 @@ function init() {
```
### Database Setup
```javascript
// Worker thread
import initSqlJs from '@jlongster/sql.js';
@ -130,6 +157,7 @@ async function setupDatabase() {
## Troubleshooting
### Common Issues
1. SharedArrayBuffer not available
- Check COOP/COEP headers
- Verify browser support
@ -146,7 +174,20 @@ async function setupDatabase() {
- Verify transaction usage
## Resources
- [Project Demo](https://priceless-keller-d097e5.netlify.app/)
- [Example Project](https://github.com/jlongster/absurd-example-project)
- [Blog Post](https://jlongster.com/future-sql-web)
- [SQL.js Documentation](https://github.com/sql-js/sql.js/)
---
**Status**: Active database development guidelines
**Priority**: High
**Estimated Effort**: Ongoing reference
**Dependencies**: Absurd SQL, SQL.js, IndexedDB
**Stakeholders**: Development team, Database team
- [Project Demo](https://priceless-keller-d097e5.netlify.app/)
- [Example Project](https://github.com/jlongster/absurd-example-project)
- [Blog Post](https://jlongster.com/future-sql-web)
- [SQL.js Documentation](https://github.com/sql-js/sql.js/)
- [SQL.js Documentation](https://github.com/sql-js/sql.js/)

5
.cursor/rules/database/legacy_dexie.mdc

@ -2,4 +2,7 @@
globs: **/databaseUtil.ts,**/AccountViewView.vue,**/ContactsView.vue,**/DatabaseMigration.vue,**/NewIdentifierView.vue
alwaysApply: false
---
All references in the codebase to Dexie apply only to migration from IndexedDb to Sqlite and will be deprecated in future versions.
# What to do with Dexie
All references in the codebase to Dexie apply only to migration from IndexedDb to
Sqlite and will be deprecated in future versions.

55
.cursor/rules/development/type_safety_guide.mdc

@ -1,5 +1,5 @@
---
globs: **/src/**/*,**/scripts/**/*,**/electron/**/*
description: when dealing with types and Typesript
alwaysApply: false
---
```json
@ -15,8 +15,8 @@ alwaysApply: false
# TypeScript Type Safety Guidelines
**Author**: Matthew Raymer
**Date**: 2025-08-16
**Status**: 🎯 **ACTIVE**
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Type safety enforcement
## Overview
@ -28,7 +28,8 @@ Practical rules to keep TypeScript strict and predictable. Minimize exceptions.
- Use explicit types. If unknown, use `unknown` and **narrow** via guards.
2. **Error handling uses guards**
- Reuse guards from `src/interfaces/**` (e.g., `isDatabaseError`, `isApiError`).
- Reuse guards from `src/interfaces/**` (e.g., `isDatabaseError`,
`isApiError`).
- Catch with `unknown`; never cast to `any`.
3. **Dynamic property access is type‑safe**
@ -43,6 +44,7 @@ Practical rules to keep TypeScript strict and predictable. Minimize exceptions.
## Type Safety Enforcement
### Core Type Safety Rules
<<<<<<< HEAD
- **No `any` Types**: Use explicit types or `unknown` with proper type guards
- **Error Handling Uses Guards**: Implement and reuse type guards from `src/interfaces/**`
- **Dynamic Property Access**: Use `keyof` + `in` checks for type-safe property access
@ -56,13 +58,38 @@ Practical rules to keep TypeScript strict and predictable. Minimize exceptions.
- **Avoid Type Assertions**: Replace `as any` with proper type guards and interfaces
- **Narrow Types Properly**: Use type guards to narrow `unknown` types safely
- **Document Type Decisions**: Explain complex type structures and their purpose
=======
- **No `any` Types**: Use explicit types or `unknown` with proper type guards
- **Error Handling Uses Guards**: Implement and reuse type guards from
`src/interfaces/**`
- **Dynamic Property Access**: Use `keyof` + `in` checks for type-safe
property access
### Type Guard Patterns
- **API Errors**: Use `isApiError(error)` guards for API error handling
- **Database Errors**: Use `isDatabaseError(error)` guards for database
operations
- **Axios Errors**: Implement `isAxiosError(error)` guards for HTTP error
handling
### Implementation Guidelines
- **Avoid Type Assertions**: Replace `as any` with proper type guards and
interfaces
- **Narrow Types Properly**: Use type guards to narrow `unknown` types
safely
- **Document Type Decisions**: Explain complex type structures and their
purpose
>>>>>>> master
## Minimal Special Cases (document in PR when used)
- **Vue refs / instances**: Use `ComponentPublicInstance` or specific component
types for dynamic refs.
- **3rd‑party libs without types**: Narrow immediately to a **known interface**;
do not leave `any` hanging.
- **Vue refs / instances**: Use `ComponentPublicInstance` or specific
component types for dynamic refs.
- **3rd‑party libs without types**: Narrow immediately to a **known
interface**; do not leave `any` hanging.
## Patterns (short)
@ -123,3 +150,15 @@ const keys = Object.keys(newSettings).filter(
- TS Handbook — https://www.typescriptlang.org/docs/
- TS‑ESLint — https://typescript-eslint.io/rules/
- Vue 3 + TS — https://vuejs.org/guide/typescript/
---
**Status**: Active type safety guidelines
**Priority**: High
**Estimated Effort**: Ongoing reference
**Dependencies**: TypeScript, ESLint, Vue 3
**Stakeholders**: Development team
- TS Handbook — https://www.typescriptlang.org/docs/
- TS‑ESLint — https://typescript-eslint.io/rules/
- Vue 3 + TS — https://vuejs.org/guide/typescript/

8
.cursor/rules/features/camera-implementation.mdc

@ -1,13 +1,13 @@
---
description:
globs:
description: when dealing with cameras in the application
alwaysApply: false
---
# Camera Implementation Documentation
## Overview
This document describes how camera functionality is implemented across the TimeSafari application. The application uses cameras for two main purposes:
This document describes how camera functionality is implemented across the
TimeSafari application. The application uses cameras for two main purposes:
1. QR Code scanning
2. Photo capture
@ -219,4 +219,4 @@ Desktop implementation (currently unimplemented).
- Multiple browsers
- iOS and Android devices
- Desktop platforms
- Various network conditions
- Various network conditions

81
.cursor/rules/investigation_report_example.mdc

@ -1,76 +1,117 @@
# Investigation Report Example
**Author**: Matthew Raymer
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Investigation methodology example
## Investigation — Registration Dialog Test Flakiness
## Objective
Identify root cause of flaky tests related to registration dialogs in contact import scenarios.
Identify root cause of flaky tests related to registration dialogs in contact
import scenarios.
## System Map
- User action → ContactInputForm → ContactsView.addContact() → handleRegistrationPrompt()
- User action → ContactInputForm → ContactsView.addContact() →
handleRegistrationPrompt()
- setTimeout(1000ms) → Modal dialog → User response → Registration API call
- Test execution → Wait for dialog → Assert dialog content → Click response button
- Test execution → Wait for dialog → Assert dialog content → Click response
button
## Findings (Evidence)
- **1-second timeout causes flakiness** — evidence: `src/views/ContactsView.vue:971-1000`; setTimeout(..., 1000) in handleRegistrationPrompt()
- **Import flow bypasses dialogs** — evidence: `src/views/ContactImportView.vue:500-520`; importContacts() calls $insertContact() directly, no handleRegistrationPrompt()
- **Dialog only appears in direct add flow** — evidence: `src/views/ContactsView.vue:774-800`; addContact() calls handleRegistrationPrompt() after database insert
- **1-second timeout causes flakiness** — evidence:
`src/views/ContactsView.vue:971-1000`; setTimeout(..., 1000) in
handleRegistrationPrompt()
- **Import flow bypasses dialogs** — evidence:
`src/views/ContactImportView.vue:500-520`; importContacts() calls
$insertContact() directly, no handleRegistrationPrompt()
- **Dialog only appears in direct add flow** — evidence:
`src/views/ContactsView.vue:774-800`; addContact() calls
handleRegistrationPrompt() after database insert
## Hypotheses & Failure Modes
- H1: 1-second timeout makes dialog appearance unpredictable; would fail when tests run faster than 1000ms
- H2: Test environment timing differs from development; watch for CI vs local test differences
- H1: 1-second timeout makes dialog appearance unpredictable; would fail when
tests run faster than 1000ms
- H2: Test environment timing differs from development; watch for CI vs local
test differences
## Corrections
- Updated: "Multiple dialogs interfere with imports" → "Import flow never triggers dialogs - they only appear in direct contact addition"
- Updated: "Complex batch registration needed" → "Simple timeout removal and test mode flag sufficient"
- Updated: "Multiple dialogs interfere with imports" → "Import flow never
triggers dialogs - they only appear in direct contact addition"
- Updated: "Complex batch registration needed" → "Simple timeout removal and
test mode flag sufficient"
## Diagnostics (Next Checks)
- [ ] Repro on CI environment vs local
- [ ] Measure actual dialog appearance timing
- [ ] Test with setTimeout removed
- [ ] Verify import flow doesn't call handleRegistrationPrompt
## Risks & Scope
- Impacted: Contact addition tests, registration workflow tests; Data: None; Users: Test suite reliability
- Impacted: Contact addition tests, registration workflow tests; Data: None;
Users: Test suite reliability
## Decision / Next Steps
- Owner: Development Team; By: 2025-01-28
- Action: Remove 1-second timeout + add test mode flag; Exit criteria: Tests pass consistently
- Action: Remove 1-second timeout + add test mode flag; Exit criteria: Tests
pass consistently
## References
- `src/views/ContactsView.vue:971-1000`
- `src/views/ContactImportView.vue:500-520`
- `src/views/ContactsView.vue:774-800`
## Competence Hooks
- Why this works: Code path tracing revealed separate execution flows, evidence disproved initial assumptions
- Common pitfalls: Assuming related functionality without tracing execution paths, over-engineering solutions to imaginary problems
- Next skill: Learn to trace code execution before proposing architectural changes
- Teach-back: "What evidence shows that contact imports bypass registration dialogs?"
---
- Why this works: Code path tracing revealed separate execution flows,
evidence disproved initial assumptions
- Common pitfalls: Assuming related functionality without tracing execution
paths, over-engineering solutions to imaginary problems
- Next skill: Learn to trace code execution before proposing architectural
changes
- Teach-back: "What evidence shows that contact imports bypass registration
dialogs?"
## Key Learning Points
### Evidence-First Approach
This investigation demonstrates the importance of:
1. **Tracing actual code execution** rather than making assumptions
2. **Citing specific evidence** with file:line references
3. **Validating problem scope** before proposing solutions
4. **Considering simpler alternatives** before complex architectural changes
### Code Path Tracing Value
By tracing the execution paths, we discovered:
- Import flow and direct add flow are completely separate
- The "multiple dialog interference" problem didn't exist
- A simple timeout removal would solve the actual issue
### Prevention of Over-Engineering
The investigation prevented:
- Unnecessary database schema changes
- Complex batch registration systems
- Migration scripts for non-existent problems
- Architectural changes based on assumptions
description:
globs:
alwaysApply: false
---
**Status**: Active investigation methodology
**Priority**: High
**Estimated Effort**: Ongoing reference
**Dependencies**: software_development.mdc
**Stakeholders**: Development team, QA team

13
.cursor/rules/logging_standards.mdc

@ -1,11 +1,7 @@
---
globs: *.vue,*.ts,*.tsx
alwaysApply: false
---
# Agent Contract — TimeSafari Logging (Unified, MANDATORY)
**Author**: Matthew Raymer
**Date**: 2025-08-15
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Mandatory logging standards
## Overview
@ -220,6 +216,7 @@ logger.debug('[FeedFilters] Filter toggled', this.hasVisibleDid);
---
**Status**: Active and enforced
**Last Updated**: 2025-08-15 08:11:46Z
**Version**: 1.0
**Maintainer**: Matthew Raymer
**Priority**: Critical
**Estimated Effort**: Ongoing reference
**Dependencies**: TimeSafari logger utility
**Stakeholders**: Development team, Code review team

4
.cursor/rules/research_diagnostic.mdc

@ -31,6 +31,7 @@ steps—**not** code changes.
## Enhanced with Software Development Ruleset
When investigating software issues, also apply:
- **Code Path Tracing**: Required for technical investigations
- **Evidence Validation**: Ensure claims are code-backed
- **Solution Complexity Assessment**: Justify architectural changes
@ -117,6 +118,7 @@ Copy/paste and fill:
## Code Path Tracing (Required for Software Investigations)
Before proposing solutions, trace the actual execution path:
- [ ] **Entry Points**: Identify where the flow begins (user action, API call, etc.)
- [ ] **Component Flow**: Map which components/methods are involved
- [ ] **Data Path**: Track how data moves through the system
@ -136,11 +138,13 @@ Before proposing solutions, trace the actual execution path:
## Integration with Other Rulesets
### With software_development.mdc
- **Enhanced Evidence Validation**: Use code path tracing for technical investigations
- **Architecture Assessment**: Apply complexity justification to proposed solutions
- **Impact Analysis**: Assess effects on existing systems before recommendations
### With base_context.mdc
- **Competence Building**: Focus on technical investigation skills
- **Collaboration**: Structure outputs for team review and discussion

101
.cursor/rules/software_development.mdc

@ -1,66 +1,144 @@
# Software Development Ruleset
**Author**: Matthew Raymer
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Core development guidelines
## Purpose
Specialized guidelines for software development tasks including code review, debugging, architecture decisions, and testing.
Specialized guidelines for software development tasks including code review,
debugging, architecture decisions, and testing.
## Core Principles
### 1. Evidence-First Development
- **Code Citations Required**: Always cite specific file:line references when making claims
- **Execution Path Tracing**: Trace actual code execution before proposing architectural changes
- **Code Citations Required**: Always cite specific file:line references when
making claims
- **Execution Path Tracing**: Trace actual code execution before proposing
architectural changes
- **Assumption Validation**: Flag assumptions as "assumed" vs "evidence-based"
### 2. Code Review Standards
- **Trace Before Proposing**: Always trace execution paths before suggesting changes
- **Trace Before Proposing**: Always trace execution paths before suggesting
changes
- **Evidence Over Inference**: Prefer code citations over logical deductions
- **Scope Validation**: Confirm the actual scope of problems before proposing solutions
- **Scope Validation**: Confirm the actual scope of problems before proposing
solutions
### 3. Problem-Solution Validation
- **Problem Scope**: Does the solution address the actual problem?
- **Evidence Alignment**: Does the solution match the evidence?
- **Complexity Justification**: Is added complexity justified by real needs?
- **Alternative Analysis**: What simpler solutions were considered?
### 4. Dependency Management & Environment Validation
- **Pre-build Validation**: Always validate critical dependencies before executing
build scripts
- **Environment Consistency**: Ensure team members have identical development
environments
- **Dependency Verification**: Check that required packages are installed and
accessible
- **Path Resolution**: Use `npx` for local dependencies to avoid PATH issues
## Required Workflows
### Before Proposing Changes
- [ ] **Code Path Tracing**: Map execution flow from entry to exit
- [ ] **Evidence Collection**: Gather specific code citations and logs
- [ ] **Assumption Surfacing**: Identify what's proven vs. inferred
- [ ] **Scope Validation**: Confirm the actual extent of the problem
- [ ] **Dependency Validation**: Verify all required dependencies are available
and accessible
### During Solution Design
- [ ] **Evidence Alignment**: Ensure solution addresses proven problems
- [ ] **Complexity Assessment**: Justify any added complexity
- [ ] **Alternative Evaluation**: Consider simpler approaches first
- [ ] **Impact Analysis**: Assess effects on existing systems
- [ ] **Environment Impact**: Assess how changes affect team member setups
## Software-Specific Competence Hooks
### Evidence Validation
- **"What code path proves this claim?"**
- **"How does data actually flow through the system?"**
- **"What am I assuming vs. what can I prove?"**
### Code Tracing
- **"What's the execution path from user action to system response?"**
- **"Which components actually interact in this scenario?"**
- **"Where does the data originate and where does it end up?"**
### Architecture Decisions
- **"What evidence shows this change is necessary?"**
- **"What simpler solution could achieve the same goal?"**
- **"How does this change affect the existing system architecture?"**
### Dependency & Environment Management
- **"What dependencies does this feature require and are they properly
declared?"**
- **"How will this change affect team member development environments?"**
- **"What validation can we add to catch dependency issues early?"**
## Dependency Management Best Practices
### Pre-build Validation
- **Check Critical Dependencies**: Validate essential tools before executing build
scripts
- **Use npx for Local Dependencies**: Prefer `npx tsx` over direct `tsx` to
avoid PATH issues
- **Environment Consistency**: Ensure all team members have identical dependency
versions
### Common Pitfalls
- **Missing npm install**: Team members cloning without running `npm install`
- **PATH Issues**: Direct command execution vs. npm script execution differences
- **Version Mismatches**: Different Node.js/npm versions across team members
### Validation Strategies
- **Dependency Check Scripts**: Implement pre-build validation for critical
dependencies
- **Environment Requirements**: Document and enforce minimum Node.js/npm versions
- **Onboarding Checklist**: Standardize team member setup procedures
### Error Messages and Guidance
- **Specific Error Context**: Provide clear guidance when dependency issues occur
- **Actionable Solutions**: Direct users to specific commands (`npm install`,
`npm run check:dependencies`)
- **Environment Diagnostics**: Implement comprehensive environment validation
tools
### Build Script Enhancements
- **Early Validation**: Check dependencies before starting build processes
- **Graceful Degradation**: Continue builds when possible but warn about issues
- **Helpful Tips**: Remind users about dependency management best practices
## Integration with Other Rulesets
### With base_context.mdc
- Inherits generic competence principles
- Adds software-specific evidence requirements
- Maintains collaboration and learning focus
### With research_diagnostic.mdc
- Enhances investigation with code path tracing
- Adds evidence validation to diagnostic workflow
- Strengthens problem identification accuracy
@ -68,6 +146,7 @@ Specialized guidelines for software development tasks including code review, deb
## Usage Guidelines
### When to Use This Ruleset
- Code reviews and architectural decisions
- Bug investigation and debugging
- Performance optimization
@ -75,11 +154,13 @@ Specialized guidelines for software development tasks including code review, deb
- Testing strategy development
### When to Combine with Others
- **base_context + software_development**: General development tasks
- **research_diagnostic + software_development**: Technical investigations
- **All three**: Complex architectural decisions or major refactoring
## Self-Check (model, before responding)
- [ ] Code path traced and documented
- [ ] Evidence cited with specific file:line references
- [ ] Assumptions clearly flagged as proven vs. inferred
@ -90,6 +171,7 @@ Specialized guidelines for software development tasks including code review, deb
- [ ] Environment impact assessed for team members
- [ ] Pre-build validation implemented where appropriate
<<<<<<< HEAD
## Additional Core Principles
### 4. Dependency Management & Environment Validation
@ -142,3 +224,12 @@ Specialized guidelines for software development tasks including code review, deb
- **Narrow Types Properly**: Use type guards to narrow `unknown` types safely
- **Document Type Decisions**: Explain complex type structures and their purpose
=======
---
**Status**: Active development guidelines
**Priority**: High
**Estimated Effort**: Ongoing
**Dependencies**: base_context.mdc, research_diagnostic.mdc
**Stakeholders**: Development team
>>>>>>> master

329
.cursor/rules/time.mdc

@ -0,0 +1,329 @@
---
alwaysApply: true
---
# Time Handling in Development Workflow
**Author**: Matthew Raymer
**Date**: 2025-08-17
**Status**: 🎯 **ACTIVE** - Production Ready
## Overview
This guide establishes **how time should be referenced and used** across the
development workflow. It is not tied to any one project, but applies to **all
feature development, issue investigations, ADRs, and documentation**.
## General Principles
- **Explicit over relative**: Always prefer absolute dates (`2025-08-17`) over
relative references like "last week."
- **ISO 8601 Standard**: Use `YYYY-MM-DD` format for all date references in
docs, issues, ADRs, and commits.
- **Time zones**: Default to **UTC** unless explicitly tied to user-facing
behavior.
- **Precision**: Only specify as much precision as needed (date vs. datetime vs.
timestamp).
- **Consistency**: Align time references across ADRs, commits, and investigation
reports.
## In Documentation & ADRs
- Record decision dates using **absolute ISO dates**.
- For ongoing timelines, state start and end explicitly (e.g., `2025-08-01` →
`2025-08-17`).
- Avoid ambiguous terms like *recently*, *last month*, or *soon*.
- For time-based experiments (e.g., A/B tests), always include:
- Start date
- Expected duration
- Review date checkpoint
## In Code & Commits
- Use **UTC timestamps** in logs, DB migrations, and serialized formats.
- In commits, link changes to **date-bound ADRs or investigation docs**.
- For migrations, include both **applied date** and **intended version window**.
- Use constants for known fixed dates; avoid hardcoding arbitrary strings.
## In Investigations & Research
- Capture **when** an issue occurred (absolute time or version tag).
- When describing failures: note whether they are **time-sensitive** (e.g., after
migrations, cache expirations).
- Record diagnostic timelines in ISO format (not relative).
- For performance regressions, annotate both **baseline timeframe** and
**measurement timeframe**.
## Collaboration Hooks
- During reviews, verify **time references are clear, absolute, and
standardized**.
- In syncs, reframe relative terms ("this week") into shared absolute
references.
- Tag ADRs with both **date created** and **review by** checkpoints.
## Self-Check Before Submitting
- [ ] Did I check the time using the **developer's actual system time and
timezone**?
- [ ] Am I using absolute ISO dates?
- [ ] Is UTC assumed unless specified otherwise?
- [ ] Did I avoid ambiguous relative terms?
- [ ] If duration matters, did I specify both start and end?
- [ ] For future work, did I include a review/revisit date?
## Real-Time Context in Developer Interactions
- The model must always resolve **"current time"** using the **developer's
actual system time and timezone**.
- When generating timestamps (e.g., in investigation logs, ADRs, or examples),
the model should:
- Use the **developer's current local time** by default.
- Indicate the timezone explicitly (e.g., `2025-08-17T10:32-05:00`).
- Optionally provide UTC alongside if context requires cross-team clarity.
- When interpreting relative terms like *now*, *today*, *last week*:
- Resolve them against the **developer's current time**.
- Convert them into **absolute ISO-8601 values** in the output.
## LLM Time Checking Instructions
**CRITICAL**: The LLM must actively query the system for current time rather
than assuming or inventing times.
### How to Check Current Time
#### 1. **Query System Time (Required)**
- **Always start** by querying the current system time using available tools
- **Never assume** what the current time is
- **Never use** placeholder values like "current time" or "now"
#### 2. **Available Time Query Methods**
- **System Clock**: Use `date` command or equivalent system time function
- **Programming Language**: Use language-specific time functions (e.g.,
`Date.now()`, `datetime.now()`)
- **Environment Variables**: Check for time-related environment variables
- **API Calls**: Use time service APIs if available
#### 3. **Required Time Information**
When querying time, always obtain:
- **Current Date**: YYYY-MM-DD format
- **Current Time**: HH:MM:SS format (24-hour)
- **Timezone**: Current system timezone or UTC offset
- **UTC Equivalent**: Convert local time to UTC for cross-team clarity
#### 4. **Time Query Examples**
```bash
# Example: Query system time
$ date
# Expected output: Mon Aug 17 10:32:45 EDT 2025
# Example: Query UTC time
$ date -u
# Expected output: Mon Aug 17 14:32:45 UTC 2025
```
```python
# Example: Python time query
import datetime
current_time = datetime.datetime.now()
utc_time = datetime.datetime.utcnow()
print(f"Local: {current_time}")
print(f"UTC: {utc_time}")
```
```javascript
// Example: JavaScript time query
const now = new Date();
const utc = new Date().toISOString();
console.log(`Local: ${now}`);
console.log(`UTC: ${utc}`);
```
#### 5. **LLM Time Checking Workflow**
1. **Query**: Actively query system for current time
2. **Validate**: Confirm time data is reasonable and current
3. **Format**: Convert to ISO 8601 format
4. **Context**: Provide both local and UTC times when helpful
5. **Document**: Show the source of time information
#### 6. **Error Handling for Time Queries**
- **If time query fails**: Ask user for current time or use "unknown time"
with explanation
- **If timezone unclear**: Default to UTC and ask for clarification
- **If time seems wrong**: Verify with user before proceeding
- **Always log**: Record when and how time was obtained
#### 7. **Time Query Verification**
Before using queried time, verify:
- [ ] Time is recent (within last few minutes)
- [ ] Timezone information is available
- [ ] UTC conversion is accurate
- [ ] Format follows ISO 8601 standard
## Model Behavior Rules
- **Never invent a "fake now"**: All "current time" references must come from
the real system clock available at runtime.
- **Check developer time zone**: If ambiguous, ask for clarification (e.g.,
"Should I use UTC or your local timezone?").
- **Format for clarity**:
- Local time: `YYYY-MM-DDTHH:mm±hh:mm`
- UTC equivalent (if needed): `YYYY-MM-DDTHH:mmZ`
## Examples
### Good
- "Feature flag rollout started on `2025-08-01` and will be reviewed on
`2025-08-21`."
- "Migration applied on `2025-07-15T14:00Z`."
- "Issue reproduced on `2025-08-17T09:00-05:00 (local)` /
`2025-08-17T14:00Z (UTC)`."
### Bad
- "Feature flag rolled out last week."
- "Migration applied recently."
- "Now is August, so we assume this was last month."
### More Examples
#### Issue Reports
- ✅ **Good**: "User reported login failure at `2025-08-17T14:30:00Z`. Issue
persisted until `2025-08-17T15:45:00Z`."
- ❌ **Bad**: "User reported login failure earlier today. Issue lasted for a
while."
#### Release Planning
- ✅ **Good**: "Feature X scheduled for release on `2025-08-25`. Testing
window: `2025-08-20` to `2025-08-24`."
- ❌ **Bad**: "Feature X will be released next week after testing."
#### Performance Monitoring
- ✅ **Good**: "Baseline performance measured on `2025-08-10T09:00:00Z`.
Regression detected on `2025-08-15T14:00:00Z`."
- ❌ **Bad**: "Performance was good last week but got worse this week."
## Technical Implementation Notes
### UTC Storage Principle
- **Store all timestamps in UTC** in databases, logs, and serialized formats
- **Convert to local time only for user display**
- **Use ISO 8601 format** for all storage: `YYYY-MM-DDTHH:mm:ss.sssZ`
### Common Implementation Patterns
#### Database Storage
```sql
-- ✅ Good: Store in UTC
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
-- ❌ Bad: Store in local time
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
```
#### API Responses
```json
// ✅ Good: Include both UTC and local time
{
"eventTime": "2025-08-17T14:00:00Z",
"localTime": "2025-08-17T10:00:00-04:00",
"timezone": "America/New_York"
}
// ❌ Bad: Only local time
{
"eventTime": "2025-08-17T10:00:00-04:00"
}
```
#### Logging
```python
# ✅ Good: Log in UTC with timezone info
logger.info(f"User action at {datetime.utcnow().isoformat()}Z (UTC)")
# ❌ Bad: Log in local time
logger.info(f"User action at {datetime.now()}")
```
### Timezone Handling Best Practices
#### 1. Always Store Timezone Information
- Include IANA timezone identifier (e.g., `America/New_York`)
- Store UTC offset at time of creation
- Handle daylight saving time transitions automatically
#### 2. User Display Considerations
- Convert UTC to user's preferred timezone
- Show timezone abbreviation when helpful
- Use relative time for recent events ("2 hours ago")
#### 3. Edge Case Handling
- **Daylight Saving Time**: Use timezone-aware libraries
- **Leap Seconds**: Handle gracefully (rare but important)
- **Invalid Times**: Validate before processing
### Common Mistakes to Avoid
#### 1. Timezone Confusion
- ❌ **Don't**: Assume server timezone is user timezone
- ✅ **Do**: Always convert UTC to user's local time for display
#### 2. Format Inconsistency
- ❌ **Don't**: Mix different time formats in the same system
- ✅ **Do**: Standardize on ISO 8601 for all storage
#### 3. Relative Time References
- ❌ **Don't**: Use relative terms in persistent storage
- ✅ **Do**: Convert relative terms to absolute timestamps immediately
## References
- [ISO 8601 Date and Time Standard](https://en.wikipedia.org/wiki/ISO_8601)
- [IANA Timezone Database](https://www.iana.org/time-zones)
- [ADR Template](./adr_template.md)
- [Research & Diagnostic Workflow](./research_diagnostic.mdc)
---
**Rule of Thumb**: Every time reference in development artifacts should be
**clear in 6 months without context**, and aligned to the **developer's actual
current time**.
**Technical Rule of Thumb**: **Store in UTC, display in local time, always
include timezone context.**
---
**Status**: Active
**Version**: 1.0
**Maintainer**: Matthew Raymer
**Next Review**: 2025-09-17

321
.cursor/rules/workflow/version_control.mdc

@ -1,102 +1,306 @@
---
alwaysApply: true
description: interacting with git
alwaysApply: false
---
# Directive: Peaceful Co-Existence with Developers
**Author**: Matthew Raymer
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Version control guidelines
## 1) Version-Control Ownership
* **MUST NOT** run `git add`, `git commit`, or any write action.
* **MUST** leave staging/committing to the developer.
- **MUST NOT** run `git add`, `git commit`, or any write action.
- **MUST** leave staging/committing to the developer.
## 2) Source of Truth for Commit Text
* **MUST** derive messages **only** from:
* files **staged** for commit (primary), and
* files **awaiting staging** (context).
* **MUST** use the **diffs** to inform content.
* **MUST NOT** invent changes or imply work not present in diffs.
- **MUST** derive messages **only** from:
- files **staged** for commit (primary), and
- files **awaiting staging** (context).
- **MUST** use the **diffs** to inform content.
- **MUST NOT** invent changes or imply work not present in diffs.
## 3) Mandatory Preview Flow
* **ALWAYS** present, before any real commit:
- **ALWAYS** present, before any real commit:
- file list + brief per-file notes,
- a **draft commit message** (copy-paste ready),
- nothing auto-applied.
* file list + brief per-file notes,
* a **draft commit message** (copy-paste ready),
* nothing auto-applied.
## 4) Version Synchronization Requirements
---
- **MUST** check for version changes in `package.json` before committing
- **MUST** ensure `CHANGELOG.md` is updated when `package.json` version
changes
- **MUST** validate version format consistency between both files
- **MUST** include version bump commits in changelog with proper semantic
versioning
### Version Sync Checklist (Before Commit)
- [ ] `package.json` version matches latest `CHANGELOG.md` entry
- [ ] New version follows semantic versioning
(MAJOR.MINOR.PATCH[-PRERELEASE])
- [ ] Changelog entry includes all significant changes since last version
- [ ] Version bump commit message follows `build(version): bump to X.Y.Z`
format
- [ ] Breaking changes properly documented with migration notes
- [ ] Alert developer in chat message that version has been updated
# Commit Message Format (Normative)
### Version Change Detection
## A. Subject Line (required)
- **Check for version changes** in staged/unstaged `package.json`
- **Alert developer** if version changed but changelog not updated
- **Suggest changelog update** with proper format and content
- **Validate semantic versioning** compliance
### Implementation Notes
- **Version Detection**: Compare `package.json` version field with latest
changelog entry
- **Semantic Validation**: Ensure version follows `X.Y.Z[-PRERELEASE]`
format
- **Changelog Format**: Follow [Keep a Changelog](https://keepachangelog.com/)
standards
- **Breaking Changes**: Use `!` in commit message and `BREAKING CHANGE:`
in changelog
- **Pre-release Versions**: Include beta/alpha/rc suffixes in both files
consistently
## Commit Message Format (Normative)
### A. Subject Line (required)
```
<type>(<scope>)<!>: <summary>
```
* **type** (lowercase, Conventional Commits): `feat|fix|refactor|perf|docs|test|build|chore|ci|revert`
* **scope**: optional module/package/area (e.g., `api`, `ui/login`, `db`)
* **!**: include when a breaking change is introduced
* **summary**: imperative mood, ≤ 72 chars, no trailing period
- **type** (lowercase, Conventional Commits):
`feat|fix|refactor|perf|docs|test|build|chore|ci|revert`
- **scope**: optional module/package/area (e.g., `api`, `ui/login`, `db`)
- **!**: include when a breaking change is introduced
- **summary**: imperative mood, ≤ 72 chars, no trailing period
**Examples**
* `fix(api): handle null token in refresh path`
* `feat(ui/login)!: require OTP after 3 failed attempts`
- `fix(api): handle null token in refresh path`
- `feat(ui/login)!: require OTP after 3 failed attempts`
## B. Body (optional, when it adds non-obvious value)
### B. Body (optional, when it adds non-obvious value)
* One blank line after subject.
* Wrap at \~72 chars.
* Explain **what** and **why**, not line-by-line “how”.
* Include brief notes like tests passing or TS/lint issues resolved **only if material**.
- One blank line after subject.
- Wrap at ~72 chars.
- Explain **what** and **why**, not line-by-line "how".
- Include brief notes like tests passing or TS/lint issues resolved
**only if material**.
**Body checklist**
* [ ] Problem/symptom being addressed
* [ ] High-level approach or rationale
* [ ] Risks, tradeoffs, or follow-ups (if any)
- [ ] Problem/symptom being addressed
- [ ] High-level approach or rationale
- [ ] Risks, tradeoffs, or follow-ups (if any)
## C. Footer (optional)
### C. Footer (optional)
* Issue refs: `Closes #123`, `Refs #456`
* Breaking change (alternative to `!`):
- Issue refs: `Closes #123`, `Refs #456`
- Breaking change (alternative to `!`):
`BREAKING CHANGE: <impact + migration note>`
* Authors: `Co-authored-by: Name <email>`
* Security: `CVE-XXXX-YYYY: <short note>` (if applicable)
---
- Authors: `Co-authored-by: Name <email>`
- Security: `CVE-XXXX-YYYY: <short note>` (if applicable)
## Content Guidance
### Include (when relevant)
* Specific fixes/features delivered
* Symptoms/problems fixed
* Brief note that tests passed or TS/lint errors resolved
- Specific fixes/features delivered
- Symptoms/problems fixed
- Brief note that tests passed or TS/lint errors resolved
### Avoid
* Vague: *improved, enhanced, better*
* Trivialities: tiny docs, one-liners, pure lint cleanups (separate, focused commits if needed)
* Redundancy: generic blurbs repeated across files
* Multi-purpose dumps: keep commits **narrow and focused**
* Long explanations that good inline code comments already cover
- Vague: *improved, enhanced, better*
- Trivialities: tiny docs, one-liners, pure lint cleanups (separate,
focused commits if needed)
- Redundancy: generic blurbs repeated across files
- Multi-purpose dumps: keep commits **narrow and focused**
- Long explanations that good inline code comments already cover
**Guiding Principle:** Let code and inline docs speak. Use commits to
highlight what isn't obvious.
## Copy-Paste Templates
### Minimal (no body)
```text
<type>(<scope>): <summary>
```
### Standard (with body & footer)
```text
<type>(<scope>)<!>: <summary>
<why-this-change?>
<what-it-does?>
<risks-or-follow-ups?>
Closes #<id>
BREAKING CHANGE: <impact + migration>
Co-authored-by: <Name> <email>
```
## Assistant Output Checklist (before showing the draft)
**Guiding Principle:** Let code and inline docs speak. Use commits to highlight what isn’t obvious.
- [ ] List changed files + 1–2 line notes per file
- [ ] Provide **one** focused draft message (subject/body/footer)
- [ ] Subject ≤ 72 chars, imperative mood, correct `type(scope)!` syntax
- [ ] Body only if it adds non-obvious value
- [ ] No invented changes; aligns strictly with diffs
- [ ] Render as a single copy-paste block for the developer
---
# Copy-Paste Templates
**Status**: Active version control guidelines
**Priority**: High
**Estimated Effort**: Ongoing reference
**Dependencies**: git, package.json, CHANGELOG.md
**Stakeholders**: Development team, AI assistants
- [ ] No invented changes; aligns strictly with diffs
- [ ] Render as a single copy-paste block for the developer
## 1) Version-Control Ownership
- **MUST NOT** run `git add`, `git commit`, or any write action.
- **MUST** leave staging/committing to the developer.
## 2) Source of Truth for Commit Text
- **MUST** derive messages **only** from:
- files **staged** for commit (primary), and
- files **awaiting staging** (context).
- **MUST** use the **diffs** to inform content.
- **MUST NOT** invent changes or imply work not present in diffs.
## 3) Mandatory Preview Flow
- **ALWAYS** present, before any real commit:
- file list + brief per-file notes,
- a **draft commit message** (copy-paste ready),
- nothing auto-applied.
## 4) Version Synchronization Requirements
- **MUST** check for version changes in `package.json` before committing
- **MUST** ensure `CHANGELOG.md` is updated when `package.json` version
changes
- **MUST** validate version format consistency between both files
- **MUST** include version bump commits in changelog with proper semantic
versioning
### Version Sync Checklist (Before Commit)
- [ ] `package.json` version matches latest `CHANGELOG.md` entry
- [ ] New version follows semantic versioning
(MAJOR.MINOR.PATCH[-PRERELEASE])
- [ ] Changelog entry includes all significant changes since last version
- [ ] Version bump commit message follows `build(version): bump to X.Y.Z`
format
- [ ] Breaking changes properly documented with migration notes
- [ ] Alert developer in chat message that version has been updated
### Version Change Detection
- **Check for version changes** in staged/unstaged `package.json`
- **Alert developer** if version changed but changelog not updated
- **Suggest changelog update** with proper format and content
- **Validate semantic versioning** compliance
### Implementation Notes
- **Version Detection**: Compare `package.json` version field with latest
changelog entry
- **Semantic Validation**: Ensure version follows `X.Y.Z[-PRERELEASE]`
format
- **Changelog Format**: Follow [Keep a Changelog](https://keepachangelog.com/)
standards
- **Breaking Changes**: Use `!` in commit message and `BREAKING CHANGE:`
in changelog
- **Pre-release Versions**: Include beta/alpha/rc suffixes in both files
consistently
## Commit Message Format (Normative)
### A. Subject Line (required)
```
<type>(<scope>)<!>: <summary>
```
- **type** (lowercase, Conventional Commits):
`feat|fix|refactor|perf|docs|test|build|chore|ci|revert`
- **scope**: optional module/package/area (e.g., `api`, `ui/login`, `db`)
- **!**: include when a breaking change is introduced
- **summary**: imperative mood, ≤ 72 chars, no trailing period
**Examples**
- `fix(api): handle null token in refresh path`
- `feat(ui/login)!: require OTP after 3 failed attempts`
## Minimal (no body)
### B. Body (optional, when it adds non-obvious value)
- One blank line after subject.
- Wrap at ~72 chars.
- Explain **what** and **why**, not line-by-line "how".
- Include brief notes like tests passing or TS/lint issues resolved
**only if material**.
**Body checklist**
- [ ] Problem/symptom being addressed
- [ ] High-level approach or rationale
- [ ] Risks, tradeoffs, or follow-ups (if any)
### C. Footer (optional)
- Issue refs: `Closes #123`, `Refs #456`
- Breaking change (alternative to `!`):
`BREAKING CHANGE: <impact + migration note>`
- Authors: `Co-authored-by: Name <email>`
- Security: `CVE-XXXX-YYYY: <short note>` (if applicable)
## Content Guidance
### Include (when relevant)
- Specific fixes/features delivered
- Symptoms/problems fixed
- Brief note that tests passed or TS/lint errors resolved
### Avoid
- Vague: *improved, enhanced, better*
- Trivialities: tiny docs, one-liners, pure lint cleanups (separate,
focused commits if needed)
- Redundancy: generic blurbs repeated across files
- Multi-purpose dumps: keep commits **narrow and focused**
- Long explanations that good inline code comments already cover
**Guiding Principle:** Let code and inline docs speak. Use commits to
highlight what isn't obvious.
## Copy-Paste Templates
### Minimal (no body)
```text
<type>(<scope>): <summary>
```
## Standard (with body & footer)
### Standard (with body & footer)
```text
<type>(<scope>)<!>: <summary>
@ -110,13 +314,22 @@ BREAKING CHANGE: <impact + migration>
Co-authored-by: <Name> <email>
```
## Assistant Output Checklist (before showing the draft)
- [ ] List changed files + 1–2 line notes per file
- [ ] Provide **one** focused draft message (subject/body/footer)
- [ ] Subject ≤ 72 chars, imperative mood, correct `type(scope)!` syntax
- [ ] Body only if it adds non-obvious value
- [ ] No invented changes; aligns strictly with diffs
- [ ] Render as a single copy-paste block for the developer
---
# Assistant Output Checklist (before showing the draft)
**Status**: Active version control guidelines
**Priority**: High
**Estimated Effort**: Ongoing reference
**Dependencies**: git, package.json, CHANGELOG.md
**Stakeholders**: Development team, AI assistants
* [ ] List changed files + 1–2 line notes per file
* [ ] Provide **one** focused draft message (subject/body/footer)
* [ ] Subject ≤ 72 chars, imperative mood, correct `type(scope)!` syntax
* [ ] Body only if it adds non-obvious value
* [ ] No invented changes; aligns strictly with diffs
* [ ] Render as a single copy-paste block for the developer

182
doc/debug-hook-guide.md

@ -0,0 +1,182 @@
# TimeSafari Debug Hook Guide
**Complete Guide for Team Members**
**Date**: 2025-01-27
**Author**: Matthew Raymer
**Status**: ✅ **ACTIVE** - Ready for production use
## 🎯 Overview
A pre-commit hook that automatically detects and prevents debug code from reaching protected branches (master, main, production, release, stable). This ensures production code remains clean while allowing free development on feature branches.
## 🚀 Quick Installation
**From within the TimeSafari repository:**
```bash
./scripts/install-debug-hook.sh
```
This automatically installs, updates, and verifies the hook in your current
repository. **Note**: Hooks are not automatically installed - you must run this
script deliberately to enable debug code checking.
## 🔧 Manual Installation
**Copy files manually:**
```bash
cp scripts/git-hooks/pre-commit /path/to/your/repo/.git/hooks/
cp scripts/git-hooks/debug-checker.config /path/to/your/repo/.git/hooks/
chmod +x /path/to/your/repo/.git/hooks/pre-commit
```
## 📋 What Gets Installed
- **`pre-commit`** - Main hook script (executable)
- **`debug-checker.config`** - Configuration file
- **`README.md`** - Documentation and troubleshooting
**Note**: Hooks are stored in `scripts/git-hooks/` and must be deliberately
installed by each developer. They are not automatically active.
## 🎯 How It Works
1. **Deliberate Installation**: Hooks must be explicitly installed by each
developer
2. **Branch Detection**: Only runs on protected branches
3. **File Filtering**: Automatically skips tests, scripts, and documentation
4. **Pattern Matching**: Detects debug code using regex patterns
5. **Commit Prevention**: Blocks commits containing debug code
## 🔒 Installation Philosophy
**Why deliberate installation?**
- **Developer choice**: Each developer decides whether to use the hook
- **No forced behavior**: Hooks don't interfere with existing workflows
- **Local control**: Hooks are installed locally, not globally
- **Easy removal**: Can be uninstalled at any time
- **Team flexibility**: Some developers may prefer different tools
## 🌿 Branch Behavior
- **Protected branches** (master, main, production, release, stable): Hook runs automatically
- **Feature branches**: Hook is skipped, allowing free development with debug code
## 🔍 Debug Patterns Detected
- **Console statements**: `console.log`, `console.debug`, `console.error`
- **Template debug**: `Debug:`, `debug:` in Vue templates
- **Debug constants**: `DEBUG_`, `debug_` variables
- **HTML debug**: `<!-- debug` comments
- **Debug attributes**: `debug="true"` attributes
- **Vue debug**: `v-if="debug"`, `v-show="debug"`
- **Debug TODOs**: `TODO debug`, `FIXME debug`
## 📁 Files Automatically Skipped
- Test files: `*.test.js`, `*.spec.ts`, `*.test.vue`
- Scripts: `scripts/` directory
- Test directories: `test-*` directories
- Documentation: `docs/`, `*.md`, `*.txt`
- Config files: `*.json`, `*.yml`, `*.yaml`
- IDE files: `.cursor/` directory
## ✅ Verification
**After installation, verify it's working:**
```bash
# Check if files exist
ls -la .git/hooks/pre-commit
ls -la .git/hooks/debug-checker.config
# Test the hook manually
.git/hooks/pre-commit
# Test with actual commit
echo "console.log('test')" > test.vue
git add test.vue
git commit -m "test" # Should be blocked
```
## 📊 Example Output
```
❌ Debug code detected in staged files!
Branch: master
Files checked: 1
Errors found: 3
🚨 AccountViewView.vue: Found debug pattern 'console\.'
🚨 AccountViewView.vue: Found debug pattern 'Debug:'
🚨 AccountViewView.vue: Found debug pattern 'DEBUG_'
💡 Please remove debug code before committing to master
```
## ⚙️ Configuration
Edit `.git/hooks/debug-checker.config` to customize:
- **Protected branches**: Add/remove branches as needed
- **Debug patterns**: Customize what gets detected
- **Skip patterns**: Adjust file filtering rules
## 🚨 Emergency Bypass
If you absolutely need to commit debug code to a protected branch:
```bash
git commit --no-verify -m "emergency: debug code needed"
```
⚠️ **Warning**: This bypasses all pre-commit hooks. Use sparingly.
## 🔄 Updates
When the hook is updated in the main repository:
```bash
./scripts/install-debug-hook.sh
```
## 🚨 Troubleshooting
| Issue | Solution |
|-------|----------|
| Hook not running | Check if on protected branch, verify permissions |
| Permission denied | Run `chmod +x .git/hooks/pre-commit` |
| Files not found | Ensure you're copying from TimeSafari repo |
| False positives | Edit `debug-checker.config` to customize patterns |
## 🧪 Testing
A test script is available at `scripts/test-debug-hook.sh` to verify the hook works correctly.
## 💡 Best Practices
1. **Use feature branches** for development with debug code
2. **Use proper logging** instead of console statements (`logger.info`, `logger.debug`)
3. **Test thoroughly** before merging to protected branches
4. **Review commits** to ensure no debug code slips through
5. **Keep hooks updated** across all repositories
## 📚 Additional Resources
- **Hook documentation**: `scripts/git-hooks/README.md`
- **Configuration**: `scripts/git-hooks/debug-checker.config`
- **Test script**: `scripts/test-debug-hook.sh`
- **Installation script**: `scripts/install-debug-hook.sh`
## 🎯 Team Workflow
**Recommended setup:**
1. **Repository setup**: Include hook files in `.githooks/` directory
2. **Team onboarding**: Run installation script in each repo
3. **Updates**: Re-run installation script when hooks are updated
4. **Documentation**: Keep this guide updated
---
**Status**: Active and enforced
**Last Updated**: 2025-01-27
**Maintainer**: Matthew Raymer

103
scripts/git-hooks/README.md

@ -0,0 +1,103 @@
# TimeSafari Git Hooks
This directory contains custom Git hooks for the TimeSafari project.
## Debug Code Checker Hook
### Overview
The `pre-commit` hook automatically checks for debug code when committing to protected branches (master, main, production, release). This prevents debug statements from accidentally reaching production code.
### How It Works
1. **Branch Detection**: Only runs on protected branches (configurable)
2. **File Filtering**: Automatically skips test files, scripts, and documentation
3. **Pattern Matching**: Detects common debug patterns using regex
4. **Commit Prevention**: Blocks commits containing debug code
### Protected Branches (Default)
- `master`
- `main`
- `production`
- `release`
- `stable`
### Debug Patterns Detected
- **Console statements**: `console.log`, `console.debug`, `console.error`
- **Template debug**: `Debug:`, `debug:` in Vue templates
- **Debug constants**: `DEBUG_`, `debug_` variables
- **HTML debug**: `<!-- debug` comments
- **Debug attributes**: `debug="true"` attributes
- **Vue debug**: `v-if="debug"`, `v-show="debug"`
- **Debug TODOs**: `TODO debug`, `FIXME debug`
### Files Automatically Skipped
- Test files: `*.test.js`, `*.spec.ts`, `*.test.vue`
- Scripts: `scripts/` directory
- Test directories: `test-*` directories
- Documentation: `docs/`, `*.md`, `*.txt`
- Config files: `*.json`, `*.yml`, `*.yaml`
- IDE files: `.cursor/` directory
### Configuration
Edit `.git/hooks/debug-checker.config` to customize:
- Protected branches
- Debug patterns
- Skip patterns
- Logging level
### Testing the Hook
Run the test script to verify the hook works:
```bash
./scripts/test-debug-hook.sh
```
### Manual Testing
1. Make changes to a file with debug code
2. Stage the file: `git add <filename>`
3. Try to commit: `git commit -m 'test'`
4. Hook should prevent commit if debug code is found
### Bypassing the Hook (Emergency)
If you absolutely need to commit debug code to a protected branch:
```bash
git commit --no-verify -m "emergency: debug code needed"
```
⚠️ **Warning**: This bypasses all pre-commit hooks. Use sparingly and only in emergencies.
### Troubleshooting
#### Hook not running
- Ensure the hook is executable: `chmod +x .git/hooks/pre-commit`
- Check if you're on a protected branch
- Verify the hook file exists and has correct permissions
#### False positives
- Add legitimate debug patterns to skip patterns in config
- Use proper logging levels (`logger.info`, `logger.debug`) instead of console
- Move debug code to feature branches first
#### Hook too strict
- Modify debug patterns in config file
- Add more file types to skip patterns
- Adjust protected branch list
### Best Practices
1. **Use feature branches** for development with debug code
2. **Use proper logging** instead of console statements
3. **Test thoroughly** before merging to protected branches
4. **Review commits** to ensure no debug code slips through
5. **Keep config updated** as project needs change
### Integration with CI/CD
This hook works locally. For CI/CD pipelines, consider:
- Running the same checks in your build process
- Adding ESLint rules for console statements
- Using TypeScript strict mode
- Adding debug code detection to PR checks
### Support
If you encounter issues:
1. Check the hook output for specific error messages
2. Verify your branch is in the protected list
3. Review the configuration file
4. Test with the provided test script
5. Check file permissions and git setup

86
scripts/git-hooks/debug-checker.config

@ -0,0 +1,86 @@
# TimeSafari Debug Checker Configuration
# Edit this file to customize protected branches and debug patterns
# Protected branches where debug code checking is enforced
# Add or remove branches as needed
PROTECTED_BRANCHES=(
"master"
"main"
"production"
"release"
"stable"
)
# Debug patterns to detect (regex patterns)
# Add or remove patterns as needed
DEBUG_PATTERNS=(
# Console statements
"console\."
# Template debug text
"Debug:"
"debug:"
# Debug constants and variables
"DEBUG_"
"debug_"
# HTML debug comments
"<!-- debug"
# Debug attributes
"debug.*="
# Vue debug patterns
"v-if.*debug"
"v-show.*debug"
# Common debug text
"TODO.*debug"
"FIXME.*debug"
# Debug imports (uncomment if you want to catch these)
# "import.*debug"
# "require.*debug"
)
# Files and directories to skip during checking
# Add patterns to exclude from debug checking
SKIP_PATTERNS=(
"\.(test|spec)\.(js|ts|vue)$" # Test files (must have .test. or .spec.)
"^scripts/" # Scripts directory
"^test-.*/" # Test directories (must end with /)
"^\.git/" # Git directory
"^node_modules/" # Dependencies
"^docs/" # Documentation
"^\.cursor/" # Cursor IDE files
"\.md$" # Markdown files
"\.txt$" # Text files
"\.json$" # JSON config files
"\.yml$" # YAML config files
"\.yaml$" # YAML config files
)
# Files that are whitelisted for console statements
# These files may contain intentional console.log statements that are
# properly whitelisted with eslint-disable-next-line no-console comments
WHITELIST_FILES=(
"src/services/platforms/WebPlatformService.ts" # Worker context logging
"src/services/platforms/CapacitorPlatformService.ts" # Platform-specific logging
"src/services/platforms/ElectronPlatformService.ts" # Electron-specific logging
"src/services/QRScanner/.*" # QR Scanner services
"src/utils/logger.ts" # Logger utility itself
"src/utils/LogCollector.ts" # Log collection utilities
"scripts/.*" # Build and utility scripts
"test-.*/.*" # Test directories
".*\.test\..*" # Test files
".*\.spec\..*" # Spec files
)
# Logging level (debug, info, warn, error)
LOG_LEVEL="info"
# Exit codes
EXIT_SUCCESS=0
EXIT_DEBUG_FOUND=1
EXIT_ERROR=2

252
scripts/git-hooks/pre-commit

@ -0,0 +1,252 @@
#!/bin/bash
# TimeSafari Pre-commit Hook - Debug Code Checker
# Only runs on master or specified branches to catch debug code before it reaches production
# Hook directory
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$HOOK_DIR/debug-checker.config"
# Default configuration (fallback if config file is missing)
DEFAULT_PROTECTED_BRANCHES=("master" "main" "production" "release")
DEFAULT_DEBUG_PATTERNS=(
"console\."
"Debug:"
"debug:"
"DEBUG_"
"debug_"
"<!-- debug"
"debug.*="
)
DEFAULT_WHITELIST_FILES=(
"src/services/platforms/WebPlatformService.ts"
"src/services/platforms/CapacitorPlatformService.ts"
"src/services/platforms/ElectronPlatformService.ts"
)
# Load configuration from file if it exists
load_config() {
if [[ -f "$CONFIG_FILE" ]]; then
# Source the config file to load variables
# We'll use a safer approach by reading and parsing
PROTECTED_BRANCHES=()
DEBUG_PATTERNS=()
SKIP_PATTERNS=()
WHITELIST_FILES=()
# Read protected branches
while IFS= read -r line; do
if [[ "$line" =~ ^PROTECTED_BRANCHES=\( ]]; then
# Start reading array
while IFS= read -r line; do
if [[ "$line" =~ ^\)$ ]]; then
break
fi
if [[ "$line" =~ \"([^\"]+)\" ]]; then
PROTECTED_BRANCHES+=("${BASH_REMATCH[1]}")
fi
done
fi
done < "$CONFIG_FILE"
# Read debug patterns
while IFS= read -r line; do
if [[ "$line" =~ ^DEBUG_PATTERNS=\( ]]; then
while IFS= read -r line; do
if [[ "$line" =~ ^\)$ ]]; then
break
fi
if [[ "$line" =~ \"([^\"]+)\" ]]; then
DEBUG_PATTERNS+=("${BASH_REMATCH[1]}")
fi
done
fi
done < "$CONFIG_FILE"
# Read skip patterns
while IFS= read -r line; do
if [[ "$line" =~ ^SKIP_PATTERNS=\( ]]; then
while IFS= read -r line; do
if [[ "$line" =~ ^\)$ ]]; then
break
fi
if [[ "$line" =~ \"([^\"]+)\" ]]; then
SKIP_PATTERNS+=("${BASH_REMATCH[1]}")
fi
done
fi
done < "$CONFIG_FILE"
# Read whitelist files
while IFS= read -r line; do
if [[ "$line" =~ ^WHITELIST_FILES=\( ]]; then
while IFS= read -r line; do
if [[ "$line" =~ ^\)$ ]]; then
break
fi
if [[ "$line" =~ \"([^\"]+)\" ]]; then
WHITELIST_FILES+=("${BASH_REMATCH[1]}")
fi
done
fi
done < "$CONFIG_FILE"
fi
# Use defaults if config loading failed
if [[ ${#PROTECTED_BRANCHES[@]} -eq 0 ]]; then
PROTECTED_BRANCHES=("${DEFAULT_PROTECTED_BRANCHES[@]}")
fi
if [[ ${#DEBUG_PATTERNS[@]} -eq 0 ]]; then
DEBUG_PATTERNS=("${DEFAULT_DEBUG_PATTERNS[@]}")
fi
if [[ ${#SKIP_PATTERNS[@]} -eq 0 ]]; then
SKIP_PATTERNS=("${DEFAULT_SKIP_PATTERNS[@]}")
fi
if [[ ${#WHITELIST_FILES[@]} -eq 0 ]]; then
WHITELIST_FILES=("${DEFAULT_WHITELIST_FILES[@]}")
fi
}
# Check if current branch is protected
is_protected_branch() {
local branch="$1"
for protected in "${PROTECTED_BRANCHES[@]}"; do
if [[ "$branch" == "$protected" ]]; then
return 0
fi
done
return 1
}
# Check if file should be skipped
should_skip_file() {
local file="$1"
for pattern in "${SKIP_PATTERNS[@]}"; do
if [[ "$file" =~ $pattern ]]; then
return 0
fi
done
return 1
}
# Check if file is whitelisted for console statements
is_whitelisted_file() {
local file="$1"
for whitelisted in "${WHITELIST_FILES[@]}"; do
if [[ "$file" =~ $whitelisted ]]; then
return 0
fi
done
return 1
}
# Main execution
main() {
# Load configuration
load_config
# Get current branch name
CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
if [[ -z "$CURRENT_BRANCH" ]]; then
echo "⚠️ Could not determine current branch, skipping debug check"
exit 0
fi
# Check if we should run the hook
if ! is_protected_branch "$CURRENT_BRANCH"; then
echo "🔒 Pre-commit hook skipped - not on protected branch ($CURRENT_BRANCH)"
echo " Protected branches: ${PROTECTED_BRANCHES[*]}"
exit 0
fi
echo "🔍 Running debug code check on protected branch: $CURRENT_BRANCH"
echo " Using config: $CONFIG_FILE"
# Get all staged files (modified, added, copied, merged)
ALL_STAGED_FILES=$(git diff --cached --name-only)
if [ -z "$ALL_STAGED_FILES" ]; then
echo "✅ No staged files to check"
exit 0
fi
# Initialize error tracking
ERRORS_FOUND=0
ERROR_MESSAGES=()
FILES_CHECKED=0
# Check each staged file for debug patterns
for file in $ALL_STAGED_FILES; do
# Skip files that should be ignored
if should_skip_file "$file"; then
continue
fi
FILES_CHECKED=$((FILES_CHECKED + 1))
# Check for debug patterns in the file
for pattern in "${DEBUG_PATTERNS[@]}"; do
# Skip console pattern checks for whitelisted files
if [[ "$pattern" == "console\." ]] && is_whitelisted_file "$file"; then
continue
fi
# For new files, check the file content directly
# For modified files, check the staged diff
if [[ -f "$file" ]]; then
# New file - check content directly
if grep -E "$pattern" "$file" > /dev/null; then
ERRORS_FOUND=$((ERRORS_FOUND + 1))
ERROR_MESSAGES+=("🚨 $file: Found debug pattern '$pattern'")
fi
else
# Modified file - check staged diff
if git diff --cached "$file" | grep -E "$pattern" > /dev/null; then
ERRORS_FOUND=$((ERRORS_FOUND + 1))
ERROR_MESSAGES+=("🚨 $file: Found debug pattern '$pattern'")
fi
fi
done
done
# Report results
if [ $ERRORS_FOUND -gt 0 ]; then
echo ""
echo "❌ Debug code detected in staged files!"
echo " Branch: $CURRENT_BRANCH"
echo " Files checked: $FILES_CHECKED"
echo " Errors found: $ERRORS_FOUND"
echo ""
for msg in "${ERROR_MESSAGES[@]}"; do
echo " $msg"
done
echo ""
echo "💡 Please remove debug code before committing to $CURRENT_BRANCH"
echo " Common debug patterns to check:"
echo " - console.log, console.debug, console.error"
echo " - Debug: or debug: in templates"
echo " - DEBUG_ constants"
echo " - HTML comments with debug"
echo ""
echo " If debug code is intentional, consider:"
echo " - Moving to a feature branch first"
echo " - Using proper logging levels (logger.info, logger.debug)"
echo " - Adding debug code to .gitignore or .debugignore"
echo ""
echo " Configuration file: $CONFIG_FILE"
exit 1
else
echo "✅ No debug code found in $FILES_CHECKED staged files"
exit 0
fi
}
# Run main function
main "$@"

171
scripts/install-debug-hook.sh

@ -0,0 +1,171 @@
#!/bin/bash
# TimeSafari Debug Hook Installer
# Run this script in any repository to install the debug pre-commit hook
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}🔧 TimeSafari Debug Hook Installer${NC}"
echo "============================================="
# Check if we're in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo -e "${RED}❌ Error: Not in a git repository${NC}"
echo "Please run this script from within a git repository"
exit 1
fi
# Get repository root
REPO_ROOT=$(git rev-parse --show-toplevel)
HOOKS_DIR="$REPO_ROOT/.git/hooks"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo -e "${BLUE}Repository:${NC} $REPO_ROOT"
echo -e "${BLUE}Hooks directory:${NC} $HOOKS_DIR"
echo -e "${BLUE}Script directory:${NC} $SCRIPT_DIR"
# Check if hooks directory exists
if [[ ! -d "$HOOKS_DIR" ]]; then
echo -e "${RED}❌ Error: Hooks directory not found${NC}"
echo "This repository may not be properly initialized"
exit 1
fi
# Check if we have the hook files in the repository
HOOK_SCRIPT="$SCRIPT_DIR/git-hooks/pre-commit"
CONFIG_FILE="$SCRIPT_DIR/git-hooks/debug-checker.config"
if [[ ! -f "$HOOK_SCRIPT" ]]; then
echo -e "${RED}❌ Error: Pre-commit hook script not found${NC}"
echo "Expected location: $HOOK_SCRIPT"
echo "Make sure you're running this from the TimeSafari repository"
exit 1
fi
if [[ ! -f "$CONFIG_FILE" ]]; then
echo -e "${RED}❌ Error: Debug checker config not found${NC}"
echo "Expected location: $CONFIG_FILE"
echo "Make sure you're running this from the TimeSafari repository"
exit 1
fi
# Check if already installed
if [[ -f "$HOOKS_DIR/pre-commit" && -f "$HOOKS_DIR/debug-checker.config" ]]; then
echo -e "${YELLOW}⚠️ Debug hook already appears to be installed${NC}"
echo -e " Checking if update is needed..."
# Check if files are different
if diff "$HOOK_SCRIPT" "$HOOKS_DIR/pre-commit" > /dev/null 2>&1; then
echo -e " ${GREEN}${NC} Hook script is up to date"
HOOK_UP_TO_DATE=true
else
echo -e " ${YELLOW}⚠️ Hook script differs - will update${NC}"
HOOK_UP_TO_DATE=false
fi
if diff "$CONFIG_FILE" "$HOOKS_DIR/debug-checker.config" > /dev/null 2>&1; then
echo -e " ${GREEN}${NC} Config file is up to date"
CONFIG_UP_TO_DATE=true
else
echo -e " ${YELLOW}⚠️ Config file differs - will update${NC}"
CONFIG_UP_TO_DATE=false
fi
if [[ "$HOOK_UP_TO_DATE" == true && "$CONFIG_UP_TO_DATE" == true ]]; then
echo -e "\n${GREEN}✅ Debug hook is already up to date!${NC}"
echo -e " No installation needed"
else
echo -e "\n${BLUE}Updating existing installation...${NC}"
fi
else
echo -e "\n${BLUE}Installing debug hook...${NC}"
fi
# Copy/update the hook script if needed
if [[ "$HOOK_UP_TO_DATE" != true ]]; then
cp "$HOOK_SCRIPT" "$HOOKS_DIR/pre-commit"
chmod +x "$HOOKS_DIR/pre-commit"
echo -e " ${GREEN}${NC} Pre-commit hook installed/updated"
fi
# Copy/update the config file if needed
if [[ "$CONFIG_UP_TO_DATE" != true ]]; then
cp "$CONFIG_FILE" "$HOOKS_DIR/debug-checker.config"
echo -e " ${GREEN}${NC} Configuration file installed/updated"
fi
# Copy/update the README if needed
README_FILE="$SCRIPT_DIR/git-hooks/README.md"
if [[ -f "$README_FILE" ]]; then
if [[ ! -f "$HOOKS_DIR/README.md" ]] || ! diff "$README_FILE" "$HOOKS_DIR/README.md" > /dev/null 2>&1; then
cp "$README_FILE" "$HOOKS_DIR/README.md"
echo -e " ${GREEN}${NC} Documentation installed/updated"
else
echo -e " ${GREEN}${NC} Documentation is up to date"
fi
fi
echo -e "\n${GREEN}🎉 Debug hook installation complete!${NC}"
# Test the installation
echo -e "\n${BLUE}Testing installation...${NC}"
if [[ -x "$HOOKS_DIR/pre-commit" ]]; then
echo -e " ${GREEN}${NC} Hook is executable"
else
echo -e " ${RED}${NC} Hook is not executable"
fi
if [[ -f "$HOOKS_DIR/debug-checker.config" ]]; then
echo -e " ${GREEN}${NC} Config file exists"
else
echo -e " ${RED}${NC} Config file missing"
fi
# Show current branch status
CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo "detached")
echo -e "\n${BLUE}Current branch:${NC} $CURRENT_BRANCH"
# Check if this is a protected branch
PROTECTED_BRANCHES=("master" "main" "production" "release" "stable")
IS_PROTECTED=false
for branch in "${PROTECTED_BRANCHES[@]}"; do
if [[ "$CURRENT_BRANCH" == "$branch" ]]; then
IS_PROTECTED=true
break
fi
done
if [[ "$IS_PROTECTED" == true ]]; then
echo -e "${YELLOW}⚠️ You're on a protected branch ($CURRENT_BRANCH)${NC}"
echo -e " The debug hook will now run on all commits to this branch"
echo -e " Consider switching to a feature branch for development"
else
echo -e "${GREEN}✅ You're on a feature branch ($CURRENT_BRANCH)${NC}"
echo -e " The debug hook will be skipped on this branch"
echo -e " You can develop with debug code freely"
fi
echo -e "\n${BLUE}Next steps:${NC}"
echo "1. The hook will now run automatically on protected branches"
echo "2. Test it by trying to commit a file with debug code"
echo "3. Use feature branches for development with debug code"
echo "4. Check the README.md in .git/hooks/ for more information"
echo -e "\n${BLUE}To test the hook:${NC}"
echo "1. Create a test file with debug code (e.g., console.log('test'))"
echo "2. Stage it: git add <filename>"
echo "3. Try to commit: git commit -m 'test'"
echo "4. The hook should prevent the commit if debug code is found"
echo -e "\n${BLUE}To uninstall:${NC}"
echo "rm $HOOKS_DIR/pre-commit"
echo "rm $HOOKS_DIR/debug-checker.config"
echo "rm $HOOKS_DIR/README.md"

117
scripts/test-debug-hook.sh

@ -0,0 +1,117 @@
#!/bin/bash
# Test script for the debug pre-commit hook
# This script helps verify that the hook is working correctly
set -e
echo "🧪 Testing TimeSafari Debug Pre-commit Hook"
echo "============================================="
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Test directory
TEST_DIR="$(mktemp -d)"
echo -e "${BLUE}Created test directory: $TEST_DIR${NC}"
# Function to cleanup
cleanup() {
echo -e "${YELLOW}Cleaning up test directory...${NC}"
rm -rf "$TEST_DIR"
}
# Set trap to cleanup on exit
trap cleanup EXIT
# Function to run test
run_test() {
local test_name="$1"
local test_file="$2"
local expected_exit="$3"
echo -e "\n${BLUE}Running test: $test_name${NC}"
# Create test file
echo "$test_file" > "$TEST_DIR/test.vue"
# Stage the file
cd "$TEST_DIR"
git init > /dev/null 2>&1
git add test.vue > /dev/null 2>&1
# Run the hook
if bash ../../.git/hooks/pre-commit > hook_output.txt 2>&1; then
exit_code=0
else
exit_code=$?
fi
# Check result
if [[ $exit_code -eq $expected_exit ]]; then
echo -e " ${GREEN}✅ PASS${NC} - Exit code: $exit_code (expected: $expected_exit)"
else
echo -e " ${RED}❌ FAIL${NC} - Exit code: $exit_code (expected: $expected_exit)"
echo -e " ${YELLOW}Hook output:${NC}"
cat hook_output.txt
fi
# Cleanup git
rm -rf .git
rm -f hook_output.txt
}
# Test cases
echo -e "\n${BLUE}Test Case 1: Clean file (should pass)${NC}"
run_test "Clean file" "// No debug code here" 0
echo -e "\n${BLUE}Test Case 2: Console statement (should fail)${NC}"
run_test "Console statement" "console.log('debug info')" 1
echo -e "\n${BLUE}Test Case 3: Debug template (should fail)${NC}"
run_test "Debug template" "Debug: {{ isMapReady ? 'Map Ready' : 'Map Loading' }}" 1
echo -e "\n${BLUE}Test Case 4: Debug constant (should fail)${NC}"
run_test "Debug constant" "const DEBUG_MODE = true" 1
echo -e "\n${BLUE}Test Case 5: Mixed content (should fail)${NC}"
run_test "Mixed content" "// Some normal code\nconsole.debug('test')\n// More normal code" 1
echo -e "\n${BLUE}Test Case 6: HTML debug comment (should fail)${NC}"
run_test "HTML debug comment" "<!-- debug: this is debug info -->" 1
echo -e "\n${BLUE}Test Case 7: Debug attribute (should fail)${NC}"
run_test "Debug attribute" "<div debug='true'>content</div>" 1
echo -e "\n${BLUE}Test Case 8: Test file (should be skipped)${NC}"
run_test "Test file" "console.log('this should be skipped')" 0
# Test branch detection
echo -e "\n${BLUE}Testing branch detection...${NC}"
cd "$TEST_DIR"
git init > /dev/null 2>&1
git checkout -b feature-branch > /dev/null 2>&1
echo "console.log('debug')" > test.vue
git add test.vue > /dev/null 2>&1
if bash ../../.git/hooks/pre-commit > hook_output.txt 2>&1; then
echo -e " ${GREEN}✅ PASS${NC} - Hook skipped on feature branch"
else
echo -e " ${RED}❌ FAIL${NC} - Hook should have been skipped on feature branch"
echo -e " ${YELLOW}Hook output:${NC}"
cat hook_output.txt
fi
rm -rf .git
rm -f hook_output.txt
echo -e "\n${GREEN}🎉 All tests completed!${NC}"
echo -e "\n${BLUE}To test manually:${NC}"
echo "1. Make changes to a file with debug code"
echo "2. Stage the file: git add <filename>"
echo "3. Try to commit: git commit -m 'test'"
echo "4. The hook should prevent the commit if debug code is found"

6
src/interfaces/common.ts

@ -60,9 +60,13 @@ export interface AxiosErrorResponse {
[key: string]: unknown;
};
status?: number;
statusText?: string;
config?: unknown;
};
config?: unknown;
config?: {
url?: string;
[key: string]: unknown;
};
[key: string]: unknown;
}

23
src/services/ProfileService.ts

@ -124,17 +124,11 @@ export class ProfileService {
async deleteProfile(activeDid: string): Promise<boolean> {
try {
const headers = await getHeaders(activeDid);
logger.debug("Attempting to delete profile for DID:", activeDid);
logger.debug("Using partner API server:", this.partnerApiServer);
logger.debug("Request headers:", headers);
const url = `${this.partnerApiServer}/api/partner/userProfile`;
logger.debug("DELETE request URL:", url);
const response = await this.axios.delete(url, { headers });
if (response.status === 200 || response.status === 204) {
logger.debug("Profile deleted successfully");
if (response.status === 204 || response.status === 200) {
logger.info("Profile deleted successfully");
return true;
} else {
logger.error("Unexpected response status when deleting profile:", {
@ -248,7 +242,7 @@ export class ProfileService {
}
/**
* Type guard for API errors
* Type guard for API errors with proper typing
*/
private isApiError(error: unknown): error is {
response?: {
@ -276,6 +270,17 @@ export class ProfileService {
private isAxiosError(error: unknown): error is AxiosError {
return error instanceof AxiosError;
}
/**
* Extract error URL safely from error object
*/
private getErrorUrl(error: unknown): string | undefined {
if (this.isApiError(error) && error.config) {
const config = error.config as { url?: string };
return config.url;
}
return undefined;
}
}
/**

10
src/views/AccountViewView.vue

@ -182,9 +182,6 @@
@change="onLocationCheckboxChange"
/>
<label for="includeUserProfileLocation">Include Location</label>
<span class="text-xs text-slate-400 ml-2"
>(Debug: {{ isMapReady ? "Map Ready" : "Map Loading" }})</span
>
</div>
<div v-if="includeUserProfileLocation" class="mb-4 aspect-video">
<p class="text-sm mb-2 text-slate-500">
@ -924,8 +921,11 @@ export default class AccountViewView extends Vue {
// Fix Leaflet icon issues in modern bundlers
// This prevents the "Cannot read properties of undefined (reading 'Default')" error
if (L.Icon.Default) {
delete (L.Icon.Default.prototype as { _getIconUrl?: unknown })
._getIconUrl;
// Type-safe way to handle Leaflet icon prototype
const iconDefault = L.Icon.Default.prototype as Record<string, unknown>;
if ("_getIconUrl" in iconDefault) {
delete iconDefault._getIconUrl;
}
L.Icon.Default.mergeOptions({
iconRetinaUrl:
"https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon-2x.png",

Loading…
Cancel
Save