# Growup Pro - Krayin CRM Whitelabel Multi-tenant ## Project Overview **Growup Pro** is a whitelabel implementation of [Krayin Laravel CRM](https://github.com/krayin/laravel-crm) with multi-tenancy support. The platform allows multiple companies/organizations to use the same CRM instance with complete data isolation through subdomain-based tenancy. **CURRENT STATUS: DEBUGGING PHASE** - **Multi-tenancy implementation**: Installed but encountering issues. - **Issue 1**: `localhost` not recognized as central domain (TenantCouldNotBeIdentifiedOnDomainException). - **Issue 2**: Tenant instances (`tenant1.localhost`) load but missing CSS (Asset 404). - **Goal**: Fix central domain detection and static asset serving for tenants. ### Key Differentiators from Krayin - **Rebranding**: Complete visual overhaul with Growup Pro branding - **Multi-tenancy**: Isolated environments per client organization - **Localization**: Full Portuguese (pt-BR) translation - **White-label ready**: Easy customization per tenant ## Tech Stack - **Framework**: Laravel (check composer.json for exact version) - **Base CRM**: Krayin Laravel CRM - **Database**: MySQL/PostgreSQL - **Multi-tenancy Package**: [Tenancy for Laravel](https://tenancyforlaravel.com/docs/v3/introduction) (v3) - **Frontend**: Blade templates with Alpine.js (Krayin default) - **PHP Version**: 8.1+ - **Containerization**: Docker with Docker Compose - **Orchestration**: Docker Swarm - **Management**: Portainer - **CI/CD**: Gitea Actions (GitHub Actions compatible) - **Error Tracking**: Sentry for Laravel - **Code Quality**: PHPStan (static analysis) + Laravel Pint (code formatter) - **CDN**: Cloudflare (caching and DDoS protection) - **PRODUCTION ONLY** ## Project Structure ``` . ├── .gitea/ │ └── workflows/ # Gitea Actions CI/CD pipelines │ ├── deploy.yml # Production deployment │ ├── deploy-staging.yml # Staging environment deployment │ └── tests.yml # Automated testing pipeline ├── .husky/ # Git hooks (pre-commit, pre-push) ├── Makefile # Common development commands ├── app/ │ ├── Models/ # Eloquent models (tenant-scoped) │ ├── Http/ │ │ ├── Controllers/ # Application controllers │ │ └── Middleware/ # Custom middleware (tenant identification) │ └── Providers/ # Service providers ├── config/ │ └── tenancy.php # Tenancy for Laravel configuration ├── database/ │ ├── migrations/ # Database migrations │ │ ├── tenant/ # Tenant-specific migrations │ │ └── landlord/ # Central database migrations │ └── seeders/ # Seeders for tenants and central data │ ├── DemoTenantSeeder.php # Creates demo tenants for testing │ └── ProductionSeeder.php # Production data seeding ├── docker/ │ ├── Dockerfile # Application container definition │ ├── docker-compose.yml # Local development orchestration │ └── docker-compose.prod.yml # Production stack definition ├── packages/ # Krayin core packages │ └── Webkul/ │ └── ... ├── public/ │ └── assets/ # Growup Pro assets (logos, images) ├── resources/ │ ├── lang/ │ │ └── pt_BR/ # Portuguese translations │ └── views/ # Blade templates (Growup Pro customized) └── routes/ ├── web.php # Central app routes ├── tenant.php # Tenant-specific routes ├── admin.php # Admin dashboard routes (tenant management) └── api.php # API routes ``` ## Multi-tenancy Configuration ### Package: Tenancy for Laravel We use **Tenancy for Laravel v3** for robust multi-tenant architecture with automatic database switching and tenant identification. ### Tenant Identification Strategy - **Method**: Subdomain-based identification - **Domain**: `growuppro.com.br` - **Pattern**: `{tenant}.growuppro.com.br` - **Examples**: - `empresa1.growuppro.com.br` → Tenant: empresa1 - `empresa2.growuppro.com.br` → Tenant: empresa2 - `demo.growuppro.com.br` → Tenant: demo ### Data Isolation - **Approach**: Separate database per tenant (recommended by Tenancy for Laravel) - Database naming: `tenant_{tenant_id}` (e.g., `tenant_empresa1`) - Central database: `growuppro_central` (stores tenant metadata, domains, users) - Automatic tenant context switching via middleware - Models automatically scoped to current tenant ### Tenant Features Each tenant has isolated: - **Data**: Leads, contacts, deals, products, activities - **Users**: Separate user base with roles/permissions - **Settings**: Email configuration, notifications, workflows - **Customization**: Optional CSS overrides, email templates ## Branding & Localization ### Growup Pro Visual Identity - **Application Name**: Growup Pro (replacing all Krayin mentions) - **Logo**: Custom Growup Pro logo in all interfaces - **Color Scheme**: [Define primary/secondary colors when ready] - **Typography**: [Define font family when ready] - **UI/UX**: Modern, clean interface aligned with Growup Pro brand ### Translation (pt-BR) - All user-facing text translated to Portuguese (Brazil) - Language files in `resources/lang/pt_BR/` - Default locale: `pt_BR` (set in `config/app.php`) - Maintain translation keys for easy updates - Include tenant-customizable text snippets ### Customization Locations 1. **Logo**: `public/assets/images/logo.png` (central) and tenant-specific storage 2. **Translations**: `resources/lang/pt_BR/` 3. **Views**: `resources/views/` (customized Krayin templates) 4. **Styles**: `public/assets/css/custom.css` (Growup Pro overrides) 5. **Config**: `config/growuppro.php` (application-specific settings) ## Docker & Deployment Architecture ### Container Strategy The application runs in Docker containers orchestrated by Docker Swarm and managed through Portainer. ### Docker Compose Structure - **Development**: `docker-compose.yml` (local development with hot-reload) - **Production**: `docker-compose.prod.yml` (optimized for Swarm deployment) ### Services Typical stack includes: - **app**: PHP-FPM application container (Growup Pro) - **nginx-proxy-manager**: Nginx Proxy Manager for reverse proxy, SSL, and domain management (managed via Portainer) - **database**: MySQL/PostgreSQL (central + tenants) - **redis**: Session and cache storage - **queue**: Laravel queue worker for background jobs - **scheduler**: Laravel scheduler (cron jobs) ### Image Management - **Registry**: GitHub Container Registry (GHCR) - **Image naming**: `ghcr.io/cauefaleiros/growup-pro:latest` - **Tagging strategy**: Git commit SHA and semantic versioning - **Tags**: `latest` (production), `dev` (development), `v{version}` (releases) ## CI/CD Pipeline with Gitea Actions ### About Gitea Actions Gitea Actions (available since Gitea 1.19) is a built-in CI/CD solution similar and mostly compatible with GitHub Actions. It uses the same YAML workflow format and is compatible with most GitHub Actions marketplace plugins. **Key Components:** - **Gitea Server**: Hosts repositories and triggers workflows - **act_runner**: Standalone runner program (written in Go) that executes jobs, based on a fork of nektos/act - **Workflows**: YAML files stored in `.gitea/workflows/` directory (compatible with GitHub Actions syntax) **Compatibility:** - Same YAML syntax as GitHub Actions - Can use most actions from GitHub marketplace (e.g., `actions/checkout@v4`, `actions/setup-node@v4`) - Workflows are portable between GitHub and Gitea with minimal changes ### Deployment Flow ``` Developer pushes code to GitHub ↓ GitHub Actions workflow triggered ↓ 1. Run tests (PHPUnit, Pest) 2. Build Docker image 3. Tag image with commit SHA ↓ Push image to GitHub Container Registry (GHCR) ↓ Call Portainer API (webhook or direct API) ↓ Portainer updates Docker Stack definition ↓ Docker Swarm pulls new image ↓ Swarm performs rolling update (zero-downtime) ↓ Health checks verify deployment ↓ Old containers removed ``` ### GitHub Actions Workflow Location: `.github/workflows/deploy.yml` Key steps: 1. **Checkout code** 2. **Setup PHP & dependencies** (Composer install) 3. **Run code quality checks** (PHPStan, Pint) 4. **Run tests** (PHPUnit/Pest - ensure code quality) 5. **Build Docker image** with build args 6. **Login to GHCR** using GitHub token 7. **Push image** with appropriate tags 8. **Trigger Portainer** via API to update stack 9. **Verify deployment** (health check endpoint) 10. **Notify team** (Slack/Discord webhook on success/failure) ### Environment Variables Managed through: - **GitHub Secrets**: Sensitive data (API keys, tokens, Sentry DSN) - **Portainer**: Stack environment variables - **Docker Swarm Secrets**: Database credentials, API keys ### Portainer Integration - **Portainer URL**: `https://148.230.76.122:9443` - **API Endpoint**: `https://148.230.76.122:9443/api` - **Authentication**: API token (stored in GitHub Secrets) - **Stack Management**: Update existing stack with new image tag - **Webhooks**: Optional webhook for automated redeploy - **Nginx Proxy Manager**: Managed through Portainer for SSL certificates and domain routing ## Coding Conventions ### Models All tenant-scoped models automatically inherit tenant context through Tenancy for Laravel: ```php id(); $table->string('title'); $table->decimal('value', 10, 2); // No tenant_id needed - separate databases per tenant $table->timestamps(); }); // database/migrations/2024_xx_xx_create_tenants_table.php (central) Schema::create('tenants', function (Blueprint $table) { $table->string('id')->primary(); $table->string('company_name'); $table->string('subdomain')->unique(); $table->timestamps(); }); ``` ### Routes ```php // routes/tenant.php - Runs in tenant context Route::middleware(['tenant'])->group(function () { Route::get('/dashboard', [DashboardController::class, 'index']); Route::resource('leads', LeadController::class); }); // routes/web.php - Central app (tenant selection, etc.) Route::get('/', [HomeController::class, 'index']); Route::post('/register-tenant', [TenantController::class, 'register']); ``` ## Important Files to Know ### Configuration - `config/app.php` - Application configuration (locale: pt_BR) - `config/tenancy.php` - Tenancy for Laravel settings - `config/growuppro.php` - Custom Growup Pro configuration - `app/Http/Kernel.php` - Middleware registration ### Krayin Core - `packages/Webkul/` - Krayin core packages (**never modify directly**) - Extend functionality through Laravel's standard practices (service providers, custom packages) ### Docker & Deployment - `docker/Dockerfile` - Application container definition - `docker-compose.yml` - Local development environment - `docker-compose.prod.yml` - Production stack for Swarm - `.github/workflows/deploy.yml` - CI/CD pipeline ### Branding - `public/assets/images/logo.png` - Growup Pro logo - `resources/lang/pt_BR/` - Portuguese translations - `resources/views/layouts/app.blade.php` - Main layout (branded) ## CRITICAL: Krayin Authentication Issues (MUST RESOLVE BEFORE MULTI-TENANCY) **IMPORTANT:** Multi-tenancy implementation is ON HOLD until we stabilize Krayin's base authentication system. We have experienced critical login issues that must be resolved first. ### Known Authentication Problems #### Problem 1: Error 419 - CSRF Token Mismatch **Symptoms:** - User enters credentials - Form submission returns 419 error - Login fails even with correct credentials **Possible Causes:** - Session driver misconfiguration (`file` vs `redis` vs `database`) - Session cookie not being set properly - Domain/subdomain mismatch in session configuration - `APP_URL` mismatch with actual access URL - CSRF token expiration (session timeout too short) - Reverse proxy stripping session cookies **Debug Steps:** ```bash # Check current session driver grep SESSION_DRIVER .env # Clear all caches php artisan cache:clear php artisan config:clear php artisan route:clear php artisan view:clear # Check session files (if using file driver) ls -la storage/framework/sessions/ # Test session configuration php artisan tinker >>> session()->put('test', 'value'); >>> session()->get('test'); # Should return 'value' ``` **Potential Fixes:** 1. **Ensure APP_URL matches access URL exactly:** ```env # If accessing via localhost:8000 APP_URL=http://localhost:8000 # If accessing via IP APP_URL=http://192.168.1.100:8000 ``` 2. **Check session configuration** (`config/session.php`): ```php 'domain' => env('SESSION_DOMAIN', null), // Should match your domain 'secure' => env('SESSION_SECURE_COOKIE', false), // false for HTTP, true for HTTPS 'same_site' => 'lax', // Not 'strict' - can cause issues ``` 3. **Verify CSRF middleware** is present in `app/Http/Kernel.php`: ```php protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, // THIS IS CRITICAL // ... ], ]; ``` 4. **Check CSRF exceptions** (if login route needs to be excluded): ```php // app/Http/Middleware/VerifyCsrfToken.php protected $except = [ // Add routes here ONLY as last resort ]; ``` #### Problem 2: Tenant Database Connection Issues **Symptoms:** - Login attempt fails silently - Database connection errors in logs - Can't authenticate against tenant-specific users table **Possible Causes:** - Tenant database doesn't exist yet - Database migrations not run on tenant database - Wrong database being queried (central vs tenant) - Tenant context not initialized before authentication attempt **Debug Steps:** ```bash # List all databases php artisan tinker >>> DB::select('SHOW DATABASES'); # Check which database Laravel is connected to >>> DB::connection()->getDatabaseName(); # Verify users table exists in tenant DB >>> Schema::connection('tenant')->hasTable('users'); ``` **Critical Notes for Multi-tenancy:** - Authentication MUST work in single-tenant (non-multi-tenant) mode FIRST - Only after stable authentication should we add tenant context switching - Tenant middleware should NOT interfere with session/CSRF handling #### Problem 3: Infinite Login Redirect Loop (CRITICAL - UNRESOLVED) **Symptoms:** - User enters valid credentials - Form submits successfully (no 419 error) - Page redirects back to login page - User is never authenticated - Dashboard never loads - No error messages displayed **This is the MOST CRITICAL issue and must be debugged thoroughly.** **Possible Causes:** 1. **Session not persisting after authentication:** - Session written but immediately destroyed - Session driver issue (file permissions, Redis connection) - Session ID regeneration failing 2. **Authentication middleware misconfigured:** - `Auth` middleware blocking authenticated users - Wrong guard being checked - Middleware order issues in Kernel.php 3. **Redirect logic broken:** - `redirectTo` property in LoginController pointing to login route - Intended destination not being preserved - Route name/path mismatch 4. **Auth guard misconfigured:** - Wrong guard specified in `config/auth.php` - Provider not finding users correctly - User model relationship issues 5. **Cookie domain/path mismatch:** - Session cookie being set but not read back - Domain attribute too restrictive - Path attribute incorrect **Detailed Debug Steps:** ```bash # 1. Enable query logging to see what's happening # Add to AppServiceProvider boot(): DB::listen(function ($query) { Log::info('Query: ' . $query->sql . ' - Bindings: ' . json_encode($query->bindings)); }); # 2. Add extensive logging to login process # In LoginController or wherever authentication happens: Log::info('Login attempt for: ' . request()->email); Log::info('Session ID before auth: ' . session()->getId()); # After Auth::attempt(): Log::info('Auth attempt result: ' . (Auth::check() ? 'success' : 'failed')); Log::info('Session ID after auth: ' . session()->getId()); Log::info('Authenticated user: ' . (Auth::user() ? Auth::user()->id : 'none')); # 3. Check session files directly # If using file driver: tail -f storage/logs/laravel.log & # Make login attempt # Check if session file is created and contains auth data: cat storage/framework/sessions/* # 4. Test authentication in Tinker php artisan tinker >>> $user = User::first(); >>> Auth::login($user); >>> Auth::check(); # Should return true >>> session()->all(); # Check session data >>> session()->save(); # Manually save session ``` **Configuration Files to Check:** 1. **config/auth.php** ```php 'defaults' => [ 'guard' => 'web', // Verify this matches your usage 'passwords' => 'users', ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, // Verify model path ], ], ``` 2. **config/session.php** ```php 'driver' => env('SESSION_DRIVER', 'file'), 'lifetime' => env('SESSION_LIFETIME', 120), 'expire_on_close' => false, 'encrypt' => false, 'files' => storage_path('framework/sessions'), 'connection' => env('SESSION_CONNECTION', null), 'table' => 'sessions', 'store' => env('SESSION_STORE', null), 'lottery' => [2, 100], 'cookie' => env('SESSION_COOKIE', Str::slug(env('APP_NAME', 'laravel'), '_').'_session'), 'path' => '/', 'domain' => env('SESSION_DOMAIN', null), // Should be NULL for localhost 'secure' => env('SESSION_SECURE_COOKIE', false), // FALSE for HTTP 'http_only' => true, 'same_site' => 'lax', // NOT 'strict' ``` 3. **Verify LoginController redirect logic:** ```php // Typical Laravel LoginController protected $redirectTo = '/dashboard'; // NOT '/login'! // Or method: protected function redirectTo() { return '/dashboard'; // Verify this route exists and is accessible } // Check authenticated() method isn't causing issues: protected function authenticated(Request $request, $user) { // Should NOT return redirect to login Log::info('User authenticated: ' . $user->id); } ``` 4. **Check middleware in routes:** ```php // routes/web.php Route::middleware(['auth'])->group(function () { Route::get('/dashboard', [DashboardController::class, 'index']); }); // Verify 'auth' middleware is defined in Kernel.php // and uses the correct guard ``` **Testing Methodology:** 1. **Isolate the problem:** ```bash # Create a minimal test route Route::get('/test-auth', function () { Auth::login(User::first()); return [ 'authenticated' => Auth::check(), 'user_id' => Auth::id(), 'session_id' => session()->getId(), 'session_data' => session()->all(), ]; }); ``` 2. **Test session persistence separately:** ```bash Route::get('/test-session-write', function () { session(['test_key' => 'test_value_' . time()]); return 'Session written: ' . session('test_key'); }); Route::get('/test-session-read', function () { return 'Session read: ' . session('test_key', 'NOT FOUND'); }); ``` 3. **Test authentication without redirect:** ```bash Route::post('/test-login', function (Request $request) { $credentials = $request->only('email', 'password'); if (Auth::attempt($credentials)) { return [ 'status' => 'success', 'user' => Auth::user()->only(['id', 'email']), 'session_id' => session()->getId(), ]; } return ['status' => 'failed']; }); ``` **Critical Checklist Before Multi-tenancy:** - [ ] Session driver works correctly (can write and read session data) - [ ] CSRF protection works (no 419 errors) - [ ] Auth::attempt() returns true for valid credentials - [ ] Auth::check() returns true immediately after Auth::attempt() - [ ] Session persists across requests (test with simple session()->put/get) - [ ] User can access protected routes after authentication - [ ] No infinite redirect loops - [ ] Login process completes in browser devtools Network tab (check for redirect chains) - [ ] Session cookie is set and sent back with subsequent requests (check devtools Application/Storage) **DO NOT proceed with multi-tenancy until ALL checklist items pass.** ### Debugging Tools ```bash # Enable debug mode APP_DEBUG=true # Tail logs in real-time tail -f storage/logs/laravel.log # Check Redis connection (if using Redis sessions) redis-cli ping # Check MySQL connection php artisan tinker >>> DB::connection()->getPdo(); # Dump session driver configuration php artisan tinker >>> config('session.driver'); >>> config('session.files'); >>> config('session.connection'); # Test file permissions ls -la storage/framework/sessions/ # Should be writable by web server user ``` ### Next Steps After Resolving Authentication 1. Document the exact fix that resolved the issue 2. Create test cases to prevent regression 3. Only then begin multi-tenancy implementation 4. Add monitoring/logging to detect authentication issues early --- ## Development Workflow ### Development Environments The project uses multiple environments for safe deployment: 1. **Local Development** (`localhost`) - Docker Compose for local stack - Hot reload enabled - Debug mode on 2. **Staging Environment** (`staging.growuppro.com.br`) - Production-like environment - Deployed from `staging` branch - Used for testing before production - Same infrastructure as production 3. **Production Environment** (`growuppro.com.br`) - Live environment - Deployed from `main` branch - Zero-downtime deployments ### Local Development 1. Clone repository 2. Copy `.env.example` to `.env` and configure 3. Run `docker-compose up -d` 4. Access: `http://localhost` or configured local domain 5. Create test tenants: `php artisan tenants:create` ### Making Changes 1. **Never modify Krayin core** - extend via Laravel patterns 2. **Test with multiple tenants** - always verify isolation 3. **Follow PSR-12** coding standards (enforced by Pint) 4. **Run quality checks** before committing: ```bash make lint # Run PHPStan + Pint make test # Run test suite ``` 5. **Write tests** for new features (PHPUnit/Pest) 6. **Update translations** when adding UI text 7. **Document breaking changes** in pull requests 8. **Use pre-commit hooks** to catch issues early ### Testing Strategy - **Unit Tests**: Core business logic, services - **Feature Tests**: Tenant isolation, API endpoints - **Browser Tests**: Multi-tenant user flows (Dusk) - **Database Tests**: Migration rollback/forward - Test with at least 2-3 active tenants - **CI/CD Integration**: All tests run automatically on push - **Coverage Goal**: Minimum 70% code coverage ### Deployment Process 1. **Create feature branch** from `main` 2. **Develop and test locally** 3. **Push to `staging` branch** for staging deployment 4. **Test on staging environment** (`staging.growuppro.com.br`) 5. **Create Pull Request** to `main` (after PR approval) 6. **Merge to `main`** - GitHub Actions runs automatically 7. **Monitor deployment** in Portainer 8. **Verify health checks** pass 9. **Test critical flows** on production 10. **Sentry** monitors for runtime errors ## Common Tasks ### Quick Development Commands (Makefile) ```bash make dev # Start local development environment make prod # Start production-like local environment make test # Run test suite make lint # Run PHPStan + Pint checks make fix # Auto-fix code style issues make deploy-staging # Deploy to staging make deploy-prod # Deploy to production make logs # Show application logs make shell # Enter application container shell make db-fresh # Fresh database with seeders make tenant-create # Create a new demo tenant ``` ### Creating a tenant-scoped feature 1. Create migration in `database/migrations/tenant/` 2. Run migrations: `php artisan tenants:migrate` 3. Create model (no special traits needed) 4. Add routes in `routes/tenant.php` 5. Build controller with tenant-aware logic ### Adding a new translation 1. Edit `resources/lang/pt_BR/{file}.php` 2. Add translation key and Portuguese text 3. Use in Blade: `{{ __('messages.welcome') }}` 4. Test across different tenant contexts ### Customizing tenant branding 1. Store settings in Tenant model (JSON or relations) 2. Load in middleware or service provider 3. Pass to views via view composer 4. Cache for performance: `tenant()->cache('branding')` ### Updating Docker image 1. Modify `docker/Dockerfile` as needed 2. Test locally: `make build` or `docker-compose build app` 3. Push changes to GitHub 4. CI/CD handles the rest automatically ### Creating demo tenants for testing ```bash # Using artisan command php artisan tenants:seed # Or via Makefile make tenant-create # Specify tenant details php artisan tenants:create \ --domain=demo.growuppro.com.br \ --name="Empresa Demo" \ --email=admin@demo.com ``` ### Managing code quality ```bash # Run static analysis ./vendor/bin/phpstan analyse # Check code style ./vendor/bin/pint --test # Auto-fix code style ./vendor/bin/pint # Or use Makefile shortcuts make lint # Check only make fix # Auto-fix ``` ### Setting up pre-commit hooks ```bash # Install Husky (or similar) npm install --save-dev husky # Initialize hooks npx husky init # Add pre-commit hook echo "make lint && make test" > .husky/pre-commit chmod +x .husky/pre-commit ``` ## Environment Variables ### Required Variables ```env # Application APP_NAME="Growup Pro" APP_ENV=production APP_KEY=base64:... APP_URL=https://growuppro.com.br APP_LOCALE=pt_BR APP_DEBUG=false # Database (Central) DB_CONNECTION=mysql DB_HOST=database DB_PORT=3306 DB_DATABASE=growuppro_central DB_USERNAME=growuppro DB_PASSWORD=secure_password # Tenancy TENANCY_DATABASE_PREFIX=tenant_ CENTRAL_DOMAINS=growuppro.com.br # Redis REDIS_HOST=redis REDIS_PASSWORD=null REDIS_PORT=6379 # Cache & Queue CACHE_DRIVER=redis QUEUE_CONNECTION=redis SESSION_DRIVER=redis # Sentry (Error Tracking) SENTRY_LARAVEL_DSN=https://xxx@sentry.io/xxx SENTRY_TRACES_SAMPLE_RATE=0.2 SENTRY_PROFILES_SAMPLE_RATE=0.2 # Gitea Container Registry (or GitHub Container Registry as fallback) REGISTRY_URL=gitea.yourdomain.com REGISTRY_USERNAME=cauefaleiros REGISTRY_PASSWORD=... # Or use token # GitHub Container Registry (GHCR) - if using as fallback GHCR_TOKEN=ghp_... GHCR_USERNAME=cauefaleiros GHCR_IMAGE=ghcr.io/cauefaleiros/growup-pro # Portainer PORTAINER_URL=https://148.230.76.122:9443 PORTAINER_API_TOKEN=ptr_... PORTAINER_STACK_ID=... # Cloudflare (Optional - for API integration) CLOUDFLARE_API_TOKEN=... CLOUDFLARE_ZONE_ID=... ``` ## Admin Dashboard for Tenant Management The platform includes a comprehensive admin dashboard for managing tenants and monitoring platform health. ### Dashboard Features **Tenant Management:** - View all active tenants with key metrics - Create/edit/delete tenant accounts - Suspend or activate tenant access - View tenant resource usage (storage, bandwidth, users) - Manage tenant subscriptions and billing **Analytics & Monitoring:** - Total active tenants count - Growth metrics (new tenants per month) - Resource utilization per tenant - Most active tenants (by usage) - Revenue tracking (if applicable) - System health overview **Tenant Details View:** - Company information and contact details - Subdomain and custom domain settings - User count and activity logs - Storage usage and database size - Last login and activity timestamps - Custom branding settings (logo, colors) **Bulk Operations:** - Bulk tenant creation via CSV import - Batch notifications to multiple tenants - Mass configuration updates - Export tenant data for reporting **System Settings:** - Default tenant configurations - Resource limits and quotas - Email templates for tenant communications - Feature flags management - Maintenance mode per tenant ### Access Control - Admin dashboard accessible only to super admins - Route: `/admin` (protected by `SuperAdmin` middleware) - Audit logs for all admin actions - Two-factor authentication required ### Implementation Notes - Built with Filament Admin Panel (recommended) or custom Blade views - Real-time updates using Livewire - Caching for performance (tenant list, metrics) - API endpoints for programmatic access - Webhooks for tenant lifecycle events (created, suspended, deleted) ## Notes for Gemini AI Assistant ### Context Awareness - This is **Growup Pro**, not Krayin - always use correct branding - All text should be in **Portuguese (pt-BR)** when user-facing - Consider **tenant context** in all suggestions - Respect **Docker/Swarm constraints** in infrastructure suggestions ### Code Suggestions - Prefer extending over modifying Krayin core - Ensure **tenant isolation** in all data operations - Follow **Tenancy for Laravel best practices** - Include proper **error handling** (tenant not found, DB connection issues) - Suggest **Docker-compatible** solutions (env vars, volumes, etc.) - Always consider **Sentry error tracking** when suggesting error handling - Recommend **testable code** (dependency injection, mockable services) - Suggest **code quality improvements** when reviewing code (PHPStan compliance) ### Infrastructure Suggestions - Consider **Docker Swarm** constraints (secrets, configs, networks) - Suggest **zero-downtime** deployment strategies - Include **health checks** in Docker configurations - Recommend **scalable** solutions (horizontal scaling, load balancing) ### Translation Reminders - Always provide Portuguese translations for new strings - Check existing translation files before adding new keys - Maintain consistent terminology across the application ## Quality Assurance & Best Practices ### Code Quality Tools The project enforces code quality through automated tools: **PHPStan (Static Analysis):** - Level 5 minimum (configurable in `phpstan.neon`) - Catches type errors, undefined variables, incorrect method calls - Runs on every commit (pre-commit hook) - Must pass before deployment **Laravel Pint (Code Formatter):** - PSR-12 coding standard enforcement - Automatic code formatting - Consistent code style across the team - Can auto-fix issues: `./vendor/bin/pint` **Pre-commit Hooks:** - Automatically run before every commit - Prevents committing code that doesn't pass quality checks - Fast feedback loop for developers - Configured via Husky or similar ### Error Tracking with Sentry **Setup:** ```bash composer require sentry/sentry-laravel php artisan sentry:publish --dsn ``` **Features:** - Real-time error notifications - Complete stack traces with context - User tracking (which tenant experienced the error) - Performance monitoring - Release tracking (know which deployment introduced bugs) **Configuration:** ```php // config/sentry.php 'dsn' => env('SENTRY_LARAVEL_DSN'), 'environment' => env('APP_ENV'), 'traces_sample_rate' => 0.2, // 20% of requests 'profiles_sample_rate' => 0.2, ``` **Tenant Context:** Always include tenant information in Sentry reports: ```php \Sentry\configureScope(function (\Sentry\State\Scope $scope): void { $scope->setTag('tenant_id', tenant('id')); $scope->setContext('tenant', [ 'name' => tenant('name'), 'domain' => tenant('domain'), ]); }); ``` ### Testing Standards - **Coverage minimum**: 70% code coverage - **Test pyramid**: More unit tests, fewer integration/feature tests - **Tenant isolation tests**: Critical - must verify data doesn't leak - **Performance tests**: Ensure queries are optimized (N+1 detection) - **CI enforcement**: All tests must pass before merge ## Resources & Documentation ### Project Specific - [Krayin CRM Docs](https://devdocs.krayincrm.com/) - [Krayin GitHub](https://github.com/krayin/laravel-crm) - [Tenancy for Laravel Docs](https://tenancyforlaravel.com/docs/v3/introduction) ### Infrastructure - [Docker Documentation](https://docs.docker.com/) - [Docker Compose Reference](https://docs.docker.com/compose/compose-file/) - [Docker Swarm Guide](https://docs.docker.com/engine/swarm/) - [Portainer Documentation](https://docs.portainer.io/) - [Portainer API Reference](https://docs.portainer.io/api/docs) ### CI/CD - [Gitea Actions Documentation](https://docs.gitea.com/usage/actions/overview) - [Gitea Actions Quickstart](https://docs.gitea.com/usage/actions/quickstart) - [act_runner Documentation](https://gitea.com/gitea/act_runner) - [GitHub Actions (for compatibility reference)](https://docs.github.com/en/actions) - [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) - [Docker Build Actions](https://github.com/docker/build-push-action) ### Laravel & PHP - [Laravel Documentation](https://laravel.com/docs) - [Laravel Multi-tenancy Patterns](https://laravel-news.com/multi-tenancy) - [PSR-12 Coding Standard](https://www.php-fig.org/psr/psr-12/) --- **Project**: Growup Pro **Base**: Krayin Laravel CRM (Whitelabel) **Current Phase**: Initial setup - multi-tenancy integration and Docker infrastructure **Domain**: growuppro.com.br **Language**: Portuguese (pt-BR) **Deployment**: Docker Swarm + Portainer + GitHub Actions CI/CD