Compare commits
1 Commits
units-mock
...
sw-cleanup
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f0d10d93d |
@@ -1,310 +0,0 @@
|
||||
# Cursor Markdown Ruleset for TimeSafari Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
This ruleset enforces consistent markdown formatting standards across all project
|
||||
documentation, ensuring readability, maintainability, and compliance with
|
||||
markdownlint best practices.
|
||||
|
||||
## General Formatting Standards
|
||||
|
||||
### Line Length
|
||||
|
||||
- **Maximum line length**: 80 characters
|
||||
- **Exception**: Code blocks (JSON, shell, TypeScript, etc.) - no line length
|
||||
enforcement
|
||||
- **Rationale**: Ensures readability across different screen sizes and terminal
|
||||
widths
|
||||
|
||||
### Blank Lines
|
||||
|
||||
- **Headings**: Must be surrounded by blank lines above and below
|
||||
- **Lists**: Must be surrounded by blank lines above and below
|
||||
- **Code blocks**: Must be surrounded by blank lines above and below
|
||||
- **Maximum consecutive blank lines**: 1 (no multiple blank lines)
|
||||
- **File start**: No blank lines at the beginning of the file
|
||||
- **File end**: Single newline character at the end
|
||||
|
||||
### Whitespace
|
||||
|
||||
- **No trailing spaces**: Remove all trailing whitespace from lines
|
||||
- **No tabs**: Use spaces for indentation
|
||||
- **Consistent indentation**: 2 spaces for list items and nested content
|
||||
|
||||
## Heading Standards
|
||||
|
||||
### Format
|
||||
|
||||
- **Style**: ATX-style headings (`#`, `##`, `###`, etc.)
|
||||
- **Case**: Title case for general headings
|
||||
- **Code references**: Use backticks for file names and technical terms
|
||||
- ✅ `### Current package.json Scripts`
|
||||
- ❌ `### Current Package.json Scripts`
|
||||
|
||||
### Hierarchy
|
||||
|
||||
- **H1 (#)**: Document title only
|
||||
- **H2 (##)**: Major sections
|
||||
- **H3 (###)**: Subsections
|
||||
- **H4 (####)**: Sub-subsections
|
||||
- **H5+**: Avoid deeper nesting
|
||||
|
||||
## List Standards
|
||||
|
||||
### Unordered Lists
|
||||
|
||||
- **Marker**: Use `-` (hyphen) consistently
|
||||
- **Indentation**: 2 spaces for nested items
|
||||
- **Blank lines**: Surround lists with blank lines
|
||||
|
||||
### Ordered Lists
|
||||
|
||||
- **Format**: `1.`, `2.`, `3.` (sequential numbering)
|
||||
- **Indentation**: 2 spaces for nested items
|
||||
- **Blank lines**: Surround lists with blank lines
|
||||
|
||||
### Task Lists
|
||||
|
||||
- **Format**: `- [ ]` for incomplete, `- [x]` for complete
|
||||
- **Use case**: Project planning, checklists, implementation tracking
|
||||
|
||||
## Code Block Standards
|
||||
|
||||
### Fenced Code Blocks
|
||||
|
||||
- **Syntax**: Triple backticks with language specification
|
||||
- **Languages**: `json`, `bash`, `typescript`, `javascript`, `yaml`, `markdown`
|
||||
- **Blank lines**: Must be surrounded by blank lines above and below
|
||||
- **Line length**: No enforcement within code blocks
|
||||
|
||||
### Inline Code
|
||||
|
||||
- **Format**: Single backticks for inline code references
|
||||
- **Use case**: File names, commands, variables, properties
|
||||
|
||||
## Special Content Standards
|
||||
|
||||
### JSON Examples
|
||||
|
||||
```json
|
||||
{
|
||||
"property": "value",
|
||||
"nested": {
|
||||
"property": "value"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Shell Commands
|
||||
|
||||
```bash
|
||||
# Command with comment
|
||||
npm run build:web
|
||||
|
||||
# Multi-line command
|
||||
VITE_GIT_HASH=`git log -1 --pretty=format:%h` \
|
||||
vite build --config vite.config.web.mts
|
||||
```
|
||||
|
||||
### TypeScript Examples
|
||||
|
||||
```typescript
|
||||
// Function with JSDoc
|
||||
/**
|
||||
* Get environment configuration
|
||||
* @param env - Environment name
|
||||
* @returns Environment config object
|
||||
*/
|
||||
const getEnvironmentConfig = (env: string) => {
|
||||
switch (env) {
|
||||
case 'prod':
|
||||
return { /* production settings */ };
|
||||
default:
|
||||
return { /* development settings */ };
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## File Structure Standards
|
||||
|
||||
### Document Header
|
||||
|
||||
```markdown
|
||||
# Document Title
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: YYYY-MM-DD
|
||||
**Status**: 🎯 **STATUS** - Brief description
|
||||
|
||||
## Overview
|
||||
|
||||
Brief description of the document's purpose and scope.
|
||||
```
|
||||
|
||||
### Section Organization
|
||||
|
||||
1. **Overview/Introduction**
|
||||
2. **Current State Analysis**
|
||||
3. **Implementation Plan**
|
||||
4. **Technical Details**
|
||||
5. **Testing & Validation**
|
||||
6. **Next Steps**
|
||||
|
||||
## Markdownlint Configuration
|
||||
|
||||
### Required Rules
|
||||
|
||||
```json
|
||||
{
|
||||
"MD013": { "code_blocks": false },
|
||||
"MD012": true,
|
||||
"MD022": true,
|
||||
"MD031": true,
|
||||
"MD032": true,
|
||||
"MD047": true,
|
||||
"MD009": true
|
||||
}
|
||||
```
|
||||
|
||||
### Rule Explanations
|
||||
|
||||
- **MD013**: Line length (disabled for code blocks)
|
||||
- **MD012**: No multiple consecutive blank lines
|
||||
- **MD022**: Headings should be surrounded by blank lines
|
||||
- **MD031**: Fenced code blocks should be surrounded by blank lines
|
||||
- **MD032**: Lists should be surrounded by blank lines
|
||||
- **MD047**: Files should end with a single newline
|
||||
- **MD009**: No trailing spaces
|
||||
|
||||
## Validation Commands
|
||||
|
||||
### Check Single File
|
||||
|
||||
```bash
|
||||
npx markdownlint docs/filename.md
|
||||
```
|
||||
|
||||
### Check All Documentation
|
||||
|
||||
```bash
|
||||
npx markdownlint docs/
|
||||
```
|
||||
|
||||
### Auto-fix Common Issues
|
||||
|
||||
```bash
|
||||
# Remove trailing spaces
|
||||
sed -i 's/[[:space:]]*$//' docs/filename.md
|
||||
|
||||
# Remove multiple blank lines
|
||||
sed -i '/^$/N;/^\n$/D' docs/filename.md
|
||||
|
||||
# Add newline at end if missing
|
||||
echo "" >> docs/filename.md
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Implementation Plans
|
||||
|
||||
```markdown
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Foundation (Day 1)
|
||||
|
||||
#### 1.1 Component Setup
|
||||
|
||||
- [ ] Create new component file
|
||||
- [ ] Add basic structure
|
||||
- [ ] Implement core functionality
|
||||
|
||||
#### 1.2 Configuration
|
||||
|
||||
- [ ] Update configuration files
|
||||
- [ ] Add environment variables
|
||||
- [ ] Test configuration loading
|
||||
```
|
||||
|
||||
### Status Tracking
|
||||
|
||||
```markdown
|
||||
**Status**: ✅ **COMPLETE** - All phases finished
|
||||
**Progress**: 75% (15/20 components)
|
||||
**Next**: Ready for testing phase
|
||||
```
|
||||
|
||||
### Performance Metrics
|
||||
|
||||
```markdown
|
||||
#### 📊 Performance Metrics
|
||||
- **Build Time**: 2.3 seconds (50% faster than baseline)
|
||||
- **Bundle Size**: 1.2MB (30% reduction)
|
||||
- **Success Rate**: 100% (no failures in 50 builds)
|
||||
```
|
||||
|
||||
## Enforcement
|
||||
|
||||
### Pre-commit Hooks
|
||||
|
||||
- Run markdownlint on all changed markdown files
|
||||
- Block commits with linting violations
|
||||
- Auto-fix common issues when possible
|
||||
|
||||
### CI/CD Integration
|
||||
|
||||
- Include markdownlint in build pipeline
|
||||
- Generate reports for documentation quality
|
||||
- Fail builds with critical violations
|
||||
|
||||
### Team Guidelines
|
||||
|
||||
- All documentation PRs must pass markdownlint
|
||||
- Use provided templates for new documents
|
||||
- Follow established patterns for consistency
|
||||
|
||||
## Templates
|
||||
|
||||
### New Document Template
|
||||
|
||||
```markdown
|
||||
# Document Title
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: YYYY-MM-DD
|
||||
**Status**: 🎯 **PLANNING** - Ready for Implementation
|
||||
|
||||
## Overview
|
||||
|
||||
Brief description of the document's purpose and scope.
|
||||
|
||||
## Current State
|
||||
|
||||
Description of current situation or problem.
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Foundation
|
||||
|
||||
- [ ] Task 1
|
||||
- [ ] Task 2
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Review and approve plan**
|
||||
2. **Begin implementation**
|
||||
3. **Test and validate**
|
||||
|
||||
---
|
||||
|
||||
**Status**: Ready for implementation
|
||||
**Priority**: Medium
|
||||
**Estimated Effort**: X days
|
||||
**Dependencies**: None
|
||||
**Stakeholders**: Development team
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-07-09
|
||||
**Version**: 1.0
|
||||
**Maintainer**: Matthew Raymer
|
||||
@@ -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
|
||||
---
|
||||
@@ -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 (2–3 prompts for dev
|
||||
discussion).
|
||||
|
||||
## 9. Dependency Management
|
||||
|
||||
- Key deps: `@capacitor/core`, `electron`, `vue`.
|
||||
- Use conditional `import()` for platform-specific libs.
|
||||
|
||||
## 10. Security Considerations
|
||||
|
||||
- **Permissions**: Always check + request gracefully.
|
||||
- **Storage**: Secure storage for sensitive data; encrypt when possible.
|
||||
- **Audits**: Schedule quarterly security reviews.
|
||||
|
||||
## 11. ADR Process
|
||||
|
||||
- All major architecture choices → log in `doc/adr/`.
|
||||
- Use ADR template with Context, Decision, Consequences, Status.
|
||||
- Link related ADRs in PR descriptions.
|
||||
|
||||
> 🔗 **Human Hook:** When proposing a new ADR, schedule a 30-min
|
||||
> design sync for discussion, not just async review.
|
||||
|
||||
## 12. Collaboration Hooks
|
||||
|
||||
- **QR features**: Sync with Security before merging → permissions &
|
||||
privacy.
|
||||
- **New platform builds**: Demo in team meeting → confirm UX
|
||||
differences.
|
||||
- **Critical ADRs**: Present in guild or architecture review.
|
||||
|
||||
## Self-Check
|
||||
|
||||
- [ ] Does this feature implement a shared interface?
|
||||
- [ ] Are fallbacks + errors handled gracefully?
|
||||
- [ ] Have relevant ADRs been updated/linked?
|
||||
- [ ] Did I add competence hooks or prompts for the team?
|
||||
- [ ] Was human interaction (sync/review/demo) scheduled?
|
||||
|
||||
---
|
||||
|
||||
**Status**: Active architecture guidelines
|
||||
**Priority**: High
|
||||
**Estimated Effort**: Ongoing reference
|
||||
**Dependencies**: Vue 3, Capacitor, Electron, Vite
|
||||
**Stakeholders**: Development team, Architecture team
|
||||
|
||||
- [ ] Are fallbacks + errors handled gracefully?
|
||||
- [ ] Have relevant ADRs been updated/linked?
|
||||
- [ ] Did I add competence hooks or prompts for the team?
|
||||
- [ ] Was human interaction (sync/review/demo) scheduled?
|
||||
# TimeSafari Cross-Platform Architecture Guide
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: 2025-08-19
|
||||
**Status**: 🎯 **ACTIVE** - Architecture guidelines
|
||||
|
||||
## 1. Platform Support Matrix
|
||||
|
||||
| Feature | Web (PWA) | Capacitor (Mobile) | Electron (Desktop) |
|
||||
|---------|-----------|--------------------|-------------------|
|
||||
| QR Code Scanning | WebInlineQRScanner | @capacitor-mlkit/barcode-scanning | Not Implemented |
|
||||
| Deep Linking | URL Parameters | App URL Open Events | Not Implemented |
|
||||
| File System | Limited (Browser API) | Capacitor Filesystem | Electron fs |
|
||||
| Camera Access | MediaDevices API | Capacitor Camera | Not Implemented |
|
||||
| Platform Detection | Web APIs | Capacitor.isNativePlatform() | process.env checks |
|
||||
|
||||
## 2. Project Structure
|
||||
|
||||
### Core Directories
|
||||
|
||||
```
|
||||
src/
|
||||
├── components/ # Vue components
|
||||
├── services/ # Platform services and business logic
|
||||
├── views/ # Page components
|
||||
├── router/ # Vue router configuration
|
||||
├── types/ # TypeScript type definitions
|
||||
├── utils/ # Utility functions
|
||||
├── lib/ # Core libraries
|
||||
├── platforms/ # Platform-specific implementations
|
||||
├── electron/ # Electron-specific code
|
||||
├── constants/ # Application constants
|
||||
├── db/ # Database related code
|
||||
├── interfaces/ # TypeScript interfaces
|
||||
└── assets/ # Static assets
|
||||
```
|
||||
|
||||
### Entry Points
|
||||
|
||||
- `main.ts` → Base entry
|
||||
- `main.common.ts` → Shared init
|
||||
- `main.capacitor.ts` → Mobile entry
|
||||
- `main.electron.ts` → Electron entry
|
||||
- `main.web.ts` → Web entry
|
||||
|
||||
## 3. Service Architecture
|
||||
|
||||
### Service Organization
|
||||
|
||||
```tree
|
||||
services/
|
||||
├── QRScanner/
|
||||
│ ├── WebInlineQRScanner.ts
|
||||
│ └── interfaces.ts
|
||||
├── platforms/
|
||||
│ ├── WebPlatformService.ts
|
||||
│ ├── CapacitorPlatformService.ts
|
||||
│ └── ElectronPlatformService.ts
|
||||
└── factory/
|
||||
└── PlatformServiceFactory.ts
|
||||
```
|
||||
|
||||
### Factory Pattern
|
||||
|
||||
Use a **singleton factory** to select platform services via
|
||||
`process.env.VITE_PLATFORM`.
|
||||
|
||||
## 4. Feature Guidelines
|
||||
|
||||
### QR Code Scanning
|
||||
|
||||
- Define `QRScannerService` interface.
|
||||
- Implement platform-specific classes (`WebInlineQRScanner`, Capacitor,
|
||||
etc).
|
||||
- Provide `addListener` and `onStream` hooks for composability.
|
||||
|
||||
### Deep Linking
|
||||
|
||||
- URL format: `timesafari://<route>[/<param>][?query=value]`
|
||||
- Web: `router.beforeEach` → parse query
|
||||
- Capacitor: `App.addListener("appUrlOpen", …)`
|
||||
|
||||
## 5. Build Process
|
||||
|
||||
- `vite.config.common.mts` → shared config
|
||||
- Platform configs: `vite.config.web.mts`, `.capacitor.mts`,
|
||||
`.electron.mts`
|
||||
- Use `process.env.VITE_PLATFORM` for conditional loading.
|
||||
|
||||
```bash
|
||||
npm run build:web
|
||||
npm run build:capacitor
|
||||
npm run build:electron
|
||||
```
|
||||
|
||||
## 6. Testing Strategy
|
||||
|
||||
- **Unit tests** for services.
|
||||
- **Playwright** for Web + Capacitor:
|
||||
- `playwright.config-local.ts` includes web + Pixel 5.
|
||||
- **Electron tests**: add `spectron` or Playwright-Electron.
|
||||
- Mark tests with platform tags:
|
||||
|
||||
```ts
|
||||
test.skip(!process.env.MOBILE_TEST, "Mobile-only test");
|
||||
```
|
||||
|
||||
> 🔗 **Human Hook:** Before merging new tests, hold a short sync (≤15
|
||||
> min) with QA to align on coverage and flaky test risks.
|
||||
|
||||
## 7. Error Handling
|
||||
|
||||
- Global Vue error handler → logs with component name.
|
||||
- Platform-specific wrappers log API errors with platform prefix
|
||||
(`[Capacitor API Error]`, etc).
|
||||
- Use structured logging (not `console.log`).
|
||||
|
||||
## 8. Best Practices
|
||||
|
||||
- Keep platform code **isolated** in `platforms/`.
|
||||
- Always define a **shared interface** first.
|
||||
- Use feature detection, not platform detection, when possible.
|
||||
- Dependency injection for services → improves testability.
|
||||
- Maintain **Competence Hooks** in PRs (2–3 prompts for dev
|
||||
discussion).
|
||||
|
||||
## 9. Dependency Management
|
||||
|
||||
- Key deps: `@capacitor/core`, `electron`, `vue`.
|
||||
- Use conditional `import()` for platform-specific libs.
|
||||
|
||||
## 10. Security Considerations
|
||||
|
||||
- **Permissions**: Always check + request gracefully.
|
||||
- **Storage**: Secure storage for sensitive data; encrypt when possible.
|
||||
- **Audits**: Schedule quarterly security reviews.
|
||||
|
||||
## 11. ADR Process
|
||||
|
||||
- All major architecture choices → log in `doc/adr/`.
|
||||
- Use ADR template with Context, Decision, Consequences, Status.
|
||||
- Link related ADRs in PR descriptions.
|
||||
|
||||
> 🔗 **Human Hook:** When proposing a new ADR, schedule a 30-min
|
||||
> design sync for discussion, not just async review.
|
||||
|
||||
## 12. Collaboration Hooks
|
||||
|
||||
- **QR features**: Sync with Security before merging → permissions &
|
||||
privacy.
|
||||
- **New platform builds**: Demo in team meeting → confirm UX
|
||||
differences.
|
||||
- **Critical ADRs**: Present in guild or architecture review.
|
||||
|
||||
## 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?
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -1,193 +0,0 @@
|
||||
---
|
||||
globs: **/db/databaseUtil.ts, **/interfaces/absurd-sql.d.ts, **/src/registerSQLWorker.js, **/
|
||||
services/AbsurdSqlDatabaseService.ts
|
||||
alwaysApply: false
|
||||
---
|
||||
# Absurd SQL - Cursor Development Guide
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: 2025-08-19
|
||||
**Status**: 🎯 **ACTIVE** - Database development guidelines
|
||||
|
||||
## Project Overview
|
||||
|
||||
Absurd SQL is a backend implementation for sql.js that enables persistent
|
||||
SQLite databases in the browser by using IndexedDB as a block storage system.
|
||||
This guide provides rules and best practices for developing with this project
|
||||
in Cursor.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
absurd-sql/
|
||||
├── src/ # Source code
|
||||
├── dist/ # Built files
|
||||
├── package.json # Dependencies and scripts
|
||||
├── rollup.config.js # Build configuration
|
||||
└── jest.config.js # Test configuration
|
||||
```
|
||||
|
||||
## Development Rules
|
||||
|
||||
### 1. Worker Thread Requirements
|
||||
|
||||
- All SQL operations MUST be performed in a worker thread
|
||||
- Main thread should only handle worker initialization and communication
|
||||
- Never block the main thread with database operations
|
||||
|
||||
### 2. Code Organization
|
||||
|
||||
- Keep worker code in separate files (e.g., `*.worker.js`)
|
||||
- Use ES modules for imports/exports
|
||||
- Follow the project's existing module structure
|
||||
|
||||
### 3. Required Headers
|
||||
|
||||
When developing locally or deploying, ensure these headers are set:
|
||||
|
||||
```
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
||||
```
|
||||
|
||||
### 4. Browser Compatibility
|
||||
|
||||
- Primary target: Modern browsers with SharedArrayBuffer support
|
||||
- Fallback mode: Safari (with limitations)
|
||||
- Always test in both modes
|
||||
|
||||
### 5. Database Configuration
|
||||
|
||||
Recommended database settings:
|
||||
|
||||
```sql
|
||||
PRAGMA journal_mode=MEMORY;
|
||||
PRAGMA page_size=8192; -- Optional, but recommended
|
||||
```
|
||||
|
||||
### 6. Development Workflow
|
||||
|
||||
1. Install dependencies:
|
||||
|
||||
```bash
|
||||
yarn add @jlongster/sql.js absurd-sql
|
||||
```
|
||||
|
||||
2. Development commands:
|
||||
- `yarn build` - Build the project
|
||||
- `yarn jest` - Run tests
|
||||
- `yarn serve` - Start development server
|
||||
|
||||
### 7. Testing Guidelines
|
||||
|
||||
- Write tests for both SharedArrayBuffer and fallback modes
|
||||
- Use Jest for testing
|
||||
- Include performance benchmarks for critical operations
|
||||
|
||||
### 8. Performance Considerations
|
||||
|
||||
- Use bulk operations when possible
|
||||
- Monitor read/write performance
|
||||
- Consider using transactions for multiple operations
|
||||
- Avoid unnecessary database connections
|
||||
|
||||
### 9. Error Handling
|
||||
|
||||
- Implement proper error handling for:
|
||||
- Worker initialization failures
|
||||
- Database connection issues
|
||||
- Concurrent access conflicts (in fallback mode)
|
||||
- Storage quota exceeded scenarios
|
||||
|
||||
### 10. Security Best Practices
|
||||
|
||||
- Never expose database operations directly to the client
|
||||
- Validate all SQL queries
|
||||
- Implement proper access controls
|
||||
- Handle sensitive data appropriately
|
||||
|
||||
### 11. Code Style
|
||||
|
||||
- Follow ESLint configuration
|
||||
- Use async/await for asynchronous operations
|
||||
- Document complex database operations
|
||||
- Include comments for non-obvious optimizations
|
||||
|
||||
### 12. Debugging
|
||||
|
||||
- Use `jest-debug` for debugging tests
|
||||
- Monitor IndexedDB usage in browser dev tools
|
||||
- Check worker communication in console
|
||||
- Use performance monitoring tools
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Worker Initialization
|
||||
|
||||
```javascript
|
||||
// Main thread
|
||||
import { initBackend } from 'absurd-sql/dist/indexeddb-main-thread';
|
||||
|
||||
function init() {
|
||||
let worker = new Worker(new URL('./index.worker.js', import.meta.url));
|
||||
initBackend(worker);
|
||||
}
|
||||
```
|
||||
|
||||
### Database Setup
|
||||
|
||||
```javascript
|
||||
// Worker thread
|
||||
import initSqlJs from '@jlongster/sql.js';
|
||||
import { SQLiteFS } from 'absurd-sql';
|
||||
import IndexedDBBackend from 'absurd-sql/dist/indexeddb-backend';
|
||||
|
||||
async function setupDatabase() {
|
||||
let SQL = await initSqlJs({ locateFile: file => file });
|
||||
let sqlFS = new SQLiteFS(SQL.FS, new IndexedDBBackend());
|
||||
SQL.register_for_idb(sqlFS);
|
||||
|
||||
SQL.FS.mkdir('/sql');
|
||||
SQL.FS.mount(sqlFS, {}, '/sql');
|
||||
|
||||
return new SQL.Database('/sql/db.sqlite', { filename: true });
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. SharedArrayBuffer not available
|
||||
- Check COOP/COEP headers
|
||||
- Verify browser support
|
||||
- Test fallback mode
|
||||
|
||||
2. Worker initialization failures
|
||||
- Check file paths
|
||||
- Verify module imports
|
||||
- Check browser console for errors
|
||||
|
||||
3. Performance issues
|
||||
- Monitor IndexedDB usage
|
||||
- Check for unnecessary operations
|
||||
- Verify transaction usage
|
||||
|
||||
## Resources
|
||||
|
||||
- [Project Demo](https://priceless-keller-d097e5.netlify.app/)
|
||||
- [Example Project](https://github.com/jlongster/absurd-example-project)
|
||||
- [Blog Post](https://jlongster.com/future-sql-web)
|
||||
- [SQL.js Documentation](https://github.com/sql-js/sql.js/)
|
||||
|
||||
---
|
||||
|
||||
**Status**: Active database development guidelines
|
||||
**Priority**: High
|
||||
**Estimated Effort**: Ongoing reference
|
||||
**Dependencies**: Absurd SQL, SQL.js, IndexedDB
|
||||
**Stakeholders**: Development team, Database team
|
||||
- [Project Demo](https://priceless-keller-d097e5.netlify.app/)
|
||||
- [Example Project](https://github.com/jlongster/absurd-example-project)
|
||||
- [Blog Post](https://jlongster.com/future-sql-web)
|
||||
- [SQL.js Documentation](https://github.com/sql-js/sql.js/)
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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 type‑safe**
|
||||
- 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.
|
||||
- **3rd‑party 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`
|
||||
- [ ] Guard‑based error paths verified
|
||||
- [ ] Dynamic ops are type‑safe
|
||||
- [ ] Prefer existing types over re‑inventing
|
||||
|
||||
## Tools
|
||||
|
||||
- `npm run lint-fix` — lint & auto‑fix
|
||||
- `npm run type-check` — strict type compilation (CI + pre‑release)
|
||||
- IDE: enable strict TS, ESLint/TS ESLint, Volar (Vue 3)
|
||||
|
||||
## References
|
||||
|
||||
- TS Handbook — https://www.typescriptlang.org/docs/
|
||||
- TS‑ESLint — https://typescript-eslint.io/rules/
|
||||
- Vue 3 + TS — https://vuejs.org/guide/typescript/
|
||||
|
||||
---
|
||||
|
||||
**Status**: Active type safety guidelines
|
||||
**Priority**: High
|
||||
**Estimated Effort**: Ongoing reference
|
||||
**Dependencies**: TypeScript, ESLint, Vue 3
|
||||
**Stakeholders**: Development team
|
||||
|
||||
- TS Handbook — https://www.typescriptlang.org/docs/
|
||||
- TS‑ESLint — https://typescript-eslint.io/rules/
|
||||
- Vue 3 + TS — https://vuejs.org/guide/typescript/
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -1,366 +0,0 @@
|
||||
---
|
||||
globs: ["*.md", "*.mdc"]
|
||||
alwaysApply: false
|
||||
---
|
||||
# Cursor Markdown Ruleset for TimeSafari Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
This ruleset enforces consistent markdown formatting standards across all project
|
||||
documentation, ensuring readability, maintainability, and compliance with
|
||||
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
|
||||
|
||||
### Line Length
|
||||
|
||||
- **Maximum line length**: 80 characters
|
||||
- **Exception**: Code blocks (JSON, shell, TypeScript, etc.) - no line length
|
||||
enforcement
|
||||
- **Rationale**: Ensures readability across different screen sizes and terminal
|
||||
widths
|
||||
|
||||
### Blank Lines
|
||||
|
||||
- **Headings**: Must be surrounded by blank lines above and below
|
||||
- **Lists**: Must be surrounded by blank lines above and below
|
||||
- **Code blocks**: Must be surrounded by blank lines above and below
|
||||
- **Maximum consecutive blank lines**: 1 (no multiple blank lines)
|
||||
- **File start**: No blank lines at the beginning of the file
|
||||
- **File end**: Single newline character at the end
|
||||
|
||||
### Whitespace
|
||||
|
||||
- **No trailing spaces**: Remove all trailing whitespace from lines
|
||||
- **No tabs**: Use spaces for indentation
|
||||
- **Consistent indentation**: 2 spaces for list items and nested content
|
||||
|
||||
## Heading Standards
|
||||
|
||||
### Format
|
||||
|
||||
- **Style**: ATX-style headings (`#`, `##`, `###`, etc.)
|
||||
- **Case**: Title case for general headings
|
||||
- **Code references**: Use backticks for file names and technical terms
|
||||
- ✅ `### Current package.json Scripts`
|
||||
- ❌ `### Current Package.json Scripts`
|
||||
|
||||
### Hierarchy
|
||||
|
||||
- **H1 (#)**: Document title only
|
||||
- **H2 (##)**: Major sections
|
||||
- **H3 (###)**: Subsections
|
||||
- **H4 (####)**: Sub-subsections
|
||||
- **H5+**: Avoid deeper nesting
|
||||
|
||||
## List Standards
|
||||
|
||||
### Unordered Lists
|
||||
|
||||
- **Marker**: Use `-` (hyphen) consistently
|
||||
- **Indentation**: 2 spaces for nested items
|
||||
- **Blank lines**: Surround lists with blank lines
|
||||
|
||||
### Ordered Lists
|
||||
|
||||
- **Format**: `1.`, `2.`, `3.` (sequential numbering)
|
||||
- **Indentation**: 2 spaces for nested items
|
||||
- **Blank lines**: Surround lists with blank lines
|
||||
|
||||
### Task Lists
|
||||
|
||||
- **Format**: `- [ ]` for incomplete, `- [x]` for complete
|
||||
- **Use case**: Project planning, checklists, implementation tracking
|
||||
|
||||
## Code Block Standards
|
||||
|
||||
### Fenced Code Blocks
|
||||
|
||||
- **Syntax**: Triple backticks with language specification
|
||||
- **Languages**: `json`, `bash`, `typescript`, `javascript`, `yaml`, `markdown`
|
||||
- **Blank lines**: Must be surrounded by blank lines above and below
|
||||
- **Line length**: No enforcement within code blocks
|
||||
|
||||
### Inline Code
|
||||
|
||||
- **Format**: Single backticks for inline code references
|
||||
- **Use case**: File names, commands, variables, properties
|
||||
|
||||
## Special Content Standards
|
||||
|
||||
### JSON Examples
|
||||
|
||||
```json
|
||||
{
|
||||
"property": "value",
|
||||
"nested": {
|
||||
"property": "value"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Shell Commands
|
||||
|
||||
```bash
|
||||
# Command with comment
|
||||
npm run build:web
|
||||
|
||||
# Multi-line command
|
||||
VITE_GIT_HASH=`git log -1 --pretty=format:%h` \
|
||||
vite build --config vite.config.web.mts
|
||||
```
|
||||
|
||||
### TypeScript Examples
|
||||
|
||||
```typescript
|
||||
// Function with JSDoc
|
||||
/**
|
||||
* Get environment configuration
|
||||
* @param env - Environment name
|
||||
* @returns Environment config object
|
||||
*/
|
||||
const getEnvironmentConfig = (env: string) => {
|
||||
switch (env) {
|
||||
case 'prod':
|
||||
return { /* production settings */ };
|
||||
default:
|
||||
return { /* development settings */ };
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## File Structure Standards
|
||||
|
||||
### Document Header
|
||||
|
||||
```markdown
|
||||
# Document Title
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: YYYY-MM-DD
|
||||
**Status**: 🎯 **STATUS** - Brief description
|
||||
|
||||
## Overview
|
||||
|
||||
Brief description of the document's purpose and scope.
|
||||
```
|
||||
|
||||
### Section Organization
|
||||
|
||||
1. **Overview/Introduction**
|
||||
2. **Current State Analysis**
|
||||
3. **Implementation Plan**
|
||||
4. **Technical Details**
|
||||
5. **Testing & Validation**
|
||||
6. **Next Steps**
|
||||
|
||||
## Markdownlint Configuration
|
||||
|
||||
### Required Rules
|
||||
|
||||
```json
|
||||
{
|
||||
"MD013": { "code_blocks": false },
|
||||
"MD012": true,
|
||||
"MD022": true,
|
||||
"MD031": true,
|
||||
"MD032": true,
|
||||
"MD047": true,
|
||||
"MD009": true
|
||||
}
|
||||
```
|
||||
|
||||
### Rule Explanations
|
||||
|
||||
- **MD013**: Line length (disabled for code blocks)
|
||||
- **MD012**: No multiple consecutive blank lines
|
||||
- **MD022**: Headings should be surrounded by blank lines
|
||||
- **MD031**: Fenced code blocks should be surrounded by blank lines
|
||||
- **MD032**: Lists should be surrounded by blank lines
|
||||
- **MD047**: Files should end with a single newline
|
||||
- **MD009**: No trailing spaces
|
||||
|
||||
## Validation Commands
|
||||
|
||||
### Check Single File
|
||||
|
||||
```bash
|
||||
npx markdownlint docs/filename.md
|
||||
```
|
||||
|
||||
### Check All Documentation
|
||||
|
||||
```bash
|
||||
npx markdownlint docs/
|
||||
```
|
||||
|
||||
### Auto-fix Common Issues
|
||||
|
||||
```bash
|
||||
# Remove trailing spaces
|
||||
sed -i 's/[[:space:]]*$//' docs/filename.md
|
||||
|
||||
# Remove multiple blank lines
|
||||
sed -i '/^$/N;/^\n$/D' docs/filename.md
|
||||
|
||||
# Add newline at end if missing
|
||||
echo "" >> docs/filename.md
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Implementation Plans
|
||||
|
||||
```markdown
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Foundation (Day 1)
|
||||
|
||||
#### 1.1 Component Setup
|
||||
|
||||
- [ ] Create new component file
|
||||
- [ ] Add basic structure
|
||||
- [ ] Implement core functionality
|
||||
|
||||
#### 1.2 Configuration
|
||||
|
||||
- [ ] Update configuration files
|
||||
- [ ] Add environment variables
|
||||
- [ ] Test configuration loading
|
||||
```
|
||||
|
||||
### Status Tracking
|
||||
|
||||
```markdown
|
||||
**Status**: ✅ **COMPLETE** - All phases finished
|
||||
**Progress**: 75% (15/20 components)
|
||||
**Next**: Ready for testing phase
|
||||
```
|
||||
|
||||
### Performance Metrics
|
||||
|
||||
```markdown
|
||||
#### 📊 Performance Metrics
|
||||
- **Build Time**: 2.3 seconds (50% faster than baseline)
|
||||
- **Bundle Size**: 1.2MB (30% reduction)
|
||||
- **Success Rate**: 100% (no failures in 50 builds)
|
||||
```
|
||||
|
||||
## Enforcement
|
||||
|
||||
### Pre-commit Hooks
|
||||
|
||||
- Run markdownlint on all changed markdown files
|
||||
- Block commits with linting violations
|
||||
- Auto-fix common issues when possible
|
||||
|
||||
### CI/CD Integration
|
||||
|
||||
- Include markdownlint in build pipeline
|
||||
- Generate reports for documentation quality
|
||||
- Fail builds with critical violations
|
||||
|
||||
### Team Guidelines
|
||||
|
||||
- All documentation PRs must pass markdownlint
|
||||
- Use provided templates for new documents
|
||||
- Follow established patterns for consistency
|
||||
|
||||
## Templates
|
||||
|
||||
### New Document Template
|
||||
|
||||
```markdown
|
||||
# Document Title
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: YYYY-MM-DD
|
||||
**Status**: 🎯 **PLANNING** - Ready for Implementation
|
||||
|
||||
## Overview
|
||||
|
||||
Brief description of the document's purpose and scope.
|
||||
|
||||
## Current State
|
||||
|
||||
Description of current situation or problem.
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Foundation
|
||||
|
||||
- [ ] Task 1
|
||||
- [ ] Task 2
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Review and approve plan**
|
||||
2. **Begin implementation**
|
||||
3. **Test and validate**
|
||||
|
||||
---
|
||||
|
||||
**Status**: Ready for implementation
|
||||
**Priority**: Medium
|
||||
**Estimated Effort**: X days
|
||||
**Dependencies**: None
|
||||
**Stakeholders**: Development team
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-07-09
|
||||
**Version**: 1.0
|
||||
**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
|
||||
```
|
||||
@@ -1,222 +0,0 @@
|
||||
---
|
||||
description: when dealing with cameras in the application
|
||||
alwaysApply: false
|
||||
---
|
||||
# Camera Implementation Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes how camera functionality is implemented across the
|
||||
TimeSafari application. The application uses cameras for two main purposes:
|
||||
|
||||
1. QR Code scanning
|
||||
2. Photo capture
|
||||
|
||||
## Components
|
||||
|
||||
### QRScannerDialog.vue
|
||||
|
||||
Primary component for QR code scanning in web browsers.
|
||||
|
||||
**Key Features:**
|
||||
|
||||
- Uses `qrcode-stream` for web-based QR scanning
|
||||
- Supports both front and back cameras
|
||||
- Provides real-time camera status feedback
|
||||
- Implements error handling with user-friendly messages
|
||||
- Includes camera switching functionality
|
||||
|
||||
**Camera Access Flow:**
|
||||
|
||||
1. Checks for camera API availability
|
||||
2. Enumerates available video devices
|
||||
3. Requests camera permissions
|
||||
4. Initializes camera stream with preferred settings
|
||||
5. Handles various error conditions with specific messages
|
||||
|
||||
### PhotoDialog.vue
|
||||
|
||||
Component for photo capture and selection.
|
||||
|
||||
**Key Features:**
|
||||
|
||||
- Cross-platform photo capture interface
|
||||
- Image cropping capabilities
|
||||
- File selection fallback
|
||||
- Unified interface for different platforms
|
||||
|
||||
## Services
|
||||
|
||||
### QRScanner Services
|
||||
|
||||
#### WebDialogQRScanner
|
||||
|
||||
Web-based implementation of QR scanning.
|
||||
|
||||
**Key Methods:**
|
||||
|
||||
- `checkPermissions()`: Verifies camera permission status
|
||||
- `requestPermissions()`: Requests camera access
|
||||
- `isSupported()`: Checks for camera API support
|
||||
- Handles various error conditions with specific messages
|
||||
|
||||
#### CapacitorQRScanner
|
||||
|
||||
Native implementation using Capacitor's MLKit.
|
||||
|
||||
**Key Features:**
|
||||
|
||||
- Uses `@capacitor-mlkit/barcode-scanning`
|
||||
- Supports both front and back cameras
|
||||
- Implements permission management
|
||||
- Provides continuous scanning capability
|
||||
|
||||
### Platform Services
|
||||
|
||||
#### WebPlatformService
|
||||
|
||||
Web-specific implementation of platform features.
|
||||
|
||||
**Camera Capabilities:**
|
||||
|
||||
- Uses HTML5 file input with capture attribute
|
||||
- Falls back to file selection if camera unavailable
|
||||
- Processes captured images for consistent format
|
||||
|
||||
#### CapacitorPlatformService
|
||||
|
||||
Native implementation using Capacitor.
|
||||
|
||||
**Camera Features:**
|
||||
|
||||
- Uses `Camera.getPhoto()` for native camera access
|
||||
- Supports image editing
|
||||
- Configures high-quality image capture
|
||||
- Handles base64 image processing
|
||||
|
||||
#### ElectronPlatformService
|
||||
|
||||
Desktop implementation (currently unimplemented).
|
||||
|
||||
**Status:**
|
||||
|
||||
- Camera functionality not yet implemented
|
||||
- Planned to use Electron's media APIs
|
||||
|
||||
## Platform-Specific Considerations
|
||||
|
||||
### iOS
|
||||
|
||||
- Requires `NSCameraUsageDescription` in Info.plist
|
||||
- Supports both front and back cameras
|
||||
- Implements proper permission handling
|
||||
|
||||
### Android
|
||||
|
||||
- Requires camera permissions in manifest
|
||||
- Supports both front and back cameras
|
||||
- Handles permission requests through Capacitor
|
||||
|
||||
### Web
|
||||
|
||||
- Requires HTTPS for camera access
|
||||
- Implements fallback mechanisms
|
||||
- Handles browser compatibility issues
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Common Error Scenarios
|
||||
|
||||
1. No camera found
|
||||
2. Permission denied
|
||||
3. Camera in use by another application
|
||||
4. HTTPS required
|
||||
5. Browser compatibility issues
|
||||
|
||||
### Error Response
|
||||
|
||||
- User-friendly error messages
|
||||
- Troubleshooting tips
|
||||
- Clear instructions for resolution
|
||||
- Platform-specific guidance
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Permission Management
|
||||
|
||||
- Explicit permission requests
|
||||
- Permission state tracking
|
||||
- Graceful handling of denied permissions
|
||||
|
||||
### Data Handling
|
||||
|
||||
- Secure image processing
|
||||
- Proper cleanup of camera resources
|
||||
- No persistent storage of camera data
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Camera Access
|
||||
|
||||
1. Always check for camera availability
|
||||
2. Request permissions explicitly
|
||||
3. Handle all error conditions
|
||||
4. Provide clear user feedback
|
||||
5. Implement proper cleanup
|
||||
|
||||
### Performance
|
||||
|
||||
1. Optimize camera resolution
|
||||
2. Implement proper resource cleanup
|
||||
3. Handle camera switching efficiently
|
||||
4. Manage memory usage
|
||||
|
||||
### User Experience
|
||||
|
||||
1. Clear status indicators
|
||||
2. Intuitive camera controls
|
||||
3. Helpful error messages
|
||||
4. Smooth camera switching
|
||||
5. Responsive UI feedback
|
||||
|
||||
## Future Improvements
|
||||
|
||||
### Planned Enhancements
|
||||
|
||||
1. Implement Electron camera support
|
||||
2. Add advanced camera features
|
||||
3. Improve error handling
|
||||
4. Enhance user feedback
|
||||
5. Optimize performance
|
||||
|
||||
### Known Issues
|
||||
|
||||
1. Electron camera implementation pending
|
||||
2. Some browser compatibility limitations
|
||||
3. Platform-specific quirks to address
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Key Packages
|
||||
|
||||
- `@capacitor-mlkit/barcode-scanning`
|
||||
- `qrcode-stream`
|
||||
- `vue-picture-cropper`
|
||||
- Platform-specific camera APIs
|
||||
|
||||
## Testing
|
||||
|
||||
### Test Scenarios
|
||||
|
||||
1. Permission handling
|
||||
2. Camera switching
|
||||
3. Error conditions
|
||||
4. Platform compatibility
|
||||
5. Performance metrics
|
||||
|
||||
### Test Environment
|
||||
|
||||
- Multiple browsers
|
||||
- iOS and Android devices
|
||||
- Desktop platforms
|
||||
- Various network conditions
|
||||
@@ -1,207 +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/Doesn’t* 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 Contract’s **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 Doesn’t (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 / Don’t (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**.
|
||||
- **Don’t** use marketing language or meta narration (“Perfect!”, “tool called”, “new chat”).
|
||||
- **Don’t** 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/Doesn’t 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 Doesn’t (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`)
|
||||
- Apply Playwright test investigation rules (see `.cursor/rules/playwright_test_investigation.mdc`)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
## Non‑Negotiables (DO THIS)
|
||||
|
||||
- You **MUST** use the project logger; **DO NOT** use any `console.*`
|
||||
methods.
|
||||
- Import exactly as:
|
||||
- `import { logger } from '@/utils/logger'`
|
||||
- If `@` alias is unavailable, compute the correct relative path (do not
|
||||
fail).
|
||||
- Call signatures use **rest parameters**: `logger.info(message, ...args)`
|
||||
- Prefer primitives/IDs and small objects in `...args`; **never build a
|
||||
throwaway object** just to "wrap context".
|
||||
- Production defaults: Web = `warn+`, Electron = `error`, Dev/Capacitor =
|
||||
`info+` (override via `VITE_LOG_LEVEL`).
|
||||
- **Database persistence**: `info|warn|error` are persisted; `debug` is not.
|
||||
Use `logger.toDb(msg, level?)` for DB-only.
|
||||
|
||||
## Available Logger API (Authoritative)
|
||||
|
||||
- `logger.debug(message, ...args)` — verbose internals, timings, input/output
|
||||
shapes
|
||||
- `logger.log(message, ...args)` — synonym of `info` for general info
|
||||
- `logger.info(message, ...args)` — lifecycle, state changes, success paths
|
||||
- `logger.warn(message, ...args)` — recoverable issues, retries, degraded mode
|
||||
- `logger.error(message, ...args)` — failures, thrown exceptions, aborts
|
||||
- `logger.toDb(message, level?)` — DB-only entry (default level = `info`)
|
||||
- `logger.toConsoleAndDb(message, isError)` — console + DB (use sparingly)
|
||||
- `logger.withContext(componentName)` — returns a scoped logger
|
||||
|
||||
## Level Guidelines (Use These Heuristics)
|
||||
|
||||
### DEBUG
|
||||
|
||||
Use for method entry/exit, computed values, filters, loops, retries, and
|
||||
external call payload sizes.
|
||||
|
||||
```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 — Auto‑Rewrites (Apply Every Time)
|
||||
|
||||
- Exact transforms:
|
||||
- `console.debug(...)` → `logger.debug(...)`
|
||||
- `console.log(...)` → `logger.log(...)` (or `logger.info(...)` when
|
||||
clearly stateful)
|
||||
- `console.info(...)` → `logger.info(...)`
|
||||
- `console.warn(...)` → `logger.warn(...)`
|
||||
- `console.error(...)` → `logger.error(...)`
|
||||
|
||||
- Multi-arg handling:
|
||||
- First arg becomes `message` (stringify safely if non-string).
|
||||
- Remaining args map 1:1 to `...args`:
|
||||
`console.info(msg, a, b)` → `logger.info(String(msg), a, b)`
|
||||
|
||||
- Sole `Error`:
|
||||
- `console.error(err)` → `logger.error(err.message, err)`
|
||||
|
||||
- **Object-wrapping cleanup**: Replace `{{ userId, meta }}` wrappers with
|
||||
separate args:
|
||||
`logger.info('User signed in', userId, meta)`
|
||||
|
||||
## DB Logging Rules
|
||||
|
||||
- `debug` **never** persists automatically.
|
||||
- `info|warn|error` persist automatically.
|
||||
- For DB-only events (no console), call `logger.toDb('Message',
|
||||
'info'|'warn'|'error')`.
|
||||
|
||||
## Exceptions (Tightly Scoped)
|
||||
|
||||
Allowed paths (still prefer logger):
|
||||
|
||||
- `**/*.test.*`, `**/*.spec.*`
|
||||
- `scripts/dev/**`, `scripts/migrate/**`
|
||||
|
||||
To intentionally keep `console.*`, add a pragma on the previous line:
|
||||
|
||||
```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
|
||||
@@ -1,356 +0,0 @@
|
||||
---
|
||||
description: when working with playwright tests either generating them or using them to test code
|
||||
alwaysApply: false
|
||||
---
|
||||
# Playwright Test Investigation — Harbor Pilot Directive
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: 2025-08-21T14:22Z
|
||||
**Status**: 🎯 **ACTIVE** - Playwright test debugging guidelines
|
||||
|
||||
## Objective
|
||||
Provide systematic approach for investigating Playwright test failures with focus on UI element conflicts, timing issues, and selector ambiguity.
|
||||
|
||||
## Context & Scope
|
||||
- **Audience**: Developers debugging Playwright test failures
|
||||
- **In scope**: Test failure analysis, selector conflicts, UI state investigation, timing issues
|
||||
- **Out of scope**: Test writing best practices, CI/CD configuration
|
||||
|
||||
## Artifacts & Links
|
||||
- Test results: `test-results/` directory
|
||||
- Error context: `error-context.md` files with page snapshots
|
||||
- Trace files: `trace.zip` files for failed tests
|
||||
- HTML reports: Interactive test reports with screenshots
|
||||
|
||||
## Environment & Preconditions
|
||||
- OS/Runtime: Linux/Windows/macOS with Node.js
|
||||
- Versions: Playwright test framework, browser drivers
|
||||
- Services: Local test server (localhost:8080), test data setup
|
||||
- Auth mode: None required for test investigation
|
||||
|
||||
## Architecture / Process Overview
|
||||
Playwright test investigation follows a systematic diagnostic workflow that leverages built-in debugging tools and error context analysis.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Test Failure] --> B[Check Error Context]
|
||||
B --> C[Analyze Page Snapshot]
|
||||
C --> D[Identify UI Conflicts]
|
||||
D --> E[Check Trace Files]
|
||||
E --> F[Verify Selector Uniqueness]
|
||||
F --> G[Test Selector Fixes]
|
||||
G --> H[Document Root Cause]
|
||||
|
||||
B --> I[Check Test Results Directory]
|
||||
I --> J[Locate Failed Test Results]
|
||||
J --> K[Extract Error Details]
|
||||
|
||||
D --> L[Multiple Alerts?]
|
||||
L --> M[Button Text Conflicts?]
|
||||
M --> N[Timing Issues?]
|
||||
|
||||
E --> O[Use Trace Viewer]
|
||||
O --> P[Analyze Action Sequence]
|
||||
P --> Q[Identify Failure Point]
|
||||
```
|
||||
|
||||
## Interfaces & Contracts
|
||||
|
||||
### Test Results Structure
|
||||
| Component | Format | Content | Validation |
|
||||
|---|---|---|---|
|
||||
| Error Context | Markdown | Page snapshot in YAML | Verify DOM state matches test expectations |
|
||||
| Trace Files | ZIP archive | Detailed execution trace | Use `npx playwright show-trace` |
|
||||
| HTML Reports | Interactive HTML | Screenshots, traces, logs | Check browser for full report |
|
||||
| JSON Results | JSON | Machine-readable results | Parse for automated analysis |
|
||||
|
||||
### Investigation Commands
|
||||
| Step | Command | Expected Output | Notes |
|
||||
|---|---|---|---|
|
||||
| Locate failed tests | `find test-results -name "*test-name*"` | Test result directories | Use exact test name patterns |
|
||||
| Check error context | `cat test-results/*/error-context.md` | Page snapshots | Look for UI state conflicts |
|
||||
| View traces | `npx playwright show-trace trace.zip` | Interactive trace viewer | Analyze exact failure sequence |
|
||||
|
||||
## Repro: End-to-End Investigation Procedure
|
||||
|
||||
### 1. Locate Failed Test Results
|
||||
```bash
|
||||
# Find all results for a specific test
|
||||
find test-results -name "*test-name*" -type d
|
||||
|
||||
# Check for error context files
|
||||
find test-results -name "error-context.md" | head -5
|
||||
```
|
||||
|
||||
### 2. Analyze Error Context
|
||||
```bash
|
||||
# Read error context for specific test
|
||||
cat test-results/test-name-test-description-browser/error-context.md
|
||||
|
||||
# Look for UI conflicts in page snapshot
|
||||
grep -A 10 -B 5 "button.*Yes\|button.*No" test-results/*/error-context.md
|
||||
```
|
||||
|
||||
### 3. Check Trace Files
|
||||
```bash
|
||||
# List available trace files
|
||||
find test-results -name "*.zip" | grep trace
|
||||
|
||||
# View trace in browser
|
||||
npx playwright show-trace test-results/test-name/trace.zip
|
||||
```
|
||||
|
||||
### 4. Investigate Selector Issues
|
||||
```typescript
|
||||
// Check for multiple elements with same text
|
||||
await page.locator('button:has-text("Yes")').count(); // Should be 1
|
||||
|
||||
// Use more specific selectors
|
||||
await page.locator('div[role="alert"]:has-text("Register") button:has-text("Yes")').click();
|
||||
```
|
||||
|
||||
## What Works (Evidence)
|
||||
- ✅ **Error context files** provide page snapshots showing exact DOM state at failure
|
||||
- **Time**: 2025-08-21T14:22Z
|
||||
- **Evidence**: `test-results/60-new-activity-New-offers-for-another-user-chromium/error-context.md` shows both alerts visible
|
||||
- **Verify at**: Error context files in test results directory
|
||||
|
||||
- ✅ **Trace files** capture detailed execution sequence for failed tests
|
||||
- **Time**: 2025-08-21T14:22Z
|
||||
- **Evidence**: `trace.zip` files available for all failed tests
|
||||
- **Verify at**: Use `npx playwright show-trace <filename>`
|
||||
|
||||
- ✅ **Page snapshots** reveal UI conflicts like multiple alerts with duplicate button text
|
||||
- **Time**: 2025-08-21T14:22Z
|
||||
- **Evidence**: YAML snapshots show registration + export alerts simultaneously
|
||||
- **Verify at**: Error context markdown files
|
||||
|
||||
## What Doesn't (Evidence & Hypotheses)
|
||||
- ❌ **Generic selectors** fail with multiple similar elements at `test-playwright/testUtils.ts:161`
|
||||
- **Time**: 2025-08-21T14:22Z
|
||||
- **Evidence**: `button:has-text("Yes")` matches both "Yes" and "Yes, Export Data"
|
||||
- **Hypothesis**: Selector ambiguity due to multiple alerts with conflicting button text
|
||||
- **Next probe**: Use more specific selectors or dismiss alerts sequentially
|
||||
|
||||
- ❌ **Timing-dependent tests** fail due to alert stacking at `src/views/ContactsView.vue:860,1283`
|
||||
- **Time**: 2025-08-21T14:22Z
|
||||
- **Evidence**: Both alerts use identical 1000ms delays, ensuring simultaneous display
|
||||
- **Hypothesis**: Race condition between alert displays creates UI conflicts
|
||||
- **Next probe**: Implement alert queuing or prevent overlapping alerts
|
||||
|
||||
## Risks, Limits, Assumptions
|
||||
- **Trace file size**: Large trace files may impact storage and analysis time
|
||||
- **Browser compatibility**: Trace viewer requires specific browser support
|
||||
- **Test isolation**: Shared state between tests may affect investigation results
|
||||
- **Timing sensitivity**: Tests may pass/fail based on system performance
|
||||
|
||||
## Next Steps
|
||||
| Owner | Task | Exit Criteria | Target Date (UTC) |
|
||||
|---|---|---|---|
|
||||
| Development Team | Fix test selectors for multiple alerts | All tests pass consistently | 2025-08-22 |
|
||||
| Development Team | Implement alert queuing system | No overlapping alerts with conflicting buttons | 2025-08-25 |
|
||||
| Development Team | Add test IDs to alert buttons | Unique selectors for all UI elements | 2025-08-28 |
|
||||
|
||||
## References
|
||||
- [Playwright Trace Viewer Documentation](https://playwright.dev/docs/trace-viewer)
|
||||
- [Playwright Test Results](https://playwright.dev/docs/test-reporters)
|
||||
- [Test Investigation Workflow](./research_diagnostic.mdc)
|
||||
|
||||
## Competence Hooks
|
||||
- **Why this works**: Systematic investigation leverages Playwright's built-in debugging tools to identify root causes
|
||||
- **Common pitfalls**: Generic selectors fail with multiple similar elements; timing issues create race conditions; alert stacking causes UI conflicts
|
||||
- **Next skill unlock**: Implement unique test IDs and handle alert dismissal order in test flows
|
||||
- **Teach-back**: "How would you investigate a Playwright test failure using error context, trace files, and page snapshots?"
|
||||
|
||||
## Collaboration Hooks
|
||||
- **Reviewers**: QA team, test automation engineers
|
||||
- **Sign-off checklist**: Error context analyzed, trace files reviewed, root cause identified, fix implemented and tested
|
||||
|
||||
## Assumptions & Limits
|
||||
- Test results directory structure follows Playwright conventions
|
||||
- Trace files are enabled in configuration (`trace: "retain-on-failure"`)
|
||||
- Error context files contain valid YAML page snapshots
|
||||
- Browser environment supports trace viewer functionality
|
||||
|
||||
---
|
||||
|
||||
**Status**: Active investigation directive
|
||||
**Priority**: High
|
||||
**Maintainer**: Development team
|
||||
**Next Review**: 2025-09-21
|
||||
# Playwright Test Investigation — Harbor Pilot Directive
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: 2025-08-21T14:22Z
|
||||
**Status**: 🎯 **ACTIVE** - Playwright test debugging guidelines
|
||||
|
||||
## Objective
|
||||
Provide systematic approach for investigating Playwright test failures with focus on UI element conflicts, timing issues, and selector ambiguity.
|
||||
|
||||
## Context & Scope
|
||||
- **Audience**: Developers debugging Playwright test failures
|
||||
- **In scope**: Test failure analysis, selector conflicts, UI state investigation, timing issues
|
||||
- **Out of scope**: Test writing best practices, CI/CD configuration
|
||||
|
||||
## Artifacts & Links
|
||||
- Test results: `test-results/` directory
|
||||
- Error context: `error-context.md` files with page snapshots
|
||||
- Trace files: `trace.zip` files for failed tests
|
||||
- HTML reports: Interactive test reports with screenshots
|
||||
|
||||
## Environment & Preconditions
|
||||
- OS/Runtime: Linux/Windows/macOS with Node.js
|
||||
- Versions: Playwright test framework, browser drivers
|
||||
- Services: Local test server (localhost:8080), test data setup
|
||||
- Auth mode: None required for test investigation
|
||||
|
||||
## Architecture / Process Overview
|
||||
Playwright test investigation follows a systematic diagnostic workflow that leverages built-in debugging tools and error context analysis.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Test Failure] --> B[Check Error Context]
|
||||
B --> C[Analyze Page Snapshot]
|
||||
C --> D[Identify UI Conflicts]
|
||||
D --> E[Check Trace Files]
|
||||
E --> F[Verify Selector Uniqueness]
|
||||
F --> G[Test Selector Fixes]
|
||||
G --> H[Document Root Cause]
|
||||
|
||||
B --> I[Check Test Results Directory]
|
||||
I --> J[Locate Failed Test Results]
|
||||
J --> K[Extract Error Details]
|
||||
|
||||
D --> L[Multiple Alerts?]
|
||||
L --> M[Button Text Conflicts?]
|
||||
M --> N[Timing Issues?]
|
||||
|
||||
E --> O[Use Trace Viewer]
|
||||
O --> P[Analyze Action Sequence]
|
||||
P --> Q[Identify Failure Point]
|
||||
```
|
||||
|
||||
## Interfaces & Contracts
|
||||
|
||||
### Test Results Structure
|
||||
| Component | Format | Content | Validation |
|
||||
|---|---|---|---|
|
||||
| Error Context | Markdown | Page snapshot in YAML | Verify DOM state matches test expectations |
|
||||
| Trace Files | ZIP archive | Detailed execution trace | Use `npx playwright show-trace` |
|
||||
| HTML Reports | Interactive HTML | Screenshots, traces, logs | Check browser for full report |
|
||||
| JSON Results | JSON | Machine-readable results | Parse for automated analysis |
|
||||
|
||||
### Investigation Commands
|
||||
| Step | Command | Expected Output | Notes |
|
||||
|---|---|---|---|
|
||||
| Locate failed tests | `find test-results -name "*test-name*"` | Test result directories | Use exact test name patterns |
|
||||
| Check error context | `cat test-results/*/error-context.md` | Page snapshots | Look for UI state conflicts |
|
||||
| View traces | `npx playwright show-trace trace.zip` | Interactive trace viewer | Analyze exact failure sequence |
|
||||
|
||||
## Repro: End-to-End Investigation Procedure
|
||||
|
||||
### 1. Locate Failed Test Results
|
||||
```bash
|
||||
# Find all results for a specific test
|
||||
find test-results -name "*test-name*" -type d
|
||||
|
||||
# Check for error context files
|
||||
find test-results -name "error-context.md" | head -5
|
||||
```
|
||||
|
||||
### 2. Analyze Error Context
|
||||
```bash
|
||||
# Read error context for specific test
|
||||
cat test-results/test-name-test-description-browser/error-context.md
|
||||
|
||||
# Look for UI conflicts in page snapshot
|
||||
grep -A 10 -B 5 "button.*Yes\|button.*No" test-results/*/error-context.md
|
||||
```
|
||||
|
||||
### 3. Check Trace Files
|
||||
```bash
|
||||
# List available trace files
|
||||
find test-results -name "*.zip" | grep trace
|
||||
|
||||
# View trace in browser
|
||||
npx playwright show-trace test-results/test-name/trace.zip
|
||||
```
|
||||
|
||||
### 4. Investigate Selector Issues
|
||||
```typescript
|
||||
// Check for multiple elements with same text
|
||||
await page.locator('button:has-text("Yes")').count(); // Should be 1
|
||||
|
||||
// Use more specific selectors
|
||||
await page.locator('div[role="alert"]:has-text("Register") button:has-text("Yes")').click();
|
||||
```
|
||||
|
||||
## What Works (Evidence)
|
||||
- ✅ **Error context files** provide page snapshots showing exact DOM state at failure
|
||||
- **Time**: 2025-08-21T14:22Z
|
||||
- **Evidence**: `test-results/60-new-activity-New-offers-for-another-user-chromium/error-context.md` shows both alerts visible
|
||||
- **Verify at**: Error context files in test results directory
|
||||
|
||||
- ✅ **Trace files** capture detailed execution sequence for failed tests
|
||||
- **Time**: 2025-08-21T14:22Z
|
||||
- **Evidence**: `trace.zip` files available for all failed tests
|
||||
- **Verify at**: Use `npx playwright show-trace <filename>`
|
||||
|
||||
- ✅ **Page snapshots** reveal UI conflicts like multiple alerts with duplicate button text
|
||||
- **Time**: 2025-08-21T14:22Z
|
||||
- **Evidence**: YAML snapshots show registration + export alerts simultaneously
|
||||
- **Verify at**: Error context markdown files
|
||||
|
||||
## What Doesn't (Evidence & Hypotheses)
|
||||
- ❌ **Generic selectors** fail with multiple similar elements at `test-playwright/testUtils.ts:161`
|
||||
- **Time**: 2025-08-21T14:22Z
|
||||
- **Evidence**: `button:has-text("Yes")` matches both "Yes" and "Yes, Export Data"
|
||||
- **Hypothesis**: Selector ambiguity due to multiple alerts with conflicting button text
|
||||
- **Next probe**: Use more specific selectors or dismiss alerts sequentially
|
||||
|
||||
- ❌ **Timing-dependent tests** fail due to alert stacking at `src/views/ContactsView.vue:860,1283`
|
||||
- **Time**: 2025-08-21T14:22Z
|
||||
- **Evidence**: Both alerts use identical 1000ms delays, ensuring simultaneous display
|
||||
- **Hypothesis**: Race condition between alert displays creates UI conflicts
|
||||
- **Next probe**: Implement alert queuing or prevent overlapping alerts
|
||||
|
||||
## Risks, Limits, Assumptions
|
||||
- **Trace file size**: Large trace files may impact storage and analysis time
|
||||
- **Browser compatibility**: Trace viewer requires specific browser support
|
||||
- **Test isolation**: Shared state between tests may affect investigation results
|
||||
- **Timing sensitivity**: Tests may pass/fail based on system performance
|
||||
|
||||
## Next Steps
|
||||
| Owner | Task | Exit Criteria | Target Date (UTC) |
|
||||
|---|---|---|---|
|
||||
| Development Team | Fix test selectors for multiple alerts | All tests pass consistently | 2025-08-22 |
|
||||
| Development Team | Implement alert queuing system | No overlapping alerts with conflicting buttons | 2025-08-25 |
|
||||
| Development Team | Add test IDs to alert buttons | Unique selectors for all UI elements | 2025-08-28 |
|
||||
|
||||
## References
|
||||
- [Playwright Trace Viewer Documentation](https://playwright.dev/docs/trace-viewer)
|
||||
- [Playwright Test Results](https://playwright.dev/docs/test-reporters)
|
||||
- [Test Investigation Workflow](./research_diagnostic.mdc)
|
||||
|
||||
## Competence Hooks
|
||||
- **Why this works**: Systematic investigation leverages Playwright's built-in debugging tools to identify root causes
|
||||
- **Common pitfalls**: Generic selectors fail with multiple similar elements; timing issues create race conditions; alert stacking causes UI conflicts
|
||||
- **Next skill unlock**: Implement unique test IDs and handle alert dismissal order in test flows
|
||||
- **Teach-back**: "How would you investigate a Playwright test failure using error context, trace files, and page snapshots?"
|
||||
|
||||
## Collaboration Hooks
|
||||
- **Reviewers**: QA team, test automation engineers
|
||||
- **Sign-off checklist**: Error context analyzed, trace files reviewed, root cause identified, fix implemented and tested
|
||||
|
||||
## Assumptions & Limits
|
||||
- Test results directory structure follows Playwright conventions
|
||||
- Trace files are enabled in configuration (`trace: "retain-on-failure"`)
|
||||
- Error context files contain valid YAML page snapshots
|
||||
- Browser environment supports trace viewer functionality
|
||||
|
||||
---
|
||||
|
||||
**Status**: Active investigation directive
|
||||
**Priority**: High
|
||||
**Maintainer**: Development team
|
||||
**Next Review**: 2025-09-21
|
||||
@@ -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.**
|
||||
@@ -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** — 1–2 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 X–Y); 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:** 10–15m 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`
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,714 +0,0 @@
|
||||
```json
|
||||
{
|
||||
"coaching_level": "standard",
|
||||
"socratic_max_questions": 2,
|
||||
"verbosity": "normal",
|
||||
"timebox_minutes": null,
|
||||
"format_enforcement": "strict"
|
||||
}
|
||||
```
|
||||
|
||||
# Unit Testing & Mocks — Universal Development Guide
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: 2025-08-21T09:40Z
|
||||
**Status**: 🎯 **ACTIVE** - Comprehensive testing standards
|
||||
|
||||
## Overview
|
||||
|
||||
This guide establishes **unified unit testing and mocking standards** for Vue
|
||||
and React projects, ensuring consistent, maintainable test patterns using
|
||||
Vitest, JSDOM, and component testing utilities. All tests follow F.I.R.S.T.
|
||||
principles with comprehensive mock implementations.
|
||||
|
||||
## Scope and Goals
|
||||
|
||||
**Scope**: Applies to all unit tests, mock implementations, and testing
|
||||
infrastructure in any project workspace.
|
||||
|
||||
**Goal**: One consistent testing approach with comprehensive mock coverage,
|
||||
100% test coverage for simple components, and maintainable test patterns.
|
||||
|
||||
## Non‑Negotiables (DO THIS)
|
||||
|
||||
- **MUST** use Vitest + JSDOM for unit testing; **DO NOT** use Jest or other
|
||||
frameworks
|
||||
- **MUST** implement comprehensive mock levels (Simple, Standard, Complex) for
|
||||
all components
|
||||
- **MUST** achieve 100% line coverage for simple components (<100 lines)
|
||||
- **MUST** follow F.I.R.S.T. principles: Fast, Independent, Repeatable,
|
||||
Self-validating, Timely
|
||||
- **MUST** use centralized test utilities from `src/test/utils/`
|
||||
|
||||
## Testing Infrastructure
|
||||
|
||||
### **Core Technologies**
|
||||
|
||||
- **Vitest**: Fast unit testing framework with Vue/React support
|
||||
- **JSDOM**: Browser-like environment for Node.js testing
|
||||
- **@vue/test-utils**: Vue component testing utilities
|
||||
- **TypeScript**: Full type safety for tests and mocks
|
||||
|
||||
### **Configuration Files**
|
||||
|
||||
- `vitest.config.ts` - Vitest configuration with JSDOM environment
|
||||
- `src/test/setup.ts` - Global test configuration and mocks
|
||||
- `src/test/utils/` - Centralized testing utilities
|
||||
|
||||
### **Global Mocks**
|
||||
|
||||
```typescript
|
||||
// Required browser API mocks
|
||||
ResizeObserver, IntersectionObserver, localStorage, sessionStorage,
|
||||
matchMedia, console methods (reduced noise)
|
||||
```
|
||||
|
||||
## Mock Implementation Standards
|
||||
|
||||
### **Mock Architecture Levels**
|
||||
|
||||
#### **1. Simple Mock (Basic Testing)**
|
||||
|
||||
```typescript
|
||||
// Minimal interface compliance
|
||||
class ComponentSimpleMock {
|
||||
// Essential props and methods only
|
||||
// Basic computed properties
|
||||
// No complex behavior
|
||||
}
|
||||
```
|
||||
|
||||
#### **2. Standard Mock (Integration Testing)**
|
||||
|
||||
```typescript
|
||||
// Full interface compliance
|
||||
class ComponentStandardMock {
|
||||
// All props, methods, computed properties
|
||||
// Realistic behavior simulation
|
||||
// Helper methods for test scenarios
|
||||
}
|
||||
```
|
||||
|
||||
#### **3. Complex Mock (Advanced Testing)**
|
||||
|
||||
```typescript
|
||||
// Enhanced testing capabilities
|
||||
class ComponentComplexMock extends ComponentStandardMock {
|
||||
// Mock event listeners
|
||||
// Performance testing hooks
|
||||
// Error scenario simulation
|
||||
// Accessibility testing support
|
||||
}
|
||||
```
|
||||
|
||||
### **Mock Component Structure**
|
||||
|
||||
Each mock component provides:
|
||||
|
||||
- Same interface as original component
|
||||
- Simplified behavior for testing
|
||||
- Helper methods for test scenarios
|
||||
- Computed properties for state validation
|
||||
|
||||
### **Enhanced Mock Architecture Validation** ✅ **NEW**
|
||||
|
||||
The three-tier mock architecture (Simple/Standard/Complex) has been successfully
|
||||
validated through real-world implementation:
|
||||
|
||||
#### **Tier 1: Simple Mock**
|
||||
|
||||
```typescript
|
||||
class ComponentSimpleMock {
|
||||
// Basic interface compliance
|
||||
// Minimal implementation for simple tests
|
||||
// Fast execution for high-volume testing
|
||||
}
|
||||
```
|
||||
|
||||
#### **Tier 2: Standard Mock**
|
||||
|
||||
```typescript
|
||||
class ComponentStandardMock {
|
||||
// Full interface implementation
|
||||
// Realistic behavior simulation
|
||||
// Helper methods for common scenarios
|
||||
}
|
||||
```
|
||||
|
||||
#### **Tier 3: Complex Mock**
|
||||
|
||||
```typescript
|
||||
class ComponentComplexMock {
|
||||
// Enhanced testing capabilities
|
||||
// Validation and error simulation
|
||||
// Advanced state management
|
||||
// Performance testing support
|
||||
}
|
||||
```
|
||||
|
||||
#### **Factory Function Pattern**
|
||||
|
||||
```typescript
|
||||
// Specialized factory functions for common use cases
|
||||
export const createComponentMock = () =>
|
||||
new ComponentStandardMock({ type: 'default' })
|
||||
|
||||
export const createSpecializedMock = () =>
|
||||
new ComponentComplexMock({
|
||||
options: { filter: 'active', sort: 'name' }
|
||||
})
|
||||
```
|
||||
|
||||
### **Mock Usage Examples**
|
||||
|
||||
```typescript
|
||||
export default class ComponentMock {
|
||||
// Props simulation
|
||||
props: ComponentProps
|
||||
|
||||
// Computed properties
|
||||
get computedProp(): boolean {
|
||||
return this.props.condition
|
||||
}
|
||||
|
||||
// Mock methods
|
||||
mockMethod(): void {
|
||||
// Simulate behavior
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
getCssClasses(): string[] {
|
||||
return ['base-class', 'conditional-class']
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Test Patterns
|
||||
|
||||
### **Component Testing Template**
|
||||
|
||||
```typescript
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { createComponentWrapper } from '@/test/utils/componentTestUtils'
|
||||
|
||||
describe('ComponentName', () => {
|
||||
let wrapper: VueWrapper<any>
|
||||
|
||||
const mountComponent = (props = {}) => {
|
||||
return mount(ComponentName, {
|
||||
props: { ...defaultProps, ...props }
|
||||
})
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = mountComponent()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
wrapper?.unmount()
|
||||
})
|
||||
|
||||
describe('Component Rendering', () => {
|
||||
it('should render correctly', () => {
|
||||
expect(wrapper.exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### **Mock Integration Testing**
|
||||
|
||||
```typescript
|
||||
import ComponentMock from '@/test/__mocks__/Component.mock'
|
||||
|
||||
it('should work with mock component', () => {
|
||||
const mock = new ComponentMock()
|
||||
expect(mock.shouldShow).toBe(true)
|
||||
})
|
||||
```
|
||||
|
||||
### **Event Testing**
|
||||
|
||||
```typescript
|
||||
it('should emit event when triggered', async () => {
|
||||
await wrapper.find('button').trigger('click')
|
||||
expect(wrapper.emitted('event-name')).toBeTruthy()
|
||||
})
|
||||
```
|
||||
|
||||
### **Prop Validation**
|
||||
|
||||
```typescript
|
||||
it('should accept all required props', () => {
|
||||
wrapper = mountComponent()
|
||||
expect(wrapper.vm.propName).toBeDefined()
|
||||
})
|
||||
```
|
||||
|
||||
## Test Categories
|
||||
|
||||
### **Required Coverage Areas**
|
||||
|
||||
1. **Component Rendering** - Existence, structure, conditional rendering
|
||||
2. **Component Styling** - CSS classes, responsive design, framework
|
||||
integration
|
||||
3. **Component Props** - Required/optional prop handling, type validation
|
||||
4. **User Interactions** - Click events, form inputs, keyboard navigation
|
||||
5. **Component Methods** - Method existence, functionality, return values
|
||||
6. **Edge Cases** - Empty/null props, rapid interactions, state changes
|
||||
7. **Error Handling** - Invalid props, malformed data, graceful degradation
|
||||
8. **Accessibility** - Semantic HTML, ARIA attributes, keyboard navigation
|
||||
9. **Performance** - Render time, memory leaks, rapid re-renders
|
||||
10. **Integration** - Parent-child interaction, dependency injection
|
||||
|
||||
### **Error Handling Testing**
|
||||
|
||||
```typescript
|
||||
const invalidPropCombinations = [
|
||||
null, undefined, 'invalid', 0, -1, {}, [],
|
||||
() => {}, NaN, Infinity
|
||||
]
|
||||
|
||||
invalidPropCombinations.forEach(invalidProp => {
|
||||
it(`should handle invalid prop: ${invalidProp}`, () => {
|
||||
wrapper = mountComponent({ prop: invalidProp })
|
||||
expect(wrapper.exists()).toBe(true)
|
||||
// Verify graceful handling
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## Centralized Test Utilities
|
||||
|
||||
### **Component Testing Utilities**
|
||||
|
||||
```typescript
|
||||
import {
|
||||
createComponentWrapper,
|
||||
createTestDataFactory,
|
||||
testLifecycleEvents,
|
||||
testComputedProperties,
|
||||
testWatchers,
|
||||
testPerformance,
|
||||
testAccessibility,
|
||||
testErrorHandling
|
||||
} from '@/test/utils/componentTestUtils'
|
||||
|
||||
// Component wrapper factory
|
||||
const wrapperFactory = createComponentWrapper(
|
||||
Component,
|
||||
defaultProps,
|
||||
globalOptions
|
||||
)
|
||||
|
||||
// Test data factory
|
||||
const createTestProps = createTestDataFactory({
|
||||
prop1: 'default',
|
||||
prop2: true
|
||||
})
|
||||
```
|
||||
|
||||
### **Test Data Factories**
|
||||
|
||||
```typescript
|
||||
import {
|
||||
createMockContact,
|
||||
createMockProject,
|
||||
createMockUser
|
||||
} from '@/test/factories/contactFactory'
|
||||
|
||||
const testContact = createMockContact({
|
||||
id: 'test-1',
|
||||
name: 'Test User'
|
||||
})
|
||||
```
|
||||
|
||||
## Coverage Standards
|
||||
|
||||
### **Coverage Standards by Component Complexity**
|
||||
|
||||
| Component Complexity | Line Coverage | Branch Coverage | Function Coverage |
|
||||
|---------------------|---------------|-----------------|-------------------|
|
||||
| **Simple (<100 lines)** | 100% | 100% | 100% |
|
||||
| **Medium (100-300 lines)** | 95% | 90% | 100% |
|
||||
| **Complex (300+ lines)** | 90% | 85% | 100% |
|
||||
|
||||
### **Current Coverage Status**
|
||||
|
||||
- **Simple Components**: Ready for implementation
|
||||
- **Medium Components**: Ready for expansion
|
||||
- **Complex Components**: Ready for expansion
|
||||
- **Overall Coverage**: Varies by project implementation
|
||||
|
||||
### **Test Infrastructure Requirements**
|
||||
|
||||
- **Test Framework**: Vitest + JSDOM recommended
|
||||
- **Component Testing**: Vue Test Utils integration
|
||||
- **Mock Architecture**: Three-tier system (Simple/Standard/Complex)
|
||||
- **Test Categories**: 10 comprehensive categories
|
||||
- **Coverage Goals**: 100% for simple components, 90%+ for complex
|
||||
|
||||
## Testing Philosophy
|
||||
|
||||
### **Defensive Programming Validation**
|
||||
|
||||
- **Real-world edge case protection** against invalid API responses
|
||||
- **System stability assurance** preventing cascading failures
|
||||
- **Production readiness** ensuring graceful error handling
|
||||
|
||||
### **Comprehensive Error Scenarios**
|
||||
|
||||
- **Invalid input testing** with 10+ different invalid prop combinations
|
||||
- **Malformed data testing** with various corrupted data structures
|
||||
- **Extreme value testing** with boundary conditions and edge cases
|
||||
- **Concurrent error testing** with rapid state changes
|
||||
|
||||
### **Benefits Beyond Coverage**
|
||||
|
||||
1. **Defensive Programming Validation** - Components handle unexpected data
|
||||
gracefully
|
||||
2. **Real-World Resilience** - Tested against actual failure scenarios
|
||||
3. **Developer Confidence** - Safe to refactor and extend components
|
||||
4. **Production Stability** - Reduced support tickets and user complaints
|
||||
|
||||
## Advanced Testing Patterns
|
||||
|
||||
### **Performance Testing** ✅ **NEW**
|
||||
|
||||
- Render time benchmarks
|
||||
- Memory leak detection
|
||||
- Rapid re-render efficiency
|
||||
- Component cleanup validation
|
||||
|
||||
#### **Advanced Performance Testing Patterns**
|
||||
|
||||
```typescript
|
||||
// Memory leak detection
|
||||
it('should not cause memory leaks during prop changes', async () => {
|
||||
const initialMemory = (performance as any).memory?.usedJSHeapSize || 0
|
||||
|
||||
for (let i = 0; i < 100; i++) {
|
||||
await wrapper.setProps({
|
||||
queryParams: { iteration: i.toString() }
|
||||
})
|
||||
}
|
||||
|
||||
const finalMemory = (performance as any).memory?.usedJSHeapSize || 0
|
||||
const memoryIncrease = finalMemory - initialMemory
|
||||
|
||||
// Memory increase should be reasonable (less than 10MB)
|
||||
expect(memoryIncrease).toBeLessThan(10 * 1024 * 1024)
|
||||
})
|
||||
|
||||
// Rapid re-render efficiency
|
||||
it('should handle rapid re-renders efficiently', async () => {
|
||||
const start = performance.now()
|
||||
|
||||
for (let i = 0; i < 50; i++) {
|
||||
await wrapper.setProps({
|
||||
entityType: i % 2 === 0 ? 'type1' : 'type2',
|
||||
queryParams: { index: i.toString() }
|
||||
})
|
||||
}
|
||||
|
||||
const end = performance.now()
|
||||
expect(end - start).toBeLessThan(500) // 500ms threshold for 50 updates
|
||||
})
|
||||
```
|
||||
|
||||
### **Snapshot Testing** ✅ **NEW**
|
||||
|
||||
- DOM structure validation
|
||||
- CSS class regression detection
|
||||
- Accessibility attribute consistency
|
||||
- Visual structure verification
|
||||
|
||||
#### **Snapshot Testing Implementation**
|
||||
|
||||
```typescript
|
||||
describe('Snapshot Testing', () => {
|
||||
it('should maintain consistent DOM structure', () => {
|
||||
expect(wrapper.html()).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should maintain consistent structure with different props', () => {
|
||||
wrapper = mountComponent({ type: 'alternative' })
|
||||
expect(wrapper.html()).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should maintain consistent structure with query params', () => {
|
||||
wrapper = mountComponent({
|
||||
queryParams: { filter: 'active', sort: 'name' }
|
||||
})
|
||||
expect(wrapper.html()).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### **Mock Integration Testing** ✅ **NEW**
|
||||
|
||||
- Mock component validation
|
||||
- Factory function testing
|
||||
- Mock behavior verification
|
||||
- Integration with testing utilities
|
||||
|
||||
#### **Mock Integration Testing Patterns**
|
||||
|
||||
```typescript
|
||||
describe('Mock Integration Testing', () => {
|
||||
it('should work with simple mock', () => {
|
||||
const mock = new ComponentSimpleMock()
|
||||
expect(mock.navigationRoute).toEqual({
|
||||
name: 'default',
|
||||
query: {}
|
||||
})
|
||||
})
|
||||
|
||||
it('should work with standard mock', () => {
|
||||
const mock = new ComponentStandardMock({
|
||||
type: 'special',
|
||||
name: 'test'
|
||||
})
|
||||
expect(mock.getType()).toBe('special')
|
||||
expect(mock.getName()).toBe('test')
|
||||
})
|
||||
|
||||
it('should work with complex mock', () => {
|
||||
const mock = new ComponentComplexMock({
|
||||
type: 'advanced',
|
||||
options: { filter: 'active' }
|
||||
})
|
||||
|
||||
expect(mock.isValidState()).toBe(true)
|
||||
expect(mock.getValidationErrors()).toEqual([])
|
||||
})
|
||||
|
||||
it('should work with factory functions', () => {
|
||||
const defaultMock = createComponentMock()
|
||||
const specializedMock = createSpecializedMock()
|
||||
|
||||
expect(defaultMock.getType()).toBe('default')
|
||||
expect(specializedMock.getOptions()).toHaveProperty('filter')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## Project Implementation Tracking
|
||||
|
||||
### **Setting Up Project-Specific Tracking**
|
||||
|
||||
Each project should maintain its own tracking file to monitor testing progress
|
||||
and coverage metrics. This keeps the universal MDC clean while providing a
|
||||
template for project implementation.
|
||||
|
||||
#### **Recommended Project Tracking Structure**
|
||||
|
||||
```tree
|
||||
src/test/
|
||||
├── README.md # Testing documentation
|
||||
├── PROJECT_COVERAGE_TRACKING.md # Project-specific progress tracking
|
||||
├── __mocks__/ # Mock implementations
|
||||
├── utils/ # Test utilities
|
||||
└── [test files]
|
||||
```
|
||||
|
||||
#### **Project Tracking File Template**
|
||||
|
||||
Create a `PROJECT_COVERAGE_TRACKING.md` file with:
|
||||
|
||||
- **Current Coverage Status**: Component-by-component breakdown
|
||||
- **Implementation Progress**: Phase completion status
|
||||
- **Test Infrastructure Status**: Framework setup and metrics
|
||||
- **Next Steps**: Immediate priorities and long-term goals
|
||||
- **Lessons Learned**: Project-specific insights and best practices
|
||||
|
||||
#### **Example Project Tracking Sections**
|
||||
|
||||
```markdown
|
||||
# [Project Name] Testing Coverage Tracking
|
||||
|
||||
## Current Coverage Status
|
||||
- Simple Components: X/Y at 100% coverage
|
||||
- Medium Components: X/Y ready for expansion
|
||||
- Complex Components: X/Y planned
|
||||
|
||||
## Implementation Progress
|
||||
- Phase 1: Simple Components ✅ COMPLETE
|
||||
- Phase 2: Medium Components 🔄 IN PROGRESS
|
||||
- Phase 3: Complex Components 🔄 PLANNED
|
||||
|
||||
## Test Infrastructure Status
|
||||
- Total Tests: X tests passing
|
||||
- Test Files: X files
|
||||
- Mock Files: X implementations
|
||||
- Overall Coverage: X% (focused on simple components)
|
||||
```
|
||||
|
||||
### **Integration with Universal MDC**
|
||||
|
||||
- **MDC provides**: Testing patterns, mock architecture, best practices
|
||||
- **Project tracking provides**: Implementation status, coverage metrics,
|
||||
progress
|
||||
- **Separation ensures**: MDC remains reusable, project data stays local
|
||||
- **Template approach**: Other projects can copy and adapt the structure
|
||||
|
||||
### **Benefits of This Approach**
|
||||
|
||||
1. **Universal Reusability**: MDC works for any project
|
||||
2. **Project Visibility**: Clear tracking of implementation progress
|
||||
3. **Template Reuse**: Easy to set up tracking in new projects
|
||||
4. **Clean Separation**: No project data polluting universal guidance
|
||||
5. **Scalability**: Multiple projects can use the same MDC
|
||||
|
||||
## Best Practices
|
||||
|
||||
### **Test Organization**
|
||||
|
||||
1. **Group related tests** using `describe` blocks
|
||||
2. **Use descriptive test names** that explain the scenario
|
||||
3. **Keep tests focused** on one specific behavior
|
||||
4. **Use helper functions** for common setup
|
||||
|
||||
### **Mock Design**
|
||||
|
||||
1. **Maintain interface compatibility** with original components
|
||||
2. **Provide helper methods** for common test scenarios
|
||||
3. **Include computed properties** for state validation
|
||||
4. **Document mock behavior** clearly
|
||||
|
||||
### **Coverage Goals**
|
||||
|
||||
1. **100% line coverage** for simple components
|
||||
2. **100% branch coverage** for conditional logic
|
||||
3. **100% function coverage** for all methods
|
||||
4. **Edge case coverage** for error scenarios
|
||||
|
||||
### **Lessons Learned from Implementation** ✅ **NEW**
|
||||
|
||||
#### **1. Performance Testing Best Practices**
|
||||
|
||||
- **Memory leak detection**: Use `performance.memory.usedJSHeapSize` for
|
||||
memory profiling
|
||||
- **Render time benchmarking**: Set realistic thresholds (100ms for single
|
||||
render, 500ms for 50 updates)
|
||||
- **Rapid re-render testing**: Test with 50+ prop changes to ensure
|
||||
stability
|
||||
|
||||
#### **2. Snapshot Testing Implementation**
|
||||
|
||||
- **DOM structure validation**: Use `toMatchSnapshot()` for consistent
|
||||
structure verification
|
||||
- **Prop variation testing**: Test snapshots with different prop combinations
|
||||
- **Regression prevention**: Snapshots catch unexpected DOM changes
|
||||
|
||||
#### **3. Mock Integration Validation**
|
||||
|
||||
- **Mock self-testing**: Test that mocks work correctly with testing
|
||||
utilities
|
||||
- **Factory function testing**: Validate specialized factory functions
|
||||
- **Mock behavior verification**: Ensure mocks simulate real component
|
||||
behavior
|
||||
|
||||
#### **4. Edge Case Coverage**
|
||||
|
||||
- **Null/undefined handling**: Test with `null as any` and `undefined`
|
||||
props
|
||||
- **Extreme values**: Test with very long strings and large numbers
|
||||
- **Rapid changes**: Test with rapid prop changes to ensure stability
|
||||
|
||||
#### **5. Accessibility Testing**
|
||||
|
||||
- **Semantic structure**: Verify proper HTML elements and hierarchy
|
||||
- **Component attributes**: Check component-specific attributes
|
||||
- **Text content**: Validate text content and trimming
|
||||
|
||||
## Future Improvements
|
||||
|
||||
### **Implemented Enhancements**
|
||||
|
||||
1. ✅ **Error handling** - Component error states and exception handling
|
||||
2. ✅ **Performance testing** - Render time benchmarks and memory leak
|
||||
detection
|
||||
3. ✅ **Integration testing** - Parent-child component interaction and
|
||||
dependency injection
|
||||
4. ✅ **Snapshot testing** - DOM structure validation and CSS class
|
||||
regression detection
|
||||
5. ✅ **Accessibility compliance** - ARIA attributes and semantic structure
|
||||
validation
|
||||
|
||||
### **Future Enhancements**
|
||||
|
||||
1. **Visual regression testing** - Automated UI consistency checks
|
||||
2. **Cross-browser compatibility** testing
|
||||
3. **Service layer integration** testing
|
||||
4. **End-to-end component** testing
|
||||
5. **Advanced performance** profiling
|
||||
|
||||
### **Coverage Expansion**
|
||||
|
||||
1. **Medium complexity components** (100-300 lines)
|
||||
2. **Complex components** (300+ lines)
|
||||
3. **Service layer testing**
|
||||
4. **Utility function testing**
|
||||
5. **API integration testing**
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### **Common Issues**
|
||||
|
||||
1. **Import errors**: Check path aliases in `vitest.config.ts`
|
||||
2. **Mock not found**: Verify mock file exists and exports correctly
|
||||
3. **Test failures**: Check for timing issues with async operations
|
||||
4. **Coverage gaps**: Add tests for uncovered code paths
|
||||
|
||||
### **Debug Tips**
|
||||
|
||||
1. **Use `console.log`** in tests for debugging
|
||||
2. **Check test output** for detailed error messages
|
||||
3. **Verify component props** are being passed correctly
|
||||
4. **Test one assertion at a time** to isolate issues
|
||||
|
||||
---
|
||||
|
||||
**Status**: Active testing standards
|
||||
**Priority**: High
|
||||
**Estimated Effort**: Ongoing reference
|
||||
**Dependencies**: Vitest, JSDOM, Vue Test Utils
|
||||
**Stakeholders**: Development team, QA team
|
||||
|
||||
## Competence Hooks
|
||||
|
||||
- *Why this works*: Three-tier mock architecture provides flexibility,
|
||||
comprehensive test categories ensure thorough coverage, performance testing
|
||||
catches real-world issues early
|
||||
- *Common pitfalls*: Not testing mocks themselves, missing edge case
|
||||
coverage, ignoring performance implications
|
||||
- *Next skill unlock*: Implement medium complexity component testing with
|
||||
established patterns
|
||||
- *Teach-back*: Explain how the three-tier mock architecture supports
|
||||
different testing needs
|
||||
|
||||
## Collaboration Hooks
|
||||
|
||||
- **Reviewers**: Testing team, component developers, architecture team
|
||||
- **Sign-off checklist**: All simple components at 100% coverage, mock
|
||||
utilities documented, test patterns established, coverage expansion plan
|
||||
approved
|
||||
|
||||
## Assumptions & Limits
|
||||
|
||||
- Assumes Vue/React component architecture
|
||||
- Requires Vitest + JSDOM testing environment
|
||||
- Mock complexity scales with component complexity
|
||||
- Performance testing requires browser-like environment
|
||||
|
||||
## References
|
||||
|
||||
- [Vitest Documentation](https://vitest.dev/)
|
||||
- [Vue Test Utils](https://test-utils.vuejs.org/)
|
||||
- [JSDOM](https://github.com/jsdom/jsdom)
|
||||
- [Testing Best Practices](https://testing-library.com/docs/guiding-principles)
|
||||
|
||||
- **Sign-off checklist**: All simple components at 100% coverage, mock
|
||||
utilities documented, test patterns established, coverage expansion plan
|
||||
approved
|
||||
@@ -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 + 1–2 line notes per file
|
||||
- [ ] Provide **one** focused draft message (subject/body/footer)
|
||||
- [ ] Subject ≤ 72 chars, imperative mood, correct `type(scope)!` syntax
|
||||
- [ ] Body only if it adds non-obvious value
|
||||
- [ ] No invented changes; aligns strictly with diffs
|
||||
- [ ] Render as a single copy-paste block for the developer
|
||||
|
||||
---
|
||||
|
||||
**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 + 1–2 line notes per file
|
||||
- [ ] Provide **one** focused draft message (subject/body/footer)
|
||||
- [ ] Subject ≤ 72 chars, imperative mood, correct `type(scope)!` syntax
|
||||
- [ ] Body only if it adds non-obvious value
|
||||
- [ ] No invented changes; aligns strictly with diffs
|
||||
- [ ] Render as a single copy-paste block for the developer
|
||||
|
||||
---
|
||||
|
||||
**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
|
||||
171
.dockerignore
171
.dockerignore
@@ -1,171 +0,0 @@
|
||||
# TimeSafari Docker Ignore File
|
||||
# Author: Matthew Raymer
|
||||
# Description: Excludes unnecessary files from Docker build context
|
||||
#
|
||||
# Benefits:
|
||||
# - Faster build times
|
||||
# - Smaller build context
|
||||
# - Reduced image size
|
||||
# - Better security (excludes sensitive files)
|
||||
|
||||
# Dependencies
|
||||
node_modules
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Build outputs
|
||||
# dist - Allow dist directory for Docker builds (contains pre-built assets)
|
||||
dist-*
|
||||
build
|
||||
*.tsbuildinfo
|
||||
|
||||
# Development files
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
CHANGELOG.md
|
||||
CONTRIBUTING.md
|
||||
BUILDING.md
|
||||
LICENSE
|
||||
|
||||
# IDE and editor files
|
||||
.vscode
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Dependency directories
|
||||
jspm_packages/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# Test files
|
||||
test-playwright
|
||||
test-playwright-results
|
||||
test-results
|
||||
test-scripts
|
||||
|
||||
# Documentation
|
||||
doc
|
||||
|
||||
# Scripts (keep only what's needed for build)
|
||||
scripts/test-*.sh
|
||||
scripts/*.js
|
||||
scripts/README.md
|
||||
|
||||
# Platform-specific files
|
||||
android
|
||||
ios
|
||||
electron
|
||||
|
||||
# Docker files (avoid recursive copying)
|
||||
Dockerfile*
|
||||
docker-compose*
|
||||
.dockerignore
|
||||
|
||||
# CI/CD files
|
||||
|
||||
.gitlab-ci.yml
|
||||
.travis.yml
|
||||
.circleci
|
||||
|
||||
# Temporary files
|
||||
tmp
|
||||
temp
|
||||
|
||||
# Backup files
|
||||
*.bak
|
||||
*.backup
|
||||
|
||||
# Archive files
|
||||
*.tar
|
||||
*.tar.gz
|
||||
*.zip
|
||||
*.rar
|
||||
|
||||
# Certificate files
|
||||
*.pem
|
||||
*.key
|
||||
*.crt
|
||||
*.p12
|
||||
|
||||
# Configuration files that might contain secrets
|
||||
*.secrets
|
||||
secrets.json
|
||||
config.local.json
|
||||
@@ -1,18 +0,0 @@
|
||||
# Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.
|
||||
|
||||
# Logging Configuration - Development environment gets maximum visibility
|
||||
VITE_LOG_LEVEL=debug
|
||||
|
||||
# iOS doesn't like spaces in the app title.
|
||||
TIME_SAFARI_APP_TITLE="TimeSafari_Dev"
|
||||
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
|
||||
|
||||
|
||||
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
|
||||
VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000
|
||||
# Using shared server by default to ease setup, which works for shared test users.
|
||||
VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app
|
||||
VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000
|
||||
#VITE_DEFAULT_PUSH_SERVER... can't be set up with localhost domain
|
||||
VITE_PASSKEYS_ENABLED=true
|
||||
@@ -1,13 +0,0 @@
|
||||
# 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
|
||||
# This is the claim ID for actions in the BVC project.
|
||||
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01GXYPFF7FA03NXKPYY142PY4H
|
||||
VITE_DEFAULT_ENDORSER_API_SERVER=https://api.endorser.ch
|
||||
|
||||
VITE_DEFAULT_IMAGE_API_SERVER=https://image-api.timesafari.app
|
||||
VITE_DEFAULT_PARTNER_API_SERVER=https://partner-api.endorser.ch
|
||||
VITE_DEFAULT_PUSH_SERVER=https://timesafari.app
|
||||
18
.env.test
18
.env.test
@@ -1,18 +0,0 @@
|
||||
# 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.
|
||||
TIME_SAFARI_APP_TITLE="TimeSafari_Test"
|
||||
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).
|
||||
|
||||
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
|
||||
VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch
|
||||
|
||||
VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app
|
||||
VITE_DEFAULT_PARTNER_API_SERVER=https://test-partner-api.endorser.ch
|
||||
VITE_DEFAULT_PUSH_SERVER=https://test.timesafari.app
|
||||
VITE_PASSKEYS_ENABLED=true
|
||||
32
.eslintrc.js
32
.eslintrc.js
@@ -2,37 +2,19 @@ module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true,
|
||||
es2022: true,
|
||||
},
|
||||
ignorePatterns: [
|
||||
'node_modules/',
|
||||
'dist/',
|
||||
'dist-electron/',
|
||||
'*.d.ts'
|
||||
],
|
||||
extends: [
|
||||
"plugin:vue/vue3-recommended",
|
||||
"plugin:vue/vue3-essential",
|
||||
"eslint:recommended",
|
||||
"@vue/typescript/recommended",
|
||||
"plugin:prettier/recommended"
|
||||
"plugin:prettier/recommended",
|
||||
],
|
||||
// parserOptions: {
|
||||
// ecmaVersion: 2020,
|
||||
// },
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
},
|
||||
rules: {
|
||||
"max-len": ["warn", {
|
||||
code: 100,
|
||||
ignoreComments: true,
|
||||
ignorePattern: '^\\s*class="[^"]*"$',
|
||||
ignoreStrings: true,
|
||||
ignoreTemplateLiterals: true,
|
||||
ignoreUrls: true,
|
||||
}],
|
||||
"no-console": process.env.NODE_ENV === "production" ? "error" : "warn",
|
||||
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "warn",
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"@typescript-eslint/no-unnecessary-type-constraint": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
|
||||
},
|
||||
};
|
||||
|
||||
120
.gitignore
vendored
120
.gitignore
vendored
@@ -1,12 +1,7 @@
|
||||
squashfs-root
|
||||
dist-electron
|
||||
dist-electon-build
|
||||
.DS_Store
|
||||
node_modules
|
||||
dist
|
||||
/dist
|
||||
signature.bin
|
||||
# generated during `npm run build`
|
||||
sw_scripts-combined.js
|
||||
*.pem
|
||||
verified.txt
|
||||
myenv
|
||||
@@ -30,116 +25,3 @@ pnpm-debug.log*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
/dist-electron-build/
|
||||
/dist-capacitor/
|
||||
/test-playwright-results/
|
||||
playwright-tests
|
||||
dist-electron-packages
|
||||
.ruby-version
|
||||
+.env
|
||||
|
||||
# Test files generated by scripts test-ios.js & test-android.js
|
||||
.generated/
|
||||
|
||||
.env.default
|
||||
vendor/
|
||||
|
||||
# Build logs
|
||||
build_logs/
|
||||
|
||||
# PWA icon files generated by capacitor-assets
|
||||
icons
|
||||
|
||||
*.log
|
||||
|
||||
# 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
|
||||
|
||||
# Temporary and generated files
|
||||
temp.*
|
||||
*.tmp
|
||||
*.temp
|
||||
*.bak
|
||||
*.cache
|
||||
git.diff.*
|
||||
*.har
|
||||
|
||||
# Development artifacts
|
||||
dev-dist/
|
||||
*.map
|
||||
|
||||
# OS generated files
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
|
||||
# Capacitor build outputs and generated files
|
||||
android/app/build/
|
||||
android/capacitor-cordova-android-plugins/build/
|
||||
ios/App/App/public/assets/
|
||||
ios/App/App/build/
|
||||
ios/App/build/
|
||||
|
||||
# Capacitor build artifacts (covered by android/app/build/ above)
|
||||
|
||||
# Keep these Capacitor files in version control:
|
||||
# - capacitor.config.json (root, electron, ios)
|
||||
# - src/main.capacitor.ts
|
||||
# - vite.config.capacitor.mts
|
||||
# - android/capacitor.settings.gradle
|
||||
# - android/app/capacitor.build.gradle
|
||||
# - android/app/src/main/assets/capacitor.plugins.json
|
||||
|
||||
# Electron build outputs and generated files
|
||||
electron/build/
|
||||
electron/app/
|
||||
electron/dist/
|
||||
electron/out/
|
||||
|
||||
# Keep these Electron files in version control:
|
||||
# - electron/src/preload.ts (source)
|
||||
# - electron/src/index.ts (source)
|
||||
# - electron/src/setup.ts (source)
|
||||
# - electron/package.json
|
||||
# - electron/electron-builder.config.json
|
||||
# - electron/build-packages.sh
|
||||
# - electron/live-runner.js
|
||||
# - electron/resources/electron-publisher-custom.js
|
||||
|
||||
# Gradle cache files
|
||||
android/.gradle/file-system.probe
|
||||
android/.gradle/caches/
|
||||
|
||||
coverage/
|
||||
.husky-enabled
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
# Husky Git Hooks - Optional Activation
|
||||
|
||||
## How to Enable Husky Locally
|
||||
|
||||
### Option 1: Environment Variable (Session Only)
|
||||
```bash
|
||||
export HUSKY_ENABLED=1
|
||||
```
|
||||
|
||||
### Option 2: Local File (Persistent)
|
||||
```bash
|
||||
touch .husky-enabled
|
||||
```
|
||||
|
||||
### Option 3: Global Configuration
|
||||
```bash
|
||||
git config --global husky.enabled true
|
||||
```
|
||||
|
||||
## Available Hooks
|
||||
|
||||
- **pre-commit**: Runs `npm run lint-fix` before commits
|
||||
- **commit-msg**: Validates commit message format
|
||||
|
||||
## Disable Hooks
|
||||
|
||||
```bash
|
||||
unset HUSKY_ENABLED
|
||||
rm .husky-enabled
|
||||
```
|
||||
|
||||
## Why This Approach?
|
||||
|
||||
- Hooks are committed to git for consistency
|
||||
- Hooks don't run unless explicitly enabled
|
||||
- Each developer can choose to use them
|
||||
- No automatic activation on other systems
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
#
|
||||
# Husky Helper Script - Conditional Activation
|
||||
# This file is sourced by all Husky hooks
|
||||
#
|
||||
if [ -z "$husky_skip_init" ]; then
|
||||
# Check if Husky is enabled for this user
|
||||
if [ "$HUSKY_ENABLED" != "1" ] && [ ! -f .husky-enabled ]; then
|
||||
echo "Husky is not enabled. To enable:"
|
||||
echo " export HUSKY_ENABLED=1"
|
||||
echo " or create .husky-enabled file"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
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
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
# Only run if Husky is enabled
|
||||
if [ "$HUSKY_ENABLED" = "1" ] || [ -f .husky-enabled ]; then
|
||||
echo "Running commit-msg hooks..."
|
||||
npx commitlint --edit "$1"
|
||||
else
|
||||
echo "Husky commit-msg hook skipped (not enabled)"
|
||||
exit 0
|
||||
fi
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
# Only run if Husky is enabled
|
||||
if [ "$HUSKY_ENABLED" = "1" ] || [ -f .husky-enabled ]; then
|
||||
echo "Running pre-commit hooks..."
|
||||
npm run lint-fix
|
||||
else
|
||||
echo "Husky pre-commit hook skipped (not enabled)"
|
||||
exit 0
|
||||
fi
|
||||
@@ -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
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"MD013": {"code_blocks": false}}
|
||||
@@ -1 +0,0 @@
|
||||
18.19.0
|
||||
2541
BUILDING.md
2541
BUILDING.md
File diff suppressed because it is too large
Load Diff
793
CHANGELOG.md
793
CHANGELOG.md
@@ -5,800 +5,21 @@ 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/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.0.7] - 2025.08.18
|
||||
|
||||
### 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
|
||||
|
||||
- Photo is pinned to profile mode
|
||||
|
||||
### Fixed
|
||||
|
||||
- Deep link URLs (and other prod settings)
|
||||
- Error in BVC begin view
|
||||
|
||||
## [1.0.2] - 2025.06.20 - 276e0a741bc327de3380c4e508cccb7fee58c06d
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Version on feed title
|
||||
|
||||
## [1.0.1] - 2025.06.20
|
||||
|
||||
### Added
|
||||
|
||||
- Allow a user to block someone else's content from view
|
||||
|
||||
## [1.0.0] - 2025.06.20 - 5aa693de6337e5dbb278bfddc6bd39094bc14f73
|
||||
|
||||
### Added
|
||||
|
||||
- Web-oriented migration from IndexedDB to SQLite
|
||||
|
||||
## [0.5.8]
|
||||
|
||||
### Added
|
||||
|
||||
- /deep-link/ path for URLs that are shared with people
|
||||
|
||||
### Changed
|
||||
|
||||
- External links now go to /deep-link/...
|
||||
- Feed visuals now have arrow imagery from giver to receiver
|
||||
|
||||
## [0.4.7]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Cameras everywhere
|
||||
|
||||
### Changed
|
||||
|
||||
- IndexedDB -> SQLite
|
||||
|
||||
## [0.4.5] - 2025.02.23
|
||||
|
||||
### Added
|
||||
|
||||
- Total amounts of gives on project page
|
||||
|
||||
### Changed in DB or environment
|
||||
|
||||
- Requires Endorser.ch version 4.2.6+
|
||||
|
||||
## [0.4.4] - 2025.02.17
|
||||
|
||||
### Fixed in 0.4.4
|
||||
|
||||
- On production (due to data?) the search results would disappear after scrolling down. Now we don't show any results when going to the people map with a shortcut.
|
||||
|
||||
## [0.4.3] - 2025.02.17
|
||||
|
||||
### Added in 0.4.3
|
||||
|
||||
- Discover query parameter searchPeople to go directly to the people map
|
||||
|
||||
## [0.4.2] - 2025.02.17
|
||||
|
||||
### Added
|
||||
|
||||
- Capacitor on iOS and Android
|
||||
|
||||
### Fixed
|
||||
|
||||
- Path issues
|
||||
|
||||
## [0.4.1] - 2025.02.16
|
||||
|
||||
### Fixed in 0.4.1
|
||||
|
||||
- nostr build issue
|
||||
- Linting
|
||||
|
||||
## [0.4.0] - 2025.02.14
|
||||
|
||||
### Changed
|
||||
|
||||
- Images in the home feed now take up the full width of the card.
|
||||
- Clicking the image previously, would open the image in a new tab. Now, clicking the image opens the image in a lightbox view.
|
||||
|
||||
### Added in 0.4.0
|
||||
|
||||
- Clicking an image also now displays an in-app lightbox view of the image.
|
||||
- The lightbox view includes a download button for the image in mobile view.
|
||||
|
||||
## [0.3.57] - 2025.02.11
|
||||
|
||||
### Added in 0.3.57
|
||||
|
||||
- Automatic user creation in onboarding meetings
|
||||
|
||||
## [0.3.55] - 2025.02.07
|
||||
|
||||
### Added in 0.3.55
|
||||
|
||||
- End time for projects
|
||||
|
||||
## [0.3.54] - 2025.02.06
|
||||
|
||||
### Added in 0.3.54
|
||||
|
||||
- Group onboarding meetings
|
||||
|
||||
## [0.3.53] - 2025.01.30
|
||||
|
||||
### Added in 0.3.53
|
||||
|
||||
- Hints for contacting the creator of a project
|
||||
|
||||
## [0.3.52] - 2025.01.22
|
||||
|
||||
### Fixed in 0.3.52
|
||||
|
||||
- User profile endpoint server for map was broken.
|
||||
|
||||
## [0.3.51] - 2025.01.22
|
||||
|
||||
### Fixed in 0.3.51
|
||||
|
||||
- User profile map jumped on first zoom.
|
||||
|
||||
## [0.3.50] - 2025.01.20 - b9fedcd3fd3e34c3fb0fc79150d1a81a76eaeb40
|
||||
|
||||
### Added in 0.3.50
|
||||
|
||||
- User public profiles
|
||||
|
||||
## [0.3.49] - 2025.01.09 - 36301ed238ff84df25bb11a8d44a295ee7eaf0f8
|
||||
|
||||
### Changed in 0.3.49
|
||||
|
||||
- Make all external contact links direct to the contact-import page.
|
||||
- Handle all new-single-contact JWTs in the contacts page, and multiple-contact JWTs in the contacts-import page.
|
||||
|
||||
## [0.3.48] - 2025.01.08 - 398f3e64a376789f7eb1c400cd886f5a2cacd588 (but app shows 07c4e58)
|
||||
|
||||
### Added in 0.3.48
|
||||
|
||||
- More sanity-checks on contact-import JWT
|
||||
|
||||
## [0.3.47] - 2025.01.06 - 5bf6dd1ee32ca7cc46d39bd7afca58365b422f93
|
||||
|
||||
### Added in 0.3.47
|
||||
|
||||
- Notes on contacts page with new contact-edit page
|
||||
- Contact methods (only on contact-edit page and under DID details)
|
||||
- DID view with no DID shows user's info.
|
||||
|
||||
### Changed in 0.3.47
|
||||
|
||||
- URL for user's contact info is now URL to this app (not endorser.ch).
|
||||
- Extended details (eg. full claim) is beneath details link on claim page.
|
||||
|
||||
## [0.3.46] - 2025.01.03 - 9e7056616b5e5acc51e5a8cf7354d408029fefb3
|
||||
|
||||
### Added in 0.3.46
|
||||
|
||||
- More action-oriented questions for the gift prompts
|
||||
|
||||
### Fixed in 0.3.46
|
||||
|
||||
- Contact-list import set visibility for all, even if not chosen.
|
||||
|
||||
## [0.3.45] - 2025.01.01 - 65402dc68ce69ccc6cb9aa8d2e7a9249bf4298e0
|
||||
|
||||
### Fixed in 0.3.45
|
||||
|
||||
- Previous project links stayed when following a link.
|
||||
|
||||
## [0.3.44] - 2024.12.31 - 694b22987b05482e4527c2478bbe15e6b6f3b532
|
||||
|
||||
### Added in 0.3.44
|
||||
|
||||
- Project counts on a map
|
||||
|
||||
## [0.3.42] - 2024.12.27 - 9751934bc24a1040415a8cfeacbae59ed91f92a5
|
||||
|
||||
### Added in 0.3.42
|
||||
|
||||
- Link from certificate page to the claim
|
||||
|
||||
### Changed in 0.3.42
|
||||
|
||||
- Contact data sharing is now a verified JWT.
|
||||
- Feed pictures are larger.
|
||||
|
||||
## [0.3.41] - 2024.12.21 - ff6d14138f26daea6216b051562f0a04681f69fc
|
||||
|
||||
### Added in 0.3.41
|
||||
|
||||
- Link from certificate page to the claim
|
||||
|
||||
## [0.3.40] - 2024.12.20 - 77290d9fed3c364243793dc3e9bfe2e994a016b8
|
||||
|
||||
### Added in 0.3.40
|
||||
|
||||
- Only show issuer on certificate if it's not the agent.
|
||||
|
||||
## [0.3.39] - 2024.12.20 - d8819155e2acd2b57fdab523168fa5d1d09e80cc
|
||||
|
||||
### Added in 0.3.39
|
||||
|
||||
- Page for a framed claim certificate
|
||||
|
||||
## [0.3.38] - 2024.12.14 - f8cae5ad4fee1f114320dcce052299eab12108b2
|
||||
|
||||
### Fixed in 0.3.38
|
||||
|
||||
- Error on BVC confirmation screen (from IndexedDB refactor)
|
||||
|
||||
## [0.3.37] - 2024.12.13 - 4d805b43cd25eed73cdd6651f36ad1ec8c109555
|
||||
|
||||
### Added in 0.3.37
|
||||
|
||||
- Record a give from a project on the project page.
|
||||
- New button on home page opens the gifted dialog.
|
||||
- On confirmation buttons on the project page gives, mark when unavailable and explain why.
|
||||
|
||||
### Changed in 0.3.37
|
||||
|
||||
- Moved the secret into IndexedDB (and out of localStorage) for more reliability.
|
||||
- New "invite" destination page helps troubleshoot when JWT link doesn't come through.
|
||||
|
||||
### Fixed in 0.3.37
|
||||
|
||||
- Problem showing claim issuer name
|
||||
- Problem going "back" from a project page
|
||||
|
||||
## [0.3.36] - 2024.11.24 - c8d23647d165016f8a8f575e13d32583242e53ac
|
||||
|
||||
### Changed in 0.3.36
|
||||
|
||||
- More friendly default reminder message
|
||||
- Blue borders around people to indicate clickability
|
||||
|
||||
## [0.3.35] - 2024.11.24 - bff7d0a6320b70349185e26bfac72e3bb17f76df
|
||||
|
||||
### Added in 0.3.35
|
||||
|
||||
- Daily reliable, hard-coded notification message
|
||||
- Setting to change the partner API server
|
||||
|
||||
## [0.3.33] - 2024.11.07 - adb7b16ecf1343c39cba71a7d6bb0e7a973e1102
|
||||
|
||||
### Fixed in 0.3.33
|
||||
|
||||
- Affirm Delivery button on offer claim page didn't work.
|
||||
- Plans were not showing by default on project page.
|
||||
|
||||
## [0.3.32] - 2024.11.06 - 9a3fa38a3fd28f977e06f0265fc39e635c9c5ccd
|
||||
|
||||
### Added in 0.3.32
|
||||
|
||||
- Highlight in green new offers to user & to user's projects on the front page.
|
||||
|
||||
## [0.3.31] - 2024.10.25 - 07c02ab98a09d293dd90d9289a7872e7d681d296
|
||||
|
||||
### Changed in 0.3.31
|
||||
|
||||
- Onboarding messages about offers
|
||||
|
||||
## [0.3.30]
|
||||
|
||||
### Added in 0.3.30
|
||||
|
||||
- Onboarding messages
|
||||
|
||||
## [0.3.29] - 2024.10.09 - babd3832bdfe0c40eaa3869de1b41399a51713c1
|
||||
|
||||
### Added in 0.3.29
|
||||
|
||||
- Invite for a contact to join immediately
|
||||
|
||||
### Changed in 0.3.29
|
||||
|
||||
- Send signed data to nostr endpoints to verify public key ownership.
|
||||
- Enhanced help & help onboarding.
|
||||
|
||||
### Changed in DB or environment
|
||||
|
||||
- Uses Endorser.ch version 4.1.1
|
||||
|
||||
## [0.3.28] - 2024.09.30 - 84720b94049d29cc0ddd99c50cef2e7176130133
|
||||
|
||||
### Added in 0.3.28
|
||||
|
||||
- Posting to nostr apps Trustroots & TripHopping
|
||||
- Display of providers on claim view page
|
||||
|
||||
### Changed in 0.3.28
|
||||
|
||||
- Switched BVC-meeting-ending gift to be a gift from the group.
|
||||
|
||||
### Changed in DB or environment in 0.3.28
|
||||
|
||||
- Requires Endorser.ch version 4.1.0
|
||||
|
||||
## [0.3.27] - 2024.09.22 - ee23e6f005e47f5bd6f04d804599f6395371b0e4
|
||||
|
||||
### Fixed in 0.3.27
|
||||
|
||||
- Error loading BVC claims to confirm
|
||||
- Really allow visibility of bulk-imported contacts
|
||||
|
||||
## [0.3.26] - 2024.09.16 - 8263ed2b29947b3ccc6f3133bbc9454c222bce28
|
||||
|
||||
### Added in 0.3.26
|
||||
|
||||
- Separate 'isRegistered' flag for each account
|
||||
|
||||
### Fixed in 0.3.26
|
||||
|
||||
- Failure to assign offers to their project
|
||||
- Alert when looking at one's own activity if not in contacts.
|
||||
|
||||
## [0.3.25] - 2024.08.30 - dcbe02d877aecb4cdef2643d90e6595d246a9f82
|
||||
|
||||
### Added in 0.3.25
|
||||
|
||||
- "Ideas" now jumps directly to giving prompt or contact list.
|
||||
|
||||
### Fixed in 0.3.25
|
||||
|
||||
- Empty giver name on gifted-details view
|
||||
- Previously visited project would show up on the giving-details page.
|
||||
|
||||
### Removed in 0.3.25
|
||||
|
||||
- All unnecessary localStorage for project IDs
|
||||
|
||||
## [0.3.23] - 2024.08.30
|
||||
|
||||
### Added in 0.3.23
|
||||
|
||||
- Sections in Help for different kinds of users
|
||||
- Discovery page parameters so that links with search text work
|
||||
- Message when no projects are found
|
||||
|
||||
## [0.3.21] - 2024.08.24 - a7b89f4bb6da928d56daeffaae7741fa74cc80bf
|
||||
|
||||
### Added in 0.3.21
|
||||
|
||||
- Send list of contacts to someone, and move individual contact actions to detail page.
|
||||
- Prompt for name in pop-up, and send to different contact-sharing screens.
|
||||
|
||||
### Changed in 0.3.21
|
||||
|
||||
- Moved contact actions from list onto detail page
|
||||
|
||||
## [0.3.20] - 2024.08.18 - 4064eb75a9743ca268bf00016fa0a5fc5dec4e30
|
||||
|
||||
### Fixed in 0.3.20
|
||||
|
||||
- Bad "give" verbiage on offer page
|
||||
- Failing offer test
|
||||
|
||||
## [0.3.19] - 2024.08.18 - ee9c14942ceba993bf21a11249601f205158ec71
|
||||
|
||||
### Added in 0.3.19
|
||||
|
||||
- Update of an offer
|
||||
- Recipient description in offer list
|
||||
|
||||
### Fixed in 0.3.19
|
||||
|
||||
- List of offers wasn't showing.
|
||||
- Destination page after sharing photo was wrong.
|
||||
|
||||
## [0.3.17] - 2024.07.11 - cefa384ff1a2d922848c370640c096c529920fab
|
||||
|
||||
### Added in 0.3.17
|
||||
|
||||
- Photos on more screens
|
||||
|
||||
### Fixed in 0.3.17
|
||||
|
||||
- Share of a photo, including sharing a photo from webkit/Safari which never worked
|
||||
|
||||
### Changed in DB or environment in 0.3.17
|
||||
|
||||
- Nothing (though there's a new temp field in IndexedDB)
|
||||
|
||||
## [0.3.15] - 2024.08.04 - c8f0f2c2b16b9f0b4b47d40f7bf29058c7baa68e
|
||||
|
||||
### Added in 0.3.15
|
||||
|
||||
- Edit gives
|
||||
- Page to edit claim JSON before submitting
|
||||
- Update of imported contacts
|
||||
- Improve messaging on give dialog
|
||||
- Section for gives provided by plan
|
||||
- Deletion of an identity
|
||||
- UI for choosing a passkey creation (not enabled on prod)
|
||||
- Cache signatures for reports for passkey-signed requests
|
||||
- Refactor: consolidate alternative signing, eg. for passkeys & did:peer
|
||||
- Playwright tests
|
||||
|
||||
### Changed in 0.3.15
|
||||
|
||||
- Linked projects display below description (instead of at bottom)
|
||||
|
||||
### Fixed in 0.3.15
|
||||
|
||||
- Visibility toggle appearance
|
||||
|
||||
### Changed in DB or environment in 0.3.15
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.3.14] - 2024.06.22 - 1611d22892f683f43856d2503eee7f391b6bbce8
|
||||
|
||||
### Added in 0.3.14
|
||||
|
||||
- Clearer give-confirmation screen
|
||||
- BX currency <https://thebx.medium.com/>
|
||||
- Deselection of project on gifted details page
|
||||
|
||||
### Fixed in 0.3.14
|
||||
|
||||
- Don't show registration pop-up for a new contact that is registered
|
||||
|
||||
### Changed in DB or environment in 0.3.14
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.3.13] - 2024.05.24 - 08b67984e443c58d9178ad3776013b0bce7afddc
|
||||
|
||||
### Added in 0.3.13
|
||||
|
||||
- Photos on projects
|
||||
|
||||
### Changed in DB or environment in 0.3.13
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.3.12] - 2024.05.19 - 141fb39ad19c44d82fe1a33bf85115beacf50870
|
||||
|
||||
### Fixed in 0.3.12
|
||||
|
||||
- Photo share (share_target) failed because requests were sent to server
|
||||
|
||||
### Changed in DB or environment in 0.3.12
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.3.11] - 2024.05.19 - 567bcad88dfb7e9ac8fea72530d1163985e4a7cc
|
||||
|
||||
### Added in 0.3.11
|
||||
|
||||
- Choose a file for gifts, and a URL for gifts & profiles
|
||||
|
||||
### Fixed in 0.3.11
|
||||
|
||||
- Multiple button pushes were required to switch camera
|
||||
|
||||
### Changed in DB or environment in 0.3.11
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.3.10] - 2024.05.11 - 03ac31d98110f7828cf9acb366db8d01b185f64c
|
||||
|
||||
### Added in 0.3.10
|
||||
|
||||
- Share an image
|
||||
- Choose a file on the device for a profile image
|
||||
|
||||
### Changed in DB or environment in 0.3.10
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.3.9] - 2024.04.28 - 874e717e698b93a1ace9f588e675b8a3dccd7617
|
||||
|
||||
### Added in 0.3.9
|
||||
|
||||
- Offers on contacts page
|
||||
- Checks on front page until they show as registered
|
||||
|
||||
### Changed in 0.3.9
|
||||
|
||||
- Scanned contacts now add immediately and prompt for registration.
|
||||
- Better UI for gives on contact page
|
||||
- Better UI for all confirmation messages
|
||||
|
||||
### Fixed in 0.3.9
|
||||
|
||||
- Repeated elements at top of main feed
|
||||
|
||||
### Changed in DB or environment in 0.3.9
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.3.8] - 2024.04.20 - 15c026c80ce03a26cae3ff80b0888934c101c7e2
|
||||
|
||||
### Added in 0.3.8
|
||||
|
||||
- Profile image for user
|
||||
|
||||
### Fixed in 0.3.8
|
||||
|
||||
- Slow loading of home page feed
|
||||
|
||||
### Changed in DB or environment in 0.3.8
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.3.7] - 2024.04.10 - cf18f1543a700d62a5f9e764905a4aafe1fb229b
|
||||
|
||||
### Added in 0.3.7
|
||||
|
||||
- Filter on home page feed
|
||||
- Ability to set time of daily notification
|
||||
- Jump to app on click of notification
|
||||
|
||||
### Changed in 0.3.7
|
||||
|
||||
- Built with vite
|
||||
- Descriptions on home page to include projects
|
||||
|
||||
### Changed in DB or environment in 0.3.7
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.3.6] - 2024.03.24 - 3a07e31d6313ab95711265562d9023c42916e141
|
||||
|
||||
### Added in 0.3.6
|
||||
|
||||
- Button to mirror photo during video
|
||||
- More detailed onboarding help screen
|
||||
- Public-data blurb
|
||||
|
||||
### Changed in DB or environment in 0.3.6
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.3.5] - 2024.03.23 - 28754bdfb1e11aa221dd49a5dce4219b69cf6a9d
|
||||
|
||||
### Added in 0.3.5
|
||||
|
||||
- Photo on gift records
|
||||
|
||||
### Fixed in 0.3.5
|
||||
|
||||
- Environment variable for BVC meetings project
|
||||
- Environment variables and build enhancements for test vs prod
|
||||
|
||||
### Changed in DB or environment in 0.3.5
|
||||
|
||||
- New environment variable for image API server
|
||||
- Test that a new browser session will get the right default APIs.
|
||||
- Test that a new browser session will send the right BVC meetings project.
|
||||
|
||||
## [0.2.17] - 2024.03.01 - 3612ea42240c5e1b7d7eff29a39ff18f1b869b36
|
||||
|
||||
### Added in 0.2.17
|
||||
|
||||
- Shortcut page for Bountiful Voluntaryist Community
|
||||
|
||||
### Changed in 0.2.17
|
||||
|
||||
- More readable, targeted summaries in home-page feed items
|
||||
|
||||
### Changed in DB
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.2.14] - 2024.02.14 - 5f9edea1167dbfb64e16648764eed8c09b24eaeb
|
||||
|
||||
### Changed in 0.2.14
|
||||
|
||||
- Combine all service worker scripts into a single file.
|
||||
|
||||
### Changed in DB in 0.2.14
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.2.13] - 2024.02.07
|
||||
|
||||
### Added in 0.2.13
|
||||
|
||||
- Display of user's offers
|
||||
- Check for valid DIDs
|
||||
|
||||
### Fixed in 0.2.13
|
||||
|
||||
- Name display on give prompt
|
||||
- Non-numbers on number input & autocapitalize on URL input
|
||||
|
||||
### Changed in DB in 0.2.13
|
||||
|
||||
- Nothing
|
||||
|
||||
## [0.2.12] - 2024.02.01
|
||||
|
||||
### Added in 0.2.12
|
||||
|
||||
- Prompts for gratitude
|
||||
|
||||
## [0.2.11] - 2024.01.28
|
||||
|
||||
### Added in 0.2.11
|
||||
|
||||
- Actions to share claim data with contacts
|
||||
- Bulk CSV import from Endorser Mobile export
|
||||
- Dates on give summaries
|
||||
|
||||
## [0.2.10] - 2024.01.18 - 667e1e8890b42de59cd939caca1a01c7a7a702be
|
||||
|
||||
### Added in 0.2.10
|
||||
|
||||
- Person identicons for contacts
|
||||
- Confirmation & delivery directly from project page
|
||||
- Offer dialog now allows units
|
||||
- Links from claim detail page to the fulfilled project or offer
|
||||
- Link to project from home feed
|
||||
- Copy to clipboard in more places
|
||||
|
||||
### Fixed in 0.2.10
|
||||
|
||||
- "More Contacts" for give on project page now links correctly.
|
||||
|
||||
## [0.2.9] - 2024.01.15 - e5e702f8a5a53a6efbed48d35f0bc3cee63024a0
|
||||
|
||||
### Fixed in 0.2.9
|
||||
|
||||
- Set visibility for new contact.
|
||||
|
||||
## [0.2.8] - 2024.01.14
|
||||
|
||||
### Added in 0.2.8
|
||||
|
||||
- Automatic ID creation from home page
|
||||
- Agent who can also edit a project
|
||||
|
||||
### Fixed in 0.2.8
|
||||
|
||||
- Cannot declare anonymous gift
|
||||
|
||||
## [0.2.7] - 2024.01.12
|
||||
|
||||
### Added in 0.2.7
|
||||
|
||||
- Give to fulfill a particular offer
|
||||
- Give as part of a trade as opposed to a donation
|
||||
- Error notifications on import
|
||||
|
||||
### Changed in 0.2.7
|
||||
|
||||
- Library security updates
|
||||
- Visibility of actions & confirmations on claim page
|
||||
|
||||
### Fixed in 0.2.7
|
||||
|
||||
- Name of offerer
|
||||
|
||||
## [0.2.2] - 2024.01.05
|
||||
|
||||
### Added in 0.2.2
|
||||
|
||||
- Check for notification capability on front screen
|
||||
- Contact next-public-key-hash in manual textual input
|
||||
- Confirmation for contact visibility change
|
||||
- YAML rendering of full claim details
|
||||
- Hints for onboarding on the contact screen
|
||||
|
||||
## [0.2.0] - 2024.01.04
|
||||
|
||||
### Added in 0.2.0
|
||||
|
||||
- Contact next-public-key-hash
|
||||
- Icon for Android
|
||||
- More thorough messaging and testing for notifications
|
||||
|
||||
## [0.1.9] - 2024.01.01
|
||||
|
||||
### Added in 0.1.9
|
||||
|
||||
- Import for contacts and settings
|
||||
- Second download button for DuckDuckGo
|
||||
|
||||
### Changed in 0.1.9
|
||||
|
||||
- Removed some keys from Dexie's IndexedDB declarations
|
||||
|
||||
## [0.1.8] - 2023.12.27- d26d1d360152a7d0e559b68486e85b72b88bd9ff
|
||||
|
||||
### Added in 0.1.8
|
||||
|
||||
- DB logging for service-worker events
|
||||
- Help page for notifications
|
||||
- Test notification & web-push triggers inside app
|
||||
- Check that the app is installed
|
||||
|
||||
### Fixed in 0.1.8
|
||||
|
||||
- Project issuer display name
|
||||
|
||||
## [0.1.7] - 2023.12.19 - 91c6c7c11c71f96006cc876fc946f1f98a274ba2
|
||||
|
||||
### Changed in 0.1.7
|
||||
|
||||
- Icons
|
||||
|
||||
### Fixed in 0.1.7
|
||||
|
||||
- Notification switch now shows message
|
||||
- Prod/test server warning message at top of page
|
||||
|
||||
## [0.1.6] - 2023.12.17 - b445b1234fbfcf6b37d695373f259aab0eda1118
|
||||
|
||||
### Added in 0.1.6
|
||||
|
||||
- Infinite scroll on home page
|
||||
|
||||
### Changed in 0.1.6
|
||||
|
||||
- UI improvements
|
||||
- Show web-push subscription info
|
||||
- Icon
|
||||
|
||||
## [0.1.5] - 2023.12.09 - 9c36bb509a9bae9bb3306d3bd9eeb144b67aa8ad
|
||||
|
||||
### Added in 0.1.5
|
||||
|
||||
- Web push notifications (though not finalized)
|
||||
- Credentials details page
|
||||
- See more data without an ID
|
||||
- Change units of a give
|
||||
|
||||
## [0.1.4] - 2023.11.20 - 7311d36726f3667ec4c68f241f91d404273ad4db
|
||||
|
||||
### Added in 0.1.4
|
||||
|
||||
- Offer on a project
|
||||
|
||||
### Changed in 0.1.4
|
||||
|
||||
- Automatically set as visible when importing a contact
|
||||
- Web push notifications
|
||||
|
||||
## [0.1.3] - 2023.11.08 - 910f57ec7d2e50803ae3d04f4b927e0f5219fbde
|
||||
|
||||
### Added in 0.1.3
|
||||
|
||||
### Added
|
||||
- Contact name editing
|
||||
|
||||
### Changed in 0.1.3
|
||||
|
||||
### Changed
|
||||
- Don't show actions on front page if not registered.
|
||||
|
||||
### Removed in 0.1.3
|
||||
|
||||
### Removed
|
||||
- Home page Notiwind test buttons
|
||||
|
||||
|
||||
## [0.1.2] - 2023.11.01 - 7f6c93802911a030a89fe3706e18b5c17151e5bb
|
||||
|
||||
### Added in 0.1.2
|
||||
|
||||
### Added
|
||||
- Basics: create ID, record a give, declare a project, search, and get notifications.
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# Contributing
|
||||
|
||||
Welcome! We are happy to have your help with this project.
|
||||
|
||||
We expect contributions to include automated tests and pass linting. Run the `test-all` task.
|
||||
Note that some previous features don't have tests and adding more will make you friends quick.
|
||||
|
||||
Note that all contributions will be under our [license, modeled after SQLite](https://github.com/trentlarson/endorser-ch/blob/master/LICENSE).
|
||||
|
||||
If you want to see a code of conduct, we're probably not the people you want to hang with.
|
||||
Basically, we'll work together as long as we both enjoy it, and we'll stop when that stops.
|
||||
170
Dockerfile
170
Dockerfile
@@ -1,170 +0,0 @@
|
||||
# TimeSafari Docker Build
|
||||
# Author: Matthew Raymer
|
||||
# Description: Multi-stage Docker build for TimeSafari web application
|
||||
#
|
||||
# Build Process:
|
||||
# 1. Base stage: Node.js with build dependencies
|
||||
# 2. Builder stage: Copy pre-built web assets from host
|
||||
# 3. Production stage: Nginx server with optimized assets
|
||||
#
|
||||
# Note: Web assets are built on the host using npm scripts before Docker build
|
||||
#
|
||||
# Security Features:
|
||||
# - Non-root user execution
|
||||
# - Minimal attack surface with Alpine Linux
|
||||
# - Multi-stage build to reduce image size
|
||||
# - No build dependencies in final image
|
||||
#
|
||||
# Usage:
|
||||
# IMPORTANT: Build web assets first, then build Docker image
|
||||
#
|
||||
# Using npm scripts (recommended):
|
||||
# Production: npm run build:web:docker:prod
|
||||
# Test: npm run build:web:docker:test
|
||||
# Development: npm run build:web:docker
|
||||
#
|
||||
# Manual workflow:
|
||||
# 1. Build web assets: npm run build:web:build -- --mode production
|
||||
# 2. Build Docker: docker build -t timesafari:latest .
|
||||
#
|
||||
# Note: For development, use npm run build:web directly (no Docker needed)
|
||||
#
|
||||
# Build Arguments:
|
||||
# BUILD_MODE: development, test, or production (default: production)
|
||||
# NODE_ENV: node environment (default: production)
|
||||
#
|
||||
# Environment Variables:
|
||||
# NODE_ENV: Build environment (development/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
|
||||
# =============================================================================
|
||||
FROM node:22-alpine3.20 AS base
|
||||
|
||||
# Install system dependencies for build process
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
git \
|
||||
python3 \
|
||||
py3-pip \
|
||||
py3-setuptools \
|
||||
make \
|
||||
g++ \
|
||||
gcc \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# Create non-root user for security
|
||||
RUN addgroup -g 1001 -S nodejs && \
|
||||
adduser -S nextjs -u 1001
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files for dependency installation
|
||||
# Note: These files are in the project root (crowd-funder-for-time-pwa directory)
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies with security audit
|
||||
RUN npm ci --only=production --audit --fund=false && \
|
||||
npm audit fix --audit-level=moderate || true
|
||||
|
||||
# =============================================================================
|
||||
# BUILDER STAGE - Copy pre-built assets
|
||||
# =============================================================================
|
||||
FROM base AS builder
|
||||
|
||||
# Define build arguments with defaults
|
||||
ARG BUILD_MODE=production
|
||||
ARG NODE_ENV=production
|
||||
|
||||
# Set environment variables from build arguments
|
||||
ENV BUILD_MODE=${BUILD_MODE}
|
||||
ENV NODE_ENV=${NODE_ENV}
|
||||
|
||||
# Copy pre-built assets from host
|
||||
# Note: dist/ directory is in the project root (crowd-funder-for-time-pwa directory)
|
||||
COPY dist/ ./dist/
|
||||
|
||||
# Verify build output exists
|
||||
RUN ls -la dist/ || (echo "Build output not found in dist/ directory" && exit 1)
|
||||
|
||||
# =============================================================================
|
||||
# PRODUCTION STAGE - Nginx server
|
||||
# =============================================================================
|
||||
FROM nginx:alpine AS production
|
||||
|
||||
# Define build arguments for production stage
|
||||
ARG BUILD_MODE=production
|
||||
ARG NODE_ENV=production
|
||||
|
||||
# Set environment variables
|
||||
ENV BUILD_MODE=${BUILD_MODE}
|
||||
ENV NODE_ENV=${NODE_ENV}
|
||||
|
||||
# Install security updates and clean cache
|
||||
RUN apk update && \
|
||||
apk upgrade && \
|
||||
apk add --no-cache \
|
||||
curl \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# Use existing nginx user from base image (nginx user and group already exist)
|
||||
# No need to create new user as nginx:alpine already has nginx user
|
||||
|
||||
# Copy main nginx configuration
|
||||
COPY docker/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
# Copy production nginx configuration
|
||||
COPY docker/default.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Copy built assets from builder stage
|
||||
COPY --from=builder --chown=nginx:nginx /app/dist /usr/share/nginx/html
|
||||
|
||||
# Create necessary directories with proper permissions
|
||||
RUN mkdir -p /var/cache/nginx /var/log/nginx /tmp && \
|
||||
chown -R nginx:nginx /var/cache/nginx /var/log/nginx /tmp && \
|
||||
chown -R nginx:nginx /usr/share/nginx/html
|
||||
|
||||
# Switch to non-root user
|
||||
USER nginx
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost/ || exit 1
|
||||
|
||||
# Start nginx with proper signal handling
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
# =============================================================================
|
||||
# TEST STAGE - For test environment testing
|
||||
# =============================================================================
|
||||
FROM production AS test
|
||||
|
||||
# Define build arguments for test stage
|
||||
ARG BUILD_MODE=test
|
||||
ARG NODE_ENV=test
|
||||
|
||||
# Set environment variables
|
||||
ENV BUILD_MODE=${BUILD_MODE}
|
||||
ENV NODE_ENV=${NODE_ENV}
|
||||
|
||||
# Copy test-specific nginx configuration
|
||||
COPY docker/staging.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Health check for staging
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost/health || exit 1
|
||||
|
||||
# Start nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
134
Gemfile.lock
134
Gemfile.lock
@@ -1,134 +0,0 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.7)
|
||||
base64
|
||||
nkf
|
||||
rexml
|
||||
activesupport (7.2.2.1)
|
||||
base64
|
||||
benchmark (>= 0.3)
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.3.1)
|
||||
connection_pool (>= 2.2.5)
|
||||
drb
|
||||
i18n (>= 1.6, < 2)
|
||||
logger (>= 1.4.2)
|
||||
minitest (>= 5.1)
|
||||
securerandom (>= 0.3)
|
||||
tzinfo (~> 2.0, >= 2.0.5)
|
||||
addressable (2.8.7)
|
||||
public_suffix (>= 2.0.2, < 7.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
json (>= 1.5.1)
|
||||
atomos (0.1.3)
|
||||
base64 (0.2.0)
|
||||
benchmark (0.4.0)
|
||||
bigdecimal (3.1.9)
|
||||
claide (1.1.0)
|
||||
cocoapods (1.16.2)
|
||||
addressable (~> 2.8)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.16.2)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 2.1, < 3.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.6.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
fourflusher (>= 2.3.0, < 3.0)
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.8.0)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (>= 2.3.0, < 3.0)
|
||||
xcodeproj (>= 1.27.0, < 2.0)
|
||||
cocoapods-core (1.16.2)
|
||||
activesupport (>= 5.0, < 8)
|
||||
addressable (~> 2.8)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
fuzzy_match (~> 2.0.4)
|
||||
nap (~> 1.0)
|
||||
netrc (~> 0.11)
|
||||
public_suffix (~> 4.0)
|
||||
typhoeus (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.5)
|
||||
cocoapods-downloader (2.1)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.1)
|
||||
cocoapods-trunk (1.6.0)
|
||||
nap (>= 0.8, < 2.0)
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.2.0)
|
||||
colored2 (3.1.2)
|
||||
concurrent-ruby (1.3.5)
|
||||
connection_pool (2.5.0)
|
||||
drb (2.2.1)
|
||||
escape (0.0.4)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
ffi (1.17.1)
|
||||
ffi (1.17.1-aarch64-linux-gnu)
|
||||
ffi (1.17.1-aarch64-linux-musl)
|
||||
ffi (1.17.1-arm-linux-gnu)
|
||||
ffi (1.17.1-arm-linux-musl)
|
||||
ffi (1.17.1-arm64-darwin)
|
||||
ffi (1.17.1-x86-linux-gnu)
|
||||
ffi (1.17.1-x86-linux-musl)
|
||||
ffi (1.17.1-x86_64-darwin)
|
||||
ffi (1.17.1-x86_64-linux-gnu)
|
||||
ffi (1.17.1-x86_64-linux-musl)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
httpclient (2.9.0)
|
||||
mutex_m
|
||||
i18n (1.14.7)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.10.2)
|
||||
logger (1.6.6)
|
||||
minitest (5.25.5)
|
||||
molinillo (0.8.0)
|
||||
mutex_m (0.3.0)
|
||||
nanaimo (0.4.0)
|
||||
nap (1.1.0)
|
||||
netrc (0.11.0)
|
||||
nkf (0.2.0)
|
||||
public_suffix (4.0.7)
|
||||
rexml (3.4.1)
|
||||
ruby-macho (2.5.1)
|
||||
securerandom (0.4.1)
|
||||
typhoeus (1.4.1)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
xcodeproj (1.27.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.4.0)
|
||||
rexml (>= 3.3.6, < 4.0)
|
||||
|
||||
PLATFORMS
|
||||
aarch64-linux-gnu
|
||||
aarch64-linux-musl
|
||||
arm-linux-gnu
|
||||
arm-linux-musl
|
||||
arm64-darwin
|
||||
ruby
|
||||
x86-linux-gnu
|
||||
x86-linux-musl
|
||||
x86_64-darwin
|
||||
x86_64-linux-gnu
|
||||
x86_64-linux-musl
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods
|
||||
|
||||
BUNDLED WITH
|
||||
2.6.5
|
||||
8
LICENSE
8
LICENSE
@@ -1,8 +0,0 @@
|
||||
The author disclaims copyright to this source code. In place of a legal notice, here is a blessing:
|
||||
|
||||
May you do good and not evil.
|
||||
May you find forgiveness for yourself and forgive others.
|
||||
May you share freely, never taking more than you give.
|
||||
|
||||
________________________________________________________________
|
||||
from https://www.sqlite.org/src/info/689401a6cfb4c234 and memorialized here https://spdx.org/licenses/blessing.html
|
||||
@@ -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`
|
||||
@@ -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.
|
||||
200
README.md
200
README.md
@@ -1,118 +1,130 @@
|
||||
# Time Safari Application
|
||||
# TimeSafari.app - Crowd-Funder for Time - PWA
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Version**: 1.0.8-beta
|
||||
**Description**: Time Safari Application
|
||||
## Project setup
|
||||
|
||||
## 🛡️ Build Architecture Guard
|
||||
We have pkgx.dev set up in package.json, so you can use `dev` to set up the dev environment.
|
||||
|
||||
This project uses **Husky Git hooks** to protect the build system
|
||||
architecture. When you modify build-critical files, the system
|
||||
automatically blocks commits until you update `BUILDING.md`.
|
||||
|
||||
### Quick Setup
|
||||
|
||||
```bash
|
||||
npm run guard:setup # Install and activate the guard
|
||||
```
|
||||
|
||||
### How It Works
|
||||
|
||||
- **Pre-commit**: Blocks commits if build files changed without
|
||||
BUILDING.md updates
|
||||
- **Pre-push**: Blocks pushes if commits contain undocumented build
|
||||
changes
|
||||
- **Protected paths**: `scripts/`, `vite.config.*`, `electron/`,
|
||||
`android/`, `ios/`, etc.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Test the guard manually
|
||||
npm run guard:test
|
||||
|
||||
# Emergency bypass (use sparingly)
|
||||
git commit --no-verify
|
||||
git push --no-verify
|
||||
```
|
||||
|
||||
**📚 Full documentation**: See `README-BUILD-GUARD.md`
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 18+
|
||||
- npm, yarn, or pnpm
|
||||
- Git
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run guard:setup # Sets up Build Architecture Guard
|
||||
```
|
||||
|
||||
### Development
|
||||
|
||||
```bash
|
||||
npm run build:web:dev # Build web version
|
||||
npm run build:ios:test # Build iOS test version
|
||||
npm run build:android:test # Build Android test version
|
||||
npm run build:electron:dev # Build Electron dev version
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
```bash
|
||||
npm run test:web # Run web tests
|
||||
npm run test:mobile # Run mobile tests
|
||||
npm run test:all # Run all tests
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
## 📁 Project Structure
|
||||
### Compiles and minifies for production
|
||||
|
||||
```text
|
||||
timesafari/
|
||||
├── 📁 src/ # Source code
|
||||
├── 📁 scripts/ # Build and automation scripts
|
||||
├── 📁 electron/ # Electron configuration
|
||||
├── 📁 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
|
||||
If you are deploying in a subdirectory, add it to `publicPath` in vue.config.js, eg: `publicPath: "/app/time-tracker/",`
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
## 🔧 Build System
|
||||
```
|
||||
npx prettier --write ./sw_scripts/
|
||||
```
|
||||
to make sure the service worker scripts are in proper form
|
||||
|
||||
This project supports multiple platforms:
|
||||
... then copy the contents of the `sw_scripts` folder to the `dist` folder - except additional_scripts.js.
|
||||
|
||||
- **Web**: Vite-based build with service worker support
|
||||
- **Mobile**: Capacitor-based iOS and Android builds
|
||||
- **Desktop**: Electron-based cross-platform desktop app
|
||||
- **Docker**: Containerized deployment options
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
- **`BUILDING.md`** - Complete build system guide
|
||||
- **`README-BUILD-GUARD.md`** - Build Architecture Guard documentation
|
||||
- **`pull_request_template.md`** - PR template for build changes
|
||||
## Tests
|
||||
|
||||
## 🤝 Contributing
|
||||
### Register new user on test server
|
||||
|
||||
1. **Follow the Build Architecture Guard** - Update BUILDING.md when modifying build files
|
||||
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
|
||||
On the test server, User #0 has rights to register others, so you can start
|
||||
playing one of two ways:
|
||||
|
||||
## 📄 License
|
||||
- Import the keys for the test User `did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F` by importing this seed phrase:
|
||||
`rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage`
|
||||
(Other test users are found [here](https://github.com/trentlarson/endorser-ch/blob/master/test/util.js).)
|
||||
|
||||
[Add your license information here]
|
||||
- Alternatively, register someone else under User #0 automatically:
|
||||
|
||||
---
|
||||
* In the `src/views/AccountViewView.vue` file, uncomment the lines referring to "testServerRegisterUser".
|
||||
|
||||
**Note**: The Build Architecture Guard is active and will block
|
||||
commits/pushes that modify build files without proper documentation
|
||||
updates. See `README-BUILD-GUARD.md` for complete details.
|
||||
* Visit the `/account` page.
|
||||
|
||||
### Create multiple identifiers
|
||||
|
||||
Under the "Your Identity" screen, click "Advanced", click "Switch Identity / No Identity", then "Add Another Identity...".
|
||||
|
||||
### Create keys with alternate tools
|
||||
|
||||
[This page](openssl_signing_console.rst) is a tool to create a JWT from a locally-generated keypair.
|
||||
|
||||
### Web-push
|
||||
|
||||
For your own web-push tests, change the 'vapid' URL in App.vue, and install apps on the same domain.
|
||||
|
||||
### Icons
|
||||
|
||||
To add an icon, add to main.ts and reference with `fa` element and `icon` attribute with the hyphenated name.
|
||||
|
||||
### Manual walk-through
|
||||
|
||||
- Clear the browser cache for localhost for a new user.
|
||||
- See that it's using the test API.
|
||||
- On each page, verify the messaging.
|
||||
- On the home page, see the feed without names, and see a message prompting to generate an ID.
|
||||
- On the discovery page, check that they can see projects, and set a search area to see projects nearby.
|
||||
- As User #0 in another browser on the test API, add a give & a project. (See User #0 details above.)
|
||||
- With the new user on the home page, see the feed that shows User #0 in network but without the name.
|
||||
- As the new user on the contacts page, add User #0 as a contact.
|
||||
- On the home page, see the feed that shows User #0 with a name.
|
||||
- Generate an ID.
|
||||
- On the home page, check that it now prompts them to get registered.
|
||||
- On the account page, check that they see messages on limits.
|
||||
- Register the ID from User #0.
|
||||
- As the new user on the home page, check that they can now record a gift.
|
||||
- On the contacts page, check that they cannot register someone else yet.
|
||||
- Walk through the functions on each page.
|
||||
|
||||
|
||||
|
||||
## Scenarios
|
||||
|
||||
- Create a new identity as prompted. Go to "Your Identity" screen and copy the ID to the clipboard.
|
||||
|
||||
- Go back to /start and import test User `did:ethr:0x000Ee5654b9742f6Fe18ea970e32b97ee2247B51` with this this seed phrase:
|
||||
`rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage`
|
||||
(Other test users are found [here](https://github.com/trentlarson/endorser-ch/blob/master/test/util.js).)
|
||||
|
||||
- Go to "Your Contacts" screen and add the ID you copied to the clipboard, and hit "+" to add them.
|
||||
|
||||
- Click on the "Registration Unknown" button and register that person to be able to make claims as them.
|
||||
|
||||
### Clear/Reset data & restart
|
||||
|
||||
* Clear cache for localhost.
|
||||
* Unregister service worker (in Chrome, go to `chrome://serviceworker-internals/`; in Firefox, go to `about:serviceworkers` or `about:debugging`).
|
||||
* Clear notification permission (in Chrome, go to `chrome://settings/content/notifications`; in Firefox, go to `about:preferences` and search).
|
||||
|
||||
|
||||
|
||||
|
||||
## Other
|
||||
|
||||
### Reference Material
|
||||
|
||||
* 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/).
|
||||
|
||||
|
||||
### Kudos
|
||||
|
||||
Gifts make the world go 'round!
|
||||
|
||||
* [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]() 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)
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
|
||||
# What to do about storage for native apps?
|
||||
|
||||
## 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.
|
||||
|
||||
* Apple WebKit puts a [7-day cap on IndexedDB](https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/).
|
||||
|
||||
* The web standards expose a `persist` method to mark memory as persistent, and [supposedly WebView supports it](https://developer.mozilla.org/en-US/docs/Web/API/StorageManager/persisted), but too many other things indicate it's not reliable. I've talked with [ChatGPT](https://chatgpt.com/share/68322f40-84c8-8007-b213-855f7962989a) & Venice & Claude (in Cursor); [this answer from Perplexity](https://www.perplexity.ai/search/which-platforms-prompt-the-use-HUQLqy4qQD2cRbkmO4CgHg) says that most platforms don't prompt and Safari doesn't support it; I don't know if that means WebKit as well.
|
||||
|
||||
* Capacitor says [not to trust it on iOS](https://capacitorjs.com/docs/v6/guides/storage).
|
||||
|
||||
Also, with sensitive data, the accounts info should be encrypted.
|
||||
|
||||
# Options
|
||||
|
||||
* There is a community [SQLite plugin for Capacitor](https://github.com/capacitor-community/sqlite) with encryption by [SQLCipher](https://github.com/sqlcipher/sqlcipher).
|
||||
|
||||
* [This tutorial](https://jepiqueau.github.io/2023/09/05/Ionic7Vue-SQLite-CRUD-App.html#part-1---web---table-of-contents) shows how that plugin works for web as well as native.
|
||||
|
||||
* Capacitor abstracts [user preferences in an API](https://capacitorjs.com/docs/apis/preferences), which uses different underlying libraries on iOS & Android. Unfortunately, it won't do any filtering or searching, and is only meant for small amounts of data. (It could be used for settings and for identifiers, but contacts will grow and image blobs won't work.)
|
||||
|
||||
* There are hints that Capacitor offers another custom storage API but all I could find was that Preferences API.
|
||||
|
||||
* [Ionic Storage](https://ionic.io/docs/secure-storage) is an enterprise solution, which also supports encryption.
|
||||
|
||||
* Not an option yet: Dexie may support SQLite in [a future version](https://dexie.org/roadmap/dexie5.0).
|
||||
|
||||
# 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.
|
||||
|
||||
* After that is delivered, write a migration for current web users from IndexedDB to SQLite.
|
||||
|
||||
# Current method calls
|
||||
|
||||
... which is not 100% complete because the AI that generated thus claimed no usage of 'temp' DB.
|
||||
|
||||
### Secret Database (secretDB) - Used for storing the encryption key
|
||||
|
||||
secretDB.open() - Opens the database
|
||||
secretDB.secret.get(MASTER_SECRET_KEY) - Retrieves the secret key
|
||||
secretDB.secret.add({ id: MASTER_SECRET_KEY, secret }) - Adds a new secret key
|
||||
|
||||
### Accounts Database (accountsDB) - Used for storing sensitive account information
|
||||
|
||||
accountsDB.open() - Opens the database
|
||||
accountsDB.accounts.count() - Counts number of accounts
|
||||
accountsDB.accounts.toArray() - Gets all accounts
|
||||
accountsDB.accounts.where("did").equals(did).first() - Gets a specific account by DID
|
||||
accountsDB.accounts.add(account) - Adds a new account
|
||||
|
||||
### Non-sensitive Database (db) - Used for settings, contacts, logs, and temp data
|
||||
|
||||
Settings operations:
|
||||
export all settings (Dexie format)
|
||||
db.settings.get(MASTER_SETTINGS_KEY) - Gets default settings
|
||||
db.settings.where("accountDid").equals(did).first() - Gets account-specific settings
|
||||
db.settings.where("accountDid").equals(did).modify(settingsChanges) - Updates account settings
|
||||
db.settings.add(settingsChanges) - Adds new settings
|
||||
db.settings.count() - Counts number of settings
|
||||
db.settings.update(key, changes) - Updates settings
|
||||
|
||||
Contacts operations:
|
||||
export all contacts (Dexie format)
|
||||
db.contacts.toArray() - Gets all contacts
|
||||
db.contacts.add(contact) - Adds a new contact
|
||||
db.contacts.update(did, contactData) - Updates a contact
|
||||
db.contacts.delete(did) - Deletes a contact
|
||||
db.contacts.where("did").equals(did).first() - Gets a specific contact by DID
|
||||
|
||||
Logs operations:
|
||||
db.logs.get(todayKey) - Gets logs for a specific day
|
||||
db.logs.update(todayKey, { message: fullMessage }) - Updates logs
|
||||
db.logs.clear() - Clears all logs
|
||||
184
TODO.md
184
TODO.md
@@ -1,184 +0,0 @@
|
||||
# Test Improvements TODO
|
||||
|
||||
## ImageViewer Mock Units - Completed ✅
|
||||
- [x] Create comprehensive mock units for ImageViewer component
|
||||
- [x] Implement 4 mock levels (Simple, Standard, Complex, Integration)
|
||||
- [x] Fix template structure issues (Teleport/Transition complexity)
|
||||
- [x] Resolve event simulation problems (SupportedEventInterface errors)
|
||||
- [x] Fix platform detection logic (mobile vs desktop)
|
||||
- [x] Implement analytics tracking in integration mock
|
||||
- [x] Achieve 38/39 tests passing (97% success rate)
|
||||
|
||||
## Immediate Test Improvements Needed 🔧
|
||||
|
||||
### 1. Fix Remaining ImageViewer Test
|
||||
- [ ] **Fix mobile share button test** - Vue reactivity issue with computed properties
|
||||
- [ ] Investigate Vue 3 reactivity system for computed properties
|
||||
- [ ] Try different approaches: `nextTick()`, `flushPromises()`, or reactive refs
|
||||
- [ ] Consider using `shallowRef()` for userAgent to force reactivity
|
||||
|
||||
### 2. Event Simulation Improvements
|
||||
- [ ] **Create global event simulation utilities**
|
||||
- [ ] Build `triggerEvent()` helper that works with Vue Test Utils
|
||||
- [ ] Handle `SupportedEventInterface` errors consistently
|
||||
- [ ] Create fallback methods for problematic event types
|
||||
- [ ] **Improve test environment setup**
|
||||
- [ ] Configure proper DOM environment for event simulation
|
||||
- [ ] Mock browser APIs more comprehensively
|
||||
- [ ] Add global test utilities for common patterns
|
||||
|
||||
### 3. Mock Architecture Enhancements
|
||||
- [ ] **Create reusable mock patterns**
|
||||
- [ ] Extract common mock utilities (`createMockUserAgent`, etc.)
|
||||
- [ ] Build mock factory patterns for other components
|
||||
- [ ] Create mock validation helpers
|
||||
- [ ] **Improve mock documentation**
|
||||
- [ ] Add JSDoc comments to all mock functions
|
||||
- [ ] Create usage examples for each mock level
|
||||
- [ ] Document mock limitations and workarounds
|
||||
|
||||
## Component-Specific Test Improvements 🧪
|
||||
|
||||
### 4. Expand Mock Units to Other Components
|
||||
- [ ] **QR Scanner Component**
|
||||
- [ ] Create mock for `WebInlineQRScanner`
|
||||
- [ ] Mock camera permissions and device detection
|
||||
- [ ] Test platform-specific behavior (web vs mobile)
|
||||
- [ ] **Platform Service Components**
|
||||
- [ ] Mock `CapacitorPlatformService`
|
||||
- [ ] Mock `WebPlatformService`
|
||||
- [ ] Mock `ElectronPlatformService`
|
||||
- [ ] **Database Components**
|
||||
- [ ] Mock `AbsurdSqlDatabaseService`
|
||||
- [ ] Test migration scenarios
|
||||
- [ ] Mock IndexedDB operations
|
||||
|
||||
### 5. Integration Test Improvements
|
||||
- [ ] **Cross-component communication**
|
||||
- [ ] Test ImageViewer + QR Scanner integration
|
||||
- [ ] Test platform service + component interactions
|
||||
- [ ] Mock complex user workflows
|
||||
- [ ] **End-to-end scenarios**
|
||||
- [ ] Complete user journeys (scan → view → share)
|
||||
- [ ] Error recovery flows
|
||||
- [ ] Performance testing scenarios
|
||||
|
||||
## Test Infrastructure Improvements 🏗️
|
||||
|
||||
### 6. Test Environment Setup
|
||||
- [ ] **Improve Vitest configuration**
|
||||
- [ ] Add proper DOM environment setup
|
||||
- [ ] Configure global mocks for browser APIs
|
||||
- [ ] Add test utilities for common patterns
|
||||
- [ ] **Create test helpers**
|
||||
- [ ] `createComponentWrapper()` utility
|
||||
- [ ] `mockPlatformService()` helper
|
||||
- [ ] `simulateUserInteraction()` utilities
|
||||
|
||||
### 7. Performance Testing
|
||||
- [ ] **Add performance benchmarks**
|
||||
- [ ] Component render time testing
|
||||
- [ ] Memory usage monitoring
|
||||
- [ ] Image loading performance tests
|
||||
- [ ] **Load testing scenarios**
|
||||
- [ ] Multiple ImageViewer instances
|
||||
- [ ] Large image handling
|
||||
- [ ] Concurrent operations
|
||||
|
||||
## Quality Assurance Improvements 📊
|
||||
|
||||
### 8. Test Coverage Enhancement
|
||||
- [ ] **Add missing test scenarios**
|
||||
- [ ] Edge cases for image formats
|
||||
- [ ] Network error handling
|
||||
- [ ] Accessibility compliance tests
|
||||
- [ ] **Mutation testing**
|
||||
- [ ] Verify test quality with mutation testing
|
||||
- [ ] Ensure tests catch actual bugs
|
||||
- [ ] Improve test reliability
|
||||
|
||||
### 9. Test Documentation
|
||||
- [ ] **Create test guidelines**
|
||||
- [ ] Best practices for Vue component testing
|
||||
- [ ] Mock unit design patterns
|
||||
- [ ] Troubleshooting common test issues
|
||||
- [ ] **Add test examples**
|
||||
- [ ] Example test files for each component type
|
||||
- [ ] Integration test examples
|
||||
- [ ] Performance test examples
|
||||
|
||||
## Advanced Testing Features 🚀
|
||||
|
||||
### 10. Visual Regression Testing
|
||||
- [ ] **Add visual testing**
|
||||
- [ ] Screenshot comparison for ImageViewer
|
||||
- [ ] Visual diff testing for UI changes
|
||||
- [ ] Cross-platform visual consistency
|
||||
- [ ] **Accessibility testing**
|
||||
- [ ] Automated accessibility checks
|
||||
- [ ] Screen reader compatibility tests
|
||||
- [ ] Keyboard navigation testing
|
||||
|
||||
### 11. Contract Testing
|
||||
- [ ] **API contract testing**
|
||||
- [ ] Test component prop contracts
|
||||
- [ ] Event emission contracts
|
||||
- [ ] Service interface contracts
|
||||
- [ ] **Mock contract validation**
|
||||
- [ ] Ensure mocks match real component behavior
|
||||
- [ ] Validate mock completeness
|
||||
- [ ] Test mock accuracy
|
||||
|
||||
## Priority Levels 📋
|
||||
|
||||
### High Priority (Next Sprint)
|
||||
1. Fix mobile share button test
|
||||
2. Create global event simulation utilities
|
||||
3. Expand mock units to QR Scanner component
|
||||
4. Improve test environment setup
|
||||
|
||||
### Medium Priority (Next Month)
|
||||
1. Create reusable mock patterns
|
||||
2. Add performance testing
|
||||
3. Improve test documentation
|
||||
4. Add visual regression testing
|
||||
|
||||
### Low Priority (Future)
|
||||
1. Advanced integration testing
|
||||
2. Contract testing
|
||||
3. Mutation testing
|
||||
4. Cross-platform visual testing
|
||||
|
||||
## Success Metrics 📈
|
||||
|
||||
### Current Status
|
||||
- ✅ **97% test pass rate** (38/39 tests)
|
||||
- ✅ **4 mock levels** implemented
|
||||
- ✅ **Comprehensive coverage** of ImageViewer functionality
|
||||
- ✅ **Behavior-focused testing** approach working
|
||||
|
||||
### Target Metrics
|
||||
- [ ] **100% test pass rate** (fix remaining test)
|
||||
- [ ] **10+ components** with mock units
|
||||
- [ ] **< 100ms** average test execution time
|
||||
- [ ] **90%+ code coverage** for critical components
|
||||
- [ ] **Zero flaky tests** in CI/CD pipeline
|
||||
|
||||
## Notes 📝
|
||||
|
||||
### Lessons Learned
|
||||
- Vue 3 reactivity can be tricky with computed properties in tests
|
||||
- Direct method calls work better than `trigger()` for complex events
|
||||
- Mock levels provide excellent flexibility for different testing needs
|
||||
- Behavior-focused testing is more maintainable than implementation-focused
|
||||
|
||||
### Technical Debt
|
||||
- Some TypeScript linter errors in mock files (non-blocking)
|
||||
- Event simulation needs better abstraction
|
||||
- Test environment could be more robust
|
||||
- Mock documentation could be more comprehensive
|
||||
|
||||
---
|
||||
|
||||
*Last updated: 2025-01-07*
|
||||
*Status: Active development*
|
||||
101
android/.gitignore
vendored
101
android/.gitignore
vendored
@@ -1,101 +0,0 @@
|
||||
# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore
|
||||
|
||||
app/build/*
|
||||
!app/build/.npmkeep
|
||||
|
||||
# Copied web assets
|
||||
app/src/main/assets/public
|
||||
|
||||
# Generated Config files
|
||||
app/src/main/assets/capacitor.config.json
|
||||
app/src/main/assets/capacitor.plugins.json
|
||||
app/src/main/res/xml/config.xml
|
||||
|
||||
# secrets
|
||||
app/gradle.properties.secrets
|
||||
app/time-safari-upload-key-pkcs12.jks
|
||||
|
||||
# Built application files
|
||||
*.apk
|
||||
*.aar
|
||||
*.ap_
|
||||
*.aab
|
||||
|
||||
# Files for the ART/Dalvik VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# Generated files
|
||||
bin/
|
||||
gen/
|
||||
out/
|
||||
# Uncomment the following line in case you need and you don't have the release build type files in your app
|
||||
# release/
|
||||
|
||||
# Gradle files
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Proguard folder generated by Eclipse
|
||||
proguard/
|
||||
|
||||
# Log Files
|
||||
*.log
|
||||
|
||||
# Android Studio Navigation editor temp files
|
||||
.navigation/
|
||||
|
||||
# Android Studio captures folder
|
||||
captures/
|
||||
|
||||
# IntelliJ
|
||||
*.iml
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/gradle.xml
|
||||
.idea/assetWizardSettings.xml
|
||||
.idea/dictionaries
|
||||
.idea/libraries
|
||||
# Android Studio 3 in .gitignore file.
|
||||
.idea/caches
|
||||
.idea/modules.xml
|
||||
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
|
||||
.idea/navEditor.xml
|
||||
|
||||
# Keystore files
|
||||
# Uncomment the following lines if you do not want to check your keystore files in.
|
||||
#*.jks
|
||||
#*.keystore
|
||||
|
||||
# External native build folder generated in Android Studio 2.2 and later
|
||||
.externalNativeBuild
|
||||
.cxx/
|
||||
|
||||
# Google Services (e.g. APIs or Firebase)
|
||||
# google-services.json
|
||||
|
||||
# Freeline
|
||||
freeline.py
|
||||
freeline/
|
||||
freeline_project_description.json
|
||||
|
||||
# Version control
|
||||
vcs.xml
|
||||
|
||||
# lint
|
||||
lint/intermediates/
|
||||
lint/generated/
|
||||
lint/outputs/
|
||||
lint/tmp/
|
||||
# lint/reports/
|
||||
|
||||
# Android Profiling
|
||||
*.hprof
|
||||
|
||||
# Cordova plugins for Capacitor
|
||||
capacitor-cordova-android-plugins
|
||||
@@ -1,119 +0,0 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
// These are sample values to set in gradle.properties.secrets
|
||||
// MY_KEYSTORE_FILE=time-safari-upload-key-pkcs12.jks
|
||||
// MY_KEYSTORE_PASSWORD=...
|
||||
// MY_KEY_ALIAS=time-safari-key-alias
|
||||
// MY_KEY_PASSWORD=...
|
||||
|
||||
// Try to load from environment variables first
|
||||
project.ext.MY_KEYSTORE_FILE = System.getenv('ANDROID_KEYSTORE_FILE') ?: ""
|
||||
project.ext.MY_KEYSTORE_PASSWORD = System.getenv('ANDROID_KEYSTORE_PASSWORD') ?: ""
|
||||
project.ext.MY_KEY_ALIAS = System.getenv('ANDROID_KEY_ALIAS') ?: ""
|
||||
project.ext.MY_KEY_PASSWORD = System.getenv('ANDROID_KEY_PASSWORD') ?: ""
|
||||
|
||||
// If no environment variables, try to load from secrets file
|
||||
if (!project.ext.MY_KEYSTORE_FILE) {
|
||||
def secretsPropertiesFile = rootProject.file("app/gradle.properties.secrets")
|
||||
if (secretsPropertiesFile.exists()) {
|
||||
Properties secretsProperties = new Properties()
|
||||
secretsProperties.load(new FileInputStream(secretsPropertiesFile))
|
||||
secretsProperties.each { name, value ->
|
||||
project.ext[name] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'app.timesafari'
|
||||
compileSdk rootProject.ext.compileSdkVersion
|
||||
defaultConfig {
|
||||
applicationId "app.timesafari.app"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 40
|
||||
versionName "1.0.7"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
// Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61
|
||||
ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
release {
|
||||
if (project.ext.MY_KEYSTORE_FILE &&
|
||||
project.ext.MY_KEYSTORE_PASSWORD &&
|
||||
project.ext.MY_KEY_ALIAS &&
|
||||
project.ext.MY_KEY_PASSWORD) {
|
||||
|
||||
storeFile file(project.ext.MY_KEYSTORE_FILE)
|
||||
storePassword project.ext.MY_KEYSTORE_PASSWORD
|
||||
keyAlias project.ext.MY_KEY_ALIAS
|
||||
keyPassword project.ext.MY_KEY_PASSWORD
|
||||
}
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
// Only sign if we have the signing config
|
||||
if (signingConfigs.release.storeFile != null) {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
bundle {
|
||||
language {
|
||||
enableSplit = true
|
||||
}
|
||||
density {
|
||||
enableSplit = true
|
||||
}
|
||||
abi {
|
||||
enableSplit = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
flatDir{
|
||||
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
|
||||
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
|
||||
implementation project(':capacitor-android')
|
||||
implementation project(':capacitor-community-sqlite')
|
||||
implementation "androidx.biometric:biometric:1.2.0-alpha05"
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
||||
implementation project(':capacitor-cordova-android-plugins')
|
||||
}
|
||||
|
||||
apply from: 'capacitor.build.gradle'
|
||||
|
||||
try {
|
||||
def servicesJSON = file('google-services.json')
|
||||
if (servicesJSON.text) {
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
}
|
||||
} catch(Exception e) {
|
||||
logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
|
||||
|
||||
android {
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
|
||||
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
|
||||
dependencies {
|
||||
implementation project(':capacitor-community-sqlite')
|
||||
implementation project(':capacitor-mlkit-barcode-scanning')
|
||||
implementation project(':capacitor-app')
|
||||
implementation project(':capacitor-camera')
|
||||
implementation project(':capacitor-filesystem')
|
||||
implementation project(':capacitor-share')
|
||||
implementation project(':capawesome-capacitor-file-picker')
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (hasProperty('postBuildExtras')) {
|
||||
postBuildExtras()
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "123456789000",
|
||||
"project_id": "timesafari-app",
|
||||
"storage_bucket": "timesafari-app.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:123456789000:android:1234567890abcdef",
|
||||
"android_client_info": {
|
||||
"package_name": "app.timesafari.app"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDummyKeyForBuildPurposesOnly12345"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
21
android/app/proguard-rules.pro
vendored
21
android/app/proguard-rules.pro
vendored
@@ -1,21 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.getcapacitor.myapp;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
|
||||
@Test
|
||||
public void useAppContext() throws Exception {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
|
||||
assertEquals("app.timesafari.app", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
|
||||
android:exported="true"
|
||||
android:label="@string/title_activity_main"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/AppTheme.NoActionBarLaunch">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="timesafari" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
<!-- Permissions -->
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-feature android:name="android.hardware.camera" android:required="true" />
|
||||
</manifest>
|
||||
@@ -1,121 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
[
|
||||
{
|
||||
"pkg": "@capacitor-community/sqlite",
|
||||
"classpath": "com.getcapacitor.community.database.sqlite.CapacitorSQLitePlugin"
|
||||
},
|
||||
{
|
||||
"pkg": "@capacitor-mlkit/barcode-scanning",
|
||||
"classpath": "io.capawesome.capacitorjs.plugins.mlkit.barcodescanning.BarcodeScannerPlugin"
|
||||
},
|
||||
{
|
||||
"pkg": "@capacitor/app",
|
||||
"classpath": "com.capacitorjs.plugins.app.AppPlugin"
|
||||
},
|
||||
{
|
||||
"pkg": "@capacitor/camera",
|
||||
"classpath": "com.capacitorjs.plugins.camera.CameraPlugin"
|
||||
},
|
||||
{
|
||||
"pkg": "@capacitor/filesystem",
|
||||
"classpath": "com.capacitorjs.plugins.filesystem.FilesystemPlugin"
|
||||
},
|
||||
{
|
||||
"pkg": "@capacitor/share",
|
||||
"classpath": "com.capacitorjs.plugins.share.SharePlugin"
|
||||
},
|
||||
{
|
||||
"pkg": "@capawesome/capacitor-file-picker",
|
||||
"classpath": "io.capawesome.capacitorjs.plugins.filepicker.FilePickerPlugin"
|
||||
}
|
||||
]
|
||||
@@ -1,15 +0,0 @@
|
||||
package app.timesafari;
|
||||
|
||||
import android.os.Bundle;
|
||||
import com.getcapacitor.BridgeActivity;
|
||||
//import com.getcapacitor.community.sqlite.SQLite;
|
||||
|
||||
public class MainActivity extends BridgeActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Initialize SQLite
|
||||
//registerPlugin(SQLite.class);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<WebView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -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>
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<resources>
|
||||
<string name="app_name">TimeSafari</string>
|
||||
<string name="title_activity_main">TimeSafari</string>
|
||||
<string name="package_name">timesafari.app</string>
|
||||
<string name="custom_url_scheme">timesafari.app</string>
|
||||
</resources>
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="android:background">@null</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="AppTheme.NoActionBarLaunch" parent="Theme.SplashScreen">
|
||||
<item name="android:background">@drawable/splash</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<widget version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
||||
<access origin="*" />
|
||||
|
||||
|
||||
</widget>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<external-path name="my_images" path="." />
|
||||
<cache-path name="my_cache_images" path="." />
|
||||
<files-path name="my_files" path="." />
|
||||
</paths>
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.getcapacitor.myapp;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
|
||||
@Test
|
||||
public void addition_isCorrect() throws Exception {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.12.1'
|
||||
classpath 'com.google.gms:google-services:4.4.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
apply from: "variables.gradle"
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
ext {
|
||||
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
|
||||
cordovaAndroidVersion = project.hasProperty('cordovaAndroidVersion') ? rootProject.ext.cordovaAndroidVersion : '10.1.1'
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.2.1'
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
namespace "capacitor.cordova.android.plugins"
|
||||
compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 34
|
||||
defaultConfig {
|
||||
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
|
||||
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 34
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
flatDir{
|
||||
dirs 'src/main/libs', 'libs'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'src/main/libs', include: ['*.jar'])
|
||||
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
||||
implementation "org.apache.cordova:framework:$cordovaAndroidVersion"
|
||||
// SUB-PROJECT DEPENDENCIES START
|
||||
|
||||
// SUB-PROJECT DEPENDENCIES END
|
||||
}
|
||||
|
||||
// PLUGIN GRADLE EXTENSIONS START
|
||||
apply from: "cordova.variables.gradle"
|
||||
// PLUGIN GRADLE EXTENSIONS END
|
||||
|
||||
for (def func : cdvPluginPostBuildExtras) {
|
||||
func()
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
|
||||
ext {
|
||||
cdvMinSdkVersion = project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
|
||||
// Plugin gradle extensions can append to this to have code run at the end.
|
||||
cdvPluginPostBuildExtras = []
|
||||
cordovaConfig = [:]
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:amazon="http://schemas.amazon.com/apk/res/android">
|
||||
<application android:usesCleartextTraffic="true">
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -1,24 +0,0 @@
|
||||
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
|
||||
include ':capacitor-android'
|
||||
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
|
||||
|
||||
include ':capacitor-community-sqlite'
|
||||
project(':capacitor-community-sqlite').projectDir = new File('../node_modules/@capacitor-community/sqlite/android')
|
||||
|
||||
include ':capacitor-mlkit-barcode-scanning'
|
||||
project(':capacitor-mlkit-barcode-scanning').projectDir = new File('../node_modules/@capacitor-mlkit/barcode-scanning/android')
|
||||
|
||||
include ':capacitor-app'
|
||||
project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android')
|
||||
|
||||
include ':capacitor-camera'
|
||||
project(':capacitor-camera').projectDir = new File('../node_modules/@capacitor/camera/android')
|
||||
|
||||
include ':capacitor-filesystem'
|
||||
project(':capacitor-filesystem').projectDir = new File('../node_modules/@capacitor/filesystem/android')
|
||||
|
||||
include ':capacitor-share'
|
||||
project(':capacitor-share').projectDir = new File('../node_modules/@capacitor/share/android')
|
||||
|
||||
include ':capawesome-capacitor-file-picker'
|
||||
project(':capawesome-capacitor-file-picker').projectDir = new File('../node_modules/@capawesome/capacitor-file-picker/android')
|
||||
@@ -1,23 +0,0 @@
|
||||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app's APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
android.suppressUnsupportedCompileSdk=36
|
||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
@@ -1,7 +0,0 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
248
android/gradlew
vendored
248
android/gradlew
vendored
@@ -1,248 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
92
android/gradlew.bat
vendored
92
android/gradlew.bat
vendored
@@ -1,92 +0,0 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -1,5 +0,0 @@
|
||||
include ':app'
|
||||
include ':capacitor-cordova-android-plugins'
|
||||
project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/')
|
||||
|
||||
apply from: 'capacitor.settings.gradle'
|
||||
@@ -1,16 +0,0 @@
|
||||
ext {
|
||||
minSdkVersion = 22
|
||||
compileSdkVersion = 36
|
||||
targetSdkVersion = 36
|
||||
androidxActivityVersion = '1.8.0'
|
||||
androidxAppCompatVersion = '1.6.1'
|
||||
androidxCoordinatorLayoutVersion = '1.2.0'
|
||||
androidxCoreVersion = '1.12.0'
|
||||
androidxFragmentVersion = '1.6.2'
|
||||
coreSplashScreenVersion = '1.0.1'
|
||||
androidxWebkitVersion = '1.9.0'
|
||||
junitVersion = '4.13.2'
|
||||
androidxJunitVersion = '1.1.5'
|
||||
androidxEspressoCoreVersion = '3.5.1'
|
||||
cordovaAndroidVersion = '10.1.1'
|
||||
}
|
||||
3
babel.config.js
Normal file
3
babel.config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: ["@vue/cli-plugin-babel/preset"],
|
||||
};
|
||||
4
build.sh
4
build.sh
@@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
export IMAGENAME="$(basename $PWD):1.0"
|
||||
|
||||
docker build . --network=host -t $IMAGENAME --no-cache
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
{
|
||||
"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
|
||||
},
|
||||
"CapacitorSQLite": {
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
# TimeSafari Deep Linking Documentation
|
||||
|
||||
## Type System Overview
|
||||
|
||||
The deep linking system uses a multi-layered type safety approach:
|
||||
|
||||
1. **Runtime Validation (Zod Schemas)**
|
||||
- Validates URL structure
|
||||
- Enforces parameter requirements
|
||||
- Sanitizes input data
|
||||
- Provides detailed validation errors
|
||||
- Generates TypeScript types automatically
|
||||
|
||||
2. **TypeScript Types**
|
||||
- Generated from Zod schemas using `z.infer`
|
||||
- Ensures compile-time type safety
|
||||
- Provides IDE autocompletion
|
||||
- Catches type errors during development
|
||||
- Maintains single source of truth for types
|
||||
|
||||
3. **Router Integration**
|
||||
- Type-safe parameter passing
|
||||
- Route-specific parameter validation
|
||||
- Query parameter type checking
|
||||
- Automatic type inference for route parameters
|
||||
|
||||
## Type System Implementation
|
||||
|
||||
### Zod Schema to TypeScript Type Generation
|
||||
|
||||
```typescript
|
||||
// Define the schema
|
||||
const claimSchema = z.object({
|
||||
id: z.string(),
|
||||
view: z.enum(["details", "certificate", "raw"]).optional()
|
||||
});
|
||||
|
||||
// TypeScript type is automatically generated
|
||||
type ClaimParams = z.infer<typeof claimSchema>;
|
||||
// Equivalent to:
|
||||
// type ClaimParams = {
|
||||
// id: string;
|
||||
// view?: "details" | "certificate" | "raw";
|
||||
// }
|
||||
```
|
||||
|
||||
### Type Safety Layers
|
||||
|
||||
1. **Schema Definition**
|
||||
|
||||
```typescript
|
||||
// src/interfaces/deepLinks.ts
|
||||
export const deepLinkSchemas = {
|
||||
claim: z.object({
|
||||
id: z.string(),
|
||||
view: z.enum(["details", "certificate", "raw"]).optional()
|
||||
}),
|
||||
// Other route schemas...
|
||||
};
|
||||
```
|
||||
|
||||
2. **Type Generation**
|
||||
|
||||
```typescript
|
||||
// Types are automatically generated from schemas
|
||||
export type DeepLinkParams = {
|
||||
[K in keyof typeof deepLinkSchemas]: z.infer<(typeof deepLinkSchemas)[K]>;
|
||||
};
|
||||
```
|
||||
|
||||
3. **Runtime Validation**
|
||||
|
||||
```typescript
|
||||
// In DeepLinkHandler
|
||||
const result = deepLinkSchemas.claim.safeParse(params);
|
||||
if (!result.success) {
|
||||
// Handle validation errors
|
||||
console.error(result.error);
|
||||
}
|
||||
```
|
||||
|
||||
### Error Handling Types
|
||||
|
||||
```typescript
|
||||
export interface DeepLinkError extends Error {
|
||||
code: string;
|
||||
details?: unknown;
|
||||
}
|
||||
|
||||
// Usage in error handling
|
||||
try {
|
||||
await handler.handleDeepLink(url);
|
||||
} catch (error) {
|
||||
if (error instanceof DeepLinkError) {
|
||||
// Type-safe error handling
|
||||
console.error(error.code, error.message);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation Files
|
||||
|
||||
- `src/interfaces/deepLinks.ts`: Type definitions and validation schemas
|
||||
- `src/services/deepLinks.ts`: Deep link processing service
|
||||
- `src/main.capacitor.ts`: Capacitor integration
|
||||
- `src/views/DeepLinkRedirectView.vue`: Page to handle links to both mobile and web
|
||||
|
||||
## Type Safety Examples
|
||||
|
||||
```typescript
|
||||
// Parameter type safety
|
||||
type ClaimParams = DeepLinkParams["claim"];
|
||||
// TypeScript knows this has:
|
||||
// - id: string
|
||||
// - view?: "details" | "certificate" | "raw"
|
||||
// Runtime validation
|
||||
const result = deepLinkSchemas.claim.safeParse({
|
||||
id: "123",
|
||||
view: "details"
|
||||
});
|
||||
// Validates at runtime with detailed error messages
|
||||
```
|
||||
|
||||
## Supported URL Schemes
|
||||
|
||||
All deep links follow the format: `timesafari://<route>/<param>?<query>`
|
||||
|
||||
### Claim Routes
|
||||
|
||||
- `timesafari://claim/:id`
|
||||
- Query params:
|
||||
- `view`: "details" | "certificate" | "raw"
|
||||
|
||||
- `timesafari://claim-cert/:id`
|
||||
- `timesafari://claim-add-raw/:id`
|
||||
- Query params:
|
||||
- `claim`: JSON string of claim data
|
||||
- `claimJwtId`: JWT ID for claim
|
||||
|
||||
### Contact Routes
|
||||
|
||||
- `timesafari://contact-edit/:did`
|
||||
- `timesafari://contact-import/:jwt`
|
||||
- Query params:
|
||||
- `contacts`: JSON array of contacts
|
||||
|
||||
### Project Routes
|
||||
|
||||
- `timesafari://project/:id`
|
||||
- Query params:
|
||||
- `view`: "details" | "edit"
|
||||
|
||||
### Invite Routes
|
||||
|
||||
- `timesafari://invite-one-accept/:jwt`
|
||||
- Query params:
|
||||
- `type`: "one" | "many"
|
||||
|
||||
### Gift Routes
|
||||
|
||||
- `timesafari://confirm-gift/:id`
|
||||
- Query params:
|
||||
- `action`: "confirm" | "details"
|
||||
|
||||
### Offer Routes
|
||||
|
||||
- `timesafari://offer-details/:id`
|
||||
- Query params:
|
||||
- `view`: "details"
|
||||
@@ -1,77 +0,0 @@
|
||||
# TimeSafari Docs
|
||||
|
||||
## Generating PDF from Markdown on OSx
|
||||
|
||||
This uses Pandoc and BasicTex (LaTeX) Installed through Homebrew.
|
||||
|
||||
### Set Up
|
||||
|
||||
```bash
|
||||
brew install pandoc
|
||||
|
||||
brew install basictex
|
||||
|
||||
# Setting up LaTex packages
|
||||
|
||||
# First update tlmgr
|
||||
sudo tlmgr update --self
|
||||
|
||||
# Then install LaTex packages
|
||||
sudo tlmgr install bbding
|
||||
sudo tlmgr install enumitem
|
||||
sudo tlmgr install environ
|
||||
sudo tlmgr install fancyhdr
|
||||
sudo tlmgr install framed
|
||||
sudo tlmgr install import
|
||||
sudo tlmgr install lastpage # Enables Page X of Y
|
||||
sudo tlmgr install mdframed
|
||||
sudo tlmgr install multirow
|
||||
sudo tlmgr install needspace
|
||||
sudo tlmgr install ntheorem
|
||||
sudo tlmgr install tabu
|
||||
sudo tlmgr install tcolorbox
|
||||
sudo tlmgr install textpos
|
||||
sudo tlmgr install titlesec
|
||||
sudo tlmgr install titling # Required for the fancy headers used
|
||||
sudo tlmgr install threeparttable
|
||||
sudo tlmgr install trimspaces
|
||||
sudo tlmgr install tocloft # Required for \tableofcontents generation
|
||||
sudo tlmgr install varwidth
|
||||
sudo tlmgr install wrapfig
|
||||
|
||||
# Install fonts
|
||||
sudo tlmgr install cmbright
|
||||
sudo tlmgr install collection-fontsrecommended # And set up fonts
|
||||
sudo tlmgr install fira
|
||||
sudo tlmgr install fontaxes
|
||||
sudo tlmgr install libertine # The main font the doc uses
|
||||
sudo tlmgr install opensans
|
||||
sudo tlmgr install sourceserifpro
|
||||
|
||||
```
|
||||
|
||||
#### References
|
||||
|
||||
The following guide was adapted to this project except that we install with Brew and have a few more packages.
|
||||
|
||||
Guide: <https://daniel.feldroy.com/posts/setting-up-latex-on-mac-os-x>
|
||||
|
||||
### Usage
|
||||
|
||||
Use the `pandoc` command to generate a PDF.
|
||||
|
||||
```bash
|
||||
pandoc usage-guide.md -o usage-guide.pdf
|
||||
```
|
||||
|
||||
And you can open the PDF with the `open` command.
|
||||
|
||||
```bash
|
||||
open usage-guide.pdf
|
||||
```
|
||||
|
||||
Or use this one-liner
|
||||
|
||||
```bash
|
||||
pandoc usage-guide.md -o usage-guide.pdf && open usage-guide.pdf
|
||||
```
|
||||
@@ -1,381 +0,0 @@
|
||||
# Worker-Only Database Implementation for Web Platform
|
||||
|
||||
## Overview
|
||||
|
||||
This implementation fixes the double migration issue in the TimeSafari web platform by implementing worker-only database access, similar to the Capacitor platform architecture.
|
||||
|
||||
## Problem Solved
|
||||
|
||||
**Before:** Web platform had dual database contexts:
|
||||
|
||||
- Worker thread: `registerSQLWorker.js` → `AbsurdSqlDatabaseService.initialize()` → migrations run
|
||||
- Main thread: `WebPlatformService.dbQuery()` → `databaseService.query()` → migrations run **AGAIN**
|
||||
|
||||
**After:** Single database context:
|
||||
|
||||
- Worker thread: Handles ALL database operations and initializes once
|
||||
- Main thread: Sends messages to worker, no direct database access
|
||||
|
||||
## Architecture Changes
|
||||
|
||||
### 1. Message-Based Communication
|
||||
|
||||
```typescript
|
||||
// Main Thread (WebPlatformService)
|
||||
await this.sendWorkerMessage<QueryResult>({
|
||||
type: "query",
|
||||
sql: "SELECT * FROM users",
|
||||
params: []
|
||||
});
|
||||
|
||||
// Worker Thread (registerSQLWorker.js)
|
||||
onmessage = async (event) => {
|
||||
const { id, type, sql, params } = event.data;
|
||||
if (type === "query") {
|
||||
const result = await databaseService.query(sql, params);
|
||||
postMessage({ id, type: "success", data: { result } });
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 2. Type-Safe Worker Messages
|
||||
|
||||
```typescript
|
||||
// src/interfaces/worker-messages.ts
|
||||
export interface QueryRequest extends BaseWorkerMessage {
|
||||
type: "query";
|
||||
sql: string;
|
||||
params?: unknown[];
|
||||
}
|
||||
|
||||
export type WorkerRequest =
|
||||
| QueryRequest
|
||||
| ExecRequest
|
||||
| GetOneRowRequest
|
||||
| InitRequest
|
||||
| PingRequest;
|
||||
```
|
||||
|
||||
### 3. Circular Dependency Resolution
|
||||
|
||||
#### 🔥 Critical Fix: Stack Overflow Prevention
|
||||
|
||||
**Problem**: Circular module dependency caused infinite recursion:
|
||||
|
||||
- `WebPlatformService` constructor → creates Worker
|
||||
- Worker loads `registerSQLWorker.js` → imports `databaseService`
|
||||
- Module resolution creates circular dependency → Stack Overflow
|
||||
|
||||
**Solution**: Lazy Loading in Worker
|
||||
|
||||
```javascript
|
||||
// Before (caused stack overflow)
|
||||
import databaseService from "./services/AbsurdSqlDatabaseService";
|
||||
|
||||
// After (fixed)
|
||||
let databaseService = null;
|
||||
|
||||
async function getDatabaseService() {
|
||||
if (!databaseService) {
|
||||
// Dynamic import prevents circular dependency
|
||||
const { default: service } = await import("./services/AbsurdSqlDatabaseService");
|
||||
databaseService = service;
|
||||
}
|
||||
return databaseService;
|
||||
}
|
||||
```
|
||||
|
||||
**Key Changes for Stack Overflow Fix:**
|
||||
|
||||
- ✅ Removed top-level import of database service
|
||||
- ✅ Added lazy loading with dynamic import
|
||||
- ✅ Updated all handlers to use `await getDatabaseService()`
|
||||
- ✅ Removed auto-initialization that triggered immediate loading
|
||||
- ✅ Database service only loads when first database operation occurs
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### 1. WebPlatformService Changes
|
||||
|
||||
- Removed direct database imports
|
||||
- Added worker message handling
|
||||
- Implemented timeout and error handling
|
||||
- All database methods now proxy to worker
|
||||
|
||||
### 2. Worker Thread Changes
|
||||
|
||||
- Added message-based operation handling
|
||||
- Implemented lazy loading for database service
|
||||
- Added proper error handling and response formatting
|
||||
- Fixed circular dependency with dynamic imports
|
||||
|
||||
### 3. Main Thread Changes
|
||||
|
||||
- Removed duplicate worker creation in `main.web.ts`
|
||||
- WebPlatformService now manages single worker instance
|
||||
- Added Safari compatibility with `initBackend()`
|
||||
|
||||
## Files Modified
|
||||
|
||||
1. **src/interfaces/worker-messages.ts** *(NEW)*
|
||||
- Type definitions for worker communication
|
||||
- Request and response message interfaces
|
||||
|
||||
2. **src/registerSQLWorker.js** *(MAJOR REWRITE)*
|
||||
- Message-based operation handling
|
||||
- **Fixed circular dependency with lazy loading**
|
||||
- Proper error handling and response formatting
|
||||
|
||||
3. **src/services/platforms/WebPlatformService.ts** *(MAJOR REWRITE)*
|
||||
- Worker-only database access
|
||||
- Message sending and response handling
|
||||
- Timeout and error management
|
||||
|
||||
4. **src/main.web.ts** *(SIMPLIFIED)*
|
||||
- Removed duplicate worker creation
|
||||
- Simplified initialization flow
|
||||
|
||||
5. **WORKER_ONLY_DATABASE_IMPLEMENTATION.md** *(NEW)*
|
||||
- Complete documentation of changes
|
||||
|
||||
## Benefits
|
||||
|
||||
### ✅ Fixes Double Migration Issue
|
||||
|
||||
- Database migrations now run only once in worker thread
|
||||
- No duplicate initialization between main thread and worker
|
||||
|
||||
### ✅ Prevents Stack Overflow
|
||||
|
||||
- Circular dependency resolved with lazy loading
|
||||
- Worker loads immediately without triggering database import
|
||||
- Database service loads on-demand when first operation occurs
|
||||
|
||||
### ✅ Improved Performance
|
||||
|
||||
- Single database connection
|
||||
- No redundant operations
|
||||
- Better resource utilization
|
||||
|
||||
### ✅ Better Error Handling
|
||||
|
||||
- Centralized error handling in worker
|
||||
- Type-safe message communication
|
||||
- Proper timeout handling
|
||||
|
||||
### ✅ Consistent Architecture
|
||||
|
||||
- Matches Capacitor platform pattern
|
||||
- Single-threaded database access
|
||||
- Clear separation of concerns
|
||||
|
||||
## Testing Verification
|
||||
|
||||
After implementation, you should see:
|
||||
|
||||
1. **Worker Loading**:
|
||||
|
||||
```text
|
||||
[SQLWorker] Worker loaded, ready to receive messages
|
||||
```
|
||||
|
||||
2. **Database Initialization** (only on first operation):
|
||||
|
||||
```text
|
||||
[SQLWorker] Starting database initialization...
|
||||
[SQLWorker] Database initialization completed successfully
|
||||
```
|
||||
|
||||
3. **No Stack Overflow**: Application starts without infinite recursion
|
||||
4. **Single Migration Run**: Database migrations execute only once
|
||||
5. **Functional Database**: All queries, inserts, and updates work correctly
|
||||
|
||||
## Migration from Previous Implementation
|
||||
|
||||
If upgrading from the dual-context implementation:
|
||||
|
||||
1. **Remove Direct Database Imports**: No more `import databaseService` in main thread
|
||||
2. **Update Database Calls**: Use platform service methods instead of direct database calls
|
||||
3. **Handle Async Operations**: All database operations are now async message-based
|
||||
4. **Error Handling**: Update error handling to work with worker responses
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- Worker thread isolates database operations
|
||||
- Message validation prevents malformed requests
|
||||
- Timeout handling prevents hanging operations
|
||||
- Type safety reduces runtime errors
|
||||
|
||||
## Performance Notes
|
||||
|
||||
- Initial worker creation has minimal overhead
|
||||
- Database operations have message passing overhead (negligible)
|
||||
- Single database connection is more efficient than dual connections
|
||||
- Lazy loading reduces startup time
|
||||
|
||||
## Migration Execution Flow
|
||||
|
||||
### Before (Problematic)
|
||||
|
||||
```chart
|
||||
┌────────────── ───┐ ┌─────────────────┐
|
||||
│ Main Thread │ │ Worker Thread │
|
||||
│ │ │ │
|
||||
│ WebPlatformService│ │registerSQLWorker│
|
||||
│ ↓ │ │ ↓ │
|
||||
│ databaseService │ │ databaseService │
|
||||
│ (Instance A) │ │ (Instance B) │
|
||||
│ ↓ │ │ ↓ │
|
||||
│ [Run Migrations] │ │[Run Migrations] │ ← DUPLICATE!
|
||||
└─────────────── ──┘ └─────────────────┘
|
||||
```
|
||||
|
||||
### After (Fixed)
|
||||
|
||||
```text
|
||||
┌─────────────── ──┐ ┌─────────────────┐
|
||||
│ Main Thread │ │ Worker Thread │
|
||||
│ │ │ │
|
||||
│ WebPlatformService │───→│registerSQLWorker│
|
||||
│ │ │ ↓ │
|
||||
│ [Send Messages] │ │ databaseService │
|
||||
│ │ │(Single Instance)│
|
||||
│ │ │ ↓ │
|
||||
│ │ │[Run Migrations] │ ← ONCE ONLY!
|
||||
└─────────────── ──┘ └─────────────────┘
|
||||
```
|
||||
|
||||
## New Security Considerations
|
||||
|
||||
### 1. **Message Validation**
|
||||
|
||||
- All worker messages validated for required fields
|
||||
- Unknown message types rejected with errors
|
||||
- Proper error responses prevent information leakage
|
||||
|
||||
### 2. **Timeout Protection**
|
||||
|
||||
- 30-second timeout prevents hung operations
|
||||
- Automatic cleanup of pending messages
|
||||
- Worker health checks via ping/pong
|
||||
|
||||
### 3. **Error Sanitization**
|
||||
|
||||
- Error messages logged but not exposed raw to main thread
|
||||
- Stack traces included only in development
|
||||
- Graceful handling of worker failures
|
||||
|
||||
## Testing Considerations
|
||||
|
||||
### 1. **Unit Tests Needed**
|
||||
|
||||
- Worker message handling
|
||||
- WebPlatformService worker communication
|
||||
- Error handling and timeouts
|
||||
- Migration execution (should run once only)
|
||||
|
||||
### 2. **Integration Tests**
|
||||
|
||||
- End-to-end database operations
|
||||
- Worker lifecycle management
|
||||
- Cross-browser compatibility (especially Safari)
|
||||
|
||||
### 3. **Performance Tests**
|
||||
|
||||
- Message passing overhead
|
||||
- Database operation throughput
|
||||
- Memory usage with worker communication
|
||||
|
||||
## Browser Compatibility
|
||||
|
||||
### 1. **Modern Browsers**
|
||||
|
||||
- Chrome/Edge: Full SharedArrayBuffer support
|
||||
- Firefox: Full SharedArrayBuffer support (with headers)
|
||||
- Safari: Uses IndexedDB fallback via `initBackend()`
|
||||
|
||||
### 2. **Required Headers**
|
||||
|
||||
```text
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
||||
```
|
||||
|
||||
## Deployment Notes
|
||||
|
||||
### 1. **Development**
|
||||
|
||||
- Enhanced logging shows worker message flow
|
||||
- Clear separation between worker and main thread logs
|
||||
- Easy debugging via browser DevTools
|
||||
|
||||
### 2. **Production**
|
||||
|
||||
- Reduced logging overhead
|
||||
- Optimized message passing
|
||||
- Proper error reporting without sensitive data
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### 1. **Potential Optimizations**
|
||||
|
||||
- Message batching for bulk operations
|
||||
- Connection pooling simulation
|
||||
- Persistent worker state management
|
||||
|
||||
### 2. **Additional Features**
|
||||
|
||||
- Database backup/restore via worker
|
||||
- Schema introspection commands
|
||||
- Performance monitoring hooks
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If issues arise, rollback involves:
|
||||
|
||||
1. Restore original `WebPlatformService.ts`
|
||||
2. Restore original `registerSQLWorker.js`
|
||||
3. Restore original `main.web.ts`
|
||||
4. Remove `worker-messages.ts` interface
|
||||
|
||||
## Commit Messages
|
||||
|
||||
```bash
|
||||
git add src/interfaces/worker-messages.ts
|
||||
git commit -m "Add worker message interface for type-safe database communication
|
||||
|
||||
- Define TypeScript interfaces for worker request/response messages
|
||||
- Include query, exec, getOneRow, init, and ping message types
|
||||
- Provide type safety for web platform worker messaging"
|
||||
|
||||
git add src/registerSQLWorker.js
|
||||
git commit -m "Implement message-based worker for single-point database access
|
||||
|
||||
- Replace simple auto-init with comprehensive message handler
|
||||
- Add support for query, exec, getOneRow, init, ping operations
|
||||
- Implement proper error handling and response management
|
||||
- Ensure single database initialization point to prevent double migrations"
|
||||
|
||||
git add src/services/platforms/WebPlatformService.ts
|
||||
git commit -m "Migrate WebPlatformService to worker-only database access
|
||||
|
||||
- Remove direct databaseService import to prevent dual context issue
|
||||
- Implement worker-based messaging for all database operations
|
||||
- Add worker lifecycle management with initialization tracking
|
||||
- Include message timeout and error handling for reliability
|
||||
- Add Safari compatibility with initBackend call"
|
||||
|
||||
git add src/main.web.ts
|
||||
git commit -m "Remove duplicate worker creation from main.web.ts
|
||||
|
||||
- Worker initialization now handled by WebPlatformService
|
||||
- Prevents duplicate worker creation and database contexts
|
||||
- Simplifies main thread initialization"
|
||||
|
||||
git add WORKER_ONLY_DATABASE_IMPLEMENTATION.md
|
||||
git commit -m "Document worker-only database implementation
|
||||
|
||||
- Comprehensive documentation of architecture changes
|
||||
- Explain problem solved and benefits achieved
|
||||
- Include security considerations and testing requirements"
|
||||
```
|
||||
@@ -1,125 +0,0 @@
|
||||
# Architecture Decisions
|
||||
|
||||
This document records key architectural decisions made during the development of TimeSafari.
|
||||
|
||||
## Platform Service Architecture: Mixins over Composables
|
||||
|
||||
**Date:** July 2, 2025
|
||||
**Status:** Accepted
|
||||
**Context:** Need for consistent platform service access across Vue components
|
||||
|
||||
### Decision
|
||||
|
||||
**Use Vue mixins for platform service access instead of Vue 3 Composition API composables.**
|
||||
|
||||
### Rationale
|
||||
|
||||
#### Why Mixins Were Chosen
|
||||
|
||||
1. **Existing Architecture Consistency**
|
||||
- The entire codebase uses class-based components with `vue-facing-decorator`
|
||||
- All components follow the established pattern of extending Vue class
|
||||
- Mixins integrate seamlessly with the existing architecture
|
||||
|
||||
2. **Performance Benefits**
|
||||
- **Caching Layer**: `PlatformServiceMixin` provides smart TTL-based caching
|
||||
- **Ultra-Concise Methods**: Short methods like `$db()`, `$exec()`, `$one()` reduce boilerplate
|
||||
- **Settings Shortcuts**: `$saveSettings()`, `$saveMySettings()` eliminate 90% of update boilerplate
|
||||
- **Memory Management**: WeakMap-based caching prevents memory leaks
|
||||
|
||||
3. **Developer Experience**
|
||||
- **Familiar Pattern**: Mixins are well-understood by the team
|
||||
- **Type Safety**: Full TypeScript support with proper interfaces
|
||||
- **Error Handling**: Centralized error handling across components
|
||||
- **Code Reduction**: Reduces database code by up to 80%
|
||||
|
||||
4. **Production Readiness**
|
||||
- **Mature Implementation**: `PlatformServiceMixin` is actively used and tested
|
||||
- **Comprehensive Features**: Includes transaction support, cache management, settings shortcuts
|
||||
- **Security**: Proper input validation and error handling
|
||||
|
||||
#### Why Composables Were Rejected
|
||||
|
||||
1. **Architecture Mismatch**
|
||||
- Would require rewriting all components to use Composition API
|
||||
- Breaks consistency with existing class-based component pattern
|
||||
- Requires significant refactoring effort
|
||||
|
||||
2. **Limited Features**
|
||||
- Basic platform service access without caching
|
||||
- No settings management shortcuts
|
||||
- No ultra-concise database methods
|
||||
- Would require additional development to match mixin capabilities
|
||||
|
||||
3. **Performance Considerations**
|
||||
- No built-in caching layer
|
||||
- Would require manual implementation of performance optimizations
|
||||
- More verbose for common operations
|
||||
|
||||
### Implementation
|
||||
|
||||
#### Current Usage
|
||||
|
||||
```typescript
|
||||
// Component implementation
|
||||
@Component({
|
||||
mixins: [PlatformServiceMixin],
|
||||
})
|
||||
export default class HomeView extends Vue {
|
||||
async mounted() {
|
||||
// Ultra-concise cached settings loading
|
||||
const settings = await this.$settings({
|
||||
apiServer: "",
|
||||
activeDid: "",
|
||||
isRegistered: false,
|
||||
});
|
||||
|
||||
// Cached contacts loading
|
||||
this.allContacts = await this.$contacts();
|
||||
|
||||
// Settings update with automatic cache invalidation
|
||||
await this.$saveMySettings({ isRegistered: true });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
|
||||
- **Cached Database Operations**: `$contacts()`, `$settings()`, `$accountSettings()`
|
||||
- **Settings Shortcuts**: `$saveSettings()`, `$saveMySettings()`, `$saveUserSettings()`
|
||||
- **Ultra-Concise Methods**: `$db()`, `$exec()`, `$one()`, `$query()`, `$first()`
|
||||
- **Cache Management**: `$refreshSettings()`, `$clearAllCaches()`
|
||||
- **Transaction Support**: `$withTransaction()` with automatic rollback
|
||||
|
||||
### Consequences
|
||||
|
||||
#### Positive
|
||||
|
||||
- **Consistent Architecture**: All components follow the same pattern
|
||||
- **High Performance**: Smart caching reduces database calls by 80%+
|
||||
- **Developer Productivity**: Ultra-concise methods reduce boilerplate by 90%
|
||||
- **Type Safety**: Full TypeScript support with proper interfaces
|
||||
- **Memory Safety**: WeakMap-based caching prevents memory leaks
|
||||
|
||||
#### Negative
|
||||
|
||||
- **Vue 2 Pattern**: Uses older mixin pattern instead of modern Composition API
|
||||
- **Tight Coupling**: Components are coupled to the mixin implementation
|
||||
- **Testing Complexity**: Mixins can make unit testing more complex
|
||||
|
||||
### Future Considerations
|
||||
|
||||
1. **Migration Path**: If Vue 4 or future versions deprecate mixins, we may need to migrate
|
||||
2. **Performance Monitoring**: Continue monitoring caching performance and adjust TTL values
|
||||
3. **Feature Expansion**: Add new ultra-concise methods as needed
|
||||
4. **Testing Strategy**: Develop comprehensive testing strategies for mixin-based components
|
||||
|
||||
### Related Documentation
|
||||
|
||||
- [PlatformServiceMixin Implementation](../src/utils/PlatformServiceMixin.ts)
|
||||
- [TimeSafari Cross-Platform Architecture Guide](./build-modernization-context.md)
|
||||
- [Database Migration Guide](./database-migration-guide.md)
|
||||
|
||||
---
|
||||
|
||||
*This decision was made based on the current codebase architecture and team expertise. The mixin approach provides the best balance of performance, developer experience, and architectural consistency for the TimeSafari application.*
|
||||
@@ -1,215 +0,0 @@
|
||||
# TimeSafari Asset Configuration Migration Plan
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: 2025-08-14
|
||||
**Status**: 🎯 **IMPLEMENTATION** - Ready for Execution
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines the migration from the current mixed asset management
|
||||
system to a standardized, single-source asset configuration approach using
|
||||
`capacitor-assets` as the standard generator.
|
||||
|
||||
## Current State Analysis
|
||||
|
||||
### Asset Sources (Duplicated)
|
||||
|
||||
- **`assets/` directory**: Contains `icon.png`, `splash.png`, `splash_dark.png`
|
||||
- **`resources/` directory**: Contains identical files in platform-specific subdirectories
|
||||
- **Result**: Duplicate storage, confusion about source of truth
|
||||
|
||||
### Asset Generation (Manual)
|
||||
|
||||
- **Custom scripts**: `generate-icons.sh`, `generate-ios-assets.sh`, `generate-android-icons.sh`
|
||||
- **Bypass capacitor-assets**: Manual ImageMagick-based generation
|
||||
- **Inconsistent outputs**: Different generation methods for each platform
|
||||
|
||||
### Configuration (Scattered)
|
||||
|
||||
- **`capacitor-assets.config.json`**: Basic configuration at root
|
||||
- **Platform-specific configs**: Mixed in various build scripts
|
||||
- **No validation**: No schema or consistency checks
|
||||
|
||||
## Target State
|
||||
|
||||
### Single Source of Truth
|
||||
|
||||
- **`resources/` directory**: Capacitor default location for source assets
|
||||
- **Eliminate duplication**: Remove `assets/` directory after migration
|
||||
- **Standardized paths**: All tools read from `resources/`
|
||||
|
||||
### Standardized Generation
|
||||
|
||||
- **`capacitor-assets`**: Single tool for all platform asset generation
|
||||
- **Build-time generation**: Assets generated during build, not committed
|
||||
- **Deterministic outputs**: Same inputs → same outputs every time
|
||||
|
||||
### Centralized Configuration
|
||||
|
||||
- **`config/assets/`**: All asset-related configuration files
|
||||
- **Schema validation**: JSON schema for configuration validation
|
||||
- **CI safeguards**: Automated validation and compliance checks
|
||||
|
||||
## Migration Steps
|
||||
|
||||
### Phase 1: Foundation Setup ✅
|
||||
|
||||
- [x] Create `config/assets/` directory structure
|
||||
- [x] Create asset configuration schema (`schema.json`)
|
||||
- [x] Create enhanced capacitor-assets configuration
|
||||
- [x] Convert `capacitor.config.json` to `capacitor.config.ts`
|
||||
- [x] Pin Node.js version (`.nvmrc`, `.node-version`)
|
||||
- [x] Create dev-time asset configuration generator
|
||||
- [x] Create asset configuration validator
|
||||
- [x] Add npm scripts for asset management
|
||||
- [x] Update `.gitignore` with proper asset exclusions
|
||||
- [x] Create CI workflow for asset validation
|
||||
|
||||
### Phase 2: Validation & Testing
|
||||
|
||||
- [ ] Run `npm run assets:config` to generate new configuration
|
||||
- [ ] Run `npm run assets:validate` to verify configuration
|
||||
- [ ] Test `npm run build:native` workflow
|
||||
- [ ] Verify CI workflow passes all checks
|
||||
- [ ] Confirm no platform assets are committed to VCS
|
||||
|
||||
### Phase 3: Cleanup & Removal
|
||||
|
||||
- [ ] Remove `assets/` directory (after validation)
|
||||
- [ ] Remove manual asset generation scripts
|
||||
- [ ] Remove asset checking scripts
|
||||
- [ ] Update documentation references
|
||||
- [ ] Final validation of clean state
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
resources/ # Image sources ONLY
|
||||
icon.png
|
||||
splash.png
|
||||
splash_dark.png
|
||||
|
||||
config/assets/ # Versioned config & schema
|
||||
capacitor-assets.config.json
|
||||
schema.json
|
||||
|
||||
scripts/
|
||||
assets-config.js # Dev-time config generator
|
||||
assets-validator.js # Schema validator
|
||||
```
|
||||
|
||||
### Configuration Schema
|
||||
|
||||
The schema enforces:
|
||||
|
||||
- Source files must be in `resources/` directory
|
||||
- Required fields for icon and splash sections
|
||||
- Android adaptive icon support (foreground/background/monochrome)
|
||||
- iOS LaunchScreen preferences
|
||||
- Target directory validation
|
||||
|
||||
### CI Safeguards
|
||||
|
||||
- **Schema validation**: Configuration must comply with schema
|
||||
- **Source file validation**: All referenced files must exist
|
||||
- **Platform asset denial**: Reject commits with generated assets
|
||||
- **Clean tree enforcement**: Build must not modify committed configs
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Local Validation
|
||||
|
||||
```bash
|
||||
# Generate configuration
|
||||
npm run assets:config
|
||||
|
||||
# Validate configuration
|
||||
npm run assets:validate
|
||||
|
||||
# Test build workflow
|
||||
npm run build:native
|
||||
|
||||
# Clean generated assets
|
||||
npm run assets:clean
|
||||
```
|
||||
|
||||
### CI Validation
|
||||
|
||||
- **Asset validation workflow**: Runs on asset-related changes
|
||||
- **Schema compliance**: Ensures configuration follows schema
|
||||
- **Source file existence**: Verifies all referenced files exist
|
||||
- **Platform asset detection**: Prevents committed generated assets
|
||||
- **Build tree verification**: Ensures clean tree after build
|
||||
|
||||
## Risk Mitigation
|
||||
|
||||
### Data Loss Prevention
|
||||
|
||||
- **Backup branch**: Create backup before removing `assets/`
|
||||
- **Validation checks**: Multiple validation steps before removal
|
||||
- **Gradual migration**: Phase-by-phase approach with rollback capability
|
||||
|
||||
### Build Continuity
|
||||
|
||||
- **Per-platform scripts unchanged**: All existing build orchestration preserved
|
||||
- **Standard toolchain**: Uses capacitor-assets, not custom scripts
|
||||
- **Fallback support**: Manual scripts remain until migration complete
|
||||
|
||||
### Configuration Consistency
|
||||
|
||||
- **Schema enforcement**: JSON schema prevents invalid configurations
|
||||
- **CI validation**: Automated checks catch configuration issues
|
||||
- **Documentation updates**: Clear guidance for future changes
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### Technical Requirements
|
||||
|
||||
- [ ] Single source of truth in `resources/` directory
|
||||
- [ ] All platform assets generated via `capacitor-assets`
|
||||
- [ ] No manual asset generation scripts
|
||||
- [ ] Configuration validation passes all checks
|
||||
- [ ] CI workflow enforces asset policies
|
||||
|
||||
### Quality Metrics
|
||||
|
||||
- [ ] Zero duplicate asset sources
|
||||
- [ ] 100% configuration schema compliance
|
||||
- [ ] No platform assets committed to VCS
|
||||
- [ ] Clean build tree after asset generation
|
||||
- [ ] Deterministic asset outputs
|
||||
|
||||
### User Experience
|
||||
|
||||
- [ ] Clear asset management documentation
|
||||
- [ ] Simple development commands
|
||||
- [ ] Consistent asset generation across platforms
|
||||
- [ ] Reduced confusion about asset sources
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Execute Phase 2**: Run validation and testing steps
|
||||
2. **Verify CI workflow**: Ensure all checks pass
|
||||
3. **Execute Phase 3**: Remove duplicate assets and scripts
|
||||
4. **Update documentation**: Finalize README and BUILDING.md
|
||||
5. **Team training**: Ensure all developers understand new workflow
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If issues arise during migration:
|
||||
|
||||
1. **Restore backup branch**: `git checkout backup-before-asset-migration`
|
||||
2. **Revert configuration changes**: Remove new config files
|
||||
3. **Restore manual scripts**: Re-enable previous asset generation
|
||||
4. **Investigate issues**: Identify and resolve root causes
|
||||
5. **Plan revised migration**: Adjust approach based on lessons learned
|
||||
|
||||
---
|
||||
|
||||
**Status**: Ready for Phase 2 execution
|
||||
**Priority**: High
|
||||
**Estimated Effort**: 2-3 hours
|
||||
**Dependencies**: CI workflow validation
|
||||
**Stakeholders**: Development team
|
||||
@@ -1,59 +0,0 @@
|
||||
# TimeSafari Build Modernization Context
|
||||
|
||||
**Author:** Matthew Raymer
|
||||
|
||||
## Motivation
|
||||
|
||||
- Eliminate manual hacks and post-build scripts for Electron builds
|
||||
- Ensure maintainability, reproducibility, and security of build outputs
|
||||
- Unify build, test, and deployment scripts for developer experience and CI/CD
|
||||
|
||||
## Key Technical Decisions
|
||||
|
||||
- **Vite is the single source of truth for build output**
|
||||
- All Electron build output (main process, preload, renderer HTML/CSS/JS) is managed by `vite.config.electron.mts`
|
||||
- **CSS injection for Electron is handled by a Vite plugin**
|
||||
- No more manual HTML/CSS edits or post-build scripts
|
||||
- **Build scripts are unified and robust**
|
||||
- Use `./scripts/build-electron.sh` for all Electron builds
|
||||
- No more `fix-inject-css.js` or similar hacks
|
||||
- **Output structure is deterministic and ASAR-friendly**
|
||||
- Main process: `dist-electron/main.js`
|
||||
- Preload: `dist-electron/preload.js`
|
||||
- Renderer assets: `dist-electron/www/` (HTML, CSS, JS)
|
||||
|
||||
## Security & Maintenance Checklist
|
||||
|
||||
- [x] All scripts and configs are committed and documented
|
||||
- [x] No manual file hacks remain
|
||||
- [x] All build output is deterministic and reproducible
|
||||
- [x] No sensitive data is exposed in the build process
|
||||
- [x] Documentation (`BUILDING.md`) is up to date
|
||||
|
||||
## How to Build Electron
|
||||
|
||||
1. Run:
|
||||
|
||||
```bash
|
||||
./scripts/build-electron.sh
|
||||
```
|
||||
|
||||
2. Output will be in `dist-electron/`:
|
||||
- `main.js`, `preload.js` in root
|
||||
- `www/` contains all renderer assets
|
||||
3. No manual post-processing is required
|
||||
|
||||
## Customization
|
||||
|
||||
- **Vite config:** All build output and asset handling is controlled in `vite.config.electron.mts`
|
||||
- **CSS/HTML injection:** Use Vite plugins (see `electron-css-injection` in the config) for further customization
|
||||
- **Build scripts:** All orchestration is in `scripts/` and documented in `BUILDING.md`
|
||||
|
||||
## For Future Developers
|
||||
|
||||
- Always use Vite plugins/config for build output changes
|
||||
- Never manually edit built files or inject assets post-build
|
||||
- Keep documentation and scripts in sync with the build process
|
||||
|
||||
---
|
||||
This file documents the context and rationale for the build modernization and should be included in the repository for onboarding and future reference.
|
||||
@@ -1,180 +0,0 @@
|
||||
# Circular Dependency Analysis
|
||||
|
||||
## Overview
|
||||
|
||||
This document analyzes the current state of circular dependencies in the TimeSafari codebase, particularly focusing on the migration from Dexie to SQLite and the PlatformServiceMixin implementation.
|
||||
|
||||
## Current Circular Dependency Status
|
||||
|
||||
### ✅ **EXCELLENT NEWS: All Circular Dependencies RESOLVED**
|
||||
|
||||
The codebase currently has **no active circular dependencies** that are causing runtime or compilation errors. All circular dependency issues have been successfully resolved.
|
||||
|
||||
### 🔍 **Resolved Dependency Patterns**
|
||||
|
||||
#### 1. **Logger → PlatformServiceFactory → Logger** (RESOLVED)
|
||||
|
||||
- **Status**: ✅ **RESOLVED**
|
||||
- **Previous Issue**: Logger imported `logToDb` from databaseUtil, which imported logger
|
||||
- **Solution**: Logger now uses direct database access via PlatformServiceFactory
|
||||
- **Implementation**: Self-contained `logToDatabase()` function in logger.ts
|
||||
|
||||
#### 2. **PlatformServiceMixin → databaseUtil → logger → PlatformServiceMixin** (RESOLVED)
|
||||
|
||||
- **Status**: ✅ **RESOLVED**
|
||||
- **Previous Issue**: PlatformServiceMixin imported `memoryLogs` from databaseUtil
|
||||
- **Solution**: Created self-contained `_memoryLogs` array in PlatformServiceMixin
|
||||
- **Implementation**: Self-contained memory logs implementation
|
||||
|
||||
#### 3. **databaseUtil → logger → PlatformServiceFactory → databaseUtil** (RESOLVED)
|
||||
|
||||
- **Status**: ✅ **RESOLVED**
|
||||
- **Previous Issue**: databaseUtil imported logger, which could create loops
|
||||
- **Solution**: Logger is now self-contained and doesn't import from databaseUtil
|
||||
|
||||
#### 4. **Utility Files → databaseUtil → PlatformServiceMixin** (RESOLVED)
|
||||
|
||||
- **Status**: ✅ **RESOLVED**
|
||||
- **Previous Issue**: `src/libs/util.ts` and `src/services/deepLinks.ts` imported from databaseUtil
|
||||
- **Solution**: Replaced with self-contained implementations and PlatformServiceFactory usage
|
||||
- **Implementation**:
|
||||
- Self-contained `parseJsonField()` and `mapQueryResultToValues()` functions
|
||||
- Direct PlatformServiceFactory usage for database operations
|
||||
- Console logging instead of databaseUtil logging functions
|
||||
|
||||
## Detailed Dependency Analysis
|
||||
|
||||
### ✅ **All Critical Dependencies Resolved**
|
||||
|
||||
#### PlatformServiceMixin Independence
|
||||
|
||||
- **Status**: ✅ **COMPLETE**
|
||||
- **Achievement**: PlatformServiceMixin has no external dependencies on databaseUtil
|
||||
- **Implementation**: Self-contained memory logs and utility functions
|
||||
- **Impact**: Enables complete migration of databaseUtil functions to PlatformServiceMixin
|
||||
|
||||
#### Logger Independence
|
||||
|
||||
- **Status**: ✅ **COMPLETE**
|
||||
- **Achievement**: Logger is completely self-contained
|
||||
- **Implementation**: Direct database access via PlatformServiceFactory
|
||||
- **Impact**: Eliminates all circular dependency risks
|
||||
|
||||
#### Utility Files Independence
|
||||
|
||||
- **Status**: ✅ **COMPLETE**
|
||||
- **Achievement**: All utility files no longer depend on databaseUtil
|
||||
- **Implementation**: Self-contained functions and direct platform service access
|
||||
- **Impact**: Enables complete databaseUtil migration
|
||||
|
||||
### 🎯 **Migration Readiness Status**
|
||||
|
||||
#### Files Ready for Migration (52 files)
|
||||
|
||||
1. **Components** (15 files):
|
||||
- `PhotoDialog.vue`
|
||||
- `FeedFilters.vue`
|
||||
- `UserNameDialog.vue`
|
||||
- `ImageMethodDialog.vue`
|
||||
- `OfferDialog.vue`
|
||||
- `OnboardingDialog.vue`
|
||||
- `PushNotificationPermission.vue`
|
||||
- `GiftedPrompts.vue`
|
||||
- `GiftedDialog.vue`
|
||||
- `World/components/objects/landmarks.js`
|
||||
- And 5 more...
|
||||
|
||||
2. **Views** (30+ files):
|
||||
- `IdentitySwitcherView.vue`
|
||||
- `ContactEditView.vue`
|
||||
- `ContactGiftingView.vue`
|
||||
- `ImportAccountView.vue`
|
||||
- `OnboardMeetingMembersView.vue`
|
||||
- `RecentOffersToUserProjectsView.vue`
|
||||
- `ClaimCertificateView.vue`
|
||||
- `NewActivityView.vue`
|
||||
- `HelpView.vue`
|
||||
- `NewEditProjectView.vue`
|
||||
- And 20+ more...
|
||||
|
||||
3. **Services** (5 files):
|
||||
- `deepLinks.ts` ✅ **MIGRATED**
|
||||
- `endorserServer.ts`
|
||||
- `libs/util.ts` ✅ **MIGRATED**
|
||||
- `test/index.ts`
|
||||
|
||||
### 🟢 **Healthy Dependencies**
|
||||
|
||||
#### Logger Usage (80+ files)
|
||||
|
||||
- **Status**: ✅ **HEALTHY**
|
||||
- **Pattern**: All files import logger from `@/utils/logger`
|
||||
- **Impact**: No circular dependencies, logger is self-contained
|
||||
- **Benefit**: Centralized logging with database integration
|
||||
|
||||
## Resolution Strategy - COMPLETED
|
||||
|
||||
### ✅ **Phase 1: Complete PlatformServiceMixin Independence (COMPLETE)**
|
||||
|
||||
1. **Removed memoryLogs import** from PlatformServiceMixin ✅
|
||||
2. **Created self-contained memoryLogs** implementation ✅
|
||||
3. **Added missing utility methods** to PlatformServiceMixin ✅
|
||||
|
||||
### ✅ **Phase 2: Utility Files Migration (COMPLETE)**
|
||||
|
||||
1. **Migrated deepLinks.ts** - Replaced databaseUtil logging with console logging ✅
|
||||
2. **Migrated util.ts** - Replaced databaseUtil functions with self-contained implementations ✅
|
||||
3. **Updated all PlatformServiceFactory calls** to use async pattern ✅
|
||||
|
||||
### 🎯 **Phase 3: File-by-File Migration (READY TO START)**
|
||||
|
||||
1. **High-usage files first** (views, core components)
|
||||
2. **Replace databaseUtil imports** with PlatformServiceMixin
|
||||
3. **Update function calls** to use mixin methods
|
||||
|
||||
### 🎯 **Phase 4: Cleanup (FUTURE)**
|
||||
|
||||
1. **Remove unused databaseUtil functions**
|
||||
2. **Update TypeScript interfaces**
|
||||
3. **Remove databaseUtil imports** from all files
|
||||
|
||||
## Current Status Summary
|
||||
|
||||
### ✅ **Resolved Issues**
|
||||
|
||||
1. **Logger circular dependency** - Fixed with self-contained implementation
|
||||
2. **PlatformServiceMixin circular dependency** - Fixed with self-contained memoryLogs
|
||||
3. **Utility files circular dependency** - Fixed with self-contained implementations
|
||||
4. **TypeScript compilation** - No circular dependency errors
|
||||
5. **Runtime stability** - No circular dependency crashes
|
||||
|
||||
### 🎯 **Ready for Next Phase**
|
||||
|
||||
1. **52 files** ready for databaseUtil migration
|
||||
2. **PlatformServiceMixin** fully independent and functional
|
||||
3. **Clear migration path** - Well-defined targets and strategy
|
||||
|
||||
## Benefits of Current State
|
||||
|
||||
### ✅ **Achieved**
|
||||
|
||||
1. **No runtime circular dependencies** - Application runs without crashes
|
||||
2. **Self-contained logger** - No more logger/databaseUtil loops
|
||||
3. **PlatformServiceMixin ready** - All methods implemented and independent
|
||||
4. **Utility files independent** - No more databaseUtil dependencies
|
||||
5. **Clear migration path** - Well-defined targets and strategy
|
||||
|
||||
### 🎯 **Expected After Migration**
|
||||
|
||||
1. **Complete databaseUtil migration** - Single source of truth
|
||||
2. **Eliminated circular dependencies** - Clean architecture
|
||||
3. **Improved performance** - Caching and optimization
|
||||
4. **Better maintainability** - Centralized database operations
|
||||
|
||||
---
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Created**: 2025-07-05
|
||||
**Status**: ✅ **COMPLETE - All Circular Dependencies Resolved**
|
||||
**Last Updated**: 2025-01-06
|
||||
**Note**: PlatformServiceMixin circular dependency completely resolved. Ready for Phase 2: File-by-File Migration
|
||||
@@ -1,328 +0,0 @@
|
||||
# Component Communication Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This guide establishes our preferred patterns for component communication in Vue.js applications, with a focus on maintainability, type safety, and developer experience.
|
||||
|
||||
## Core Principle: Function Props Over $emit
|
||||
|
||||
**Preference**: Use function props for business logic and data operations, reserve $emit for DOM-like events.
|
||||
|
||||
### Why Function Props?
|
||||
|
||||
1. **Better TypeScript Support**: Full type checking of parameters and return values
|
||||
2. **Superior IDE Navigation**: Ctrl+click takes you directly to implementation
|
||||
3. **Explicit Contracts**: Clear declaration of what functions a component needs
|
||||
4. **Easier Testing**: Simple to mock and test in isolation
|
||||
5. **Flexibility**: Can pass any function, not just event handlers
|
||||
|
||||
### When to Use $emit
|
||||
|
||||
1. **DOM-like Events**: `@click`, `@input`, `@submit`, `@change`
|
||||
2. **Lifecycle Events**: `@mounted`, `@before-unmount`, `@updated`
|
||||
3. **Form Validation**: `@validation-error`, `@validation-success`
|
||||
4. **Event Bubbling**: When events need to bubble through multiple components
|
||||
5. **Vue DevTools Integration**: When you want events visible in DevTools timeline
|
||||
|
||||
## Implementation Patterns
|
||||
|
||||
### Function Props Pattern
|
||||
|
||||
```typescript
|
||||
// Child Component
|
||||
@Component({
|
||||
name: "MyComponent"
|
||||
})
|
||||
export default class MyComponent extends Vue {
|
||||
@Prop({ required: true }) onSave!: (data: SaveData) => Promise<void>;
|
||||
@Prop({ required: true }) onCancel!: () => void;
|
||||
@Prop({ required: false }) onValidate?: (data: FormData) => boolean;
|
||||
|
||||
async handleSave() {
|
||||
const data = this.collectFormData();
|
||||
await this.onSave(data);
|
||||
}
|
||||
|
||||
handleCancel() {
|
||||
this.onCancel();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```vue
|
||||
<!-- Parent Template -->
|
||||
<MyComponent
|
||||
:on-save="handleSave"
|
||||
:on-cancel="handleCancel"
|
||||
:on-validate="validateForm"
|
||||
/>
|
||||
```
|
||||
|
||||
### $emit Pattern (for DOM-like events)
|
||||
|
||||
```typescript
|
||||
// Child Component
|
||||
@Component({
|
||||
name: "FormComponent"
|
||||
})
|
||||
export default class FormComponent extends Vue {
|
||||
@Emit("submit")
|
||||
handleSubmit() {
|
||||
return this.formData;
|
||||
}
|
||||
|
||||
@Emit("input")
|
||||
handleInput(value: string) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```vue
|
||||
<!-- Parent Template -->
|
||||
<FormComponent
|
||||
@submit="handleFormSubmit"
|
||||
@input="handleInputChange"
|
||||
/>
|
||||
```
|
||||
|
||||
## Automatic Code Generation Guidelines
|
||||
|
||||
### Component Template Generation
|
||||
|
||||
When generating component templates, follow these patterns:
|
||||
|
||||
#### Function Props Template
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="component-name">
|
||||
<!-- Component content -->
|
||||
<button @click="handleAction">
|
||||
{{ buttonText }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
||||
|
||||
@Component({
|
||||
name: "ComponentName"
|
||||
})
|
||||
export default class ComponentName extends Vue {
|
||||
@Prop({ required: true }) onAction!: () => void;
|
||||
@Prop({ required: true }) buttonText!: string;
|
||||
@Prop({ required: false }) disabled?: boolean;
|
||||
|
||||
handleAction() {
|
||||
if (!this.disabled) {
|
||||
this.onAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
#### $emit Template (for DOM events)
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="component-name">
|
||||
<!-- Component content -->
|
||||
<button @click="handleClick">
|
||||
{{ buttonText }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
|
||||
|
||||
@Component({
|
||||
name: "ComponentName"
|
||||
})
|
||||
export default class ComponentName extends Vue {
|
||||
@Prop({ required: true }) buttonText!: string;
|
||||
@Prop({ required: false }) disabled?: boolean;
|
||||
|
||||
@Emit("click")
|
||||
handleClick() {
|
||||
return { disabled: this.disabled };
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### Code Generation Rules
|
||||
|
||||
#### 1. Function Props for Business Logic
|
||||
|
||||
- **Data operations**: Save, delete, update, validate
|
||||
- **Navigation**: Route changes, modal opening/closing
|
||||
- **State management**: Store actions, state updates
|
||||
- **API calls**: Data fetching, form submissions
|
||||
|
||||
#### 2. $emit for User Interactions
|
||||
|
||||
- **Click events**: Button clicks, link navigation
|
||||
- **Form events**: Input changes, form submissions
|
||||
- **Lifecycle events**: Component mounting, unmounting
|
||||
- **UI events**: Focus, blur, scroll, resize
|
||||
|
||||
#### 3. Naming Conventions
|
||||
|
||||
**Function Props:**
|
||||
|
||||
```typescript
|
||||
// Action-oriented names
|
||||
onSave: (data: SaveData) => Promise<void>
|
||||
onDelete: (id: string) => Promise<void>
|
||||
onUpdate: (item: Item) => void
|
||||
onValidate: (data: FormData) => boolean
|
||||
onNavigate: (route: string) => void
|
||||
```
|
||||
|
||||
**$emit Events:**
|
||||
|
||||
```typescript
|
||||
// Event-oriented names
|
||||
@click: (event: MouseEvent) => void
|
||||
@input: (value: string) => void
|
||||
@submit: (data: FormData) => void
|
||||
@focus: (event: FocusEvent) => void
|
||||
@mounted: () => void
|
||||
```
|
||||
|
||||
### TypeScript Integration
|
||||
|
||||
#### Function Prop Types
|
||||
|
||||
```typescript
|
||||
// Define reusable function types
|
||||
interface SaveHandler {
|
||||
(data: SaveData): Promise<void>;
|
||||
}
|
||||
|
||||
interface ValidationHandler {
|
||||
(data: FormData): boolean;
|
||||
}
|
||||
|
||||
// Use in components
|
||||
@Prop({ required: true }) onSave!: SaveHandler;
|
||||
@Prop({ required: true }) onValidate!: ValidationHandler;
|
||||
```
|
||||
|
||||
#### Event Types
|
||||
|
||||
```typescript
|
||||
// Define event payload types
|
||||
interface ClickEvent {
|
||||
target: HTMLElement;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
@Emit("click")
|
||||
handleClick(): ClickEvent {
|
||||
return {
|
||||
target: this.$el,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Testing Guidelines
|
||||
|
||||
### Function Props Testing
|
||||
|
||||
```typescript
|
||||
// Easy to mock and test
|
||||
const mockOnSave = jest.fn();
|
||||
const wrapper = mount(MyComponent, {
|
||||
propsData: {
|
||||
onSave: mockOnSave
|
||||
}
|
||||
});
|
||||
|
||||
await wrapper.vm.handleSave();
|
||||
expect(mockOnSave).toHaveBeenCalledWith(expectedData);
|
||||
```
|
||||
|
||||
### $emit Testing
|
||||
|
||||
```typescript
|
||||
// Requires event simulation
|
||||
const wrapper = mount(MyComponent);
|
||||
await wrapper.find('button').trigger('click');
|
||||
expect(wrapper.emitted('click')).toBeTruthy();
|
||||
```
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### From $emit to Function Props
|
||||
|
||||
1. **Identify business logic events** (not DOM events)
|
||||
2. **Add function props** to component interface
|
||||
3. **Update parent components** to pass functions
|
||||
4. **Remove $emit decorators** and event handlers
|
||||
5. **Update tests** to use function mocks
|
||||
|
||||
### Example Migration
|
||||
|
||||
**Before ($emit):**
|
||||
|
||||
```typescript
|
||||
@Emit("save")
|
||||
handleSave() {
|
||||
return this.formData;
|
||||
}
|
||||
```
|
||||
|
||||
**After (Function Props):**
|
||||
|
||||
```typescript
|
||||
@Prop({ required: true }) onSave!: (data: FormData) => void;
|
||||
|
||||
handleSave() {
|
||||
this.onSave(this.formData);
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices Summary
|
||||
|
||||
1. **Use function props** for business logic, data operations, and complex interactions
|
||||
2. **Use $emit** for DOM-like events, lifecycle events, and simple user interactions
|
||||
3. **Be consistent** within your codebase
|
||||
4. **Document your patterns** for team alignment
|
||||
5. **Consider TypeScript** when choosing between approaches
|
||||
6. **Test both patterns** appropriately
|
||||
|
||||
## Code Generation Templates
|
||||
|
||||
### Component Generator Input
|
||||
|
||||
```typescript
|
||||
interface ComponentSpec {
|
||||
name: string;
|
||||
props: Array<{
|
||||
name: string;
|
||||
type: string;
|
||||
required: boolean;
|
||||
isFunction: boolean;
|
||||
}>;
|
||||
events: Array<{
|
||||
name: string;
|
||||
payloadType?: string;
|
||||
}>;
|
||||
template: string;
|
||||
}
|
||||
```
|
||||
|
||||
### Generated Output
|
||||
|
||||
```typescript
|
||||
// Generator should automatically choose function props vs $emit
|
||||
// based on the nature of the interaction (business logic vs DOM event)
|
||||
```
|
||||
|
||||
This guide ensures consistent, maintainable component communication patterns across the application.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user