98 lines
6.0 KiB
PHP
98 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Services\VirtualDeskInstallation;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Validation\Rule;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class VirtualDeskInstallationController extends Controller
|
|
{
|
|
public function reviewLink(Request $request, string $id): JsonResponse|RedirectResponse
|
|
{
|
|
$data = $request->validate(['version' => 'required|integer|min:1', 'available' => 'required|boolean',
|
|
'evidence' => 'required|string|min:10|max:3000', 'contact' => 'nullable|string|max:255']);
|
|
DB::transaction(function () use ($request, $id, $data) {
|
|
$link = DB::table('desk_institutional_links')->where('id', $id)->lockForUpdate()->first();
|
|
abort_unless($link !== null, 404);
|
|
abort_unless((int) $link->version === (int) $data['version'], 409);
|
|
abort_unless(filter_var($link->url, FILTER_VALIDATE_URL) && parse_url($link->url, PHP_URL_SCHEME) === 'https', 422);
|
|
DB::table('desk_institutional_links')->where('id', $id)->update(['status' => $data['available'] ? 'active' : 'unavailable',
|
|
'contact' => $data['contact'] ?? $link->contact, 'verified_at' => now(), 'verified_by' => $request->user()->id,
|
|
'version' => $link->version + 1, 'updated_at' => now()]);
|
|
DB::table('audit_events')->insert(['source_system' => 'virtual-desk', 'entity_type' => 'desk_institutional_links', 'entity_id' => $id,
|
|
'actor_user_id' => $request->user()->id, 'action' => 'institutional_link_checked',
|
|
'after_data' => json_encode(['url' => $link->url, 'prior_version' => $link->version, ...$data, 'scope' => 'availability_only_not_legal_approval'])]);
|
|
});
|
|
|
|
return $request->expectsJson() ? response()->json(['checked' => true]) : back()->with('success', 'Conferência de disponibilidade registada por sete dias.');
|
|
}
|
|
|
|
public function sources(Request $request): JsonResponse|Response
|
|
{
|
|
$read = function (string $name): array {
|
|
$file = storage_path('app/private/virtual-desk/'.$name.'.json');
|
|
if (! is_file($file)) {
|
|
return [];
|
|
}
|
|
$bytes = file_get_contents($file);
|
|
abort_unless(is_string($bytes), 503);
|
|
|
|
return json_decode($bytes, true, 512, JSON_THROW_ON_ERROR);
|
|
};
|
|
$inventory = $read('source-inventory');
|
|
$forms = $read('form-register');
|
|
$data = ['total' => count($inventory), 'attachmentCount' => array_sum(array_map(fn ($item) => count($item['attachments'] ?? []), $inventory)),
|
|
'forms' => array_map(fn ($item) => ['identifier' => $item['identifier'], 'sha256' => $item['sha256'], 'size' => $item['size'], 'edition' => $item['edition'],
|
|
'provenance' => str_contains($item['path'], DIRECTORY_SEPARATOR.'Scan'.DIRECTORY_SEPARATOR) ? 'Acervo disponibilizado — digitalização' : 'Acervo disponibilizado — fonte de desenho ou template',
|
|
'consultation' => $item['consultation'], 'legal_documentary_status' => $item['legal_documentary_status'], 'rule_use' => $item['rule_use'], 'official_confirmation' => $item['official_confirmation'], 'fields_status' => $item['fields_status']], $forms),
|
|
'source' => config('virtual-desk.source')];
|
|
|
|
return $request->expectsJson() ? response()->json($data) : Inertia::render('desk/sources', $data);
|
|
}
|
|
|
|
public function preview(Request $request, VirtualDeskInstallation $installation): JsonResponse|Response
|
|
{
|
|
$data = $installation->preview();
|
|
|
|
return $request->expectsJson() ? response()->json($data) : Inertia::render('desk/install', $data);
|
|
}
|
|
|
|
public function apply(Request $request, VirtualDeskInstallation $installation): JsonResponse|RedirectResponse
|
|
{
|
|
$data = $request->validate(['hash' => 'required|string|size:64', 'confirm' => 'accepted']);
|
|
$installation->apply($data['hash'], $request->user());
|
|
|
|
return $request->expectsJson() ? response()->json(['installed' => true]) : back()->with('success', 'Instalação concluída; serviços ainda exigem publicação explícita.');
|
|
}
|
|
|
|
public function publishService(Request $request): JsonResponse|RedirectResponse
|
|
{
|
|
$data = $request->validate(['code' => ['required', Rule::in(array_keys(config('virtual-desk.services')))], 'confirm' => 'accepted']);
|
|
$row = DB::transaction(function () use ($request, $data) {
|
|
DB::select('select pg_advisory_xact_lock(261008, 2)');
|
|
$definition = config('virtual-desk.services.'.$data['code']);
|
|
$existing = DB::table('desk_service_versions')->where('code', $data['code'])->orderByDesc('version')->first();
|
|
if ($existing && $existing->status === 'published' && json_decode($existing->definition, true) === $definition) {
|
|
return $existing;
|
|
}
|
|
$id = (string) Str::uuid();
|
|
DB::table('desk_service_versions')->insert(['id' => $id, 'code' => $data['code'], 'version' => ($existing->version ?? 0) + 1, 'status' => 'published',
|
|
'definition' => json_encode($definition), 'source' => json_encode(config('virtual-desk.source')), 'author_id' => $request->user()->id,
|
|
'published_by' => $request->user()->id, 'published_at' => now(), 'created_at' => now(), 'updated_at' => now()]);
|
|
DB::table('audit_events')->insert(['source_system' => 'virtual-desk', 'entity_type' => 'desk_service_versions', 'entity_id' => $id, 'actor_user_id' => $request->user()->id,
|
|
'action' => 'internal_service_published', 'after_data' => json_encode(['code' => $data['code'], 'nature' => 'digital_preparation_not_official_form'])]);
|
|
|
|
return DB::table('desk_service_versions')->where('id', $id)->first();
|
|
});
|
|
|
|
return $request->expectsJson() ? response()->json(['id' => $row->id], 201) : back()->with('success', 'Serviço de preparação interna publicado.');
|
|
}
|
|
}
|