Vasyka
10426d0c91
Central panel SaaS upgrade — Plans/Subscriptions/SuperAdmins/Detail page
...
Models & migrations:
- subscriptions table (company, plan, period, amount, status, dates, invoice)
- super_admins: role enum (owner/admin/support/sales/finance) + phone + notes
- Subscription model with STATUSES/PERIODS/PAYMENT_METHODS + invoice number
generator + extends company.active_until on mark_paid
- Company model: subscriptions() + latestSubscription() relations
- SuperAdmin model: role helpers (isOwner, canManageBilling, canManageTenants)
Filament Central panel:
- PlanResource (CRUD, features checklist, limits per plan, abonati count badge)
- SubscriptionResource (CRUD, mark_paid action, navigation badge for overdue)
- SuperAdminResource (CRUD, reset password, toggle 2FA, can't self-delete)
- ViewCompany page with live stats (users/clients/vehicles/WO/parts/revenue/
storage/last_login + days_until_expiry), subscriptions history table,
config snapshot, action buttons (open/issue invoice/upload logo/suspend)
- CompanyResource: row click → view, openUrlInNewTab action, recordTitleAttribute,
empty state, view route registered
- PlatformStats widget upgraded: 6 cards (incl. MRR realized this month, overdue
invoices count, click-through to filtered tables)
- RevenueChart: 12-month MRR line chart
- RecentTenants: latest 8 tenants with click-through
- PendingPayments: pending+overdue invoices table
- Database notifications enabled + Cmd+K global search
- HEAD_END render hook: PWA manifest + theme color + emoji favicon
- /admin-manifest.json route
Seeder:
- Plans aligned with new FEATURE_OPTIONS (kanban/pdf/reports/ai/api/reverb/etc)
- 4 plans: Free / Basic / Pro / Enterprise (with proper limits)
- SuperAdmin gets role='owner'
- Demo subscription for psauto on Pro plan, marked paid this month
2026-05-07 22:02:44 +00:00
Vasyka
138671a125
fix: stub login route so auth middleware redirect resolves
2026-05-07 19:47:38 +00:00
Vasyka
74c6bcb9f1
fix: api routes prefix (Laravel 12 auto-prefixes /api)
2026-05-07 19:29:04 +00:00
Vasyka
eaa05d68c1
Deploy 2: 2FA (App + Email) + REST API + CSV import-export + auto backup
...
- Filament v5 multiFactorAuthentication enabled on both panels (App + Email)
- HasAppAuthentication + HasEmailAuthentication on User and SuperAdmin
- Migration: app_authentication_secret + recovery_codes + email_authentication_at
- Sanctum REST API: /api/v1/login, /me, clients, vehicles, work-orders
- EnsureTokenMatchesTenant middleware blocks cross-tenant token usage
- CsvImportExport service: clients + vehicles bulk via plain CSV
- Import/Export buttons on Client + Vehicle list pages
- ApiTokens page in tenant panel (generate/revoke + last-used)
- BackupAllTenantsCommand + scheduler (daily 03:00, retain 14 days)
- Background scheduler in entrypoint.sh
2026-05-07 19:25:27 +00:00
Vasyka
d1e0695930
Deploy 1: i18n + Notifications + Global Search + Tests
...
- SetLocale middleware (ro/ru/en, session-first, user-persisted)
- Lang switcher in topbar (Filament render hook USER_MENU_BEFORE)
- POST /locale/{lang} route persists to user.locale + session
- Database notifications enabled on tenant panel (30s polling)
- GlobalSearch (Cmd+K / Ctrl+K) on Client, Vehicle, WorkOrder, Lead, Part
- Tests: TenantIsolation (4), AuthFlow (2), WorkOrderCalc (3), MarkupRule (3)
2026-05-07 18:22:48 +00:00
Vasyka
4b3201ca1c
Batch 2: Workload heatmap + Site PSauto + VIN search
...
═══ Workload heatmap (Încărcare STO) ═══
- /app/workload custom Page (group Analiză)
- Săptămână (Lu-Du) × posturi → matrice ore programate
- Heatmap colorat: verde→galben→roșu pe ratio capacity (10h/zi)
- Navigare săpt anterior/curent/următor
- Programări fără pod → row '— fără pod —' separat
═══ Site PSauto (landing public) ═══
- / pe tenant subdomain → resources/views/site/landing.blade.php
- Hero cu logo + nume + slogan; gradient theme color
- Servicii (din settings.services) — grid card-uri
- Locație/contact + program lucru standardizat
- Mărci suportate (din settings.cars)
- CTA: phone + email
- Footer cu tenant name + powered by AutoCRM
═══ VIN search ═══
- VinDecoder service: WMI hardcoded (24 producători EU/Asia/USA)
+ year codes (2001-2026) — pure offline, fără API extern
- /app/vin-search Page (group Depozit) cu:
• Input VIN cu uppercase + monospace
• Decode → producător/țară/an/serial
• Match VIN-uri din baza Vehicles
• Search piese din catalog (live debounce 300ms)
- Rezultatele linkează la editor Vehicle/Part
Total tenant routes: 102.
2026-05-07 17:16:09 +00:00
Vasyka
7ce78c350c
Reverb infra + Kanban live refresh
...
- laravel/reverb instalat + reverb:install (config/reverb.php, channels.php)
- routes/channels.php: tenant.{slug} private channel cu auth check
user.company_id == tenant.id
- App\Events\WorkOrderUpdated implements ShouldBroadcast pe
PrivateChannel('tenant.{slug}'); broadcastAs 'work-order.updated'
- WorkOrder::booted dispatch event la fiecare update (skip if broadcast=log)
- Filament panel BODY_END inject:
- Pusher JS de la CDN (compatibil Reverb)
- Echo client conectat la Reverb (config dinamic din env)
- Subscribe pe tenant private channel; la 'work-order.updated' →
Livewire.all().forEach($refresh)
- Kanban view: wire:poll.5s (live refresh fallback) +
x-on:autocrm:wo-updated.window=$refresh (instant când WS e activ)
Pentru moment BROADCAST_CONNECTION=log în Coolify (Reverb nu e deployat).
Când deployezi Reverb container separat:
Coolify → New App → Same repo → CMD override:
php artisan reverb:start --host=0.0.0.0 --port=8080
→ FQDN: ws.service.mir.md:8080
→ Set BROADCAST_CONNECTION=reverb pe AutoCRM app
→ Real-time instant fără cod nou.
2026-05-07 14:25:26 +00:00
Vasyka
cbc66b13c3
fix: Spatie ActivityLog v5 namespace — Models\Concerns\LogsActivity (was Traits\LogsActivity in v4)
...
Spatie\Activitylog\Traits\LogsActivity → Spatie\Activitylog\Models\Concerns\LogsActivity
Spatie\Activitylog\LogOptions → Spatie\Activitylog\Support\LogOptions
2026-05-07 11:22:36 +00:00
Vasyka
66dd0772b5
debug: /__check-activitylog to verify package install
2026-05-07 10:39:54 +00:00
Vasyka
06696727dd
Faza 6: Activity log + Kanban + Payroll + cleanup
...
══════ Activity log (Spatie) ══════
- spatie/laravel-activitylog v5 instalat
- Migration cu company_id pentru tenant scoping
- Trait Auditable (App\Models\Concerns\Auditable):
- LogOptions cu logFillable + logOnlyDirty + dontSubmitEmptyLogs
- tapActivity auto-fill company_id + causer
- Descrieri RO (creat/modificat/șters/restaurat)
- Aplicat pe: Client, Vehicle, Lead, Deal, WorkOrder, Payment, Expense
- ActivityResource (group Admin → Jurnal activitate)
- Listă read-only, scope pe tenant, filtre by description/today
══════ Kanban Work Orders ══════
- Custom Filament page la /app/kanban (group Service)
- 6 coloane (new → diagnosis → agreement → in_work → awaiting_parts → ready)
- Drag-drop nativ HTML5 cu wire:click moveCard()
- Cards arată: număr fișă, client, auto, plate, master, total
- Link 'Deschide' direct la editare WO
══════ Payroll (Salarii) ══════
Schema:
- employee_profiles: user_id, position, base_salary, works_pct, parts_pct
- payroll_runs: period (YYYY-MM), base, works_revenue/pct, parts_margin/pct,
bonus, fines, advance, total auto-calculat
- payroll_adjustments: bonus/fine/advance per period
PayrollCalculator service:
- compute($userId, $period) — calculează auto:
- Manopere finalizate de mecanic în luna respectivă (sum total)
- Marja pieselor montate de el (sell-buy * qty)
- Bonus + fines + advance from adjustments
- Total = base + works% + parts% + bonus - fines - advance
Resources Filament (group Finanțe):
- EmployeeProfileResource: profil cu % comisioane
- PayrollRunResource: salarii cu action 'Calculează luna curentă' (toți userii)
+ per-row 'Recalculează'; Sum summary pe total
- PayrollAdjustmentResource: gestionare bonus/penalizări/avansuri
══════ Cleanup ══════
- Șterse toate /__debug, /__seed, /__try-login, /__force-login, /__whoami,
/__coolify-check (security)
- Routes/web.php conține doar / redirect, /manifest.json, /sw.js
Total Filament tenant routes: 92.
2026-05-07 09:52:01 +00:00
Vasyka
9192914de4
debug: /__coolify-check route to inspect runtime config
2026-05-07 07:27:31 +00:00
Vasyka
97a1adaa7b
fix: empty stancl tenant.php (we use slug-based resolution, not domain-based)
2026-05-07 05:55:01 +00:00
Vasyka
4d5e240602
fix: / redirects to /app (tenant) or /admin (central)
2026-05-07 05:06:25 +00:00
Vasyka
8d82af2f54
Faza 3.5+3.6+4+5: Marketing, Reports, Provisioning, PWA
...
═══ Faza 3.5: Marketing ═══
Schema: msg_templates, marketing_channels, calls
Modele cu logică:
- MessageTemplate::render($context) — substituie {key} tokens
- MarketingChannel: roi/conversion_rate/cost_per_lead computed attrs
- Call: duration_formatted helper
Resources Filament (group Marketing):
- MessageTemplateResource: 5 canale (telegram/whatsapp/viber/sms/email)
- MarketingChannelResource: budget vs revenue cu ROI live calculat
- CallResource: in/out/missed cu filtre azi/missed
═══ Faza 3.6: Analytics ═══
Custom Filament Page Reports cu 6 rapoarte tab-uite:
- Finanțe: încasări/cheltuieli/profit/datorii + breakdown pe metodă/categorie
- Încărcare: fișe deschise/închise + breakdown pe status
- Mecanici: ore lucrate, manopere, venit per mecanic
- Manopere top: cele mai frecvente cu nr/ore/venit
- Piese: top vândute + low-stock
- Clienți: noi în perioadă + lead-uri pe sursă
Selector perioadă: azi / săptămâna / luna / luna trecută / anul
═══ Faza 4: Central provisioning ═══
- CoolifyClient service (Coolify v4 REST API wrapper)
- CompanyProvisioner: creează Company + admin user + roles + adaugă
subdomeniul în Coolify FQDN + trigger redeploy automat
- CreateCompany page override → folosește provisioner, returnează
notificare cu credentialele admin
- Form CompanyResource extins cu admin_name/email/password (vizibil doar create)
- Action 'Suspendă' / 'Activează' pe table cu confirmation
Env vars necesare în Coolify pentru provisioning auto:
COOLIFY_API_URL=http://65.21.20.141:8000
COOLIFY_API_TOKEN=<token>
COOLIFY_APP_UUID=g13hlrpd5g44zxl5af3ktio2
═══ Faza 5: PWA + branding ═══
- Route /manifest.json dinamic per tenant (nume, theme color, icons)
- Route /sw.js — service worker minimal (cache shell + static)
- TenantPanelProvider renderHook HEAD_END — link manifest + theme-color
+ apple-mobile-web-app meta
- TenantPanelProvider renderHook BODY_END — registrare service worker
Seed extins:
- 5 template-uri mesaje (programare/auto-gata/reminder/ITP/felicitare)
- 5 canale marketing (Google Ads/FB/IG/Telegram/Recomandări)
- 2 apeluri demo
Total Filament tenant routes: 81.
2026-05-07 04:55:33 +00:00
Vasyka
51a0bab39e
Faza 3.2: Service modules — Norme-ore, Tehnicieni, Fișe lucru
...
Schema:
- users + specialization, color, hourly_rate (pentru maistri)
- labors: catalog manopere standard cu category/ore/preț (RO+RU)
- work_orders: nr unique per tenant, status workflow (9 stări),
pay_status (3 stări), client/vehicle/master/deal/appointment refs,
complaint/diagnosis/recommendations, total auto-calculat
- wo_works: manopere per fișă, recalc auto la save/delete
- wo_parts: piese per fișă (free-text deocamdată), discount/total auto
Filament resources (group Service):
- LaborResource: CRUD + grupare pe categorie + filter active
- WorkOrderResource: form complex în 4 secțiuni (antet, diagnostic, plată)
+ 2 RelationManagers (Works, Parts)
- MasterResource: vedere User filtrată role=mechanic, edit specializare/
culoare calendar/tarif oră
Conversie auto: la adaugare manoperă din catalog Labor,
form populează numele + ore + preț/oră derivat (price/hours).
Number generator pentru WO: format WO-{YY}-{NNNN} per tenant per an,
calculat în CreateWorkOrder via WorkOrder::generateNumber().
Seed extins:
- 3 mecanici (Vasile/Andrei/Nicolae) cu culori + specializări
- 10 manopere standard din prototipul AutoCRM.html
- 1 fișă demo (BMW X5 plăcuțe Brembo) cu 1 manoperă + 1 piesă, total auto
2026-05-06 21:24:07 +00:00
Vasyka
dd74109adf
debug: /__whoami inspect session state
2026-05-06 20:24:50 +00:00
Vasyka
39fcfcc7ff
debug: /__force-login to test session persistence
2026-05-06 20:10:38 +00:00
Vasyka
907f462ed1
debug: /__try-login route to diagnose auth failure
2026-05-06 19:56:17 +00:00
Vasyka
3328f9f1c6
debug: /__seed/{token} route for manual seed + error report
2026-05-06 18:20:50 +00:00
Vasyka
c65541cb88
debug: temporary /__debug/{token} route for login diagnosis
2026-05-06 18:18:04 +00:00
Vasyka
5e32f82b3a
Initial Laravel 12 + Filament 5 + Octane skeleton
...
- Laravel 12 base
- Filament 5 (default admin panel)
- Stancl/Tenancy v3 (config + migrations only)
- Spatie Permission
- Octane FrankenPHP runtime
- Sanctum
- Dockerfile multi-stage (composer + node + frankenphp:8.4)
- Entrypoint runs migrations + caches on boot
- .env.example pre-completat cu hosturi interne Coolify
- Health endpoint /up
Repo init pentru multi-tenant SaaS pe Coolify Hetzner.
2026-05-04 12:19:55 +00:00