Feature: Data Access and Data Export Admin Service
This commit introduces the data retention and data export Admin Services, accessed by the Boboko admin UI
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Core\Privacy\Filament\Extensions;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Notifications\Notification;
|
||||
use Lunar\Admin\Support\Extending\BaseExtension;
|
||||
use Lunar\Models\Customer;
|
||||
use Modules\Core\Auth\Models\Staff;
|
||||
use Modules\Core\Privacy\PrivacyService;
|
||||
|
||||
/**
|
||||
* Adds "Request erasure" / "Request export" header actions to the Customer
|
||||
* resource's edit/view page — the panel entry point for a staff member handling
|
||||
* "a customer emailed asking to be forgotten/for their data" without needing
|
||||
* tinker/code access. Registered centrally in CorePlugin, layered alongside
|
||||
* whatever CustomerResourceExtension a consuming app registers for its own
|
||||
* form/table/relations — LunarPanel::extensions() merges per resource (see
|
||||
* docs/modules.md "Layering Module and App Configuration"), and this extension
|
||||
* deliberately only implements headerActions(), so it never conflicts with an
|
||||
* app's own extension for the same resource.
|
||||
*/
|
||||
class CustomerErasureActionsExtension extends BaseExtension
|
||||
{
|
||||
public function headerActions(array $actions): array
|
||||
{
|
||||
return [
|
||||
...$actions,
|
||||
Action::make('requestErasure')
|
||||
->label('Request Erasure')
|
||||
->icon('heroicon-o-shield-exclamation')
|
||||
->color('danger')
|
||||
->requiresConfirmation()
|
||||
->modalDescription('Opens a cancellable grace-period erasure request for this Customer account. No linked User\'s login is affected.')
|
||||
->form([
|
||||
Checkbox::make('immediate')
|
||||
->label('Erase immediately (skip the 30-day grace period)')
|
||||
->helperText('Staff-only, for a formal legal request or regulator inquiry that genuinely requires urgency — not a routine deletion. Runs synchronously, cannot be cancelled once submitted.')
|
||||
->default(false),
|
||||
])
|
||||
->action(function (Customer $record, array $data) {
|
||||
$privacyService = app(PrivacyService::class);
|
||||
|
||||
if ($data['immediate']) {
|
||||
$privacyService->requestImmediateErasureForCustomer($record, $this->currentStaff());
|
||||
|
||||
Notification::make()
|
||||
->title('Customer erased')
|
||||
->body('Erasure ran immediately — see the Erasure Requests list for the outcome.')
|
||||
->success()
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$privacyService->requestErasureForCustomer($record, $this->currentStaff());
|
||||
|
||||
Notification::make()
|
||||
->title('Erasure requested')
|
||||
->body('The grace period starts now — see the Erasure Requests list.')
|
||||
->success()
|
||||
->send();
|
||||
}),
|
||||
Action::make('requestExport')
|
||||
->label('Request Export')
|
||||
->icon('heroicon-o-arrow-down-tray')
|
||||
->requiresConfirmation()
|
||||
->action(function (Customer $record) {
|
||||
app(PrivacyService::class)->requestExportForCustomer($record);
|
||||
|
||||
Notification::make()
|
||||
->title('Export requested')
|
||||
->body('Generating in the background — see the Export Requests list once it completes.')
|
||||
->success()
|
||||
->send();
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
private function currentStaff(): Staff
|
||||
{
|
||||
return auth('staff')->user();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user