From 59303cf25f949e2b75debd43578c59675e2bda8c Mon Sep 17 00:00:00 2001 From: Konstantinos Arvanitakis Date: Mon, 24 Aug 2026 21:44:10 +0300 Subject: [PATCH] Feature: Updating Readme to reflect changes on Privacy --- README.md | 138 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 45a8329..de58319 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # Core Module -A Laravel module providing authentication, notifications, activity logging, CLI tooling, and functional types on top of the [Lunar](https://lunarphp.io) admin panel. Designed to be consumed as a standalone Composer package. +A Laravel module providing authentication, localization, product search/catalog, privacy/GDPR +tooling, notifications, activity logging, CLI tooling, and functional types on top of the +[Lunar](https://lunarphp.io) e-commerce package. Designed to be consumed as a standalone Composer +package by any Lunar-based e-shop. --- @@ -8,13 +11,83 @@ A Laravel module providing authentication, notifications, activity logging, CLI ### OTP Authentication -Passwordless login for both staff (Lunar panel) and customers via 6-digit codes delivered by email. Codes expire after 10 minutes. The Lunar panel login page is a two-step flow: email → OTP. Rate-limited to 5 attempts. +Passwordless login for both staff (Lunar panel) and customers via 6-digit codes delivered by +email. Codes expire after 10 minutes, rate-limited to 5 attempts. The Lunar panel login page is a +two-step flow (email → OTP) with a back button to return from the code step to the email step. See [`docs/otp-auth.md`](docs/otp-auth.md). +### Localization + +Locale-prefixed routing (`Modules\Core\Localization\LocaleMiddleware`) — a `locale` route +middleware, opt-in per shop, that resolves and redirects to the correct language segment +(`/el/...`, `/en/...`) based on Lunar's own language list, with caching and rename-safe +translation migration. Also brings in storefront UI label translations +(`spatie/laravel-translation-loader`) with an admin-editable `LanguageLine` resource. + +See [`docs/localization.md`](docs/localization.md). + +### Product Search & Catalog + +Two complementary services on top of Meilisearch: + +- **`Modules\Core\Search\ProductSearchService`** — locale-aware full-text product search. +- **`Modules\Core\Catalog\ProductService`** — listing/filtering (by collection, brand, price + range) and single-product lookup by id or slug, reading directly from the Meilisearch index + rather than the database. + +Both are backed by `Modules\Core\Search\ProductIndexer`, which extends Lunar's own indexer with +collections, price, variants, media, tags, and reviews — everything needed for both a listing +page and a full product detail page from one index. + +See [`docs/product-search.md`](docs/product-search.md) and +[`docs/product-listing.md`](docs/product-listing.md). + +### Product Reviews + +`Modules\Core\Review\ProductReview` — ratings/reviews with staff replies, a Filament sub-navigation +page on the product edit screen, and automatic re-indexing (via `ReviewServiceProvider`) whenever +a review is created, updated, or deleted, so a product's Meilisearch document never goes stale. + +### Privacy / GDPR Data-Subject Requests + +Right of access (export) and right of erasure, built as an extensible contract +(`Modules\Core\Privacy\Contracts\PersonalDataProvider`) rather than a fixed table list — any +module can register its own data without core knowing it exists. + +- **Two independent scopes**: erasing/exporting a Lunar `Customer` (business account) is never + the same operation as erasing/exporting a `User` (individual login) — a `Customer` erasure + never touches any linked `User`'s login, and a `User` erasure never touches a `Customer` + account's own data. See `docs/privacy.md` "User-scope vs Customer-scope". +- **Cancellable grace period** (default 30 days, configurable) before anything is actually + erased — logging back in during the window automatically reverts the request, mirroring + Shopify's own account-deletion flow. Immediate erasure exists but is staff-only by type, never + reachable from a self-service flow. +- **Sole-owner cascade**: erasing the last remaining `User` on a `Customer` also opens a (grace + period) erasure request for that now-orphaned `Customer`, so its PII doesn't sit unreachable + forever — traced back to the triggering request so login-reactivation can revert exactly that + cascade. +- **Queued export**: gathering data and writing a CSV-per-provider zip (via the generic, + reusable `Modules\Core\Export\CsvWriter`) runs as a background job; a consuming app hooks its + own notification onto the completion event via the Notification Registry (below). + +See [`docs/privacy.md`](docs/privacy.md). + +### Shopify Migration + +`Modules\Core\MigrateImport\Shopify\ShopifyExportImporter` — imports a Shopify CSV product export +(products, variants, images, collections, tags, prices) into Lunar, idempotently re-runnable via +an `import_mappings` table. Part of a source-agnostic import framework +(`boboko:migrate:import`) designed to support additional sources later. + +See [`docs/shopify-import.md`](docs/shopify-import.md). + ### Notification Registry -An event-driven notification system. Each notification class declares which event it listens to and who to notify — the registry wires up the listener automatically. All notifications extend `BaseNotification` which implements `ShouldQueue`, so delivery is async. Supports optional delays. +An event-driven notification system. Each notification class declares which event it listens to +and who to notify — the registry wires up the listener automatically. All notifications extend +`BaseNotification`, which implements `ShouldQueue`, so delivery is async. Supports optional +delays. **Creating a notification:** @@ -33,9 +106,13 @@ class MyNotification extends BaseNotification NotificationRegistry::get()->register([MyNotification::class]); ``` +See [`docs/notifications.md`](docs/notifications.md). + ### Activity Logging -Thin wrapper around [Spatie Laravel Activity Log](https://github.com/spatie/laravel-activitylog). Four standardized methods: `created()`, `updated()`, `failed()`, `deleted()`. Logs to the `lunar` channel and auto-resolves the actor from the staff session. +Thin wrapper around [Spatie Laravel Activity Log](https://github.com/spatie/laravel-activitylog). +Four standardized methods: `created()`, `updated()`, `failed()`, `deleted()`. Logs to the `lunar` +channel and auto-resolves the actor from the staff session. See [`docs/activity-log.md`](docs/activity-log.md). @@ -43,8 +120,11 @@ See [`docs/activity-log.md`](docs/activity-log.md). - Custom OTP login page replacing the default Lunar panel login - `StaffResourceExtension` — removes password field from Lunar's staff resource -- `CustomerResourceExtension` — replaces default address relation manager with a custom implementation -- `CorePlugin` — configures panel path, branding, logos, navigation items, and activity log field exclusions for staff +- `CustomerResourceExtension` — replaces default address relation manager with a custom + implementation +- Table-rate shipping (`ShippingPlugin`) registered by default +- `CorePlugin` — configures panel path, branding, logos, navigation items, and activity log + field exclusions for staff Register the plugin in your Lunar panel provider: @@ -52,30 +132,36 @@ Register the plugin in your Lunar panel provider: ->plugin(\Modules\Core\CorePlugin::make()) ``` +See [`docs/lunar.md`](docs/lunar.md) for the full Lunar reference and non-obvious gotchas hit +while building against it. + ### CLI Commands | Command | Description | |---|---| -| `core:create-admin` | Create a Lunar admin user | -| `core:anonymize` | GDPR anonymization of users and customers (local only) | -| `core:export` | Dump database + storage files to a timestamped zip | -| `core:import` | Restore from a zip export (runs anonymize automatically, local only) | -| `core:export-cleanup` | Delete old export zips, keep N most recent | +| `boboko:anonymize` | Dummy-scrub personal data in `users`/`lunar_customers` for local dev safety (local environment only — **not** the GDPR erasure tool; see Privacy above for that) | +| `boboko:export` | Dump database + storage files to a timestamped zip | +| `boboko:import` | Restore from a `boboko:export` zip archive | +| `boboko:export:cleanup` | Delete old export zips, keep N most recent | +| `boboko:migrate:import` | Import a vendor product catalog (Shopify, etc.) into Lunar | +| `boboko:privacy:process-erasure-requests` | Dispatch an erasure job for every due GDPR erasure request (wire into your own scheduler) | +| `lunar:create-admin` | Create a Lunar admin user (overrides Lunar's own command) | +| `lunar:install` | Seed default Lunar store data — countries, channel, currency, tax zone, attributes, product type (overrides Lunar's own command) | ### Functional Types -Result and Option monads for explicit error handling without exceptions. +Result and Option types for explicit error handling without exceptions. ```php // Result -$result = Success::of($value); -$result = Error::of('something went wrong'); +$result = Success::create($value); +$result = Error::create('something went wrong'); $result->map(fn($v) => ...)->flatMap(fn($v) => ...); // Option -$option = Option::fromValue($nullableValue); -$option->getOrElse('default'); -$option->map(fn($v) => ...)->filter(fn($v) => $v > 0); +$option = Some::create($value); +$option = None::create(); +$option->map(fn($v) => ...); ``` --- @@ -102,17 +188,22 @@ Then run: ```bash composer require boboko/core +php artisan vendor:publish --tag=core-config php artisan vendor:publish --tag=core-assets php artisan migrate ``` +For local core development alongside a consuming app (path-repo symlink + Docker mount), see +[`docs/modules.md`](docs/modules.md) "Docker Compose: the local-core mount". + --- ## Requirements -- PHP 8.2+ -- Laravel 11+ -- Lunar (lunarphp/lunar + lunarphp/admin) +- PHP 8.5+ +- Laravel 12+ +- Lunar 1.3 (`lunarphp/lunar`) +- Meilisearch (for product search/listing/catalog) - Spatie Laravel Activity Log --- @@ -120,7 +211,12 @@ php artisan migrate ## Documentation - [`docs/otp-auth.md`](docs/otp-auth.md) — OTP authentication flow +- [`docs/localization.md`](docs/localization.md) — Locale-prefixed routing and storefront translations +- [`docs/product-search.md`](docs/product-search.md) — Full-text product search +- [`docs/product-listing.md`](docs/product-listing.md) — Product listing/filtering/detail catalog service +- [`docs/privacy.md`](docs/privacy.md) — GDPR right of access/erasure, User-scope vs Customer-scope +- [`docs/shopify-import.md`](docs/shopify-import.md) — Shopify CSV → Lunar field mapping and import design - [`docs/activity-log.md`](docs/activity-log.md) — Activity logging -- [`docs/lunar.md`](docs/lunar.md) — Lunar framework reference - [`docs/notifications.md`](docs/notifications.md) — Notification registry +- [`docs/lunar.md`](docs/lunar.md) — Lunar framework reference and gotchas - [`docs/modules.md`](docs/modules.md) — Module architecture, Customer/User pairing, provider registration pitfalls