Bump version to 0.18.1
This commit is contained in:
@@ -4,6 +4,63 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
|
||||
## [0.18.1] - 2026-09-16
|
||||
|
||||
### Added
|
||||
- `Modules\Core\Payment\Privacy\PaymentDataProvider` — `lunar_transactions` (`card_type`/
|
||||
`last_four`) and `stripe_payment_intents` were previously uncovered by any Privacy provider.
|
||||
Pseudonymizes card metadata on erasure (same tax/accounting retention reasoning as
|
||||
`OrderDataProvider`); deletes the Stripe correlation rows outright, since their only purpose
|
||||
(resolving an async webhook callback) has already been served by the time an erasure request
|
||||
runs. No Stripe Customer object exists anywhere in this app to also request deletion of — see
|
||||
`docs/payments.md` "Reconciliation".
|
||||
- `Modules\Core\Auth\Privacy\UserSessionDataProvider` — `user_sessions` (`ip_address`,
|
||||
`user_agent`) was previously uncovered. User-scope only; deleted outright on erasure, no legal
|
||||
retention argument applies to login-session metadata.
|
||||
- `Modules\Core\Logging\Privacy\ActivityLogDataProvider` — Spatie's `activity_log` table
|
||||
(`Modules\Core\Logging\ActivityLogService`, plus several Lunar models' native `LogsActivity`)
|
||||
durably retained full PII snapshots in `properties` even after the real row was erased
|
||||
elsewhere. Redacts `properties` by subject (`Customer`/`Address`/`CartAddress`/`OrderAddress`/
|
||||
`Transaction`) on erasure; deliberately never touches `causer_id`, which is an actor reference,
|
||||
not PII content. Must run before `AddressDataProvider` in `config('core.privacy.providers')` —
|
||||
see the class's own docblock.
|
||||
- `ErasureOutcome::Failed` — a provider throwing an exception is now a genuine, distinct outcome
|
||||
from `Skipped` (a deliberate no-op), surfaced in the erasure report rather than silently
|
||||
aborting the request.
|
||||
|
||||
### Fixed
|
||||
- `PrivacyService::completeErasure()` and `ExportDataSubjectJob::handle()` ran every registered
|
||||
provider through a plain `array_map()` with no per-provider error handling — one provider
|
||||
throwing aborted the entire request, discarding every other provider's already-computed
|
||||
result and leaving the request stuck `Pending`/`Failed` with no report at all. Both now catch
|
||||
per-provider (`PrivacyService::safeErase()`, `ExportDataSubjectJob::safeExport()`), logging the
|
||||
exception and recording `ErasureOutcome::Failed`/`ProviderExportResult::$error` for that one
|
||||
provider while every other provider's result is still recorded normally. Verified live:
|
||||
simulating a throwing provider mid-erasure now correctly completes the request with a mixed
|
||||
`erased`/`failed`/`erased` report instead of leaving it `Pending` forever.
|
||||
- `CartDataProvider`/`OrderDataProvider` never covered PII-adjacent keys living in `Cart.meta`/
|
||||
`Order.meta`/`OrderAddress.meta` — `recovery_consent*`, `payment_method`, `checkout_fingerprint`
|
||||
(Cart), `terms_accepted*` (Order), and `box_now_locker` (OrderAddress) all survived an erasure
|
||||
request untouched. Both providers now clear these keys alongside their existing address/
|
||||
free-text field erasure.
|
||||
- `CustomerDataProvider::eraseForUser()` left `otp_code`/`otp_expires_at`/`otp_attempts` on an
|
||||
otherwise-erased `User` row. Now cleared alongside name/email.
|
||||
- `Modules\Core\Privacy\Filament\Resources\DataErasureRequestResource`'s "Outcome" section
|
||||
referenced `docs/privacy.md` directly in staff-facing UI text (meaningless to a user with no
|
||||
repo access) and rendered the per-provider report as raw JSON strings via a `KeyValueEntry`
|
||||
(the wrong component for a list of structured rows). Replaced with a plain-language
|
||||
description and a proper `RepeatableEntry` table (Data category / Outcome badge / Reason).
|
||||
|
||||
### Changed
|
||||
- The 5 existing Privacy providers (`CustomerDataProvider`, `AddressDataProvider`,
|
||||
`OrderDataProvider`, `CartDataProvider`, `ReviewDataProvider`) moved out of
|
||||
`Modules\Core\Privacy\Providers` into their owning domain module's own `Privacy/` subdirectory
|
||||
(e.g. `Modules\Core\Order\Privacy\OrderDataProvider`) — `Modules\Core\Privacy` now owns only
|
||||
the shared contract, request lifecycle, and DTOs/enums. Matters concretely if a module is ever
|
||||
extracted into its own composer package: the provider that knows how to erase that module's
|
||||
data now travels with it, rather than being stranded in `Privacy` depending on a package that
|
||||
no longer ships in this repo. See `docs/privacy.md` for the full reasoning.
|
||||
|
||||
## [0.18.0] - 2026-09-16
|
||||
|
||||
### Added
|
||||
|
||||
Reference in New Issue
Block a user