# Timebank.cc [![Laravel](https://img.shields.io/badge/Laravel-10.x-red.svg)](https://laravel.com) [![PHP](https://img.shields.io/badge/PHP-8.3+-blue.svg)](https://php.net) [![Version](https://img.shields.io/badge/Version-26.3.0-blue.svg)](CHANGELOG.md) [![License](https://img.shields.io/badge/License-AGPL%20v3-green.svg)](LICENSE) A community time banking platform where members exchange services using time as currency. Built with Laravel, Livewire 3, and real-time WebSocket support. > **Development Status**: Active development — not production-ready. ## Features - **Multi-Profile System**: Switch between Individual, Organization, Bank, and Admin profiles - **Time-Based Transactions**: Immutable transaction history with MySQL-level write protection - **Real-Time Messaging**: Live chat with presence indicators via Laravel Reverb - **Advanced Search**: Elasticsearch-powered with location and skill matching - **Multilingual**: English, Dutch, German, Spanish, French - **White-Label**: Theme and configuration system for custom deployments ## Prerequisites - PHP 8.3+ - MySQL 8.0+ or MariaDB 10.2+ (window function support required) - Redis - Elasticsearch 8.x - Node.js & NPM - Composer See `references/SETUP_GUIDE.md` for full server setup instructions. ## Quick Start ```bash # 1. Install dependencies composer install npm install # 2. Configure environment cp .env.example .env php artisan key:generate # Edit .env with your database, Redis, Elasticsearch, and mail settings # 3. Database php artisan migrate php artisan db:seed php artisan storage:link # 4. Search index php artisan scout:import # 5. Start services (separate terminals) php artisan serve php artisan queue:work --queue=high,messages,default,emails,mailing,low php artisan reverb:start npm run dev ``` ## Architecture ### Multi-Guard Authentication Four profile types using Laravel multi-guard auth (`web`, `admin`, `bank`, `organization`). Active guard stored in session; profile switching handled by `SwitchGuardTrait`. ### Transaction Immutability Transactions are protected at the MySQL user level — the app DB user cannot UPDATE or DELETE from the `transactions` table: ```sql REVOKE UPDATE, DELETE ON `timebank_cc`.transactions FROM 'timebank_user'@'localhost'; ``` ### White-Label Configuration Copy `config/timebank-default.php`, customize it, and set `TIMEBANK_CONFIG=your-platform` in `.env`. Use `timebank_config('key')` throughout the codebase. ### Theme System Themes are configured in `config/themes.php` and activated via `TIMEBANK_THEME`. Available themes: `timebank_cc`, `uuro`, `vegetable`, `yellow`. See `references/THEME_IMPLEMENTATION.md`. ## Technology Stack | Layer | Technology | |-------|-----------| | Backend | Laravel 10, Livewire 3, Laravel Jetstream | | Frontend | Tailwind CSS, Alpine.js, WireUI, Vite | | Database | MySQL 8+ / MariaDB 10.2+ | | Search | Elasticsearch 8.x via Laravel Scout | | Real-time | Laravel Reverb (WebSocket) | | Cache/Queue | Redis | ## Scripts ### Root-level | Script | Description | |--------|-------------| | `./deploy.sh` | Universal deployment script (local and server) | | `./deploy.sh -e server` | Deploy using server `.env` configuration | | `./deploy.sh -m` | Skip migrations | | `./deploy.sh -n` | Skip npm build | | `./seed.sh` | Run `db:seed` with elevated MySQL privileges (needed for DROP operations) | | `./deployment-htmlpurifier-fix.sh` | Set up HTMLPurifier cache (run after deploy or manually) | ### `scripts/` directory | Script | Description | |--------|-------------| | `scripts/backup-all.sh` | Master backup: database + storage | | `scripts/backup-database.sh` | Database backup only | | `scripts/backup-storage.sh` | Storage backup only | | `scripts/restore-all.sh` | Full restore: database + storage | | `scripts/restore-database.sh` | Database restore only | | `scripts/restore-storage.sh` | Storage restore only | | `scripts/cleanup-backups.sh` | Remove old backup files | | `scripts/setup-backups.sh` | Initialize backup directory structure | | `scripts/re-index-search.sh` | Rebuild Elasticsearch search indices | | `scripts/mail-switch.sh` | Toggle between Mailpit (local) and real SMTP | | `scripts/send-all-test-emails.sh` | Send all transactional test emails in all 5 languages | | `scripts/test-transactional-emails.sh` | Interactive transactional email test | | `scripts/test-inactive-warning-emails.sh` | Test inactive profile warning emails | | `scripts/test-all-warnings.sh` | Test all profile warning flows | | `scripts/test-transaction-immutability.sh` | Verify transaction immutability on active DB | | `scripts/check-elasticsearch-security.sh` | Check Elasticsearch security configuration | | `scripts/create-restricted-db-user-safe.sh` | Create restricted app DB user with write protections | | `scripts/migrate-to-example-configs.sh` | Migrate to `.example` config pattern | | `scripts/debug-db-connection.sh` | Debug database connection from `.env` | | `scripts/log.sh` | Development log viewer (do not include in production) | ## Artisan Commands ### Development & Deployment ```bash php artisan serve # Dev server php artisan queue:work --queue=high,messages,default,emails,mailing,low # Queue worker php artisan reverb:start # WebSocket server npm run dev # Asset dev server (HMR) npm run build # Production assets php artisan optimize # Rebuild config/route/view cache php artisan scout:import # Rebuild search indices (high memory) php artisan test # Run test suite php artisan database:update # Apply schema changes and data migrations php artisan config:merge --all # Merge new keys from .example config files ``` ### Profiles ```bash php artisan profiles:mark-inactive # Mark profiles inactive based on login threshold php artisan profiles:process-inactive # Send warnings and delete over-threshold profiles php artisan profiles:permanently-delete-expired # Anonymize profiles past grace period php artisan profiles:restore # Restore a soft-deleted profile ``` ### Mailings ```bash php artisan mailings:process-scheduled # Send scheduled mailings that are ready php artisan mailings:process-bounces # Process bounce emails from bounce mailbox php artisan mailings:manage-bounces # Apply threshold-based actions on bounced addresses php artisan mailings:retry-failed # Retry failed mailings outside their retry window php artisan email:send-test # Send test transactional emails ``` ### Calls / Posts ```bash php artisan calls:process-expiry # Send expiry warnings and expired notifications php artisan posts:backup # Backup posts + media to ZIP archive php artisan posts:restore # Restore posts from backup file ``` ### Tags & Skills ```bash # Export existing tags/categories to JSON (for AI-assisted translation/generation) php artisan tags:import-export export-categories php artisan tags:import-export export-tags php artisan tags:import-export export-tags --category-id=5 --locale=en # Import translated/generated tags from JSON files in imports/tags/ php artisan tags:import-export import php artisan tags:import-export import path/to/file.json php artisan tags:import-export import --dry-run # Preview without changes # Remove a tag group php artisan tags:import-export remove-group # Validate tag translations across all locales php artisan tags:validate-translations php artisan tags:validate-translations --locale=nl php artisan tags:validate-translations --show-missing php artisan tags:validate-translations --show-duplicates php artisan tags:validate-translations --show-contexts ``` Tags can also be seeded directly from the database seeders: ```bash php artisan db:seed --class=TaggableTagsTableSeeder php artisan db:seed --class=TaggableContextsTableSeeder php artisan db:seed --class=TaggableLocalesTableSeeder php artisan db:seed --class=TaggableLocaleContextTableSeeder ``` ### Translations ```bash php artisan ai-translator:translate # Translate PHP language files via AI php artisan ai-translator:translate-json # Translate JSON language files via AI php artisan ai-translator:find-unused # Find unused translation keys php artisan ai-translator:clean # Remove translated strings to prepare for re-translation ``` Translation helper scripts (in `references/translations/`): ```bash references/translations/translate-all-sequential.sh # Translate all locales sequentially references/translations/translate-new-keys.sh # Translate only new/missing keys references/translations/retranslate-informal.sh # Re-translate informal language variants ``` ## Key Configuration (`.env`) ```env TIMEBANK_CONFIG=timebank_cc TIMEBANK_THEME=timebank_cc DB_CONNECTION=mysql DB_DATABASE=timebank_cc DB_USERNAME=timebank_cc_app DB_PASSWORD=your_password ELASTICSEARCH_HOST=localhost:9200 SCOUT_DRIVER=matchish-elasticsearch BROADCAST_DRIVER=reverb REVERB_APP_ID=app-id REVERB_APP_KEY=app-key REVERB_APP_SECRET=app-secret CACHE_DRIVER=redis SESSION_DRIVER=database QUEUE_CONNECTION=redis ``` ## References | Document | Description | |----------|-------------| | `references/SETUP_GUIDE.md` | Full Debian server setup | | `references/EXTERNAL_SERVICES_REQUIREMENTS.md` | Redis, Elasticsearch, mail setup | | `references/WEBSOCKET_SETUP.md` | Reverb / WebSocket configuration | | `references/THEME_IMPLEMENTATION.md` | Theme system details | | `references/STYLE_GUIDE.md` | UI component patterns | | `references/CONFIG_MANAGEMENT.md` | White-label config management | | `references/SECURITY_OVERVIEW.md` | Security architecture | | `references/QUEUE_WORKERS_SETUP.md` | Production queue / systemd setup | ## License AGPL v3 — see [LICENSE](LICENSE).