refactor(templates): plantillas globales + asignación por proyecto (pivot)

- Migración: tabla pivot inspection_template_project; drop de phase_id (asociación
  a fase descartada); project_id se mantiene en inspection_templates por compat.
  Migra automáticamente las plantillas existentes (project_id → pivot).
- Modelos: Project::inspectionTemplates() ↔ InspectionTemplate::projects() (BTM);
  retirada la relación phase() de InspectionTemplate.
- GlobalTemplateManager (nuevo, ruta /inspection-templates, permiso manage templates):
  catálogo único global, CRUD + import CSV; sin asociación a fase ni a proyecto.
- ProjectTemplatesPicker (nuevo, ruta projects.templates, permiso edit projects):
  lista global con checkbox para asignar/desasignar plantillas al proyecto.
- ProjectMap: el selector de plantillas del mapa lee SOLO las asignadas al proyecto
  vía pivot. API móvil (bundle + /templates) adaptado al pivot.
- Eliminado el viejo TemplateManager por-proyecto, su vista wrapper y la tabla
  ImportTemplatesTable (ya no aplica: todas son globales).
- Acceso "Plantillas" añadido al menú principal (gate manage templates).

Tests: GlobalTemplatesTest (4). Suite 89 passing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-25 17:26:12 +02:00
co-authored by Claude Opus 4.7
parent 7256c87182
commit f8a68312a3
17 changed files with 386 additions and 639 deletions
@@ -49,7 +49,8 @@ class ProjectApiController extends Controller
$features = $changed(Feature::whereIn('layer_id', $allLayerIds))->get();
$inspections = $changed(Inspection::where('project_id', $project->id))->get();
$issues = $changed(Issue::where('project_id', $project->id))->get();
$templates = $changed(InspectionTemplate::where('project_id', $project->id))->get();
// Plantillas asignadas al proyecto (catálogo global vía pivot)
$templates = $changed(InspectionTemplate::whereHas('projects', fn ($q) => $q->where('projects.id', $project->id)))->get();
$allIssueIds = Issue::withTrashed()->where('project_id', $project->id)->pluck('id');
$issueTasks = $changed(IssueTask::whereIn('issue_id', $allIssueIds))->get();
@@ -92,7 +93,8 @@ class ProjectApiController extends Controller
$projectIds = Project::accessibleBy($request->user())->pluck('id');
$query = InspectionTemplate::whereIn('project_id', $projectIds);
// Plantillas asignadas a cualquier proyecto al que el usuario tenga acceso
$query = InspectionTemplate::whereHas('projects', fn ($q) => $q->whereIn('projects.id', $projectIds));
if ($since) {
$query->where('updated_at', '>', $since);
}