# TimeSafari.app - Crowd-Funder for Time - PWA

[Time Safari](https://timesafari.org/) allows people to ease into collaboration: start with expressions of gratitude
and expand to crowd-fund with time & money, then record and see the impact of contributions.

## Roadmap

See [ClickUp](https://sharing.clickup.com/9014278710/l/h/8cmnyhp-174/10573fec74e2ba0) for current priorities.

## Setup & Building

Quick start:

* For setup, we recommend [pkgx](https://pkgx.dev), which installs what you need (either automatically or with the `dev` command). Core dependencies are typescript & npm; when building for other platforms, you'll need other things such as those in the pkgx.yaml & BUILDING.md files.

```bash
npm install
npm run build:web:serve -- --test
```

To be able to take action on the platform: go to [the test page](http://localhost:8080/test) and click "Become User 0".

See [BUILDING.md](BUILDING.md) for comprehensive build instructions for all platforms (Web, Electron, iOS, Android, Docker).

## 🛡️ Build Architecture Guard

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 `doc/README-BUILD-GUARD.md`

## Development Database Clearing

TimeSafari provides a simple script-based approach to clear the local database (not the claim server) for development purposes.

## Logging Configuration

TimeSafari supports configurable logging levels via the `VITE_LOG_LEVEL` environment variable. This allows developers to control console output verbosity without modifying code.

### Quick Usage

```bash
# Show only errors
VITE_LOG_LEVEL=error npm run build:web:dev

# Show warnings and errors
VITE_LOG_LEVEL=warn npm run build:web:dev

# Show info, warnings, and errors (default)
VITE_LOG_LEVEL=info npm run build:web:dev

# Show all log levels including debug
VITE_LOG_LEVEL=debug npm run build:web:dev
```

### Available Levels

- **`error`**: Critical errors only
- **`warn`**: Warnings and errors (default for production web)
- **`info`**: Info, warnings, and errors (default for development/capacitor)
- **`debug`**: All log levels including verbose debugging

See [Logging Configuration Guide](doc/logging-configuration.md) for complete details.

### Quick Usage
```bash
# Run the database clearing script
./scripts/clear-database.sh

# Then restart your development server
npm run build:electron:dev  # For Electron
npm run build:web:dev       # For Web
```

### What It Does

#### **Electron (Desktop App)**
- Automatically finds and clears the SQLite database files
- Works on Linux, macOS, and Windows
- Clears all data and forces fresh migrations on next startup

#### **Web Browser**
- Provides instructions for using custom browser data directories
- Shows manual clearing via browser DevTools
- Ensures reliable database clearing without browser complications

### Safety Features
- ✅ **Interactive Script**: Guides you through the process
- ✅ **Platform Detection**: Automatically detects your OS
- ✅ **Clear Instructions**: Step-by-step guidance for each platform
- ✅ **Safe Paths**: Only clears TimeSafari-specific data

### Manual Commands (if needed)

#### **Electron Database Location**
```bash
# Linux
rm -rf ~/.config/TimeSafari/*

# macOS  
rm -rf ~/Library/Application\ Support/TimeSafari/*

# Windows
rmdir /s /q %APPDATA%\TimeSafari
```

#### **Web Browser (Custom Data Directory)**
```bash
# Create isolated browser profile
mkdir ~/timesafari-dev-data
```

## Domain Configuration

TimeSafari uses a centralized domain configuration system to ensure consistent
URL generation across all environments. This prevents localhost URLs from
appearing in shared links during development.

### Key Features
- ✅ **Production URLs for Sharing**: All copy link buttons use production domain
- ✅ **Environment-Specific Internal URLs**: Internal operations use appropriate
  environment URLs
- ✅ **Single Point of Control**: Change domain in one place for entire app
- ✅ **Type-Safe Configuration**: Full TypeScript support

### Quick Reference

```typescript
// For sharing functionality (environment-specific)
import { APP_SERVER } from "@/constants/app";
const shareLink = `${APP_SERVER}/deep-link/claim/123`;

// For internal operations (environment-specific)
import { APP_SERVER } from "@/constants/app";
const apiUrl = `${APP_SERVER}/api/claim/123`;
```

### Documentation

- [Constants and Configuration](src/constants/app.ts) - Core constants

## Tests

See [TESTING.md](test-playwright/TESTING.md) for detailed test instructions.

## Asset Management

TimeSafari uses a standardized asset configuration system for consistent
icon and splash screen generation across all platforms.

### Asset Sources

- **Single source of truth**: `resources/` directory (Capacitor default)
- **Source files**: `icon.png`, `splash.png`, `splash_dark.png`
- **Format**: PNG or SVG files for optimal quality

### Asset Generation

- **Configuration**: `config/assets/capacitor-assets.config.json`
- **Schema validation**: `config/assets/schema.json`
- **Build-time generation**: Platform assets generated via `capacitor-assets`
- **No VCS commits**: Generated assets are never committed to version control

### Development Commands

```bash
# Generate/update asset configurations
npm run assets:config

# Validate asset configurations
npm run assets:validate

# Clean generated platform assets (local dev only)
npm run assets:clean

# Build with asset generation
npm run build:native
```

### Environment Setup & Dependencies

Before building the application, ensure your development environment is properly
configured:

```bash
# Install all dependencies (required first time and after updates)
npm install

# Validate your development environment
npm run check:dependencies

# Check prerequisites for testing
npm run test:prerequisites
```

**Common Issues & Solutions**:

- **"tsx: command not found"**: Run `npm install` to install devDependencies
- **"capacitor-assets: command not found"**: Ensure `@capacitor/assets` is installed
- **Build failures**: Run `npm run check:dependencies` to diagnose environment issues

**Required Versions**:
- Node.js: 18+ (LTS recommended)
- npm: 8+ (comes with Node.js)
- Platform-specific tools: Android Studio, Xcode (for mobile builds)

### Platform Support

- **Android**: Adaptive icons with foreground/background, monochrome support
- **iOS**: LaunchScreen storyboard preferred, splash assets when needed
- **Web**: PWA icons generated during build to `dist/` (not committed)

### Font Awesome Icons

To add a Font Awesome icon, add to `fontawesome.ts` and reference with
`font-awesome` element and `icon` attribute with the hyphenated name.

## 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/).

* If you are deploying in a subdirectory, add it to `publicPath` in vue.config.js, eg: `publicPath: "/app/time-tracker/",`

### Code Organization

The project uses a centralized approach to type definitions and interfaces:

* `src/interfaces/` - Contains all TypeScript interfaces and type definitions
  * `deepLinks.ts` - Deep linking type system and Zod validation schemas
  * `give.ts` - Give-related interfaces and type definitions
  * `claims.ts` - Claim-related interfaces and verifiable credentials
  * `common.ts` - Shared interfaces and utility types
  * Other domain-specific interface files

Key principles:
- All interfaces and types are defined in the interfaces folder
- Zod schemas are used for runtime validation and type generation
- Domain-specific interfaces are separated into their own files
- Common interfaces are shared through `common.ts`
- Type definitions are generated from Zod schemas where possible

### Database Architecture

The application uses a platform-agnostic database layer with Vue mixins for service access:

* `src/services/PlatformService.ts` - Database interface definition
* `src/services/PlatformServiceFactory.ts` - Platform-specific service factory
* `src/services/AbsurdSqlDatabaseService.ts` - SQLite implementation
* `src/utils/PlatformServiceMixin.ts` - Vue mixin for database access with caching
* `src/db/` - Legacy Dexie database (migration in progress)

**Development Guidelines**:

- Always use `PlatformServiceMixin` for database operations in components
- Test with PlatformServiceMixin for new features
- Use migration tools for data transfer between systems
- Leverage mixin's ultra-concise methods: `$db()`, `$exec()`, `$one()`, `$contacts()`, `$settings()`

**Architecture Decision**: The project uses Vue mixins over Composition API composables for platform service access. See [Architecture Decisions](doc/architecture-decisions.md) for detailed rationale.

## 📁 Project Structure

```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
└── 📄 doc/README-BUILD-GUARD.md # Guard system documentation
```

## Known Issues

### Critical Vue Reactivity Bug
A critical Vue reactivity bug was discovered during ActiveDid migration testing where component properties fail to trigger template updates correctly.

**Impact**: The `newDirectOffersActivityNumber` element in HomeView.vue requires a watcher workaround to render correctly.

**Status**: Workaround implemented, investigation ongoing.

**Documentation**: See [Vue Reactivity Bug Report](doc/vue-reactivity-bug-report.md) for details.

## 🤝 Contributing

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

## Kudos

Gifts make the world go 'round!

* [WebStorm by JetBrains](https://www.jetbrains.com/webstorm/) for the free open-source license
* [Máximo Fernández](https://medium.com/@maxfarenas) for the 3D [code](https://github.com/maxfer03/vue-three-ns) and [explanatory post](https://medium.com/nicasource/building-an-interactive-web-portfolio-with-vue-three-js-part-three-implementing-three-js-452cb375ef80)
* [Many tools & libraries](https://gitea.anomalistdesign.com/trent_larson/crowd-funder-for-time-pwa/src/branch/master/package.json#L10) such as Nodejs.org, IntelliJ Idea, Veramo.io, Vuejs.org, threejs.org
* [Bush 3D model](https://sketchfab.com/3d-models/lupine-plant-bf30f1110c174d4baedda0ed63778439)
* [Forest floor image](https://www.goodfreephotos.com/albums/textures/leafy-autumn-forest-floor.jpg)
* Time Safari logo assisted by [DALL-E in ChatGPT](https://chat.openai.com/g/g-2fkFE8rbu-dall-e)
* [DiceBear](https://www.dicebear.com/licenses/) and [Avataaars](https://www.dicebear.com/styles/avataaars/#details) for human-looking identicons
* Some gratitude prompts thanks to [Develop Good Habits](https://www.developgoodhabits.com/gratitude-journal-prompts/)
