feat: profile_photo en contratos activos, notificaciones bilingues en reportes y foto en panel usuarios

- API contratos activos (cliente y proveedor): agrega campo profile_photo (técnico asignado o supplier, null si no tiene)
- Notificaciones push bilingues en comentarios de reporte: "Nueva actividad en tu reporte" / "New activity on your report"
- Moderador en web panel notifica a cliente y proveedor al comentar, con prefijo Moderador/Moderator
- Panel usuarios: columna de foto de perfil entre ID y Nombre

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 17:17:14 -06:00
parent 38da1b56ce
commit 0ed98c96ee
40 changed files with 1390 additions and 651 deletions

View File

@@ -20,7 +20,7 @@ class CreateUsersTable extends Migration
$table->string('profile_photo')->nullable();
$table->BigInteger('role_id')->unsigned()->nullable();
$table->string('social_id')->unique()->nullable();
$table->string('openpay_id')->unique()->nullable();
$table->string('stripe_customer_id')->unique()->nullable();
$table->string('phone')->unique()->nullable();
$table->timestamp('phone_verified_at')->nullable();
$table->string('password')->nullable();

View File

@@ -16,7 +16,11 @@ class CreateCardsTable extends Migration
Schema::create('cards', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('token');
$table->string('stripe_pm_id')->unique();
$table->string('brand');
$table->string('last4', 4);
$table->unsignedTinyInteger('exp_month');
$table->unsignedSmallInteger('exp_year');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});

View File

@@ -36,7 +36,9 @@ class CreateFinishedcontractsTable extends Migration
$table->unsignedBigInteger('parent_contract_id')->nullable();
$table->Integer('score')->nullable();
$table->timestamp('scored_at')->nullable();
$table->unsignedBigInteger('technical_id')->nullable();
$table->boolean('paid')->default(false);
$table->timestamp('paid_at')->nullable();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('set null');
$table->foreign('supplier_id')->references('id')->on('suppliers')->onDelete('set null');

View File

@@ -34,6 +34,7 @@ class CreateCurrentContractsTable extends Migration
$table->unsignedBigInteger('status_id')->nullable()->default('1');
$table->BigInteger('code')->nullable();
$table->unsignedBigInteger('parent_contract_id')->nullable();
$table->unsignedBigInteger('technical_id')->nullable();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('set null');
$table->foreign('supplier_id')->references('id')->on('suppliers')->onDelete('set null');

View File

@@ -0,0 +1,27 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePaymentBatchesTable extends Migration
{
public function up()
{
Schema::create('payment_batches', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('file_name');
$table->string('file_path');
$table->unsignedBigInteger('generated_by')->nullable();
$table->date('date_from')->nullable();
$table->date('date_to')->nullable();
$table->timestamps();
$table->foreign('generated_by')->references('id')->on('users')->onDelete('set null');
});
}
public function down()
{
Schema::dropIfExists('payment_batches');
}
}

View File

@@ -0,0 +1,42 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTechniciansTable extends Migration
{
public function up()
{
Schema::create('technicians', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('supplier_id');
$table->timestamps();
$table->unique(['user_id', 'supplier_id']);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('supplier_id')->references('id')->on('suppliers')->onDelete('cascade');
});
Schema::table('finished_contracts', function (Blueprint $table) {
$table->foreign('technical_id')->references('id')->on('technicians')->onDelete('set null');
});
Schema::table('current_contracts', function (Blueprint $table) {
$table->foreign('technical_id')->references('id')->on('technicians')->onDelete('set null');
});
}
public function down()
{
Schema::table('finished_contracts', function (Blueprint $table) {
$table->dropForeign(['technical_id']);
});
Schema::table('current_contracts', function (Blueprint $table) {
$table->dropForeign(['technical_id']);
});
Schema::dropIfExists('technicians');
}
}

View File

@@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::dropIfExists('cards');
}
public function down(): void
{
Schema::create('cards', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('stripe_pm_id')->nullable();
$table->string('brand')->nullable();
$table->string('last4')->nullable();
$table->unsignedTinyInteger('exp_month')->nullable();
$table->unsignedSmallInteger('exp_year')->nullable();
$table->timestamps();
});
}
};