Compare commits

..

1 Commits

Author SHA1 Message Date
Matthew Raymer
2e290ad488 grr: experimental diagnosis and fix for build:web:serve 2025-07-18 09:40:12 +00:00
428 changed files with 39996 additions and 17326 deletions

View File

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

View File

@@ -1,65 +0,0 @@
# ADR Template
## ADR-XXXX-YY-ZZ: [Short Title]
**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.]
## Decision
[Describe our response to these forces. We will use the past tense ("We will...").]
## Consequences
### Positive
- [List positive consequences]
### Negative
- [List negative consequences or trade-offs]
### Neutral
- [List neutral consequences or notes]
## Alternatives Considered
- **Alternative 1:** [Description] - [Why rejected]
- **Alternative 2:** [Description] - [Why rejected]
- **Alternative 3:** [Description] - [Why rejected]
## Implementation Notes
[Any specific implementation details, migration steps, or technical considerations]
## References
- [Link to relevant documentation]
- [Link to related ADRs]
- [Link to external resources]
## Related Decisions
- [List related ADRs or decisions]
---
## Usage Guidelines
1. **Copy this template** for new ADRs
2. **Number sequentially** (ADR-001, ADR-002, etc.)
3. **Use descriptive titles** that clearly indicate the decision
4. **Include all stakeholders** in the deciders list
5. **Link to related issues** and documentation
6. **Update status** as decisions evolve
7. **Store in** `doc/architecture-decisions/` directory
description:
globs:
alwaysApply: false
---

View File

@@ -1,352 +0,0 @@
---
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) |
|---------|-----------|--------------------|-------------------|
| 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 (23 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.
## 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 (23 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.
## 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?

View File

@@ -1,181 +0,0 @@
# 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 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.
## 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.
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
### Architecture
- **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)
### Current Database State
- **Database**: SQLite via Absurd SQL (browser) and native SQLite
(mobile/desktop)
- **Legacy Support**: IndexedDB (Dexie) for backward compatibility
- **Status**: Modern database architecture fully implemented
### Core Technologies
- **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
## Development Principles
### Code Organization
- **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
### Architecture Patterns
- **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
### Testing Strategy
- **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
## Current Development Focus
### Active Development
- **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
### Development Metrics
- **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
## Platform-Specific Considerations
### Web (PWA)
- **QR Scanning**: WebInlineQRScanner
- **Deep Linking**: URL parameters
- **File System**: Limited browser APIs
- **Build**: `npm run build:web` (development build)
### Mobile (Capacitor)
- **QR Scanning**: @capacitor-mlkit/barcode-scanning
- **Deep Linking**: App URL open events
- **File System**: Capacitor Filesystem
- **Build**: `npm run build:capacitor`
### Desktop (Electron)
- **File System**: Node.js fs
- **Build**: `npm run build:electron`
- **Distribution**: AppImage, DEB, DMG packages
## Development Workflow
### Build Commands
```bash
# Web (development)
npm run build:web
# Mobile
npm run build:capacitor
npm run build:native
# Desktop
npm run build:electron
npm run build:electron:appimage
npm run build:electron:deb
npm run build:electron:dmg
```
### Testing Commands
```bash
# Web E2E
npm run test:web
# 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`
---
## Status: Active application context
- **Priority**: Critical
- **Estimated Effort**: Ongoing reference
- **Dependencies**: Vue 3, TypeScript, SQLite, Capacitor, Electron
- **Stakeholders**: Development team, Product team

View File

@@ -0,0 +1,287 @@
---
description:
globs:
alwaysApply: true
---
# TimeSafari Cross-Platform Architecture Guide
## 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
### 2.1 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 and type definitions
└── assets/ # Static assets
```
### 2.2 Entry Points
```
src/
├── main.ts # Base entry
├── main.common.ts # Shared initialization
├── main.capacitor.ts # Mobile entry
├── main.electron.ts # Electron entry
└── main.web.ts # Web/PWA entry
```
### 2.3 Build Configurations
```
root/
├── vite.config.common.mts # Shared config
├── vite.config.capacitor.mts # Mobile build
├── vite.config.electron.mts # Electron build
└── vite.config.web.mts # Web/PWA build
```
## 3. Service Architecture
### 3.1 Service Organization
```
services/
├── QRScanner/ # QR code scanning service
│ ├── WebInlineQRScanner.ts
│ └── interfaces.ts
├── platforms/ # Platform-specific services
│ ├── WebPlatformService.ts
│ ├── CapacitorPlatformService.ts
│ └── ElectronPlatformService.ts
└── factory/ # Service factories
└── PlatformServiceFactory.ts
```
### 3.2 Service Factory Pattern
```typescript
// PlatformServiceFactory.ts
export class PlatformServiceFactory {
private static instance: PlatformService | null = null;
public static getInstance(): PlatformService {
if (!PlatformServiceFactory.instance) {
const platform = process.env.VITE_PLATFORM || "web";
PlatformServiceFactory.instance = createPlatformService(platform);
}
return PlatformServiceFactory.instance;
}
}
```
## 4. Feature Implementation Guidelines
### 4.1 QR Code Scanning
1. **Service Interface**
```typescript
interface QRScannerService {
checkPermissions(): Promise<boolean>;
requestPermissions(): Promise<boolean>;
isSupported(): Promise<boolean>;
startScan(): Promise<void>;
stopScan(): Promise<void>;
addListener(listener: ScanListener): void;
onStream(callback: (stream: MediaStream | null) => void): void;
cleanup(): Promise<void>;
}
```
2. **Platform-Specific Implementation**
```typescript
// WebInlineQRScanner.ts
export class WebInlineQRScanner implements QRScannerService {
private scanListener: ScanListener | null = null;
private isScanning = false;
private stream: MediaStream | null = null;
private events = new EventEmitter();
// Implementation of interface methods
}
```
### 4.2 Deep Linking
1. **URL Structure**
```typescript
// Format: timesafari://<route>[/<param>][?queryParam1=value1]
interface DeepLinkParams {
route: string;
params?: Record<string, string>;
query?: Record<string, string>;
}
```
2. **Platform Handlers**
```typescript
// Capacitor
App.addListener("appUrlOpen", handleDeepLink);
// Web
router.beforeEach((to, from, next) => {
handleWebDeepLink(to.query);
});
```
## 5. Build Process
### 5.1 Environment Configuration
```typescript
// vite.config.common.mts
export function createBuildConfig(mode: string) {
return {
define: {
'process.env.VITE_PLATFORM': JSON.stringify(mode),
// PWA is automatically enabled for web platforms via build configuration
__IS_MOBILE__: JSON.stringify(isCapacitor),
__USE_QR_READER__: JSON.stringify(!isCapacitor)
}
};
}
```
### 5.2 Platform-Specific Builds
```bash
# Build commands from package.json
"build:web": "vite build --config vite.config.web.mts",
"build:capacitor": "vite build --config vite.config.capacitor.mts",
"build:electron": "vite build --config vite.config.electron.mts"
```
## 6. Testing Strategy
### 6.1 Test Configuration
```typescript
// playwright.config-local.ts
const config: PlaywrightTestConfig = {
projects: [
{
name: 'web',
use: { browserName: 'chromium' }
},
{
name: 'mobile',
use: { ...devices['Pixel 5'] }
}
]
};
```
### 6.2 Platform-Specific Tests
```typescript
test('QR scanning works on mobile', async ({ page }) => {
test.skip(!process.env.MOBILE_TEST, 'Mobile-only test');
// Test implementation
});
```
## 7. Error Handling
### 7.1 Global Error Handler
```typescript
function setupGlobalErrorHandler(app: VueApp) {
app.config.errorHandler = (err, instance, info) => {
logger.error("[App Error]", {
error: err,
info,
component: instance?.$options.name
});
};
}
```
### 7.2 Platform-Specific Error Handling
```typescript
// API error handling for Capacitor
if (process.env.VITE_PLATFORM === 'capacitor') {
logger.error(`[Capacitor API Error] ${endpoint}:`, {
message: error.message,
status: error.response?.status
});
}
```
## 8. Best Practices
### 8.1 Code Organization
- Use platform-specific directories for unique implementations
- Share common code through service interfaces
- Implement feature detection before using platform capabilities
- Keep platform-specific code isolated in dedicated directories
- Use TypeScript interfaces for cross-platform compatibility
### 8.2 Platform Detection
```typescript
const platformService = PlatformServiceFactory.getInstance();
const capabilities = platformService.getCapabilities();
if (capabilities.hasCamera) {
// Implement camera features
}
```
### 8.3 Feature Implementation
1. Define platform-agnostic interface
2. Create platform-specific implementations
3. Use factory pattern for instantiation
4. Implement graceful fallbacks
5. Add comprehensive error handling
6. Use dependency injection for better testability
## 9. Dependency Management
### 9.1 Platform-Specific Dependencies
```json
{
"dependencies": {
"@capacitor/core": "^6.2.0",
"electron": "^33.2.1",
"vue": "^3.4.0"
}
}
```
### 9.2 Conditional Loading
```typescript
if (process.env.VITE_PLATFORM === 'capacitor') {
await import('@capacitor/core');
}
```
## 10. Security Considerations
### 10.1 Permission Handling
```typescript
async checkPermissions(): Promise<boolean> {
if (platformService.isCapacitor()) {
return await checkNativePermissions();
}
return await checkWebPermissions();
}
```
### 10.2 Data Storage
- Use secure storage mechanisms for sensitive data
- Implement proper encryption for stored data
- Follow platform-specific security guidelines
- Regular security audits and updates
This document should be updated as new features are added or platform-specific implementations change. Regular reviews ensure it remains current with the codebase.

View File

@@ -1,75 +0,0 @@
# Architecture Rules Directory
**Author**: Matthew Raymer
**Date**: 2025-08-20
**Status**: 🎯 **ACTIVE** - Architecture protection guidelines
## Overview
This directory contains MDC (Model Directive Configuration) rules that protect
critical architectural components of the TimeSafari project. These rules ensure
that changes to system architecture follow proper review, testing, and
documentation procedures.
## Available Rules
### Build Architecture Guard (`build_architecture_guard.mdc`)
Protects the multi-platform build system including:
- Vite configuration files
- Build scripts and automation
- Platform-specific configurations (iOS, Android, Electron, Web)
- Docker and deployment infrastructure
- CI/CD pipeline components
**When to use**: Any time you're modifying build scripts, configuration files,
or deployment processes.
**Authorization levels**:
- **Level 1**: Minor changes (review required)
- **Level 2**: Moderate changes (testing required)
- **Level 3**: Major changes (ADR required)
## Usage Guidelines
### For Developers
1. **Check the rule**: Before making architectural changes, review the relevant
rule
2. **Follow the process**: Use the appropriate authorization level
3. **Complete validation**: Run through the required checklist
4. **Update documentation**: Keep BUILDING.md and related docs current
### For Reviewers
1. **Verify authorization**: Ensure changes match the required level
2. **Check testing**: Confirm appropriate testing has been completed
3. **Validate documentation**: Ensure BUILDING.md reflects changes
4. **Assess risk**: Consider impact on other platforms and systems
## Integration with Other Rules
- **Version Control**: Works with `workflow/version_control.mdc`
- **Research & Diagnostic**: Supports `research_diagnostic.mdc` for
investigations
- **Software Development**: Aligns with development best practices
- **Markdown Automation**: Integrates with `docs/markdown-automation.mdc` for
consistent documentation formatting
## Emergency Procedures
If architectural changes cause system failures:
1. **Immediate rollback** to last known working state
2. **Document the failure** with full error details
3. **Investigate root cause** using diagnostic workflows
4. **Update procedures** to prevent future failures
---
**Status**: Active architecture protection
**Priority**: Critical
**Maintainer**: Development team
**Next Review**: 2025-09-20

View File

@@ -1,295 +0,0 @@
---
description: Guards against unauthorized changes to the TimeSafari building
architecture
alwaysApply: false
---
# Build Architecture Guard Directive
**Author**: Matthew Raymer
**Date**: 2025-08-20
**Status**: 🎯 **ACTIVE** - Build system protection guidelines
## Purpose
Protect the TimeSafari building architecture from unauthorized changes that
could break the multi-platform build pipeline, deployment processes, or
development workflow. This directive ensures all build system modifications
follow proper review, testing, and documentation procedures.
## Protected Architecture Components
### Core Build Infrastructure
- **Vite Configuration Files**: `vite.config.*.mts` files
- **Build Scripts**: All scripts in `scripts/` directory
- **Package Scripts**: `package.json` build-related scripts
- **Platform Configs**: `capacitor.config.ts`, `electron/`, `android/`,
`ios/`
- **Docker Configuration**: `Dockerfile`, `docker-compose.yml`
- **Environment Files**: `.env.*`, `.nvmrc`, `.node-version`
### Critical Build Dependencies
- **Build Tools**: Vite, Capacitor, Electron, Android SDK, Xcode
- **Asset Management**: `capacitor-assets.config.json`, asset scripts
- **Testing Infrastructure**: Playwright, Jest, mobile test scripts
- **CI/CD Pipeline**: GitHub Actions, build validation scripts
- **Service Worker Assembly**: `sw_scripts/`, `sw_combine.js`, WASM copy steps
## Change Authorization Requirements
### Level 1: Minor Changes (Requires Review)
- Documentation updates to `BUILDING.md`
- Non-breaking script improvements
- Test additions or improvements
- Asset configuration updates
**Process**: Code review + basic testing
### Level 2: Moderate Changes (Requires Testing)
- New build script additions
- Environment variable changes
- Dependency version updates
- Platform-specific optimizations
**Process**: Code review + platform testing + documentation update
### Level 3: Major Changes (Requires ADR)
- Build system architecture changes
- New platform support
- Breaking changes to build scripts
- Major dependency migrations
**Process**: ADR creation + comprehensive testing + team review
## Prohibited Actions
### ❌ Never Allow Without ADR
- **Delete or rename** core build scripts
- **Modify** `package.json` build script names
- **Change** Vite configuration structure
- **Remove** platform-specific build targets
- **Alter** Docker build process
- **Modify** CI/CD pipeline without testing
### ❌ Never Allow Without Testing
- **Update** build dependencies
- **Change** environment configurations
- **Modify** asset generation scripts
- **Alter** test infrastructure
- **Update** platform SDK versions
## Required Validation Checklist
### Before Any Build System Change
- [ ] **Impact Assessment**: Which platforms are affected?
- [ ] **Testing Plan**: How will this be tested across platforms?
- [ ] **Rollback Plan**: How can this be reverted if it breaks?
- [ ] **Documentation**: Will `BUILDING.md` need updates?
- [ ] **Dependencies**: Are all required tools available?
### After Build System Change
- [ ] **Web Platform**: Does `npm run build:web:dev` work?
- [ ] **Mobile Platforms**: Do iOS/Android builds succeed?
- [ ] **Desktop Platform**: Does Electron build and run?
- [ ] **Tests Pass**: Do all build-related tests pass?
- [ ] **Documentation Updated**: Is `BUILDING.md` current?
## Specific Test Commands (Minimum Required)
### Web Platform
- **Development**: `npm run build:web:dev` - serve and load app
- **Production**: `npm run build:web:prod` - verify SW and WASM present
### Mobile Platforms
- **Android**: `npm run build:android:test` or `:prod` - confirm assets copied
- **iOS**: `npm run build:ios:test` or `:prod` - verify build succeeds
### Desktop Platform
- **Electron**: `npm run build:electron:dev` and packaging for target OS
- **Verify**: Single-instance behavior and app boot
### Auto-run (if affected)
- **Test Mode**: `npm run auto-run:test` and platform variants
- **Production Mode**: `npm run auto-run:prod` and platform variants
### Clean and Rebuild
- Run relevant `clean:*` scripts and ensure re-build works
## Emergency Procedures
### Build System Broken
1. **Immediate**: Revert to last known working commit
2. **Investigation**: Create issue with full error details
3. **Testing**: Verify all platforms work after revert
4. **Documentation**: Update `BUILDING.md` with failure notes
### Platform-Specific Failure
1. **Isolate**: Identify which platform is affected
2. **Test Others**: Verify other platforms still work
3. **Rollback**: Revert platform-specific changes
4. **Investigation**: Debug in isolated environment
## Integration Points
### With Version Control
- **Branch Protection**: Require reviews for build script changes
- **Commit Messages**: Must reference ADR for major changes
- **Testing**: All build changes must pass CI/CD pipeline
### With Documentation
- **BUILDING.md**: Must be updated for any script changes
- **README.md**: Must reflect new build requirements
- **CHANGELOG.md**: Must document breaking build changes
### With Testing
- **Pre-commit**: Run basic build validation
- **CI/CD**: Full platform build testing
- **Manual Testing**: Human verification of critical paths
## Risk Matrix & Required Validation
### Environment Handling
- **Trigger**: Change to `.env.*` loading / variable names
- **Validation**: Prove `dev/test/prod` builds; show environment echo in logs
### Script Flow
- **Trigger**: Reorder steps (prebuild → build → package), new flags
- **Validation**: Dry-run + normal run, show exit codes & timing
### Platform Packaging
- **Trigger**: Electron NSIS/DMG/AppImage, Android/iOS bundle
- **Validation**: Produce installer/artifact and open it; verify single-instance,
icons, signing
### Service Worker / WASM
- **Trigger**: `sw_combine.js`, WASM copy path
- **Validation**: Verify combined SW exists and is injected; page loads offline;
WASM present
### Docker
- **Trigger**: New base image, build args
- **Validation**: Build image locally; run container; list produced `/dist`
### Signing/Notarization
- **Trigger**: Cert path/profiles
- **Validation**: Show signing logs + verify on target OS
## PR Template (Paste into Description)
- [ ] **Level**: L1 / L2 / L3 + justification
- [ ] **Files & platforms touched**:
- [ ] **Risk triggers & mitigations**:
- [ ] **Commands run (paste logs)**:
- [ ] **Artifacts (names + sha256)**:
- [ ] **Docs updated (sections/links)**:
- [ ] **Rollback steps verified**:
- [ ] **CI**: Jobs passing and artifacts uploaded
## Rollback Playbook
### Immediate Rollback
1. `git revert` or `git reset --hard <prev>`; restore prior `scripts/` or config
files
2. Rebuild affected targets; verify old behavior returns
3. Post-mortem notes → update this guard and `BUILDING.md` if gaps found
### Rollback Verification
- **Web**: `npm run build:web:dev` and `npm run build:web:prod`
- **Mobile**: `npm run build:android:test` and `npm run build:ios:test`
- **Desktop**: `npm run build:electron:dev` and packaging commands
- **Clean**: Run relevant `clean:*` scripts and verify re-build works
## ADR Trigger List
Raise an ADR when you propose any of:
- **New build stage** or reorder of canonical stages
- **Replacement of packager** / packaging format
- **New environment model** or secure secret handling scheme
- **New service worker assembly** strategy or cache policy
- **New Docker base** or multi-stage pipeline
- **Relocation of build outputs** or directory conventions
**ADR must include**: motivation, alternatives, risks, validation plan, rollback,
doc diffs.
## Competence Hooks
### Why This Works
- **Prevents Build Failures**: Catches issues before they reach production
- **Maintains Consistency**: Ensures all platforms build identically
- **Reduces Debugging Time**: Prevents build system regressions
### Common Pitfalls
- **Silent Failures**: Changes that work on one platform but break others
- **Dependency Conflicts**: Updates that create version incompatibilities
- **Documentation Drift**: Build scripts that don't match documentation
### Next Skill Unlock
- Learn to test build changes across all platforms simultaneously
### Teach-back
- "What three platforms must I test before committing a build script change?"
## Collaboration Hooks
### Team Review Requirements
- **Platform Owners**: iOS, Android, Electron, Web specialists
- **DevOps**: CI/CD pipeline maintainers
- **QA**: Testing infrastructure owners
### Discussion Prompts
- "Which platforms will be affected by this build change?"
- "How can we test this change without breaking existing builds?"
- "What's our rollback plan if this change fails?"
## Self-Check (Before Allowing Changes)
- [ ] **Authorization Level**: Is this change appropriate for the level?
- [ ] **Testing Plan**: Is there a comprehensive testing strategy?
- [ ] **Documentation**: Will BUILDING.md be updated?
- [ ] **Rollback**: Is there a safe rollback mechanism?
- [ ] **Team Review**: Have appropriate stakeholders been consulted?
- [ ] **CI/CD**: Will this pass the build pipeline?
---
**Status**: Active build system protection
**Priority**: Critical
**Estimated Effort**: Ongoing vigilance
**Dependencies**: All build system components
**Stakeholders**: Development team, DevOps, Platform owners
**Next Review**: 2025-09-20

View File

@@ -1,61 +0,0 @@
---
description: when doing anything with capacitor assets
alwaysApply: false
---
# Asset Configuration Directive
**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.
- 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.
## Config Files
- Live under: `config/assets/` (committed).
- Examples:
- `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**.
## 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
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

View File

@@ -1,154 +0,0 @@
---
alwaysApply: true
---
```json
{
"coaching_level": "standard",
"socratic_max_questions": 7,
"verbosity": "normal",
"timebox_minutes": null,
"format_enforcement": "strict"
}
```
# 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.
The model should also **encourage human interaction and collaboration** rather
than replacing it — outputs should be designed to **facilitate human discussion,
decision-making, and creativity**, not to atomize tasks into isolated, purely
machine-driven steps.
## Principles
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
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?"
## Toggle Definitions
### coaching_level
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.
### verbosity
'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.
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.
### format_enforcement
`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.
- **Pair-Programmer/Pair-Writer**: explain tradeoffs as you implement.
- **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)
- "Teach-back" (1 sentence prompt the human can answer to self-check)
- "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)
- **Competence Hooks** (the 4 learning levers above, kept terse)
- **Collaboration Hooks** (discussion prompts or group review steps)
- **Assumptions & Limits**
- **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 invented facts; mark uncertainty plainly.
- No censorship.
- Avoid outputs that bypass human review when such review is valuable.
## Related Rulesets
- **software_development.mdc**: For software-specific development practices
- **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).
- [ ] 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.

View File

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

View File

@@ -1,321 +0,0 @@
---
alwaysApply: true
version: "2.0.0"
lastUpdated: "2025-08-15"
priority: "critical"
---
# Component Creation Ideals — TimeSafari Architecture (Directive MDC, v2)
> **Agent role**: Apply these rules when creating, refactoring, or reviewing Vue components (Vue 3 with **vue-facing-decorator**). Prioritize **self-contained** components that hydrate from and persist to **PlatformServiceMixin** settings. Minimize parentchild coupling and prop drilling. Prefer **concision** where a separate component would add more API surface than value.
## 📚 Cross-References
- **Migration Example**: See `src/components/NotificationSection.vue` for successful refactor implementation
- **Parent Component**: See `src/views/AccountViewView.vue` for before/after comparison
- **Settings Infrastructure**: See `src/utils/PlatformServiceMixin.ts` for available methods
- **Related Rules**: See `.cursor/rules/` for other architectural guidelines
## Golden Rules (Enforce)
### Priority Levels
- 🔴 **CRITICAL**: Must be followed - breaking these creates architectural problems
- 🟡 **HIGH**: Strongly recommended - important for maintainability
- 🟢 **MEDIUM**: Good practice - improves code quality
1. **Self-Contained Components** 🔴 **CRITICAL**
- Do **not** require parent props for internal state or behavior.
- Hydrate on `mounted()` via `this.$accountSettings()`; persist with `this.$saveSettings()`.
- Encapsulate business logic inside the component; avoid delegating core logic to the parent.
- Prefer **computed** getters for derived values; avoid stored duplicates of derived state.
2. **Settings-First Architecture** 🔴 **CRITICAL**
- Use `PlatformServiceMixin` for reading/writing settings. Do **not** introduce new state managers (Pinia, custom stores) unless the state is *truly global*.
- Prefer **fetch-on-mount** over passing values via props.
3. **Single Responsibility** 🟡 **HIGH**
- Each component owns **one clear purpose** (UI + related logic + settings persistence). Avoid splitting UI/logic across multiple components unless reusability clearly benefits.
4. **Internal State Lifecycle** 🟡 **HIGH**
- Pattern: **defaults → hydrate on mount → computed for derived → persist on change**.
- Handle hydration errors gracefully (keep safe defaults; surface actionable UI states as needed).
5. **Minimal Props** 🔴 **CRITICAL**
- Props are for **pure configuration** (labels, limits, feature flags). Do not pass data that can be loaded internally.
- **Never** pass props that mirror settings values (e.g., `isRegistered`, `notifying*`). Load those from settings.
6. **Communication & Events** 🟡 **HIGH**
- Children may emit events for *user interactions* (e.g., `submitted`, `closed`) but **not** to offload core logic to the parent.
- Do not emit events solely to persist settings; the child handles persistence.
7. **Testing** 🟢 **MEDIUM**
- Unit tests mount components in isolation; mock `this.$accountSettings`/`this.$saveSettings`.
- Verify hydration on mount, persistence on mutation, and graceful failure on settings errors.
---
## Concision-First Decision Framework
> **Goal:** Avoid unnecessary components when a concise script, composable, or helper suffices.
**Prefer NOT making a component when:**
- **One-off UI**: used in exactly one view, unlikely to repeat.
- **Small scope**: ~≤100150 LOC, ≤3 reactive fields, ≤2 handlers.
- **Purely presentational** with trivial logic.
- **Local invariants**: behavior depends entirely on the views context.
- **Abstraction cost > benefit**: would create an anemic component with props mirroring parent state.
- **Better fit as code reuse**: logic works as a **composable/service/helper** without introducing new UI.
**Concise alternatives:**
- **Composable**: `useFeature()` encapsulates settings I/O and state.
- **Service/Module**: plain TS helpers for formatting/validation.
- **Directive**: tiny DOM behaviors that dont need a lifecycle boundary.
**When to make a component (even without reuse yet):**
- **Isolation boundary**: async side effects, permission prompts, or recoverable error states.
- **Stateful widget**: internal settings persistence, media controls, complex a11y.
- **Slots/composition**: needs flexible children or layout.
- **Different change rate**: sub-tree churns independently of the parent.
- **Testability/ownership**: clear, ownable surface thats easier to unit-test in isolation.
**Rule of Three (guardrail):**
- 1st time: inline or composable.
- 2nd time: consider shared abstraction.
- 3rd time: extract a component.
**PR language (use when choosing concision):**
- “One-off, ~80 LOC, no expected reuse. A component would add an API surface with no consumer. Keeping it local reduces cognitive load. If we see a second usage, promote to a composable; third usage, a component.”
- “Logic lives in `useX()` to keep the view concise without prop plumbing; settings stay via `PlatformServiceMixin`.”
---
## Anti-Patterns (Reject)
- Props that duplicate internal/derivable state: `:is-registered`, `:notifying-*`, etc.
- Child components that are **UI-only** while parents hold the business logic for that feature.
- Introducing Pinia/custom stores for per-component state.
- Emitting `update:*` events to push settings responsibilities to parents.
- Scattering a feature across multiple micro-components without a clear reuse reason.
- Using props for computed/derived values (e.g., `showAdvancedFeatures` as a prop).
---
## Quick Examples
### ✅ DO (Self-Contained, Settings-First)
```vue
<!-- Parent renders with no props -->
<NotificationSection />
```
```ts
// NotificationSection.vue (vue-facing-decorator + PlatformServiceMixin)
import { Component, Vue } from "vue-facing-decorator";
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
@Component({
mixins: [PlatformServiceMixin],
})
export default class NotificationSection extends Vue {
private notifyingNewActivity: boolean = false;
async mounted(): Promise<void> {
await this.hydrateFromSettings();
}
private async hydrateFromSettings(): Promise<void> {
try {
const s = await this.$accountSettings();
this.notifyingNewActivity = !!s.notifyingNewActivityTime;
} catch (err) {
// Keep defaults; optionally surface a non-blocking UI notice
}
}
private async updateNotifying(state: boolean): Promise<void> {
await this.$saveSettings({ notifyingNewActivityTime: state ? Date.now() : null });
this.notifyingNewActivity = state;
}
}
```
### ❌ DON'T (Prop-Driven Coupling)
```vue
<!-- Parent passes internal state down -->
<NotificationSection
:is-registered="isRegistered"
:notifying-new-activity="notifyingNewActivity"
/>
```
```ts
// Child receives props (anti-pattern)
export default class NotificationSection extends Vue {
isRegistered: boolean = false;
notifyingNewActivity: boolean = false;
}
```
---
## Component Structure Template (Drop-In)
```ts
/**
* ComponentName.vue — Purpose
* Owns: UI + logic + settings persistence (PlatformServiceMixin).
*/
import { Component, Vue } from "vue-facing-decorator";
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
import type { Router } from "vue-router";
@Component({
components: {
// child components here
},
mixins: [PlatformServiceMixin], // Settings access
})
export default class ComponentName extends Vue {
// Internal state
private myState: boolean = false;
private myData: string = "";
// Derived
private get isEnabled(): boolean {
return this.myState && this.hasPermissions;
}
async mounted(): Promise<void> {
await this.hydrateFromSettings();
}
private async hydrateFromSettings(): Promise<void> {
try {
const s = await this.$accountSettings();
this.myState = !!s.mySetting;
this.myData = s.myData ?? "";
} catch (err) {
// keep defaults
}
}
private async updateState(v: boolean): Promise<void> {
await this.$saveSettings({ mySetting: v });
this.myState = v;
}
async handleUserAction(): Promise<void> {
await this.updateState(true);
}
}
```
---
## Migration Playbook (Props → Self-Contained)
> **Agent, when you see a component receiving `@Prop()` values that mirror settings or internal state, apply this playbook.**
1. **Detect Anti-Props**
- Flag props matching: `is*`, `has*`, `notifying*`, or mirroring settings keys.
- Search for parent usage of these props and events.
2. **Inline State**
- Remove anti-props and `@Prop()` declarations.
- Add private fields for state inside the child.
- Add `mounted()` hydration and persistence helpers via `PlatformServiceMixin`.
3. **Parent Simplification**
- Replace `<Child :foo="..." :bar="..." @update="..."/>` with `<Child />`.
- Delete now-unused local state, watchers, and computed values that existed only to feed the child.
4. **Events**
- Keep only user-interaction events (e.g., `submitted`). Remove persistence/logic events that the child now owns.
5. **Tests**
- Update unit tests to mount child in isolation; mock settings I/O.
- Verify: hydrate on mount, persist on change, safe fallback on error.
---
## When Exceptions Are Acceptable
- **Truly Global State** across distant components → use Pinia/service *sparingly*.
- **Reusable Form Inputs** → accept `value` prop and emit `input`/`update:modelValue`; keep validation/business logic internal.
- **Configuration-Only Props** for labels, visual variants, or limits — not for state that can be fetched.
---
## Definition of Done (Checklist)
- [ ] No props required for internal state or settings-backed values.
- [ ] Uses `PlatformServiceMixin` for all settings I/O.
- [ ] Hydrates on `mounted()`, persists on mutations.
- [ ] Single-responsibility: UI + logic + persistence together.
- [ ] Computed getters for derived state.
- [ ] Unit tests mock settings and cover hydrate/persist/failure paths.
- [ ] Parent components contain no leftover `notifying-*` or similar prop wiring.
---
## Testing Snippets
```ts
// Hydration on mount
test("hydrates from settings on mount", async () => {
const wrap = mount(MyComponent);
await wrap.vm.$nextTick();
expect((wrap.vm as any).myState).toBe(true);
});
```
```ts
// Mock settings methods
jest.spyOn(wrapper.vm as any, "$accountSettings").mockResolvedValue({ mySetting: true });
jest.spyOn(wrapper.vm as any, "$saveSettings").mockResolvedValue(void 0);
```
```ts
// Graceful failure
test("handles settings load failure", async () => {
jest.spyOn(wrapper.vm as any, "$accountSettings").mockRejectedValue(new Error("DB Error"));
const wrap = mount(MyComponent);
await wrap.vm.$nextTick();
expect((wrap.vm as any).myState).toBe(false); // default
});
```
---
## Rationale (Short)
- **Concision first where appropriate** → avoid unnecessary components and API surfaces.
- **Reduced coupling** → portability and reuse when boundaries are justified.
- **Maintainability** → changes localized to the owning component.
- **Consistency** → one canonical path for settings-backed features.
**Rule of thumb:** _Can this feature operate independently, and does a component materially improve isolation or testability?_ If not, keep it concise (inline or composable).
---
## 📝 Version History
### v2.0.0 (2025-08-15)
- **Major Enhancement**: Added Concision-First Decision Framework
- **New**: Rule of Three guardrail for component extraction
- **New**: PR language guidance for code reviews
- **Enhanced**: Agent role includes concision preference
- **Refined**: Anti-patterns and examples updated
### v1.0.0 (2025-08-15)
- Initial creation based on successful NotificationSection refactor
- Established core architectural principles for self-contained components
- Added comprehensive migration playbook and testing guidelines
- Included practical examples and anti-pattern detection
### Future Enhancements
- Additional migration patterns for complex components
- Integration with automated refactoring tools
- Performance benchmarking guidelines
- Advanced testing strategies for complex state management

View File

@@ -1,8 +0,0 @@
---
globs: **/databaseUtil.ts,**/AccountViewView.vue,**/ContactsView.vue,**/DatabaseMigration.vue,**/NewIdentifierView.vue
alwaysApply: false
---
# 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.

View File

@@ -1,9 +0,0 @@
---
globs: **/src/**/*
alwaysApply: false
---
✅ use system date command to timestamp all interactions with accurate date and time
✅ python script files must always have a blank line at their end
✅ remove whitespace at the end of lines
✅ use npm run lint-fix to check for warnings
✅ do not use npm run dev let me handle running and supplying feedback

View File

@@ -1,139 +0,0 @@
---
description: when dealing with types and Typesript
alwaysApply: false
---
```json
{
"coaching_level": "light",
"socratic_max_questions": 7,
"verbosity": "concise",
"timebox_minutes": null,
"format_enforcement": "strict"
}
```
# TypeScript Type Safety Guidelines
**Author**: Matthew Raymer
**Date**: 2025-08-19
**Status**: 🎯 **ACTIVE** - Type safety enforcement
## Overview
Practical rules to keep TypeScript strict and predictable. Minimize exceptions.
## Core Rules
1. **No `any`**
- 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`).
- Catch with `unknown`; never cast to `any`.
3. **Dynamic property access is typesafe**
- Use `keyof` + `in` checks:
```ts
obj[k as keyof typeof obj]
```
- Avoid `(obj as any)[k]`.
## Type Safety Enforcement
### Core Type Safety Rules
- **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
## Minimal Special Cases (document in PR when used)
- **Vue refs / instances**: Use `ComponentPublicInstance` or specific
component types for dynamic refs.
- **3rdparty libs without types**: Narrow immediately to a **known
interface**; do not leave `any` hanging.
## Patterns (short)
### Database errors
```ts
try { await this.$addContact(contact); }
catch (e: unknown) {
if (isDatabaseError(e) && e.message.includes("Key already exists")) {
/* handle duplicate */
}
}
```
### API errors
```ts
try { await apiCall(); }
catch (e: unknown) {
if (isApiError(e)) {
const msg = e.response?.data?.error?.message;
}
}
```
### Dynamic keys
```ts
const keys = Object.keys(newSettings).filter(
k => k in newSettings && newSettings[k as keyof typeof newSettings] !== undefined
);
```
## Checklists
**Before commit**
- [ ] No `any` (except documented, justified cases)
- [ ] Errors handled via guards
- [ ] Dynamic access uses `keyof`/`in`
- [ ] Imports point to correct interfaces/types
**Code review**
- [ ] Hunt hidden `as any`
- [ ] Guardbased error paths verified
- [ ] Dynamic ops are typesafe
- [ ] Prefer existing types over reinventing
## Tools
- `npm run lint-fix` — lint & autofix
- `npm run type-check` — strict type compilation (CI + prerelease)
- IDE: enable strict TS, ESLint/TS ESLint, Volar (Vue 3)
## References
- TS Handbook — https://www.typescriptlang.org/docs/
- TSESLint — 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/
- TSESLint — https://typescript-eslint.io/rules/
- Vue 3 + TS — https://vuejs.org/guide/typescript/

View File

@@ -0,0 +1,35 @@
---
description: rules used while developing
globs:
alwaysApply: true
---
✅ use system date command to timestamp all interactions with accurate date and time
✅ python script files must always have a blank line at their end
✅ remove whitespace at the end of lines
✅ use npm run lint-fix to check for warnings
✅ do not use npm run dev let me handle running and supplying feedback
✅ do not add or commit for the user; let him control that process
always preview changes and commit message to use and allow me to copy and paste
✅ Preferred Commit Message Format
Short summary in the first line (concise and high-level).
Avoid long commit bodies unless truly necessary.
✅ Valued Content in Commit Messages
Specific fixes or features.
Symptoms or problems that were fixed.
Notes about tests passing or TS/linting errors being resolved (briefly).
❌ Avoid in Commit Messages
Vague terms: “improved”, “enhanced”, “better” — especially from AI.
Minor changes: small doc tweaks, one-liners, cleanup, or lint fixes.
Redundant blurbs: repeated across files or too generic.
Multiple overlapping purposes in a single commit — prefer narrow, focused commits.
Long explanations of what can be deduced from good in-line code comments.
Guiding Principle
Let code and inline documentation speak for themselves. Use commits to highlight what isn't obvious from reading the code.

View File

@@ -1,14 +0,0 @@
---
alwaysApply: true
---
# Directive for Documentation Generation
1. Produce a **small, focused set of documents** rather than an overwhelming volume.
2. Ensure the content is **maintainable and worth preserving**, so that humans
are motivated to keep it up to date.
3. Prioritize **educational value**: the documents must clearly explain the
workings of the system.
4. Avoid **shallow, generic, or filler explanations** often found in
AI-generated documentation.
5. Aim for **clarity, depth, and usefulness**, so readers gain genuine understanding.
6. Always check the local system date to determine current date.

View File

@@ -1,79 +0,0 @@
---
alwaysApply: true
---
# Markdown Automation System
**Author**: Matthew Raymer
**Date**: 2025-08-20
**Status**: 🎯 **ACTIVE** - Markdown formatting automation
## Overview
The Markdown Automation System ensures your markdown formatting standards are
followed **during content generation** by AI agents, not just applied after the
fact.
## AI-First Approach
### **Primary Method**: AI Agent Compliance
- **AI agents follow markdown rules** while generating content
- **No post-generation fixes needed** - content is compliant from creation
- **Consistent formatting** across all generated documentation
### **Secondary Method**: Automated Validation
- **Pre-commit hooks** catch any remaining issues
- **GitHub Actions** validate formatting before merge
- **Manual tools** for bulk fixes when needed
## How It Works
### 1. **AI Agent Compliance** (Primary)
- **When**: Every time AI generates markdown content
- **What**: AI follows markdown rules during generation
- **Result**: Content is properly formatted from creation
### 2. **Pre-commit Hooks** (Backup)
- **When**: Every time you commit
- **What**: Catches any remaining formatting issues
- **Result**: Clean, properly formatted markdown files
### 3. **GitHub Actions** (Pre-merge)
- **When**: Every pull request
- **What**: Validates markdown formatting across all files
- **Result**: Blocks merge if formatting issues exist
## AI Agent Rules Integration
The AI agent follows markdown rules defined in `.cursor/rules/docs/markdown.mdc`:
- **alwaysApply: true** - Rules are enforced during generation
- **Line Length**: AI never generates lines > 80 characters
- **Blank Lines**: AI adds proper spacing around all elements
- **Structure**: AI uses established templates and patterns
## Available Commands
### NPM Scripts
- **`npm run markdown:setup`** - Install the automation system
- **`npm run markdown:fix`** - Fix formatting in all markdown files
- **`npm run markdown:check`** - Validate formatting without fixing
## Benefits
- **No more manual fixes** - AI generates compliant content from start
- **Consistent style** - All files follow same standards
- **Faster development** - No need to fix formatting manually
---
**Status**: Active automation system
**Priority**: High
**Maintainer**: Development team
**Next Review**: 2025-09-20

View File

@@ -1,206 +0,0 @@
---
alwaysApply: true
inherits: base_context.mdc
---
```json
{
"coaching_level": "standard",
"socratic_max_questions": 2,
"verbosity": "concise",
"timebox_minutes": 10,
"format_enforcement": "strict"
}
```
# Harbor Pilot — Universal Directive for Human-Facing Technical Guides
**Author**: System/Shared
**Date**: 2025-08-21 (UTC)
**Status**: 🚢 ACTIVE — General ruleset extending *Base Context — Human Competence First*
> **Alignment with Base Context**
> - **Purpose fit**: Prioritizes human competence and collaboration while delivering reproducible artifacts.
> - **Output Contract**: This directive **adds universal constraints** for any technical topic while **inheriting** the Base Context contract sections.
> - **Toggles honored**: Uses the same toggle semantics; defaults above can be overridden by the caller.
---
## Objective
Produce a **developer-grade, reproducible guide** for any technical topic that onboards a competent practitioner **without meta narration** and **with evidence-backed steps**.
## Scope & Constraints
- **One Markdown document** as the deliverable.
- Use **absolute dates** in **UTC** (e.g., `2025-08-21T14:22Z`) — avoid “today/yesterday”.
- Include at least **one diagram** (Mermaid preferred). Choose the most fitting type:
- `sequenceDiagram` (protocols/flows), `flowchart`, `stateDiagram`, `gantt` (timelines), or `classDiagram` (schemas).
- Provide runnable examples where applicable:
- **APIs**: `curl` + one client library (e.g., `httpx` for Python).
- **CLIs**: literal command blocks and expected output snippets.
- **Code**: minimal, self-contained samples (language appropriate).
- Cite **evidence** for *Works/Doesnt* items (timestamps, filenames, line numbers, IDs/status codes, or logs).
- If something is unknown, output `TODO:<missing>` — **never invent**.
## Required Sections (extends Base Output Contract)
Follow this exact order **after** the Base Contracts **Objective → Result → Use/Run** headers:
1. **Context & Scope**
- Problem statement, audience, in/out-of-scope bullets.
2. **Artifacts & Links**
- Repos/PRs, design docs, datasets/HARs/pcaps, scripts/tools, dashboards.
3. **Environment & Preconditions**
- OS/runtime, versions/build IDs, services/endpoints/URLs, credentials/auth mode (describe acquisition, do not expose secrets).
4. **Architecture / Process Overview**
- Short prose + **one diagram** selected from the list above.
5. **Interfaces & Contracts (choose one)**
- **API-based**: Endpoint table (*Step, Method, Path/URL, Auth, Key Headers/Params, Sample Req/Resp ref*).
- **Data/Files**: I/O contract table (*Source, Format, Schema/Columns, Size, Validation rules*).
- **Systems/Hardware**: Interfaces table (*Port/Bus, Protocol, Voltage/Timing, Constraints*).
6. **Repro: End-to-End Procedure**
- Minimal copy-paste steps with code/commands and **expected outputs**.
7. **What Works (with Evidence)**
- Each item: **Time (UTC)** • **Artifact/Req IDs** • **Status/Result** • **Where to verify**.
8. **What Doesnt (Evidence & Hypotheses)**
- Each failure: locus (file/endpoint/module), evidence snippet; short hypothesis and **next probe**.
9. **Risks, Limits, Assumptions**
- SLOs/limits, rate/size caps, security boundaries (CORS/CSRF/ACLs), retries/backoff/idempotency patterns.
10. **Next Steps (Owner • Exit Criteria • Target Date)**
- Actionable, assigned, and time-bound.
11. **References**
- Canonical docs, specs, tickets, prior analyses.
> **Competence Hooks (per Base Context; keep lightweight):**
> - *Why this works* (≤3 bullets) — core invariants or guarantees.
> - *Common pitfalls* (≤3 bullets) — the traps we saw in evidence.
> - *Next skill unlock* (1 line) — the next capability to implement/learn.
> - *Teach-back* (1 line) — prompt the reader to restate the flow/architecture.
> **Collaboration Hooks (per Base Context):**
> - Name reviewers for **Interfaces & Contracts** and the **diagram**.
> - Short **sign-off checklist** before merging/publishing the guide.
## Do / Dont (Base-aligned)
- **Do** quantify progress only against a defined scope with acceptance criteria.
- **Do** include minimal sample payloads/headers or I/O schemas; redact sensitive values.
- **Do** keep commentary lean; if timeboxed, move depth to **Deferred for depth**.
- **Dont** use marketing language or meta narration (“Perfect!”, “tool called”, “new chat”).
- **Dont** include IDE-specific chatter or internal rules unrelated to the task.
## Validation Checklist (self-check before returning)
- [ ] All Required Sections present and ordered.
- [ ] Diagram compiles (basic Mermaid syntax) and fits the problem.
- [ ] If API-based, **Auth** and **Key Headers/Params** are listed for each endpoint.
- [ ] Repro section includes commands/code **and expected outputs**.
- [ ] Every Works/Doesnt item has **UTC timestamp**, **status/result**, and **verifiable evidence**.
- [ ] Next Steps include **Owner**, **Exit Criteria**, **Target Date**.
- [ ] Unknowns are `TODO:<missing>` — no fabrication.
- [ ] Base **Output Contract** sections satisfied (Objective/Result/Use/Run/Competence/Collaboration/Assumptions/References).
## Universal Template (fill-in)
```markdown
# <Title> — Working Notes (As of YYYY-MM-DDTHH:MMZ)
## Objective
<one line>
## Result
<link to the produced guide file or say “this document”>
## Use/Run
<how to apply/test and where to run samples>
## Context & Scope
- Audience: <role(s)>
- In scope: <bullets>
- Out of scope: <bullets>
## Artifacts & Links
- Repo/PR: <link>
- Data/Logs: <paths or links>
- Scripts/Tools: <paths>
- Dashboards: <links>
## Environment & Preconditions
- OS/Runtime: <details>
- Versions/Builds: <list>
- Services/Endpoints: <list>
- Auth mode: <Bearer/Session/Keys + how acquired>
## Architecture / Process Overview
<short prose>
```mermaid
<one suitable diagram: sequenceDiagram | flowchart | stateDiagram | gantt | classDiagram>
```
## Interfaces & Contracts
### If API-based
| Step | Method | Path/URL | Auth | Key Headers/Params | Sample |
|---|---|---|---|---|---|
| <…> | <…> | <…> | <…> | <…> | below |
### If Data/Files
| Source | Format | Schema/Columns | Size | Validation |
|---|---|---|---|---|
| <…> | <…> | <…> | <…> | <…> |
### If Systems/Hardware
| Interface | Protocol | Timing/Voltage | Constraints | Notes |
|---|---|---|---|---|
| <…> | <…> | <…> | <…> | <…> |
## Repro: End-to-End Procedure
```bash
# commands / curl examples (redacted where necessary)
```
```python
# minimal client library example (language appropriate)
```
> Expected output: <snippet/checks>
## What Works (Evidence)
- ✅ <short statement>
- **Time**: <YYYY-MM-DDTHH:MMZ>
- **Evidence**: file/line/log or request id/status
- **Verify at**: <where>
## What Doesnt (Evidence & Hypotheses)
- ❌ <short failure> at `<component/endpoint/file>`
- **Time**: <YYYY-MM-DDTHH:MMZ>
- **Evidence**: <snippet/id/status>
- **Hypothesis**: <short>
- **Next probe**: <short>
## Risks, Limits, Assumptions
<bullets: limits, security boundaries, retries/backoff, idempotency, SLOs>
## Next Steps
| Owner | Task | Exit Criteria | Target Date (UTC) |
|---|---|---|---|
| <name> | <action> | <measurable outcome> | <YYYY-MM-DD> |
## References
<links/titles>
## Competence Hooks
- *Why this works*: <≤3 bullets>
- *Common pitfalls*: <≤3 bullets>
- *Next skill unlock*: <1 line>
- *Teach-back*: <1 line>
## Collaboration Hooks
- Reviewers: <names/roles>
- Sign-off checklist: <≤5 checks>
## Assumptions & Limits
<bullets>
## Deferred for depth
<park deeper material here to respect timeboxing>
```
---
**Notes for Implementers:**
- Respect Base *Do-Not* (no filler, no invented facts, no censorship).
- Prefer clarity over completeness when timeboxed; capture unknowns explicitly.
- Apply historical comment management rules (see `.cursor/rules/historical_comment_management.mdc`)
- Apply realistic time estimation rules (see `.cursor/rules/realistic_time_estimation.mdc`)

View File

@@ -1,236 +0,0 @@
---
description: when comments are generated by the model
alwaysApply: false
---
# Historical Comment Management — Harbor Pilot Directive
> **Agent role**: When encountering historical comments about removed methods, deprecated patterns, or architectural changes, apply these guidelines to maintain code clarity and developer guidance.
## 🎯 Purpose
Historical comments should either be **removed entirely** or **transformed into actionable guidance** for future developers. Avoid keeping comments that merely state what was removed without explaining why or what to do instead.
## 📋 Decision Framework
### Remove Historical Comments When:
- **Obsolete Information**: Comment describes functionality that no longer exists
- **No Action Required**: Comment doesn't help future developers make decisions
- **Outdated Context**: Comment refers to old patterns that are no longer relevant
- **Self-Evident**: The current code clearly shows the current approach
### Transform Historical Comments When:
- **Architectural Context**: The change represents a significant pattern shift
- **Migration Guidance**: Future developers might need to understand the evolution
- **Decision Rationale**: The "why" behind the change is still relevant
- **Alternative Approaches**: The comment can guide future implementation choices
## 🔄 Transformation Patterns
### 1. From Removal Notice to Migration Note
```typescript
// ❌ REMOVE THIS
// turnOffNotifyingFlags method removed - notification state is now managed by NotificationSection component
// ✅ TRANSFORM TO THIS
// Note: Notification state management has been migrated to NotificationSection component
// which handles its own lifecycle and persistence via PlatformServiceMixin
```
### 2. From Deprecation Notice to Implementation Guide
```typescript
// ❌ REMOVE THIS
// This will be handled by the NewComponent now
// No need to call oldMethod() as it's no longer needed
// ✅ TRANSFORM TO THIS
// Note: This functionality has been migrated to NewComponent
// which provides better separation of concerns and testability
```
### 3. From Historical Note to Architectural Context
```typescript
// ❌ REMOVE THIS
// Old approach: used direct database calls
// New approach: uses service layer
// ✅ TRANSFORM TO THIS
// Note: Database access has been abstracted through service layer
// for better testability and platform independence
```
## 🚫 Anti-Patterns to Remove
- Comments that only state what was removed
- Comments that don't explain the current approach
- Comments that reference non-existent methods
- Comments that are self-evident from the code
- Comments that don't help future decision-making
## ✅ Best Practices
### When Keeping Historical Context:
1. **Explain the "Why"**: Why was the change made?
2. **Describe the "What"**: What is the current approach?
3. **Provide Context**: When might this information be useful?
4. **Use Actionable Language**: Guide future decisions, not just document history
### When Removing Historical Context:
1. **Verify Obsoleteness**: Ensure the information is truly outdated
2. **Check for Dependencies**: Ensure no other code references the old approach
3. **Update Related Docs**: If removing from code, consider adding to documentation
4. **Preserve in Git History**: The change is preserved in version control
## 🔍 Implementation Checklist
- [ ] Identify historical comments about removed/deprecated functionality
- [ ] Determine if comment provides actionable guidance
- [ ] Transform useful comments into migration notes or architectural context
- [ ] Remove comments that are purely historical without guidance value
- [ ] Ensure remaining comments explain current approach and rationale
- [ ] Update related documentation if significant context is removed
## 📚 Examples
### Good Historical Comment (Keep & Transform)
```typescript
// Note: Database access has been migrated from direct IndexedDB calls to PlatformServiceMixin
// This provides better platform abstraction and consistent error handling across web/mobile/desktop
// When adding new database operations, use this.$getContact(), this.$saveSettings(), etc.
```
### Bad Historical Comment (Remove)
```typescript
// Old method getContactFromDB() removed - now handled by PlatformServiceMixin
// No need to call the old method anymore
```
## 🎯 Integration with Harbor Pilot
This rule works in conjunction with:
- **Component Creation Ideals**: Maintains architectural consistency
- **Migration Patterns**: Documents evolution of patterns
- **Code Review Guidelines**: Ensures comments provide value
## 📝 Version History
### v1.0.0 (2025-08-21)
- Initial creation based on notification system cleanup
- Established decision framework for historical comment management
- Added transformation patterns and anti-patterns
- Integrated with existing Harbor Pilot architecture rules
# Historical Comment Management — Harbor Pilot Directive
> **Agent role**: When encountering historical comments about removed methods, deprecated patterns, or architectural changes, apply these guidelines to maintain code clarity and developer guidance.
## 🎯 Purpose
Historical comments should either be **removed entirely** or **transformed into actionable guidance** for future developers. Avoid keeping comments that merely state what was removed without explaining why or what to do instead.
## 📋 Decision Framework
### Remove Historical Comments When:
- **Obsolete Information**: Comment describes functionality that no longer exists
- **No Action Required**: Comment doesn't help future developers make decisions
- **Outdated Context**: Comment refers to old patterns that are no longer relevant
- **Self-Evident**: The current code clearly shows the current approach
### Transform Historical Comments When:
- **Architectural Context**: The change represents a significant pattern shift
- **Migration Guidance**: Future developers might need to understand the evolution
- **Decision Rationale**: The "why" behind the change is still relevant
- **Alternative Approaches**: The comment can guide future implementation choices
## 🔄 Transformation Patterns
### 1. From Removal Notice to Migration Note
```typescript
// ❌ REMOVE THIS
// turnOffNotifyingFlags method removed - notification state is now managed by NotificationSection component
// ✅ TRANSFORM TO THIS
// Note: Notification state management has been migrated to NotificationSection component
// which handles its own lifecycle and persistence via PlatformServiceMixin
```
### 2. From Deprecation Notice to Implementation Guide
```typescript
// ❌ REMOVE THIS
// This will be handled by the NewComponent now
// No need to call oldMethod() as it's no longer needed
// ✅ TRANSFORM TO THIS
// Note: This functionality has been migrated to NewComponent
// which provides better separation of concerns and testability
```
### 3. From Historical Note to Architectural Context
```typescript
// ❌ REMOVE THIS
// Old approach: used direct database calls
// New approach: uses service layer
// ✅ TRANSFORM TO THIS
// Note: Database access has been abstracted through service layer
// for better testability and platform independence
```
## 🚫 Anti-Patterns to Remove
- Comments that only state what was removed
- Comments that don't explain the current approach
- Comments that reference non-existent methods
- Comments that are self-evident from the code
- Comments that don't help future decision-making
## ✅ Best Practices
### When Keeping Historical Context:
1. **Explain the "Why"**: Why was the change made?
2. **Describe the "What"**: What is the current approach?
3. **Provide Context**: When might this information be useful?
4. **Use Actionable Language**: Guide future decisions, not just document history
### When Removing Historical Context:
1. **Verify Obsoleteness**: Ensure the information is truly outdated
2. **Check for Dependencies**: Ensure no other code references the old approach
3. **Update Related Docs**: If removing from code, consider adding to documentation
4. **Preserve in Git History**: The change is preserved in version control
## 🔍 Implementation Checklist
- [ ] Identify historical comments about removed/deprecated functionality
- [ ] Determine if comment provides actionable guidance
- [ ] Transform useful comments into migration notes or architectural context
- [ ] Remove comments that are purely historical without guidance value
- [ ] Ensure remaining comments explain current approach and rationale
- [ ] Update related documentation if significant context is removed
## 📚 Examples
### Good Historical Comment (Keep & Transform)
```typescript
// Note: Database access has been migrated from direct IndexedDB calls to PlatformServiceMixin
// This provides better platform abstraction and consistent error handling across web/mobile/desktop
// When adding new database operations, use this.$getContact(), this.$saveSettings(), etc.
```
### Bad Historical Comment (Remove)
```typescript
// Old method getContactFromDB() removed - now handled by PlatformServiceMixin
// No need to call the old method anymore
```
## 🎯 Integration with Harbor Pilot
This rule works in conjunction with:
- **Component Creation Ideals**: Maintains architectural consistency
- **Migration Patterns**: Documents evolution of patterns
- **Code Review Guidelines**: Ensures comments provide value
## 📝 Version History
### v1.0.0 (2025-08-21)
- Initial creation based on notification system cleanup
- Established decision framework for historical comment management
- Added transformation patterns and anti-patterns
- Integrated with existing Harbor Pilot architecture rules

View File

@@ -1,117 +0,0 @@
# 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.
## System Map
- 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
## 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
## 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
## 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"
## 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
## Decision / Next Steps
- Owner: Development Team; By: 2025-01-28
- 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?"
## 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
---
**Status**: Active investigation methodology
**Priority**: High
**Estimated Effort**: Ongoing reference
**Dependencies**: software_development.mdc
**Stakeholders**: Development team, QA team

View File

@@ -0,0 +1,6 @@
---
description:
globs:
alwaysApply: true
---
All references in the codebase to Dexie apply only to migration from IndexedDb to Sqlite and will be deprecated in future versions.

View File

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

View File

@@ -1,5 +1,5 @@
--- ---
globs: ["*.md", "*.mdc"] globs: *.md
alwaysApply: false alwaysApply: false
--- ---
# Cursor Markdown Ruleset for TimeSafari Documentation # Cursor Markdown Ruleset for TimeSafari Documentation
@@ -10,36 +10,6 @@ This ruleset enforces consistent markdown formatting standards across all projec
documentation, ensuring readability, maintainability, and compliance with documentation, ensuring readability, maintainability, and compliance with
markdownlint best practices. markdownlint best practices.
**⚠️ CRITICAL FOR AI AGENTS**: These rules must be followed DURING content
generation, not applied after the fact. Always generate markdown that complies
with these standards from the start.
## AI Generation Guidelines
### **MANDATORY**: Follow These Rules While Writing
When generating markdown content, you MUST:
1. **Line Length**: Never exceed 80 characters per line
2. **Blank Lines**: Always add blank lines around headings, lists, and code
blocks
3. **Structure**: Use proper heading hierarchy and document templates
4. **Formatting**: Apply consistent formatting patterns immediately
### **DO NOT**: Generate content that violates these rules
- ❌ Generate long lines that need breaking
- ❌ Create content without proper blank line spacing
- ❌ Use inconsistent formatting patterns
- ❌ Assume post-processing will fix violations
### **DO**: Generate compliant content from the start
- ✅ Write within 80-character limits
- ✅ Add blank lines around all structural elements
- ✅ Use established templates and patterns
- ✅ Apply formatting standards immediately
## General Formatting Standards ## General Formatting Standards
### Line Length ### Line Length
@@ -342,25 +312,3 @@ Description of current situation or problem.
**Last Updated**: 2025-07-09 **Last Updated**: 2025-07-09
**Version**: 1.0 **Version**: 1.0
**Maintainer**: Matthew Raymer **Maintainer**: Matthew Raymer
### Heading Uniqueness
- **Rule**: No duplicate heading content at the same level
- **Scope**: Within a single document
- **Rationale**: Maintains clear document structure and navigation
- **Example**:
```markdown
## Features ✅
### Authentication
### Authorization
## Features ❌ (Duplicate heading)
### Security
### Performance
```
## Features ❌ (Duplicate heading)
### Security
### Performance
```

View File

@@ -1,348 +0,0 @@
---
description: when generating text that has project task work estimates
alwaysApply: false
---
# No Time Estimates — Harbor Pilot Directive
> **Agent role**: **DO NOT MAKE TIME ESTIMATES**. Instead, use phases, milestones, and complexity levels. Time estimates are consistently wrong and create unrealistic expectations.
## 🎯 Purpose
Development time estimates are consistently wrong and create unrealistic expectations. This rule ensures we focus on phases, milestones, and complexity rather than trying to predict specific timeframes.
## 🚨 Critical Rule
**DO NOT MAKE TIME ESTIMATES**
- **Never provide specific time estimates** - they are always wrong
- **Use phases and milestones** instead of days/weeks
- **Focus on complexity and dependencies** rather than time
- **Set expectations based on progress, not deadlines**
## 📊 Planning Framework (Not Time Estimates)
### **Complexity Categories**
- **Simple**: Text changes, styling updates, minor bug fixes
- **Medium**: New features, refactoring, component updates
- **Complex**: Architecture changes, integrations, cross-platform work
- **Unknown**: New technologies, APIs, or approaches
### **Platform Complexity**
- **Single platform**: Web-only or mobile-only changes
- **Two platforms**: Web + mobile or web + desktop
- **Three platforms**: Web + mobile + desktop
- **Cross-platform consistency**: Ensuring behavior matches across all platforms
### **Testing Complexity**
- **Basic**: Unit tests for new functionality
- **Comprehensive**: Integration tests, cross-platform testing
- **User acceptance**: User testing, feedback integration
## 🔍 Planning Process (No Time Estimates)
### **Step 1: Break Down the Work**
- Identify all subtasks and dependencies
- Group related work into logical phases
- Identify critical path and blockers
### **Step 2: Define Phases and Milestones**
- **Phase 1**: Foundation work (basic fixes, core functionality)
- **Phase 2**: Enhancement work (new features, integrations)
- **Phase 3**: Polish work (testing, user experience, edge cases)
### **Step 3: Identify Dependencies**
- **Technical dependencies**: What must be built first
- **Platform dependencies**: What works on which platforms
- **Testing dependencies**: What can be tested when
### **Step 4: Set Progress Milestones**
- **Milestone 1**: Basic functionality working
- **Milestone 2**: All platforms supported
- **Milestone 3**: Fully tested and polished
## 📋 Planning Checklist (No Time Estimates)
- [ ] Work broken down into logical phases
- [ ] Dependencies identified and mapped
- [ ] Milestones defined with clear criteria
- [ ] Complexity levels assigned to each phase
- [ ] Platform requirements identified
- [ ] Testing strategy planned
- [ ] Risk factors identified
- [ ] Success criteria defined
## 🎯 Example Planning (No Time Estimates)
### **Example 1: Simple Feature**
```
Phase 1: Core implementation
- Basic functionality
- Single platform support
- Unit tests
Phase 2: Platform expansion
- Multi-platform support
- Integration tests
Phase 3: Polish
- User testing
- Edge case handling
```
### **Example 2: Complex Cross-Platform Feature**
```
Phase 1: Foundation
- Architecture design
- Core service implementation
- Basic web platform support
Phase 2: Platform Integration
- Mobile platform support
- Desktop platform support
- Cross-platform consistency
Phase 3: Testing & Polish
- Comprehensive testing
- Error handling
- User experience refinement
```
## 🚫 Anti-Patterns to Avoid
- **"This should take X days"** - Red flag for time estimation
- **"Just a few hours"** - Ignores complexity and testing
- **"Similar to X"** - Without considering differences
- **"Quick fix"** - Nothing is ever quick in software
- **"No testing needed"** - Testing always takes effort
## ✅ Best Practices
### **When Planning:**
1. **Break down everything** - no work is too small to plan
2. **Consider all platforms** - web, mobile, desktop differences
3. **Include testing strategy** - unit, integration, and user testing
4. **Account for unknowns** - there are always surprises
5. **Focus on dependencies** - what blocks what
### **When Presenting Plans:**
1. **Show the phases** - explain the logical progression
2. **Highlight dependencies** - what could block progress
3. **Define milestones** - clear success criteria
4. **Identify risks** - what could go wrong
5. **Suggest alternatives** - ways to reduce scope or complexity
## 🔄 Continuous Improvement
### **Track Progress**
- Record planned vs. actual phases completed
- Identify what took longer than expected
- Learn from complexity misjudgments
- Adjust planning process based on experience
### **Learn from Experience**
- **Underestimated complexity**: Increase complexity categories
- **Missed dependencies**: Improve dependency mapping
- **Platform surprises**: Better platform research upfront
## 🎯 Integration with Harbor Pilot
This rule works in conjunction with:
- **Project Planning**: Focuses on phases and milestones
- **Resource Allocation**: Based on complexity, not time
- **Risk Management**: Identifies blockers and dependencies
- **Stakeholder Communication**: Sets progress-based expectations
## 📝 Version History
### v2.0.0 (2025-08-21)
- **Major Change**: Completely removed time estimation approach
- **New Focus**: Phases, milestones, and complexity-based planning
- **Eliminated**: All time multipliers, estimates, and calculations
- **Added**: Dependency mapping and progress milestone framework
### v1.0.0 (2025-08-21)
- Initial creation based on user feedback about estimation accuracy
- ~~Established realistic estimation multipliers and process~~
- ~~Added comprehensive estimation checklist and examples~~
- Integrated with Harbor Pilot planning and risk management
---
## 🚨 Remember
**DO NOT MAKE TIME ESTIMATES. Use phases, milestones, and complexity instead. Focus on progress, not deadlines.**
## 🚨 Remember
**Your first estimate is wrong. Your second estimate is probably still wrong. Focus on progress, not deadlines.**
# No Time Estimates — Harbor Pilot Directive
> **Agent role**: **DO NOT MAKE TIME ESTIMATES**. Instead, use phases, milestones, and complexity levels. Time estimates are consistently wrong and create unrealistic expectations.
## 🎯 Purpose
Development time estimates are consistently wrong and create unrealistic expectations. This rule ensures we focus on phases, milestones, and complexity rather than trying to predict specific timeframes.
## 🚨 Critical Rule
**DO NOT MAKE TIME ESTIMATES**
- **Never provide specific time estimates** - they are always wrong
- **Use phases and milestones** instead of days/weeks
- **Focus on complexity and dependencies** rather than time
- **Set expectations based on progress, not deadlines**
## 📊 Planning Framework (Not Time Estimates)
### **Complexity Categories**
- **Simple**: Text changes, styling updates, minor bug fixes
- **Medium**: New features, refactoring, component updates
- **Complex**: Architecture changes, integrations, cross-platform work
- **Unknown**: New technologies, APIs, or approaches
### **Platform Complexity**
- **Single platform**: Web-only or mobile-only changes
- **Two platforms**: Web + mobile or web + desktop
- **Three platforms**: Web + mobile + desktop
- **Cross-platform consistency**: Ensuring behavior matches across all platforms
### **Testing Complexity**
- **Basic**: Unit tests for new functionality
- **Comprehensive**: Integration tests, cross-platform testing
- **User acceptance**: User testing, feedback integration
## 🔍 Planning Process (No Time Estimates)
### **Step 1: Break Down the Work**
- Identify all subtasks and dependencies
- Group related work into logical phases
- Identify critical path and blockers
### **Step 2: Define Phases and Milestones**
- **Phase 1**: Foundation work (basic fixes, core functionality)
- **Phase 2**: Enhancement work (new features, integrations)
- **Phase 3**: Polish work (testing, user experience, edge cases)
### **Step 3: Identify Dependencies**
- **Technical dependencies**: What must be built first
- **Platform dependencies**: What works on which platforms
- **Testing dependencies**: What can be tested when
### **Step 4: Set Progress Milestones**
- **Milestone 1**: Basic functionality working
- **Milestone 2**: All platforms supported
- **Milestone 3**: Fully tested and polished
## 📋 Planning Checklist (No Time Estimates)
- [ ] Work broken down into logical phases
- [ ] Dependencies identified and mapped
- [ ] Milestones defined with clear criteria
- [ ] Complexity levels assigned to each phase
- [ ] Platform requirements identified
- [ ] Testing strategy planned
- [ ] Risk factors identified
- [ ] Success criteria defined
## 🎯 Example Planning (No Time Estimates)
### **Example 1: Simple Feature**
```
Phase 1: Core implementation
- Basic functionality
- Single platform support
- Unit tests
Phase 2: Platform expansion
- Multi-platform support
- Integration tests
Phase 3: Polish
- User testing
- Edge case handling
```
### **Example 2: Complex Cross-Platform Feature**
```
Phase 1: Foundation
- Architecture design
- Core service implementation
- Basic web platform support
Phase 2: Platform Integration
- Mobile platform support
- Desktop platform support
- Cross-platform consistency
Phase 3: Testing & Polish
- Comprehensive testing
- Error handling
- User experience refinement
```
## 🚫 Anti-Patterns to Avoid
- **"This should take X days"** - Red flag for time estimation
- **"Just a few hours"** - Ignores complexity and testing
- **"Similar to X"** - Without considering differences
- **"Quick fix"** - Nothing is ever quick in software
- **"No testing needed"** - Testing always takes effort
## ✅ Best Practices
### **When Planning:**
1. **Break down everything** - no work is too small to plan
2. **Consider all platforms** - web, mobile, desktop differences
3. **Include testing strategy** - unit, integration, and user testing
4. **Account for unknowns** - there are always surprises
5. **Focus on dependencies** - what blocks what
### **When Presenting Plans:**
1. **Show the phases** - explain the logical progression
2. **Highlight dependencies** - what could block progress
3. **Define milestones** - clear success criteria
4. **Identify risks** - what could go wrong
5. **Suggest alternatives** - ways to reduce scope or complexity
## 🔄 Continuous Improvement
### **Track Progress**
- Record planned vs. actual phases completed
- Identify what took longer than expected
- Learn from complexity misjudgments
- Adjust planning process based on experience
### **Learn from Experience**
- **Underestimated complexity**: Increase complexity categories
- **Missed dependencies**: Improve dependency mapping
- **Platform surprises**: Better platform research upfront
## 🎯 Integration with Harbor Pilot
This rule works in conjunction with:
- **Project Planning**: Focuses on phases and milestones
- **Resource Allocation**: Based on complexity, not time
- **Risk Management**: Identifies blockers and dependencies
- **Stakeholder Communication**: Sets progress-based expectations
## 📝 Version History
### v2.0.0 (2025-08-21)
- **Major Change**: Completely removed time estimation approach
- **New Focus**: Phases, milestones, and complexity-based planning
- **Eliminated**: All time multipliers, estimates, and calculations
- **Added**: Dependency mapping and progress milestone framework
### v1.0.0 (2025-08-21)
- Initial creation based on user feedback about estimation accuracy
- ~~Established realistic estimation multipliers and process~~
- ~~Added comprehensive estimation checklist and examples~~
- Integrated with Harbor Pilot planning and risk management
---
## 🚨 Remember
**DO NOT MAKE TIME ESTIMATES. Use phases, milestones, and complexity instead. Focus on progress, not deadlines.**
## 🚨 Remember
**Your first estimate is wrong. Your second estimate is probably still wrong. Focus on progress, not deadlines.**

View File

@@ -1,174 +0,0 @@
---
description: Use this workflow when doing **pre-implementation research, defect investigations with uncertain repros, or clarifying system architecture and behaviors**.
alwaysApply: false
---
```json
{
"coaching_level": "light",
"socratic_max_questions": 2,
"verbosity": "concise",
"timebox_minutes": null,
"format_enforcement": "strict"
}
```
# Research & Diagnostic Workflow (R&D)
## Purpose
Provide a **repeatable, evidence-first** workflow to investigate features and
defects **before coding**. Outputs are concise reports, hypotheses, and next
steps—**not** code changes.
## When to Use
- Pre-implementation research for new features
- Defect investigations (repros uncertain, user-specific failures)
- Architecture/behavior clarifications (e.g., auth flows, merges, migrations)
---
## 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
---
## Output Contract (strict)
1) **Objective** — 12 lines
2) **System Map (if helpful)** — short diagram or bullet flow (≤8 bullets)
3) **Findings (Evidence-linked)** — bullets; each with file/function refs
4) **Hypotheses & Failure Modes** — short list, each testable
5) **Corrections** — explicit deltas from earlier assumptions (if any)
6) **Diagnostics** — what to check next (logs, DB, env, repro steps)
7) **Risks & Scope** — what could break; affected components
8) **Decision/Next Steps** — what we'll do, who's involved, by when
9) **References** — code paths, ADRs, docs
10) **Competence & Collaboration Hooks** — brief, skimmable
> Keep total length lean. Prefer links and bullets over prose.
---
## Quickstart Template
Copy/paste and fill:
```md
# Investigation — <short title>
## Objective
<one or two lines>
## System Map
- <module> → <function> → <downstream>
- <data path> → <db table> → <api>
## Findings (Evidence)
- <claim> — evidence: `src/path/file.ts:function` (lines XY); log snippet/trace id
- <claim> — evidence: `...`
## Hypotheses & Failure Modes
- H1: <hypothesis>; would fail when <condition>
- H2: <hypothesis>; watch for <signal>
## Corrections
- Updated: <old statement> → <new statement with evidence>
## Diagnostics (Next Checks)
- [ ] Repro on <platform/version>
- [ ] Inspect <table/store> for <record>
- [ ] Capture <log/trace>
## Risks & Scope
- Impacted: <areas/components>; Data: <tables/keys>; Users: <segments>
## Decision / Next Steps
- Owner: <name>; By: <date> (YYYY-MM-DD)
- Action: <spike/bugfix/ADR>; Exit criteria: <binary checks>
## References
- `src/...`
- ADR: `docs/adr/xxxx-yy-zz-something.md`
- Design: `docs/...`
## Competence Hooks
- Why this works: <≤3 bullets>
- Common pitfalls: <≤3 bullets>
- Next skill: <≤1 item>
- Teach-back: "<one question>"
```
---
## Evidence Quality Bar
- **Cite the source** (file:func, line range if possible).
- **Prefer primary evidence** (code, logs) over inference.
- **Disambiguate platform** (Web/Capacitor/Electron) and **state** (migration, auth).
- **Note uncertainty** explicitly.
---
## 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
- [ ] **Exit Points**: Confirm where the flow ends and what results
- [ ] **Evidence Collection**: Gather specific code citations for each step
---
## Collaboration Hooks
- **Syncs:** 1015m with QA/Security/Platform owners for high-risk areas.
- **ADR:** Record major decisions; link here.
- **Review:** Share repro + diagnostics checklist in PR/issue.
---
## 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
---
## Self-Check (model, before responding)
- [ ] Output matches the **Output Contract** sections.
- [ ] Each claim has **evidence** or **uncertainty** is flagged.
- [ ] Hypotheses are testable; diagnostics are actionable.
- [ ] Competence + collaboration hooks present (≤120 words total).
- [ ] Respect toggles; keep it concise.
- [ ] **Code path traced** (for software investigations).
- [ ] **Evidence validated** against actual code execution.
---
## Optional Globs (examples)
> Uncomment `globs` in the header if you want auto-attach behavior.
- `src/platforms/**`, `src/services/**` — attach during service/feature investigations
- `docs/adr/**` — attach when editing ADRs
## Referenced Files
- Consider including templates as context: `@adr_template.mdc`, `@investigation_report_example.mdc`

View File

@@ -1,225 +0,0 @@
# 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.
## 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
- **Assumption Validation**: Flag assumptions as "assumed" vs "evidence-based"
### 2. Code Review Standards
- **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
### 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
## Usage Guidelines
### When to Use This Ruleset
- Code reviews and architectural decisions
- Bug investigation and debugging
- Performance optimization
- Feature implementation planning
- 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
- [ ] Solution complexity justified by evidence
- [ ] Simpler alternatives considered and documented
- [ ] Impact on existing systems assessed
- [ ] Dependencies validated and accessible
- [ ] Environment impact assessed for team members
- [ ] Pre-build validation implemented where appropriate
## Additional Core Principles
### 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
## Additional Required Workflows
### Dependency Validation (Before Proposing Changes)
- [ ] **Dependency Validation**: Verify all required dependencies are available and accessible
### Environment Impact Assessment (During Solution Design)
- [ ] **Environment Impact**: Assess how changes affect team member setups
## Additional Competence Hooks
### 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
- **Narrow Types Properly**: Use type guards to narrow `unknown` types safely
- **Document Type Decisions**: Explain complex type structures and their purpose

View File

@@ -1,329 +0,0 @@
---
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

View File

@@ -0,0 +1,276 @@
---
description:
globs:
alwaysApply: true
---
---
description:
globs:
alwaysApply: true
---
# Time Safari 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.
The ultimate goals of Time Safari are two-fold:
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.
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.
## Core Approaches
Time Safari should help everyday users build meaningful connections and organize collective efforts by:
1. **Recognizing Contributions**: Creating permanent, verifiable records of gifts and contributions people give to each other and their communities.
2. **Facilitating Collaboration**: Making it ridiculously easy for people to ask for or propose help on projects and interests that matter to them.
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.
4. **Preserving Privacy**: Ensuring personal identifiers are only shared with explicitly authorized contacts, allowing private individuals including children to participate safely.
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.
## Technical Foundation
This application is built on a privacy-preserving claims architecture (via endorser.ch) with these key characteristics:
- **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
## User Journey
The typical progression of usage follows these stages:
1. **Gratitude & Recognition**: Users begin by expressing and recording gratitude for gifts received, building a foundation of acknowledgment.
2. **Project Proposals**: Users propose projects and ideas, reaching out to connect with others who share similar interests.
3. **Action Triggers**: Offers of help serve as triggers and motivations to execute proposed projects, moving from ideas to action.
## Context for LLM Development
When developing new functionality for Time Safari, consider these design principles:
1. **Accessibility First**: Features should be usable by non-technical users with minimal learning curve.
2. **Privacy by Design**: All features must respect user privacy and data sovereignty.
3. **Progressive Enhancement**: Core functionality should work across all devices, with richer experiences where supported.
4. **Voluntary Collaboration**: The system should enable but never coerce participation.
5. **Trust Building**: Features should help build verifiable trust between users.
6. **Network Effects**: Consider how features scale as more users join the platform.
7. **Low Resource Requirements**: The system should be lightweight enough to run on inexpensive devices users already own.
## Use Cases to Support
LLM development should focus on enhancing these key use cases:
1. **Community Building**: Tools that help people find others with shared interests and values.
2. **Project Coordination**: Features that make it easy to propose collaborative projects and to submit suggestions and offers to existing ones.
3. **Reputation Building**: Methods for users to showcase their contributions and reliability, in contexts where they explicitly reveal that information.
4. **Governance Experimentation**: Features that facilitate decision-making and collective governance.
## Constraints
When developing new features, be mindful of these constraints:
1. **Privacy Preservation**: User identifiers must remain private except when explicitly shared.
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
### 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
### Continuous Integration/Continuous Deployment (CI/CD)
- Automated testing on every commit
- Consistent build process across platforms
- Automated deployment pipelines
- Quality gates for code merging
- Environment-specific configurations
This expanded documentation provides:
1. Clear principles for development
2. Practical implementation guidelines
3. Real-world examples
4. TypeScript integration
5. Best practices for Time Safari

View File

@@ -1,335 +0,0 @@
---
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.
## 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`
### 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)
```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)
- [ ] List changed files + 12 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
---
**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`
### 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)
```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)
- [ ] List changed files + 12 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
---
**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

View File

@@ -15,7 +15,7 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
# Build outputs # Build outputs
# dist - Allow dist directory for Docker builds (contains pre-built assets) dist
dist-* dist-*
build build
*.tsbuildinfo *.tsbuildinfo
@@ -140,7 +140,7 @@ docker-compose*
.dockerignore .dockerignore
# CI/CD files # CI/CD files
.github
.gitlab-ci.yml .gitlab-ci.yml
.travis.yml .travis.yml
.circleci .circleci

View File

@@ -1,14 +1,10 @@
# Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.
# Logging Configuration - Development environment gets maximum visibility # Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.
VITE_LOG_LEVEL=debug
# iOS doesn't like spaces in the app title. # iOS doesn't like spaces in the app title.
TIME_SAFARI_APP_TITLE="TimeSafari_Dev" TIME_SAFARI_APP_TITLE="TimeSafari_Dev"
VITE_APP_SERVER=http://localhost:8080 VITE_APP_SERVER=http://localhost:8080
# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not # This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production).
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000 VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000
# Using shared server by default to ease setup, which works for shared test users. # Using shared server by default to ease setup, which works for shared test users.

View File

@@ -1,7 +1,6 @@
# Only the variables that start with VITE_ are seen in the application import.meta.env in Vue. # Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.
# Logging Configuration - Production environment gets minimal logging for performance
VITE_LOG_LEVEL=warn
VITE_APP_SERVER=https://timesafari.app VITE_APP_SERVER=https://timesafari.app
# This is the claim ID for actions in the BVC project. # This is the claim ID for actions in the BVC project.

View File

@@ -1,14 +1,9 @@
# Only the variables that start with VITE_ are seen in the application import.meta.env in Vue. # Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.
# Logging Configuration - Test environment gets balanced logging for debugging
VITE_LOG_LEVEL=info
# iOS doesn't like spaces in the app title. # iOS doesn't like spaces in the app title.
TIME_SAFARI_APP_TITLE="TimeSafari_Test" TIME_SAFARI_APP_TITLE="TimeSafari_Test"
VITE_APP_SERVER=https://test.timesafari.app VITE_APP_SERVER=https://test.timesafari.app
# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not
# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production). # This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production).
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch

View File

@@ -30,7 +30,7 @@ module.exports = {
}], }],
"no-console": process.env.NODE_ENV === "production" ? "error" : "warn", "no-console": process.env.NODE_ENV === "production" ? "error" : "warn",
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "warn", "no-debugger": process.env.NODE_ENV === "production" ? "error" : "warn",
"@typescript-eslint/no-explicit-any": "error", "@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-unnecessary-type-constraint": "off", "@typescript-eslint/no-unnecessary-type-constraint": "off",
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }] "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]

27
.github/workflows/playwright.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30

43
.gitignore vendored
View File

@@ -55,35 +55,7 @@ build_logs/
icons icons
*.log *.log
android/app/src/main/res/
# Build outputs
dist/
build/
# Generated Android assets and resources (should be generated during build)
android/app/src/main/assets/public/
# Generated Android resources (icons, splash screens, etc.)
android/app/src/main/res/drawable*/
android/app/src/main/res/mipmap*/
android/app/src/main/res/values/ic_launcher_background.xml
# Android generated assets (deny-listed in CI)
android/app/src/main/res/mipmap-*/ic_launcher*.png
android/app/src/main/res/drawable*/splash*.png
# iOS generated assets (deny-listed in CI)
ios/App/App/Assets.xcassets/**/AppIcon*.png
ios/App/App/Assets.xcassets/**/Splash*.png
# Keep these Android configuration files in version control:
# - android/app/src/main/assets/capacitor.plugins.json
# - android/app/src/main/res/values/strings.xml
# - android/app/src/main/res/values/styles.xml
# - android/app/src/main/res/layout/activity_main.xml
# - android/app/src/main/res/xml/config.xml
# - android/app/src/main/res/xml/file_paths.xml
sql-wasm.wasm sql-wasm.wasm
# Temporary and generated files # Temporary and generated files
@@ -111,7 +83,11 @@ ios/App/App/public/assets/
ios/App/App/build/ ios/App/App/build/
ios/App/build/ ios/App/build/
# Capacitor build artifacts (covered by android/app/build/ above) # Capacitor generated configs (keep source configs)
android/app/build/intermediates/assets/debug/mergeDebugAssets/capacitor.*.json
android/app/build/intermediates/compressed_assets/debug/compressDebugAssets/out/assets/capacitor.*.json.jar
android/app/build/intermediates/merged_java_res/debug/mergeDebugJavaResource/feature-capacitor-cordova-android-plugins.jar
android/app/build/outputs/aar/capacitor-cordova-android-plugins-debug.aar
# Keep these Capacitor files in version control: # Keep these Capacitor files in version control:
# - capacitor.config.json (root, electron, ios) # - capacitor.config.json (root, electron, ios)
@@ -135,9 +111,4 @@ electron/out/
# - electron/electron-builder.config.json # - electron/electron-builder.config.json
# - electron/build-packages.sh # - electron/build-packages.sh
# - electron/live-runner.js # - electron/live-runner.js
# - electron/resources/electron-publisher-custom.js # - electron/resources/electron-publisher-custom.js
# Gradle cache files
android/.gradle/file-system.probe
android/.gradle/caches/
coverage

View File

@@ -1,40 +0,0 @@
#!/usr/bin/env sh
#
# Husky Helper Script
# This file is sourced by all Husky hooks
#
if [ -z "$husky_skip_init" ]; then
debug () {
if [ "$HUSKY_DEBUG" = "1" ]; then
echo "husky (debug) - $1"
fi
}
readonly hook_name="$(basename -- "$0")"
debug "starting $hook_name..."
if [ "$HUSKY" = "0" ]; then
debug "HUSKY env variable is set to 0, skipping hook"
exit 0
fi
if [ -f ~/.huskyrc ]; then
debug "sourcing ~/.huskyrc"
. ~/.huskyrc
fi
readonly husky_skip_init=1
export husky_skip_init
sh -e "$0" "$@"
exitCode="$?"
if [ $exitCode != 0 ]; then
echo "husky - $hook_name hook exited with code $exitCode (error)"
fi
if [ $exitCode = 127 ]; then
echo "husky - command not found in PATH=$PATH"
fi
exit $exitCode
fi

View File

@@ -1,10 +0,0 @@
#!/usr/bin/env bash
#
# Husky Commit Message Hook
# Validates commit message format using commitlint
#
. "$(dirname -- "$0")/_/husky.sh"
# Run commitlint but don't fail the commit (|| true)
# This provides helpful feedback without blocking commits
npx commitlint --edit "$1" || true

View File

@@ -1,15 +0,0 @@
#!/usr/bin/env bash
#
# Husky Pre-commit Hook
# Runs Build Architecture Guard to check staged files
#
. "$(dirname -- "$0")/_/husky.sh"
echo "🔍 Running Build Architecture Guard (pre-commit)..."
bash ./scripts/build-arch-guard.sh --staged || {
echo
echo "💡 To bypass this check for emergency commits, use:"
echo " git commit --no-verify"
echo
exit 1
}

View File

@@ -1,27 +0,0 @@
#!/usr/bin/env bash
#
# Husky Pre-push Hook
# Runs Build Architecture Guard to check commits being pushed
#
. "$(dirname -- "$0")/_/husky.sh"
echo "🔍 Running Build Architecture Guard (pre-push)..."
# Get the remote branch we're pushing to
REMOTE_BRANCH="origin/$(git rev-parse --abbrev-ref HEAD)"
# Check if remote branch exists
if git show-ref --verify --quiet "refs/remotes/$REMOTE_BRANCH"; then
RANGE="$REMOTE_BRANCH...HEAD"
else
# If remote branch doesn't exist, check last commit
RANGE="HEAD~1..HEAD"
fi
bash ./scripts/build-arch-guard.sh --range "$RANGE" || {
echo
echo "💡 To bypass this check for emergency pushes, use:"
echo " git push --no-verify"
echo
exit 1
}

View File

@@ -1 +0,0 @@
18.19.0

1
.nvmrc
View File

@@ -1 +0,0 @@
18.19.0

File diff suppressed because it is too large Load Diff

View File

@@ -5,90 +5,55 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.0.7] - 2025.08.18 ## [1.0.3] - 2025.07.12
### Fixed
- Deep link for onboard-meeting-members
## [1.0.6] - 2025.08.09
### Fixed
- Deep link errors where none would validate
## [1.0.5] - 2025.07.24
### Fixed
- Export & import of contacts corrupted contact methods
## [1.0.4] - 2025.07.20 - 002f2407208d56cc59c0aa7c880535ae4cbace8b
### Fixed
- Deep link for invite-one-accept
## [1.0.3] - 2025.07.12 - a9a8ba217cd6015321911e98e6843e988dc2c4ae
### Changed ### Changed
- Photo is pinned to profile mode - Photo is pinned to profile mode
### Fixed ### Fixed
- Deep link URLs (and other prod settings) - Deep link URLs (and other prod settings)
- Error in BVC begin view - Error in BVC begin view
## [Unreleased]
### Changed
- Photo is pinned to profile mode
## [1.0.2] - 2025.06.20 - 276e0a741bc327de3380c4e508cccb7fee58c06d ## [1.0.2] - 2025.06.20 - 276e0a741bc327de3380c4e508cccb7fee58c06d
### Added ### Added
- Version on feed title - Version on feed title
## [1.0.1] - 2025.06.20 ## [1.0.1] - 2025.06.20
### Added ### Added
- Allow a user to block someone else's content from view - Allow a user to block someone else's content from view
## [1.0.0] - 2025.06.20 - 5aa693de6337e5dbb278bfddc6bd39094bc14f73 ## [1.0.0] - 2025.06.20 - 5aa693de6337e5dbb278bfddc6bd39094bc14f73
### Added ### Added
- Web-oriented migration from IndexedDB to SQLite - Web-oriented migration from IndexedDB to SQLite
## [0.5.8] ## [0.5.8]
### Added ### Added
- /deep-link/ path for URLs that are shared with people - /deep-link/ path for URLs that are shared with people
### Changed ### Changed
- External links now go to /deep-link/... - External links now go to /deep-link/...
- Feed visuals now have arrow imagery from giver to receiver - Feed visuals now have arrow imagery from giver to receiver
## [0.4.7] ## [0.4.7]
### Fixed ### Fixed
- Cameras everywhere - Cameras everywhere
### Changed ### Changed
- IndexedDB -> SQLite - IndexedDB -> SQLite
## [0.4.5] - 2025.02.23 ## [0.4.5] - 2025.02.23
### Added ### Added
- Total amounts of gives on project page - Total amounts of gives on project page
### Changed in DB or environment ### Changed in DB or environment
- Requires Endorser.ch version 4.2.6+ - Requires Endorser.ch version 4.2.6+
## [0.4.4] - 2025.02.17 ## [0.4.4] - 2025.02.17
### Fixed in 0.4.4 ### Fixed in 0.4.4

View File

@@ -36,10 +36,6 @@
# Environment Variables: # Environment Variables:
# NODE_ENV: Build environment (development/production) # NODE_ENV: Build environment (development/production)
# BUILD_MODE: Build mode for asset selection (development/test/production) # BUILD_MODE: Build mode for asset selection (development/test/production)
#
# Build Context:
# This Dockerfile is designed to work when the build context is set to
# ./crowd-funder-for-time-pwa from the parent directory (where docker-compose.yml is located)
# ============================================================================= # =============================================================================
# BASE STAGE - Common dependencies and setup # BASE STAGE - Common dependencies and setup
@@ -66,7 +62,6 @@ RUN addgroup -g 1001 -S nodejs && \
WORKDIR /app WORKDIR /app
# Copy package files for dependency installation # Copy package files for dependency installation
# Note: These files are in the project root (crowd-funder-for-time-pwa directory)
COPY package*.json ./ COPY package*.json ./
# Install dependencies with security audit # Install dependencies with security audit
@@ -87,7 +82,6 @@ ENV BUILD_MODE=${BUILD_MODE}
ENV NODE_ENV=${NODE_ENV} ENV NODE_ENV=${NODE_ENV}
# Copy pre-built assets from host # Copy pre-built assets from host
# Note: dist/ directory is in the project root (crowd-funder-for-time-pwa directory)
COPY dist/ ./dist/ COPY dist/ ./dist/
# Verify build output exists # Verify build output exists
@@ -113,21 +107,23 @@ RUN apk update && \
curl \ curl \
&& rm -rf /var/cache/apk/* && rm -rf /var/cache/apk/*
# Use existing nginx user from base image (nginx user and group already exist) # Create non-root user for nginx
# No need to create new user as nginx:alpine already has nginx user RUN addgroup -g 1001 -S nginx && \
adduser -S nginx -u 1001 -G nginx
# Copy main nginx configuration # Copy appropriate nginx configuration based on build mode
COPY docker/nginx.conf /etc/nginx/nginx.conf COPY docker/nginx.conf /etc/nginx/nginx.conf
# Copy production nginx configuration
COPY docker/default.conf /etc/nginx/conf.d/default.conf COPY docker/default.conf /etc/nginx/conf.d/default.conf
# Copy staging configuration if needed
COPY docker/staging.conf /etc/nginx/conf.d/staging.conf
# Copy built assets from builder stage # Copy built assets from builder stage
COPY --from=builder --chown=nginx:nginx /app/dist /usr/share/nginx/html COPY --from=builder --chown=nginx:nginx /app/dist /usr/share/nginx/html
# Create necessary directories with proper permissions # Create necessary directories with proper permissions
RUN mkdir -p /var/cache/nginx /var/log/nginx /tmp && \ RUN mkdir -p /var/cache/nginx /var/log/nginx /var/run && \
chown -R nginx:nginx /var/cache/nginx /var/log/nginx /tmp && \ chown -R nginx:nginx /var/cache/nginx /var/log/nginx /var/run && \
chown -R nginx:nginx /usr/share/nginx/html chown -R nginx:nginx /usr/share/nginx/html
# Switch to non-root user # Switch to non-root user
@@ -143,6 +139,8 @@ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
# Start nginx with proper signal handling # Start nginx with proper signal handling
CMD ["nginx", "-g", "daemon off;"] CMD ["nginx", "-g", "daemon off;"]
# ============================================================================= # =============================================================================
# TEST STAGE - For test environment testing # TEST STAGE - For test environment testing
# ============================================================================= # =============================================================================

View File

@@ -1,4 +1,5 @@
source "https://rubygems.org" source "https://rubygems.org"
gem "fastlane"
gem "cocoapods" gem "cocoapods"

View File

@@ -22,7 +22,26 @@ GEM
algoliasearch (1.27.5) algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3) httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1) json (>= 1.5.1)
artifactory (3.0.17)
atomos (0.1.3) atomos (0.1.3)
aws-eventstream (1.3.2)
aws-partitions (1.1066.0)
aws-sdk-core (3.220.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
base64
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.99.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.182.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.11.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0) base64 (0.2.0)
benchmark (0.4.0) benchmark (0.4.0)
bigdecimal (3.1.9) bigdecimal (3.1.9)
@@ -64,13 +83,96 @@ GEM
nap (>= 0.8, < 2.0) nap (>= 0.8, < 2.0)
netrc (~> 0.11) netrc (~> 0.11)
cocoapods-try (1.2.0) cocoapods-try (1.2.0)
colored (1.2)
colored2 (3.1.2) colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
concurrent-ruby (1.3.5) concurrent-ruby (1.3.5)
connection_pool (2.5.0) connection_pool (2.5.0)
declarative (0.0.20)
digest-crc (0.7.0)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.6.20240107)
dotenv (2.8.1)
drb (2.2.1) drb (2.2.1)
emoji_regex (3.2.3)
escape (0.0.4) escape (0.0.4)
ethon (0.16.0) ethon (0.16.0)
ffi (>= 1.15.0) ffi (>= 1.15.0)
excon (0.112.0)
faraday (1.10.4)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-cookie_jar (0.0.7)
faraday (>= 0.8.0)
http-cookie (~> 1.0.0)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.1.0)
multipart-post (~> 2.0)
faraday-net_http (1.0.2)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
faraday_middleware (1.2.1)
faraday (~> 1.0)
fastimage (2.4.0)
fastlane (2.227.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
aws-sdk-s3 (~> 1.0)
babosa (>= 1.0.3, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored (~> 1.2)
commander (~> 4.6)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 4.0)
excon (>= 0.71.0, < 1.0.0)
faraday (~> 1.0)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 1.0)
fastimage (>= 2.1.0, < 3.0.0)
fastlane-sirp (>= 1.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-apis-androidpublisher_v3 (~> 0.3)
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-env (>= 1.6.0, < 2.0.0)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
http-cookie (~> 1.0.5)
json (< 3.0.0)
jwt (>= 2.1.0, < 3)
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (>= 2.0.0, < 3.0.0)
naturally (~> 2.2)
optparse (>= 0.1.1, < 1.0.0)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.5)
simctl (~> 1.6.3)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (~> 3)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.4.0)
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
fastlane-sirp (1.0.0)
sysrandom (~> 1.0)
ffi (1.17.1) ffi (1.17.1)
ffi (1.17.1-aarch64-linux-gnu) ffi (1.17.1-aarch64-linux-gnu)
ffi (1.17.1-aarch64-linux-musl) ffi (1.17.1-aarch64-linux-musl)
@@ -85,27 +187,107 @@ GEM
fourflusher (2.3.1) fourflusher (2.3.1)
fuzzy_match (2.0.4) fuzzy_match (2.0.4)
gh_inspector (1.1.3) gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.54.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-core (0.11.3)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.a)
rexml
google-apis-iamcredentials_v1 (0.17.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-playcustomapp_v1 (0.13.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-storage_v1 (0.31.0)
google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.8.0)
google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.5.0)
google-cloud-storage (1.47.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.31.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.8.1)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.8)
domain_name (~> 0.5)
httpclient (2.9.0) httpclient (2.9.0)
mutex_m mutex_m
i18n (1.14.7) i18n (1.14.7)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
jmespath (1.6.2)
json (2.10.2) json (2.10.2)
jwt (2.10.1)
base64
logger (1.6.6) logger (1.6.6)
mini_magick (4.13.2)
mini_mime (1.1.5)
minitest (5.25.5) minitest (5.25.5)
molinillo (0.8.0) molinillo (0.8.0)
multi_json (1.15.0)
multipart-post (2.4.1)
mutex_m (0.3.0) mutex_m (0.3.0)
nanaimo (0.4.0) nanaimo (0.4.0)
nap (1.1.0) nap (1.1.0)
naturally (2.2.1)
netrc (0.11.0) netrc (0.11.0)
nkf (0.2.0) nkf (0.2.0)
optparse (0.6.0)
os (1.1.4)
plist (3.7.2)
public_suffix (4.0.7) public_suffix (4.0.7)
rake (13.2.1)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.4.1) rexml (3.4.1)
rouge (3.28.0)
ruby-macho (2.5.1) ruby-macho (2.5.1)
ruby2_keywords (0.0.5)
rubyzip (2.4.1)
securerandom (0.4.1) securerandom (0.4.1)
security (0.1.5)
signet (0.19.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.10)
CFPropertyList
naturally
sysrandom (1.0.5)
terminal-notifier (2.0.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
tty-screen (0.8.2)
tty-spinner (0.9.3)
tty-cursor (~> 0.7)
typhoeus (1.4.1) typhoeus (1.4.1)
ethon (>= 0.9.0) ethon (>= 0.9.0)
tzinfo (2.0.6) tzinfo (2.0.6)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
uber (0.1.0)
unicode-display_width (2.6.0)
word_wrap (1.0.0)
xcodeproj (1.27.0) xcodeproj (1.27.0)
CFPropertyList (>= 2.3.3, < 4.0) CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3) atomos (~> 0.1.3)
@@ -113,6 +295,10 @@ GEM
colored2 (~> 3.1) colored2 (~> 3.1)
nanaimo (~> 0.4.0) nanaimo (~> 0.4.0)
rexml (>= 3.3.6, < 4.0) rexml (>= 3.3.6, < 4.0)
xcpretty (0.4.0)
rouge (~> 3.28.0)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS PLATFORMS
aarch64-linux-gnu aarch64-linux-gnu
@@ -129,6 +315,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
cocoapods cocoapods
fastlane
BUNDLED WITH BUNDLED WITH
2.6.5 2.6.5

View File

@@ -1,290 +0,0 @@
# Build Architecture Guard - Husky Implementation
## Overview
The Build Architecture Guard protects your build system by enforcing
documentation requirements through **Git hooks**. When you modify
build-critical files, the system automatically blocks commits/pushes
until you update `BUILDING.md`.
## 🎯 **Why Husky-Only?**
**Advantages:**
-**Immediate feedback** - Hooks run before commit/push
-**Works everywhere** - No server-side CI/CD required
-**Simple setup** - One tool, one configuration
-**Fast execution** - No network delays or server queues
-**Offline support** - Works without internet connection
**Trade-offs:**
- ⚠️ **Can be bypassed** - `git commit --no-verify` or `git push --no-verify`
- ⚠️ **Developer discipline** - Relies on team following the rules
## 🏗️ **Architecture**
```bash
Developer Workflow:
1. Modify build files (scripts/, vite.config.*, etc.)
2. Try to commit → Husky pre-commit hook runs
3. Guard script checks if BUILDING.md was updated
4. ✅ Commit succeeds if docs updated
5. ❌ Commit blocked if docs missing
```
## 🚀 **Quick Start**
### 1. Install Dependencies
```bash
npm install
npm run prepare # Sets up Husky hooks
```
### 2. Test the System
```bash
# Modify a build file without updating BUILDING.md
echo "# test" >> scripts/test.sh
# Try to commit (should be blocked)
git add scripts/test.sh
git commit -m "test: add build script"
# ❌ Hook blocks commit with helpful message
```
### 3. Fix and Retry
```bash
# Update BUILDING.md with your changes
echo "## New Build Script" >> BUILDING.md
echo "Added test.sh for testing purposes" >> BUILDING.md
# Now commit should succeed
git add BUILDING.md
git commit -m "feat: add test build script with docs"
# ✅ Commit succeeds
```
## 🔧 **How It Works**
### Pre-commit Hook (`.husky/pre-commit`)
- **When**: Every `git commit`
- **What**: Runs `./scripts/build-arch-guard.sh --staged`
- **Result**: Blocks commit if build files changed without BUILDING.md update
### Pre-push Hook (`.husky/pre-push`)
- **When**: Every `git push`
- **What**: Runs `./scripts/build-arch-guard.sh --range`
- **Result**: Blocks push if commits contain undocumented build changes
### Guard Script (`scripts/build-arch-guard.sh`)
- **Detects**: Changes to build-sensitive file patterns
- **Validates**: BUILDING.md was updated alongside changes
- **Reports**: Clear error messages with guidance
## 📁 **Protected File Patterns**
The guard script monitors these paths for changes:
```text
Build Configuration:
├── vite.config.* # Vite configuration
├── capacitor.config.ts # Capacitor configuration
├── package.json # Package configuration
├── package-lock.json # Lock files
├── yarn.lock
└── pnpm-lock.yaml
Build Scripts:
├── scripts/** # All build and automation scripts
├── electron/** # Electron build files
├── android/** # Android build configuration
├── ios/** # iOS build configuration
├── sw_scripts/** # Service worker scripts
└── sw_combine.js # Service worker combination
Deployment:
├── Dockerfile # Docker configuration
└── docker/** # Docker services
```
## 🎭 **Usage Scenarios**
### Scenario 1: Adding a New Build Script
```bash
# ❌ This will be blocked
echo '#!/bin/bash' > scripts/new-build.sh
git add scripts/new-build.sh
git commit -m "feat: add new build script"
# Hook blocks: "Build-sensitive files changed but BUILDING.md not updated"
# ✅ This will succeed
echo '#!/bin/bash' > scripts/new-build.sh
echo '## New Build Script' >> BUILDING.md
echo 'Added new-build.sh for feature X' >> BUILDING.md
git add scripts/new-build.sh BUILDING.md
git commit -m "feat: add new build script with docs"
# ✅ Commit succeeds
```
### Scenario 2: Updating Vite Configuration
```bash
# ❌ This will be blocked
echo 'export default { newOption: true }' >> vite.config.ts
git add vite.config.ts
git commit -m "config: add new vite option"
# Hook blocks: "Build-sensitive files changed but BUILDING.md not updated"
# ✅ This will succeed
echo 'export default { newOption: true }' >> vite.config.ts
echo '### New Vite Option' >> BUILDING.md
echo 'Added newOption for improved performance' >> BUILDING.md
git add vite.config.ts BUILDING.md
git commit -m "config: add new vite option with docs"
# ✅ Commit succeeds
```
## 🚨 **Emergency Bypass**
**⚠️ Use sparingly and only for emergencies:**
```bash
# Skip pre-commit hook
git commit -m "emergency: critical fix" --no-verify
# Skip pre-push hook
git push --no-verify
# Remember to update BUILDING.md later!
```
## 🔍 **Troubleshooting**
### Hooks Not Running
```bash
# Reinstall hooks
npm run prepare
# Check hook files exist and are executable
ls -la .husky/
chmod +x .husky/*
# Verify Git hooks path
git config core.hooksPath
# Should show: .husky
```
### Guard Script Issues
```bash
# Test guard script manually
./scripts/build-arch-guard.sh --help
# Check script permissions
chmod +x scripts/build-arch-guard.sh
# Test with specific files
./scripts/build-arch-guard.sh --staged
```
### False Positives
```bash
# If guard blocks legitimate changes, check:
# 1. Are you modifying a protected file pattern?
# 2. Did you update BUILDING.md?
# 3. Is BUILDING.md staged for commit?
# View what the guard sees
git diff --name-only --cached
```
## 📋 **Best Practices**
### For Developers
1. **Update BUILDING.md first** - Document changes before implementing
2. **Test locally** - Run `./scripts/build-arch-guard.sh --staged` before committing
3. **Use descriptive commits** - Include context about build changes
4. **Don't bypass lightly** - Only use `--no-verify` for true emergencies
### For Teams
1. **Document the system** - Ensure everyone understands the guard
2. **Review BUILDING.md updates** - Verify documentation quality
3. **Monitor bypass usage** - Track when hooks are skipped
4. **Regular audits** - Check that BUILDING.md stays current
### For Maintainers
1. **Update protected patterns** - Modify `scripts/build-arch-guard.sh` as needed
2. **Monitor effectiveness** - Track how often the guard catches issues
3. **Team training** - Help developers understand the system
4. **Continuous improvement** - Refine patterns and error messages
## 🔄 **Customization**
### Adding New Protected Paths
Edit `scripts/build-arch-guard.sh`:
```bash
SENSITIVE=(
# ... existing patterns ...
"new-pattern/**" # Add your new pattern
"*.config.js" # Add file extensions
)
```
### Modifying Error Messages
Edit the guard script to customize:
- Error message content
- File pattern matching
- Documentation requirements
- Bypass instructions
### Adding New Validation Rules
Extend the guard script to check for:
- Specific file content patterns
- Required documentation sections
- Commit message formats
- Branch naming conventions
## 📚 **Integration with PR Template**
The `pull_request_template.md` works with this system by:
- **Guiding developers** through required documentation
- **Ensuring consistency** across all build changes
- **Providing checklist** for comprehensive updates
- **Supporting L1/L2/L3** change classification
## 🎯 **Success Metrics**
Track the effectiveness of your Build Architecture Guard:
- **Hook execution rate** - How often hooks run successfully
- **Bypass frequency** - How often `--no-verify` is used
- **Documentation quality** - BUILDING.md stays current
- **Build failures** - Fewer issues from undocumented changes
- **Team adoption** - Developers follow the process
---
**Status**: Active protection system
**Architecture**: Client-side Git hooks only
**Dependencies**: Husky, Git, Bash
**Maintainer**: Development team
**Related**: `pull_request_template.md`, `scripts/build-arch-guard.sh`

View File

@@ -1,82 +0,0 @@
# Pull Request Template
## Location
The Build Architecture Guard PR template is located at:
- **`pull_request_template.md`** (root directory)
## Usage
When creating a pull request in Gitea, this template will automatically populate the PR description with the required checklist.
## Template Features
### Change Level Classification
- **L1**: Minor changes, documentation updates
- **L2**: Moderate changes, new features, environment changes
- **L3**: Major changes, architecture changes, new platforms
### Required Fields for All Levels
- Change level selection
- Scope and impact description
- Commands executed and their output
- Documentation updates (BUILDING.md)
- Rollback verification steps
### Additional Requirements for L3
- **ADR link**: Must provide URL to Architectural Decision Record
- **Artifacts with SHA256**: Must list artifacts with cryptographic hashes
## Integration
This template works with:
- **Gitea Actions**: `.gitea/workflows/build-guard.yml`
- **Client-side hooks**: `.husky/` pre-commit and pre-push hooks
- **Guard script**: `scripts/build-arch-guard.sh`
## Example Usage
```markdown
### Change Level
- [x] Level: **L2**
**Why:** Adding new build script for Docker deployment
### Scope & Impact
- [x] Files & platforms touched: scripts/build-docker.sh,
BUILDING.md
- [x] Risk triggers: Docker build process changes
- [x] Mitigations/validation done: Tested on local Docker environment
### Commands Run
- [x] Web: `npm run build:web:docker`
- [x] Docker: `docker build -t test-image .`
### Artifacts
- [x] Names + **sha256** of artifacts/installers:
Artifacts:
```text
test-image.tar a1b2c3d4e5f6...
```
### Docs
- [x] **BUILDING.md** updated (sections): Docker deployment
- [x] Troubleshooting updated: Added Docker troubleshooting section
### Rollback
- [x] Verified steps to restore previous behavior:
1. `git revert HEAD`
2. `docker rmi test-image`
3. Restore previous BUILDING.md
```
---
**Note**: This template is enforced by the Build Architecture Guard
system. Complete all required fields to ensure your PR can be merged.

221
README.md
View File

@@ -1,118 +1,179 @@
# Time Safari Application # TimeSafari.app - Crowd-Funder for Time - PWA
**Author**: Matthew Raymer [Time Safari](https://timesafari.org/) allows people to ease into collaboration: start with expressions of gratitude
**Version**: 1.0.8-beta and expand to crowd-fund with time & money, then record and see the impact of contributions.
**Description**: Time Safari Application
## 🛡️ Build Architecture Guard ## Database Migration Status
This project uses **Husky Git hooks** to protect the build system **Current Status**: The application is undergoing a migration from Dexie (IndexedDB) to SQLite using absurd-sql. This migration is in **Phase 2** with a well-defined migration fence in place.
architecture. When you modify build-critical files, the system
automatically blocks commits until you update `BUILDING.md`.
### Quick Setup ### Migration Progress
-**SQLite Database Service**: Fully implemented with absurd-sql
-**Platform Service Layer**: Unified database interface across platforms
-**Settings Migration**: Core user settings transferred
-**Account Migration**: Identity and key management
- 🔄 **Contact Migration**: User contact data (via import interface)
- 📋 **Code Cleanup**: Remove unused Dexie imports
```bash ### Migration Fence
npm run guard:setup # Install and activate the guard The migration is controlled by a **migration fence** that separates legacy Dexie code from the new SQLite implementation. See [Migration Fence Definition](doc/migration-fence-definition.md) for complete details.
```
### How It Works **Key Points**:
- Legacy Dexie database is disabled by default
- All database operations go through `PlatformServiceMixin`
- Migration tools provide controlled access to both databases
- Clear separation between legacy and new code
- **Pre-commit**: Blocks commits if build files changed without ### Migration Documentation
BUILDING.md updates - [Migration Guide](doc/migration-to-wa-sqlite.md) - Complete migration process
- **Pre-push**: Blocks pushes if commits contain undocumented build - [Migration Fence Definition](doc/migration-fence-definition.md) - Fence boundaries and rules
changes - [Database Migration Guide](doc/database-migration-guide.md) - User-facing migration tools
- **Protected paths**: `scripts/`, `vite.config.*`, `electron/`,
`android/`, `ios/`, etc.
### Usage ## Roadmap
```bash See [project.task.yaml](project.task.yaml) for current priorities.
# Test the guard manually (Numbers at the beginning of lines are estimated hours. See [taskyaml.org](https://taskyaml.org/) for details.)
npm run guard:test
# Emergency bypass (use sparingly) ## Setup & Building
git commit --no-verify
git push --no-verify
```
**📚 Full documentation**: See `README-BUILD-GUARD.md` Quick start:
## 🚀 Quick Start * For setup, we recommend [pkgx](https://pkgx.dev), which installs what you need (either automatically or with the `dev` command). Core dependencies are typescript & npm; when building for other platforms, you'll need other things such as those in the pkgx.yaml & BUILDING.md files.
### Prerequisites
- Node.js 18+
- npm, yarn, or pnpm
- Git
### Installation
```bash ```bash
npm install npm install
npm run guard:setup # Sets up Build Architecture Guard npm run dev
``` ```
### Development See [BUILDING.md](BUILDING.md) for comprehensive build instructions for all platforms (Web, Electron, iOS, Android, Docker).
## Development Database Clearing
TimeSafari provides a simple script-based approach to clear the database for development purposes.
### Quick Usage
```bash ```bash
npm run build:web:dev # Build web version # Run the database clearing script
npm run build:ios:test # Build iOS test version ./scripts/clear-database.sh
npm run build:android:test # Build Android test version
npm run build:electron:dev # Build Electron dev version # Then restart your development server
npm run build:electron:dev # For Electron
npm run build:web:dev # For Web
``` ```
### Testing ### What It Does
#### **Electron (Desktop App)**
- Automatically finds and clears the SQLite database files
- Works on Linux, macOS, and Windows
- Clears all data and forces fresh migrations on next startup
#### **Web Browser**
- Provides instructions for using custom browser data directories
- Shows manual clearing via browser DevTools
- Ensures reliable database clearing without browser complications
### Safety Features
-**Interactive Script**: Guides you through the process
-**Platform Detection**: Automatically detects your OS
-**Clear Instructions**: Step-by-step guidance for each platform
-**Safe Paths**: Only clears TimeSafari-specific data
### Manual Commands (if needed)
#### **Electron Database Location**
```bash ```bash
npm run test:web # Run web tests # Linux
npm run test:mobile # Run mobile tests rm -rf ~/.config/TimeSafari/*
npm run test:all # Run all tests
# macOS
rm -rf ~/Library/Application\ Support/TimeSafari/*
# Windows
rmdir /s /q %APPDATA%\TimeSafari
``` ```
## 📁 Project Structure #### **Web Browser (Custom Data Directory)**
```bash
# Create isolated browser profile
mkdir ~/timesafari-dev-data
```text # Start browser with custom profile
timesafari/ google-chrome --user-data-dir=~/timesafari-dev-data
├── 📁 src/ # Source code
├── 📁 scripts/ # Build and automation scripts # Clear when needed
├── 📁 electron/ # Electron configuration rm -rf ~/timesafari-dev-data
├── 📁 android/ # Android configuration
├── 📁 ios/ # iOS configuration
├── 📁 .husky/ # Git hooks (Build Architecture Guard)
├── 📄 BUILDING.md # Build system documentation
├── 📄 pull_request_template.md # PR template
└── 📄 README-BUILD-GUARD.md # Guard system documentation
``` ```
## 🔧 Build System See the script for complete platform-specific instructions.
This project supports multiple platforms: ## Tests
- **Web**: Vite-based build with service worker support See [TESTING.md](test-playwright/TESTING.md) for detailed test instructions.
- **Mobile**: Capacitor-based iOS and Android builds
- **Desktop**: Electron-based cross-platform desktop app
- **Docker**: Containerized deployment options
## 📚 Documentation ## Icons
- **`BUILDING.md`** - Complete build system guide Application icons are in the `assets` directory, processed by the `capacitor-assets` command.
- **`README-BUILD-GUARD.md`** - Build Architecture Guard documentation
- **`pull_request_template.md`** - PR template for build changes
## 🤝 Contributing To add a Font Awesome icon, add to main.ts and reference with `font-awesome` element and `icon` attribute with the hyphenated name.
1. **Follow the Build Architecture Guard** - Update BUILDING.md when modifying build files ## Other
2. **Use the PR template** - Complete the checklist for build-related changes
3. **Test your changes** - Ensure builds work on affected platforms
4. **Document updates** - Keep BUILDING.md current and accurate
## 📄 License ### Reference Material
[Add your license information here] * Notifications can be type of `toast` (self-dismiss), `info`, `success`, `warning`, and `danger`.
They are done via [notiwind](https://www.npmjs.com/package/notiwind) and set up in App.vue.
--- * [Customize Vue configuration](https://cli.vuejs.org/config/).
**Note**: The Build Architecture Guard is active and will block * If you are deploying in a subdirectory, add it to `publicPath` in vue.config.js, eg: `publicPath: "/app/time-tracker/",`
commits/pushes that modify build files without proper documentation
updates. See `README-BUILD-GUARD.md` for complete details. ### Code Organization
The project uses a centralized approach to type definitions and interfaces:
* `src/interfaces/` - Contains all TypeScript interfaces and type definitions
* `deepLinks.ts` - Deep linking type system and Zod validation schemas
* `give.ts` - Give-related interfaces and type definitions
* `claims.ts` - Claim-related interfaces and verifiable credentials
* `common.ts` - Shared interfaces and utility types
* Other domain-specific interface files
Key principles:
- All interfaces and types are defined in the interfaces folder
- Zod schemas are used for runtime validation and type generation
- Domain-specific interfaces are separated into their own files
- Common interfaces are shared through `common.ts`
- Type definitions are generated from Zod schemas where possible
### Database Architecture
The application uses a platform-agnostic database layer with Vue mixins for service access:
* `src/services/PlatformService.ts` - Database interface definition
* `src/services/PlatformServiceFactory.ts` - Platform-specific service factory
* `src/services/AbsurdSqlDatabaseService.ts` - SQLite implementation
* `src/utils/PlatformServiceMixin.ts` - Vue mixin for database access with caching
* `src/db/` - Legacy Dexie database (migration in progress)
**Development Guidelines**:
- Always use `PlatformServiceMixin` for database operations in components
- Test with PlatformServiceMixin for new features
- Use migration tools for data transfer between systems
- Leverage mixin's ultra-concise methods: `$db()`, `$exec()`, `$one()`, `$contacts()`, `$settings()`
**Architecture Decision**: The project uses Vue mixins over Composition API composables for platform service access. See [Architecture Decisions](doc/architecture-decisions.md) for detailed rationale.
### Kudos
Gifts make the world go 'round!
* [WebStorm by JetBrains](https://www.jetbrains.com/webstorm/) for the free open-source license
* [Máximo Fernández](https://medium.com/@maxfarenas) for the 3D [code](https://github.com/maxfer03/vue-three-ns) and [explanatory post](https://medium.com/nicasource/building-an-interactive-web-portfolio-with-vue-three-js-part-three-implementing-three-js-452cb375ef80)
* [Many tools & libraries](https://gitea.anomalistdesign.com/trent_larson/crowd-funder-for-time-pwa/src/branch/master/package.json#L10) such as Nodejs.org, IntelliJ Idea, Veramo.io, Vuejs.org, threejs.org
* [Bush 3D model](https://sketchfab.com/3d-models/lupine-plant-bf30f1110c174d4baedda0ed63778439)
* [Forest floor image](https://www.goodfreephotos.com/albums/textures/leafy-autumn-forest-floor.jpg)
* Time Safari logo assisted by [DALL-E in ChatGPT](https://chat.openai.com/g/g-2fkFE8rbu-dall-e)
* [DiceBear](https://www.dicebear.com/licenses/) and [Avataaars](https://www.dicebear.com/styles/avataaars/#details) for human-looking identicons
* Some gratitude prompts thanks to [Develop Good Habits](https://www.developgoodhabits.com/gratitude-journal-prompts/)

View File

@@ -1,6 +1,7 @@
# What to do about storage for native apps? # What to do about storage for native apps?
## Problem ## Problem
We can't trust iOS IndexedDB to persist. I want to start delivering an app to people now, in preparation for presentations mid-June: Rotary on June 12 and Porcfest on June 17. We can't trust iOS IndexedDB to persist. I want to start delivering an app to people now, in preparation for presentations mid-June: Rotary on June 12 and Porcfest on June 17.
@@ -13,6 +14,7 @@ We can't trust iOS IndexedDB to persist. I want to start delivering an app to pe
Also, with sensitive data, the accounts info should be encrypted. Also, with sensitive data, the accounts info should be encrypted.
# Options # Options
* There is a community [SQLite plugin for Capacitor](https://github.com/capacitor-community/sqlite) with encryption by [SQLCipher](https://github.com/sqlcipher/sqlcipher). * There is a community [SQLite plugin for Capacitor](https://github.com/capacitor-community/sqlite) with encryption by [SQLCipher](https://github.com/sqlcipher/sqlcipher).
@@ -27,12 +29,16 @@ Also, with sensitive data, the accounts info should be encrypted.
* Not an option yet: Dexie may support SQLite in [a future version](https://dexie.org/roadmap/dexie5.0). * Not an option yet: Dexie may support SQLite in [a future version](https://dexie.org/roadmap/dexie5.0).
# Current Plan # Current Plan
* Implement SQLite for Capacitor & web, with encryption. That will allow us to test quickly and keep the same interface for native & web, but we don't deal with migrations for current web users. * Implement SQLite for Capacitor & web, with encryption. That will allow us to test quickly and keep the same interface for native & web, but we don't deal with migrations for current web users.
* After that is delivered, write a migration for current web users from IndexedDB to SQLite. * After that is delivered, write a migration for current web users from IndexedDB to SQLite.
# Current method calls # Current method calls
... which is not 100% complete because the AI that generated thus claimed no usage of 'temp' DB. ... which is not 100% complete because the AI that generated thus claimed no usage of 'temp' DB.
@@ -74,3 +80,5 @@ Logs operations:
db.logs.get(todayKey) - Gets logs for a specific day db.logs.get(todayKey) - Gets logs for a specific day
db.logs.update(todayKey, { message: fullMessage }) - Updates logs db.logs.update(todayKey, { message: fullMessage }) - Updates logs
db.logs.clear() - Clears all logs db.logs.clear() - Clears all logs

7
android/.gitignore vendored
View File

@@ -84,6 +84,13 @@ freeline.py
freeline/ freeline/
freeline_project_description.json freeline_project_description.json
# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md
# Version control # Version control
vcs.xml vcs.xml

View File

@@ -31,8 +31,8 @@ android {
applicationId "app.timesafari.app" applicationId "app.timesafari.app"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 40 versionCode 35
versionName "1.0.7" versionName "1.0.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions { aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@@ -64,14 +64,6 @@ android {
} }
} }
} }
packagingOptions {
jniLibs {
pickFirsts += ['**/lib/x86_64/libbarhopper_v3.so', '**/lib/x86_64/libimage_processing_util_jni.so', '**/lib/x86_64/libsqlcipher.so']
}
}
// Configure for 16 KB page size compatibility
// Enable bundle builds (without which it doesn't work right for bundleDebug vs bundleRelease) // Enable bundle builds (without which it doesn't work right for bundleDebug vs bundleRelease)
bundle { bundle {

View File

@@ -29,7 +29,7 @@
"splashFullScreen": true, "splashFullScreen": true,
"splashImmersive": true "splashImmersive": true
}, },
"CapSQLite": { "CapacitorSQLite": {
"iosDatabaseLocation": "Library/CapacitorDatabase", "iosDatabaseLocation": "Library/CapacitorDatabase",
"iosIsEncryption": false, "iosIsEncryption": false,
"iosBiometric": { "iosBiometric": {
@@ -57,14 +57,13 @@
] ]
}, },
"android": { "android": {
"allowMixedContent": true, "allowMixedContent": false,
"captureInput": true, "captureInput": true,
"webContentsDebuggingEnabled": false, "webContentsDebuggingEnabled": false,
"allowNavigation": [ "allowNavigation": [
"*.timesafari.app", "*.timesafari.app",
"*.jsdelivr.net", "*.jsdelivr.net",
"api.endorser.ch", "api.endorser.ch"
"10.0.2.2:3000"
] ]
}, },
"electron": { "electron": {

View File

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M2480 4005 c-25 -7 -58 -20 -75 -29 -16 -9 -40 -16 -52 -16 -17 0
-24 -7 -28 -27 -3 -16 -14 -45 -24 -65 -21 -41 -13 -55 18 -38 25 13 67 13 92
-1 15 -8 35 -4 87 17 99 39 130 41 197 10 64 -29 77 -31 107 -15 20 11 20 11
-3 35 -12 13 -30 24 -38 24 -24 1 -132 38 -148 51 -8 7 -11 20 -7 32 12 37
-40 47 -126 22z"/>
<path d="M1450 3775 c-7 -8 -18 -15 -24 -15 -7 0 -31 -14 -54 -32 -29 -22 -38
-34 -29 -40 17 -11 77 -10 77 1 0 5 16 16 35 25 60 29 220 19 290 -18 17 -9
33 -16 37 -16 4 0 31 -15 60 -34 108 -70 224 -215 282 -353 30 -71 53 -190 42
-218 -10 -27 -23 -8 -52 75 -30 90 -88 188 -120 202 -13 6 -26 9 -29 6 -3 -2
11 -51 30 -108 28 -83 35 -119 35 -179 0 -120 -22 -127 -54 -17 -11 37 -13 21
-18 -154 -5 -180 -8 -200 -32 -264 -51 -132 -129 -245 -199 -288 -21 -12 -79
-49 -129 -80 -161 -102 -294 -141 -473 -141 -228 0 -384 76 -535 259 -81 99
-118 174 -154 312 -31 121 -35 273 -11 437 19 127 19 125 -4 125 -23 0 -51
-34 -87 -104 -14 -28 -33 -64 -41 -81 -19 -34 -22 -253 -7 -445 9 -106 12
-119 44 -170 19 -30 42 -67 50 -81 64 -113 85 -140 130 -169 28 -18 53 -44 61
-62 8 -20 36 -45 83 -76 62 -39 80 -46 151 -54 44 -5 96 -13 115 -18 78 -20
238 -31 282 -19 24 6 66 8 95 5 76 -9 169 24 319 114 32 19 80 56 106 82 27
26 52 48 58 48 5 0 27 26 50 58 48 66 56 70 132 71 62 1 165 29 238 64 112 55
177 121 239 245 37 76 39 113 10 267 -12 61 -23 131 -26 156 -5 46 -5 47 46
87 92 73 182 70 263 -8 l51 -49 -6 -61 c-4 -34 -13 -85 -21 -113 -28 -103 -30
-161 -4 -228 16 -44 32 -67 55 -83 18 -11 39 -37 47 -58 10 -23 37 -53 73 -81
32 -25 69 -57 82 -71 14 -14 34 -26 47 -26 12 0 37 -7 56 -15 20 -8 66 -17
104 -20 107 -10 110 -11 150 -71 50 -75 157 -177 197 -187 18 -5 53 -24 78
-42 71 -51 176 -82 304 -89 61 -4 127 -12 147 -18 29 -9 45 -8 77 6 23 9 50
16 60 16 31 0 163 46 216 76 28 15 75 46 105 69 30 23 69 49 85 58 17 8 46 31
64 51 19 20 40 36 47 36 18 0 77 70 100 120 32 66 45 108 55 173 5 32 16 71
24 87 43 84 43 376 0 549 -27 105 -43 127 -135 188 -30 21 -65 46 -77 57 -13
11 -23 17 -23 14 0 -3 21 -46 47 -94 79 -151 85 -166 115 -263 25 -83 28 -110
28 -226 0 -144 -17 -221 -75 -335 -39 -77 -208 -244 -304 -299 -451 -263 -975
-67 -1138 426 -23 70 -26 95 -28 254 -1 108 -7 183 -14 196 -6 12 -11 31 -11
43 0 32 31 122 52 149 10 13 18 28 18 34 0 5 25 40 56 78 60 73 172 170 219
190 30 12 30 13 6 17 -15 2 -29 -2 -37 -12 -6 -9 -16 -16 -22 -16 -6 0 -23
-11 -39 -24 -15 -12 -33 -25 -40 -27 -17 -6 -82 -60 -117 -97 -65 -70 -75 -82
-107 -133 -23 -34 -35 -46 -37 -35 -3 16 20 87 44 134 6 12 9 34 6 48 -4 22
-8 25 -31 19 -14 -3 -38 -15 -53 -26 -34 -24 -34 -21 -6 28 65 112 184 206
291 227 15 3 39 9 55 12 l27 6 -24 9 c-90 35 -304 -66 -478 -225 -39 -36 -74
-66 -77 -66 -22 0 18 82 72 148 19 23 32 46 28 49 -4 4 -26 13 -49 19 -73 21
-161 54 -171 64 -6 6 -20 10 -32 10 -21 0 -21 -1 -8 -40 45 -130 8 -247 -93
-299 -25 -13 -31 0 -14 29 15 22 1 33 -22 17 -56 -36 -117 -22 -117 28 0 13
-16 47 -35 76 -22 34 -33 60 -29 73 4 16 -3 26 -26 39 -16 10 -30 21 -30 25 1
18 54 64 87 76 l38 13 -33 5 c-30 4 -115 -18 -154 -42 -13 -7 -20 -5 -27 8 -9
16 -12 16 -53 1 -160 -61 -258 -104 -258 -114 0 -7 10 -20 21 -31 103 -91 217
-297 249 -449 28 -135 41 -237 35 -276 -14 -91 -48 -170 -97 -220 -44 -47 -68
-60 -68 -40 0 6 4 12 8 15 5 3 24 35 42 72 l33 67 -6 141 c-4 103 -11 158 -26
205 -12 35 -21 70 -21 77 0 7 -20 56 -45 108 -82 173 -227 322 -392 401 -67
33 -90 39 -163 42 -108 5 -130 10 -130 28 0 20 -63 20 -80 0z"/>
<path d="M3710 3765 c0 -20 8 -28 39 -41 22 -8 42 -22 45 -30 5 -14 42 -19 70
-8 10 4 -7 21 -58 55 -41 27 -79 49 -85 49 -6 0 -11 -11 -11 -25z"/>
<path d="M3173 3734 c-9 -25 10 -36 35 -18 12 8 22 19 22 25 0 16 -50 10 -57
-7z"/>
<path d="M1982 3728 c6 -16 36 -34 44 -26 3 4 4 14 1 23 -7 17 -51 21 -45 3z"/>
<path d="M1540 3620 c0 -5 7 -10 16 -10 8 0 12 5 9 10 -3 6 -10 10 -16 10 -5
0 -9 -4 -9 -10z"/>
<path d="M4467 3624 c-4 -4 23 -27 60 -50 84 -56 99 -58 67 -9 -28 43 -107 79
-127 59z"/>
<path d="M655 3552 c-11 -2 -26 -9 -33 -14 -7 -6 -27 -18 -45 -27 -36 -18 -58
-64 -39 -83 9 -9 25 1 70 43 53 48 78 78 70 84 -2 1 -12 -1 -23 -3z"/>
<path d="M1015 3460 c-112 -24 -247 -98 -303 -165 -53 -65 -118 -214 -136
-311 -20 -113 -20 -145 -1 -231 20 -88 49 -153 102 -230 79 -113 186 -182 331
-214 108 -24 141 -24 247 1 130 30 202 72 316 181 102 100 153 227 152 384 0
142 -58 293 -150 395 -60 67 -180 145 -261 171 -75 23 -232 34 -297 19z m340
-214 c91 -43 174 -154 175 -234 0 -18 -9 -51 -21 -73 -19 -37 -19 -42 -5 -64
35 -54 12 -121 -48 -142 -22 -7 -47 -19 -55 -27 -9 -8 -41 -27 -71 -42 -50
-26 -64 -29 -155 -29 -111 0 -152 14 -206 68 -49 49 -63 85 -64 162 0 59 4 78
28 118 31 52 96 105 141 114 23 5 33 17 56 68 46 103 121 130 225 81z"/>
<path d="M3985 3464 c-44 -7 -154 -44 -200 -67 -55 -28 -138 -96 -162 -132
-10 -16 -39 -75 -64 -130 l-44 -100 0 -160 0 -160 45 -90 c53 -108 152 -214
245 -264 59 -31 215 -71 281 -71 53 0 206 40 255 67 98 53 203 161 247 253 53
113 74 193 74 280 -1 304 -253 564 -557 575 -49 2 -103 1 -120 -1z m311 -220
c129 -68 202 -209 160 -309 -15 -35 -15 -42 -1 -72 26 -55 -3 -118 -59 -129
-19 -3 -43 -15 -53 -26 -26 -29 -99 -64 -165 -78 -45 -10 -69 -10 -120 -1 -74
15 -113 37 -161 91 -110 120 -50 331 109 385 24 8 44 23 52 39 6 14 18 38 25
53 33 72 127 93 213 47z"/>
<path d="M487 3394 c-21 -12 -27 -21 -25 -40 2 -14 7 -26 12 -27 14 -3 48 48
44 66 -3 14 -6 14 -31 1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 KiB

View File

@@ -0,0 +1,11 @@
Model Information:
* title: Lupine Plant
* source: https://sketchfab.com/3d-models/lupine-plant-bf30f1110c174d4baedda0ed63778439
* author: rufusrockwell (https://sketchfab.com/rufusrockwell)
Model License:
* license type: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
* requirements: Author must be credited. Commercial use is allowed.
If you use this 3D model in your project be sure to copy paste this credit wherever you share it:
This work is based on "Lupine Plant" (https://sketchfab.com/3d-models/lupine-plant-bf30f1110c174d4baedda0ed63778439) by rufusrockwell (https://sketchfab.com/rufusrockwell) licensed under CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)

View File

@@ -0,0 +1,229 @@
{
"accessors": [
{
"bufferView": 2,
"componentType": 5126,
"count": 2759,
"max": [
41.3074951171875,
40.37548828125,
87.85917663574219
],
"min": [
-35.245540618896484,
-36.895416259765625,
-0.9094290137290955
],
"type": "VEC3"
},
{
"bufferView": 2,
"byteOffset": 33108,
"componentType": 5126,
"count": 2759,
"max": [
0.9999382495880127,
0.9986748695373535,
0.9985831379890442
],
"min": [
-0.9998949766159058,
-0.9975876212120056,
-0.411094069480896
],
"type": "VEC3"
},
{
"bufferView": 3,
"componentType": 5126,
"count": 2759,
"max": [
0.9987699389457703,
0.9998998045921326,
0.9577858448028564,
1.0
],
"min": [
-0.9987726807594299,
-0.9990445971488953,
-0.999801516532898,
1.0
],
"type": "VEC4"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 2759,
"max": [
1.0061479806900024,
0.9993550181388855
],
"min": [
0.00279300007969141,
0.0011620000004768372
],
"type": "VEC2"
},
{
"bufferView": 0,
"componentType": 5125,
"count": 6378,
"type": "SCALAR"
}
],
"asset": {
"extras": {
"author": "rufusrockwell (https://sketchfab.com/rufusrockwell)",
"license": "CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)",
"source": "https://sketchfab.com/3d-models/lupine-plant-bf30f1110c174d4baedda0ed63778439",
"title": "Lupine Plant"
},
"generator": "Sketchfab-12.68.0",
"version": "2.0"
},
"bufferViews": [
{
"buffer": 0,
"byteLength": 25512,
"name": "floatBufferViews",
"target": 34963
},
{
"buffer": 0,
"byteLength": 22072,
"byteOffset": 25512,
"byteStride": 8,
"name": "floatBufferViews",
"target": 34962
},
{
"buffer": 0,
"byteLength": 66216,
"byteOffset": 47584,
"byteStride": 12,
"name": "floatBufferViews",
"target": 34962
},
{
"buffer": 0,
"byteLength": 44144,
"byteOffset": 113800,
"byteStride": 16,
"name": "floatBufferViews",
"target": 34962
}
],
"buffers": [
{
"byteLength": 157944,
"uri": "scene.bin"
}
],
"images": [
{
"uri": "textures/lambert2SG_baseColor.png"
},
{
"uri": "textures/lambert2SG_normal.png"
}
],
"materials": [
{
"alphaCutoff": 0.2,
"alphaMode": "MASK",
"doubleSided": true,
"name": "lambert2SG",
"normalTexture": {
"index": 1
},
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 0
},
"metallicFactor": 0.0
}
}
],
"meshes": [
{
"name": "Object_0",
"primitives": [
{
"attributes": {
"NORMAL": 1,
"POSITION": 0,
"TANGENT": 2,
"TEXCOORD_0": 3
},
"indices": 4,
"material": 0,
"mode": 4
}
]
}
],
"nodes": [
{
"children": [
1
],
"matrix": [
1.0,
0.0,
0.0,
0.0,
0.0,
2.220446049250313e-16,
-1.0,
0.0,
0.0,
1.0,
2.220446049250313e-16,
0.0,
0.0,
0.0,
0.0,
1.0
],
"name": "Sketchfab_model"
},
{
"children": [
2
],
"name": "LupineSF.obj.cleaner.materialmerger.gles"
},
{
"mesh": 0,
"name": "Object_2"
}
],
"samplers": [
{
"magFilter": 9729,
"minFilter": 9987,
"wrapS": 10497,
"wrapT": 10497
}
],
"scene": 0,
"scenes": [
{
"name": "Sketchfab_Scene",
"nodes": [
0
]
}
],
"textures": [
{
"sampler": 0,
"source": 0
},
{
"sampler": 0,
"source": 1
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 MiB

View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow:

View File

@@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
</vector>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background>
<inset android:drawable="@mipmap/ic_launcher_background" android:inset="16.7%" />
</background>
<foreground>
<inset android:drawable="@mipmap/ic_launcher_foreground" android:inset="16.7%" />
</foreground>
</adaptive-icon>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background>
<inset android:drawable="@mipmap/ic_launcher_background" android:inset="16.7%" />
</background>
<foreground>
<inset android:drawable="@mipmap/ic_launcher_foreground" android:inset="16.7%" />
</foreground>
</adaptive-icon>

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>

View File

@@ -7,7 +7,7 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.12.1' classpath 'com.android.tools.build:gradle:8.11.0'
classpath 'com.google.gms:google-services:4.4.0' classpath 'com.google.gms:google-services:4.4.0'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

View File

@@ -20,4 +20,4 @@ org.gradle.jvmargs=-Xmx1536m
# Android operating system, and which are packaged with your app's APK # Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn # https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true android.useAndroidX=true
android.suppressUnsupportedCompileSdk=36 android.suppressUnsupportedCompileSdk=34

View File

@@ -1,7 +1,7 @@
ext { ext {
minSdkVersion = 22 minSdkVersion = 22
compileSdkVersion = 36 compileSdkVersion = 34
targetSdkVersion = 36 targetSdkVersion = 34
androidxActivityVersion = '1.8.0' androidxActivityVersion = '1.8.0'
androidxAppCompatVersion = '1.6.1' androidxAppCompatVersion = '1.6.1'
androidxCoordinatorLayoutVersion = '1.2.0' androidxCoordinatorLayoutVersion = '1.2.0'

2
assets/README.md Normal file
View File

@@ -0,0 +1,2 @@
Application icons are here. They are processed for android & ios by the `capacitor-assets` command, as indicated in the BUILDING.md file.

View File

Before

Width:  |  Height:  |  Size: 279 KiB

After

Width:  |  Height:  |  Size: 279 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

@@ -1,32 +0,0 @@
{
"icon": {
"android": {
"adaptive": {
"background": "#121212",
"foreground": "resources/icon.png",
"monochrome": "resources/icon.png"
},
"target": "android/app/src/main/res"
},
"ios": {
"padding": 0,
"target": "ios/App/App/Assets.xcassets/AppIcon.appiconset"
},
"source": "resources/icon.png",
"web": {
"target": "public/img/icons"
}
},
"splash": {
"android": {
"scale": "cover",
"target": "android/app/src/main/res"
},
"darkSource": "resources/splash_dark.png",
"ios": {
"target": "ios/App/App/Assets.xcassets",
"useStoryBoard": true
},
"source": "resources/splash.png"
}
}

View File

@@ -57,14 +57,13 @@
] ]
}, },
"android": { "android": {
"allowMixedContent": true, "allowMixedContent": false,
"captureInput": true, "captureInput": true,
"webContentsDebuggingEnabled": false, "webContentsDebuggingEnabled": false,
"allowNavigation": [ "allowNavigation": [
"*.timesafari.app", "*.timesafari.app",
"*.jsdelivr.net", "*.jsdelivr.net",
"api.endorser.ch", "api.endorser.ch"
"10.0.2.2:3000"
] ]
}, },
"electron": { "electron": {

View File

@@ -1,116 +0,0 @@
import { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'app.timesafari',
appName: 'TimeSafari',
webDir: 'dist',
server: {
cleartext: true
},
plugins: {
App: {
appUrlOpen: {
handlers: [
{
url: 'timesafari://*',
autoVerify: true
}
]
}
},
SplashScreen: {
launchShowDuration: 3000,
launchAutoHide: true,
backgroundColor: '#ffffff',
androidSplashResourceName: 'splash',
androidScaleType: 'CENTER_CROP',
showSpinner: false,
androidSpinnerStyle: 'large',
iosSpinnerStyle: 'small',
spinnerColor: '#999999',
splashFullScreen: true,
splashImmersive: true
},
CapSQLite: {
iosDatabaseLocation: 'Library/CapacitorDatabase',
iosIsEncryption: false,
iosBiometric: {
biometricAuth: false,
biometricTitle: 'Biometric login for TimeSafari'
},
androidIsEncryption: false,
androidBiometric: {
biometricAuth: false,
biometricTitle: 'Biometric login for TimeSafari'
},
electronIsEncryption: false
}
},
ios: {
contentInset: 'never',
allowsLinkPreview: true,
scrollEnabled: true,
limitsNavigationsToAppBoundDomains: true,
backgroundColor: '#ffffff',
allowNavigation: [
'*.timesafari.app',
'*.jsdelivr.net',
'api.endorser.ch'
]
},
android: {
allowMixedContent: true,
captureInput: true,
webContentsDebuggingEnabled: false,
allowNavigation: [
'*.timesafari.app',
'*.jsdelivr.net',
'api.endorser.ch',
'10.0.2.2:3000'
]
},
electron: {
deepLinking: {
schemes: ['timesafari']
},
buildOptions: {
appId: 'app.timesafari',
productName: 'TimeSafari',
directories: {
output: 'dist-electron-packages'
},
files: [
'dist/**/*',
'electron/**/*'
],
mac: {
category: 'public.app-category.productivity',
target: [
{
target: 'dmg',
arch: ['x64', 'arm64']
}
]
},
win: {
target: [
{
target: 'nsis',
arch: ['x64']
}
]
},
linux: {
target: [
{
target: 'AppImage',
arch: ['x64']
}
],
category: 'Utility'
}
}
}
};
export default config;

View File

@@ -1,32 +0,0 @@
{
"icon": {
"android": {
"adaptive": {
"background": "#121212",
"foreground": "resources/icon.png",
"monochrome": "resources/icon.png"
},
"target": "android/app/src/main/res"
},
"ios": {
"padding": 0,
"target": "ios/App/App/Assets.xcassets/AppIcon.appiconset"
},
"source": "resources/icon.png",
"web": {
"target": "public/img/icons"
}
},
"splash": {
"android": {
"scale": "cover",
"target": "android/app/src/main/res"
},
"darkSource": "resources/splash_dark.png",
"ios": {
"target": "ios/App/App/Assets.xcassets",
"useStoryBoard": true
},
"source": "resources/splash.png"
}
}

View File

@@ -1,119 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Capacitor Assets Configuration Schema",
"description": "Schema for validating capacitor-assets configuration files",
"type": "object",
"properties": {
"icon": {
"type": "object",
"properties": {
"source": {
"type": "string",
"pattern": "^resources/.*\\.(png|svg)$",
"description": "Source icon file path relative to project root"
},
"android": {
"type": "object",
"properties": {
"adaptive": {
"type": "object",
"properties": {
"foreground": {
"type": "string",
"pattern": "^resources/.*\\.(png|svg)$",
"description": "Foreground icon for Android adaptive icons"
},
"background": {
"type": ["string", "object"],
"description": "Background color or image for adaptive icons"
},
"monochrome": {
"type": "string",
"pattern": "^resources/.*\\.(png|svg)$",
"description": "Monochrome icon for Android 13+"
}
},
"required": ["foreground", "background"]
},
"target": {
"type": "string",
"description": "Android target directory for generated icons"
}
}
},
"ios": {
"type": "object",
"properties": {
"padding": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Padding ratio for iOS icons"
},
"target": {
"type": "string",
"description": "iOS target directory for generated icons"
}
}
},
"web": {
"type": "object",
"properties": {
"target": {
"type": "string",
"description": "Web target directory for generated icons"
}
}
}
},
"required": ["source"],
"additionalProperties": false
},
"splash": {
"type": "object",
"properties": {
"source": {
"type": "string",
"pattern": "^resources/.*\\.(png|svg)$",
"description": "Source splash screen file"
},
"darkSource": {
"type": "string",
"pattern": "^resources/.*\\.(png|svg)$",
"description": "Dark mode splash screen file"
},
"android": {
"type": "object",
"properties": {
"scale": {
"type": "string",
"enum": ["cover", "contain", "fill"],
"description": "Android splash screen scaling mode"
},
"target": {
"type": "string",
"description": "Android target directory for splash screens"
}
}
},
"ios": {
"type": "object",
"properties": {
"useStoryBoard": {
"type": "boolean",
"description": "Use LaunchScreen storyboard instead of splash assets"
},
"target": {
"type": "string",
"description": "iOS target directory for splash screens"
}
}
}
},
"required": ["source"],
"additionalProperties": false
}
},
"required": ["icon", "splash"],
"additionalProperties": false
}

Some files were not shown because too many files have changed in this diff Show More