Files
usher-manage-stack/.planning/codebase/STACK.md
2026-02-13 10:34:18 +08:00

224 lines
7.8 KiB
Markdown

# Technology Stack
**Analysis Date:** 2026-02-13
## Languages
**Primary:**
- PHP 8.1+ - Backend framework, ORM, business logic
**Secondary:**
- TypeScript - Not used (JavaScript tooling only)
- JavaScript - Frontend interactivity via Alpine.js and Vite build
## Runtime
**Environment:**
- Laravel 10 (minimum 10.10)
- PHP 8.1+ (configured in `composer.json`)
**Package Managers:**
- Composer (PHP) - Dependency management for backend
- Lockfile: `composer.lock` (present)
- npm (Node.js) - Frontend asset builds and development
- Lockfile: `package-lock.json` (present)
## Frameworks
**Core Backend:**
- Laravel 10 - Full-stack web framework for routing, models, migrations, services
- Location: `app/`, `routes/`, `config/`, `database/`
**Frontend Templating:**
- Blade (Laravel templating engine) - Server-side template rendering
- Location: `resources/views/`
**Frontend Interactivity:**
- Alpine.js 3.4 - Lightweight reactive JavaScript for form handling and DOM manipulation
- Package: `alpinejs@^3.4.2` in `package.json`
**Build & Asset Pipeline:**
- Vite 5 - Fast build tool for compiling CSS/JS
- Package: `vite@^5.0.0`
- Config: `vite.config.js` (Laravel Vite plugin configured)
- Laravel Vite Plugin - Integration between Laravel and Vite
- Package: `laravel-vite-plugin@^1.0.0`
**Styling:**
- Tailwind CSS 3.1 - Utility-first CSS framework
- Package: `tailwindcss@^3.1.0`
- Dark mode: `darkMode: 'class'` configured in tailwind config
- Forms plugin: `@tailwindcss/forms@^0.5.2` for styled form elements
- PostCSS 8.4.31 - CSS processing
- Autoprefixer 10.4.2 - Browser vendor prefixes
**Testing:**
- PHPUnit 10.1 - PHP unit testing framework
- Config: `phpunit.xml`
- Test directory: `tests/`
- Laravel Dusk 8.3 - Browser testing framework for end-to-end tests
- Run: `php artisan dusk`
- Mockery 1.4.4 - PHP mocking library for tests
**Development Quality:**
- Laravel Pint 1.0 - Code style formatter (PSR-12)
- Laravel Tinker 2.8 - Interactive PHP REPL
- Laravel Breeze 1.29 - Lightweight authentication scaffolding
- FakerPHP 1.9.1 - Fake data generation for seeders
- Spatie Ignition 2.0 - Error page debugging companion
- Collision 7.0 - Error page styling
**DevOps/Deployment:**
- Laravel Sail 1.18 - Docker-based local development environment (optional)
## Key Dependencies
**Critical Business Logic:**
- `spatie/laravel-permission` 6.23 - RBAC role and permission system
- Used for: Finance approvals, user role management
- Config: `config/permission.php`
- Tables: `roles`, `permissions`, `model_has_roles`, `model_has_permissions`, `role_has_permissions`
- `barryvdh/laravel-dompdf` 3.1 - PDF generation for finance reports
- Used for: Document export, compliance reports
- Provider: `Barryvdh\DomPDF\ServiceProvider`
- `maatwebsite/excel` 3.1 - Excel file import/export
- Used for: Member data imports, financial report exports
- Laravel 10 compatible version
**HTTP & API Integration:**
- `guzzlehttp/guzzle` 7.2 - HTTP client for external requests
- Used in: `SiteRevalidationService` for Next.js webhook calls
- Location: `app/Services/SiteRevalidationService.php`
**QR Code Generation:**
- `simplesoftwareio/simple-qrcode` 4.2 - QR code generation library
- Used for: Member ID verification, document tracking
**Authentication:**
- `laravel/sanctum` 3.3 - API token authentication and CSRF protection
- Used for: Public API endpoints (`/api/v1/*`)
- Config: `config/sanctum.php`
- Stateful domains: `localhost`, `127.0.0.1` (customizable via env)
## Configuration
**Environment Configuration:**
- `.env.example` - Template for environment variables
- Required variables (non-secret):
- `APP_NAME`, `APP_ENV`, `APP_DEBUG`, `APP_URL` - Application identity
- `DB_CONNECTION`, `DB_HOST`, `DB_PORT`, `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD` - Database
- `MAIL_MAILER`, `MAIL_HOST`, `MAIL_PORT`, `MAIL_FROM_ADDRESS` - Email
- `CACHE_DRIVER`, `QUEUE_CONNECTION`, `SESSION_DRIVER` - Caching/queueing
- `REGISTRATION_ENABLED` - Toggle public registration on/off
- `NEXTJS_REVALIDATE_URL`, `NEXTJS_REVALIDATE_TOKEN` - Webhook to frontend
- `NEXTJS_PUBLIC_PATH` - Optional: Local Next.js repo for asset syncing
**Core Configs:**
- `config/app.php` - Timezone: `Asia/Taipei`, Locale: `zh_TW`, Cipher: `AES-256-CBC`
- `config/database.php` - Database connection options (MySQL primary, SQLite dev)
- `config/auth.php` - Authentication guards (session-based), public registration toggle
- `config/mail.php` - SMTP, Mailgun, Postmark, SES support
- `config/accounting.php` - Account codes, amount tier thresholds, currency (TWD)
- `config/filesystems.php` - Local, public, private, and S3 disk definitions
- `config/cache.php` - File (default), Redis, Memcached, DynamoDB support
- `config/queue.php` - Sync (default), database, Redis, SQS, Beanstalkd support
- `config/services.php` - Third-party service credentials (Mailgun, Postmark, AWS SES, Next.js webhooks)
- `config/logging.php` - Monolog channels (stack, single, daily, Slack, Papertrail)
- `config/cors.php` - CORS policy for API endpoints
- `config/session.php` - Session driver and lifetime (120 minutes default)
## Database
**Primary (Production):**
- MySQL 5.7+ (configured in `config/database.php`)
- Character set: `utf8mb4`, Collation: `utf8mb4_unicode_ci`
- Strict mode enabled
**Development:**
- SQLite supported as alternative (`DB_CONNECTION=sqlite`)
- Location: `database/database.sqlite`
**Migrations:**
- Directory: `database/migrations/`
- Run: `php artisan migrate`
- Fresh reset: `php artisan migrate:fresh --seed`
## Caching & Session
**Cache (Default: File):**
- Driver: `file` (can be switched to Redis, Memcached, DynamoDB)
- Location: `storage/framework/cache/data/`
- Used for: Settings caching (`settings()` helper), query result caching
**Sessions (Default: File):**
- Driver: `file` (can be switched to database, Redis, etc.)
- Lifetime: 120 minutes
- Storage: `storage/framework/sessions/`
**Queue (Default: Sync):**
- Driver: `sync` (processes jobs immediately in production, can use `database`/`redis`)
- Used for: Email sending, bulk operations
- Failed jobs table: `failed_jobs`
## Email
**Mailers Supported:**
- SMTP (default) - Mailgun, custom SMTP servers
- Mailgun API
- Postmark API
- AWS SES
- Log (development)
- Failover chains (SMTP → Log)
**Dev Default:**
- Mailpit (mock SMTP server) on `localhost:1025`
- Configured in `.env.example` for local testing
**Mail Queue:**
- All transactional emails use `Mail::...->queue()` for async sending
- Location: Email classes in `app/Mail/`
## File Storage
**Private Files:**
- Disk: `private` (stores in `storage/app/`)
- Access: Served via controller responses only (no direct URL)
- Used for: Encrypted documents, sensitive uploads
**Public Files:**
- Disk: `public` (stores in `storage/app/public/`)
- URL: Accessible via `/storage/...` after running `php artisan storage:link`
- Used for: Admin-uploaded images, article attachments
**Optional S3:**
- Disk: `s3` (configured for AWS S3)
- Requires: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_DEFAULT_REGION`, `AWS_BUCKET`
**Next.js Asset Sync (Optional):**
- Location: `config/services.php``nextjs.public_path`
- Feature: Auto-copy uploaded images to Next.js `public/` directory
- Git integration: Optional auto-commit and push of assets
- Used for: Serving static images from static Next.js build
## Deployment
**Hosting Targets:**
- Dedicated servers (traditional deployment with PHP-FPM + Nginx)
- Docker (via Laravel Sail)
- Vercel/Netlify (headless API mode)
**Production Considerations:**
- Database: Migrate to MySQL 8.0+
- Cache: Switch from `file` to Redis for multi-server setups
- Queue: Switch from `sync` to `database` or `redis`
- Session: Switch from `file` to `database` or `redis`
- Mail: Configure Mailgun/SES for production email
- Storage: Use S3 for file uploads instead of local disk
- Assets: Compile with `npm run build` before deployment
---
*Stack analysis: 2026-02-13*