Skip to content

Commit 4817966

Browse files
Feature/audit (#981)
* update moox/audit logic * update setting vor moox/audit * Fix styling * update readme * add skill moox/audit --------- Co-authored-by: Reinhold-Jesse <88349887+Reinhold-Jesse@users.noreply.github.com>
1 parent 0b53ec8 commit 4817966

44 files changed

Lines changed: 2884 additions & 209 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.cursor/skills/moox-audit/SKILL.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
name: moox-audit
3+
description: >-
4+
Integrates moox/audit activity logging into Moox consumer packages (config,
5+
ServiceProvider, Filament, hooks, tests). Use when the user says moox/audit,
6+
moox-audit, protokolieren, auditieren, activity log, or names a package to
7+
audit (e.g. moox/tag, tag package).
8+
---
9+
10+
# Moox Audit — package integration
11+
12+
Config-driven activity logging via `moox/audit`. Consumer packages declare an `audit` block in package config and register it in the ServiceProvider. **No model traits** and **no Eloquent changes** on models for standard CRUD tracking.
13+
14+
Canonical package docs: [packages/audit/README.md](../../../packages/audit/README.md)
15+
16+
Gold-standard consumer: `packages/category` (`config/category.php`, `CategoryServiceProvider`).
17+
18+
## When to use
19+
20+
| User intent | Action |
21+
| --- | --- |
22+
| "Nutze skill moox/audit und protokolieren moox/tag" | Follow [integration.md](integration.md) for `packages/tag` |
23+
| "Audit für {package}" / "protokolieren {package}" | Same workflow for `packages/{package}` |
24+
| Install audit in an app | `composer require moox/audit` + `php artisan mooxaudit:install` (see package README) |
25+
| App-only model tracking | Published `config/audit.php` `models` section (no package registry) |
26+
| Custom lifecycle event | Hook or `MooxActivityLogger::log()` — see [decisions.md](decisions.md) |
27+
28+
## Integration workflow (checklist)
29+
30+
Copy and track:
31+
32+
```
33+
- [ ] 1. Inspect target package (models, translations, resource, delete side-effects)
34+
- [ ] 2. Add `audit` block to `packages/{pkg}/config/{pkg}.php`
35+
- [ ] 3. Register in `{Pkg}ServiceProvider::packageBooted()` via AuditPackageRegistry
36+
- [ ] 4. Decide hooks (pivot detach on delete?) — decisions.md
37+
- [ ] 5. Add/adjust Pest tests when behavior is new or non-trivial
38+
- [ ] 6. Run package tests + `composer lint` / `composer analyse` if touched from monorepo root
39+
```
40+
41+
**Do not** add `moox/audit` to the consumer package's `composer.json` `require`. Use `class_exists(AuditPackageRegistry::class)` so the package works without audit installed.
42+
43+
## Quick reference
44+
45+
### ServiceProvider registration
46+
47+
```php
48+
use Moox\Audit\Support\AuditPackageRegistry;
49+
50+
// in packageBooted():
51+
if (class_exists(AuditPackageRegistry::class) && config('audit.enabled', true)) {
52+
AuditPackageRegistry::register('{package_key}', config('{package_key}.audit', []));
53+
}
54+
```
55+
56+
`{package_key}` matches the config file name (`category`, `tag`, …).
57+
58+
### Config shape
59+
60+
Three sections under `{package}.audit`:
61+
62+
| Section | Purpose |
63+
| --- | --- |
64+
| `models` | Per-model tracking: preset, `log_name`, `attributes` |
65+
| `hooks` | Custom events (e.g. pivot detach on `deleting`) |
66+
| `filament` | Activity tab on resources + `aggregate_subjects` for translations |
67+
68+
Presets (`draft_main`, `draft_translation`) live in `config/audit.php`. See [decisions.md](decisions.md) for attribute selection and hooks.
69+
70+
### Filament
71+
72+
When `filament` is registered, `AuditBootstrap` adds the **Activity** relation manager automatically. No manual `getRelations()` change unless you need loose coupling — see package README.
73+
74+
## Tests
75+
76+
After integrating audit into a consumer package, add tests when you introduce hooks or non-default config. Run:
77+
78+
```bash
79+
php vendor/bin/pest --configuration=packages/{pkg}/phpunit.xml packages/{pkg}/tests
80+
```
81+
82+
Audit package tests (reference):
83+
84+
```bash
85+
php vendor/bin/pest --configuration=packages/audit/phpunit.xml packages/audit/tests/Unit
86+
```
87+
88+
## Additional resources
89+
90+
- Step-by-step templates and tag example: [integration.md](integration.md)
91+
- Presets, attributes, hooks, entry types: [decisions.md](decisions.md)
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Moox Audit — integration decisions
2+
3+
## Preset selection
4+
5+
| Model type | Preset | Entry type | Events |
6+
| --- | --- | --- | --- |
7+
| Main draft entity (`BaseDraftModel`) | `draft_main` | `audit` | created, updated, deleted, restored |
8+
| Translation row (`BaseDraftTranslationModel`) | `draft_translation` | `audit` | same + `locale` in properties |
9+
10+
Non-draft models: omit preset; set `events`, `entry_type`, `log_name`, `attributes` explicitly.
11+
12+
## Which attributes to track
13+
14+
1. Start from model `fillable` / `getCustomTranslatedAttributes()`.
15+
2. Include business-meaningful fields only (status, scope, content, relations ids users care about).
16+
3. Exclude high-churn or internal fields unless requested (`uuid`, `ulid`, `custom_properties` — case by case).
17+
4. Main draft: always consider `scope` when the model uses `HasScopedModel`.
18+
5. Translations: include `author_id` / `author_type` for enrichment; preset hides `*_by_*` morph columns.
19+
20+
## Entry types
21+
22+
| Type | When |
23+
| --- | --- |
24+
| `audit` | Default for model attribute changes (presets) |
25+
| `log` | Hooks, manual `MooxActivityLogger::log()`, side-effect events |
26+
27+
## Hooks on delete
28+
29+
Check the main model's `booted()` / `deleting` listeners:
30+
31+
| Pattern | Example | Hook approach |
32+
| --- | --- | --- |
33+
| Detach pivot rows on delete | `Category::detach…`, `Tag::detachAllTaggables()` | `deleting` hook with `entry_type` => `log` |
34+
| Built-in handler | Category categorizables | `'handler' => 'categorizables_detached'` |
35+
| No built-in handler | Tag taggables | Omit `handler`; set `event` + `description` |
36+
37+
Built-in handlers in `Moox\Audit\Support\AuditHooks`:
38+
39+
- `categorizables_detached` — logs `category_id` in properties
40+
41+
For new pivot tables, prefer a generic hook first. Add a dedicated handler in `packages/audit` only when enriched properties are required.
42+
43+
### Generic hook (no handler)
44+
45+
```php
46+
'deleting' => [
47+
'log_name' => 'tag',
48+
'entry_type' => 'log',
49+
'event' => 'taggables_detached',
50+
'description' => 'taggables_detached',
51+
],
52+
```
53+
54+
## Filament `aggregate_subjects`
55+
56+
Map translation model → relation name on the owner:
57+
58+
```php
59+
'aggregate_subjects' => [
60+
TagTranslation::class => 'translations',
61+
],
62+
```
63+
64+
Use the Eloquent relation method name from the main model / draft base.
65+
66+
## Manual logging (outside config)
67+
68+
```php
69+
use Moox\Audit\Services\MooxActivityLogger;
70+
71+
MooxActivityLogger::log('my-channel', 'Something happened', [
72+
'entry_type' => 'log',
73+
'event' => 'exported',
74+
'subject' => $model,
75+
'properties' => ['format' => 'csv'],
76+
'scope' => 'default',
77+
]);
78+
```
79+
80+
Use for one-off flows not covered by model config or hooks.
81+
82+
## Tests — when required
83+
84+
| Change | Test |
85+
| --- | --- |
86+
| New package audit config only | Optional smoke test if package has audit test harness |
87+
| New hook handler in `moox/audit` | Unit test in `packages/audit/tests` |
88+
| Consumer-specific hook behavior | Feature/unit test in consumer package |
89+
90+
## Out of scope for consumer integration
91+
92+
- Publishing `activity_log` migrations (app / `mooxaudit:install`)
93+
- Registering `AuditPlugin` in `AdminPanelProvider` (app)
94+
- Adding traits to models for CRUD tracking (not used in Moox audit)
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
# Moox Audit — integration templates
2+
3+
## 1. Discover the target package
4+
5+
Read before editing:
6+
7+
| File | What to extract |
8+
| --- | --- |
9+
| `packages/{pkg}/src/Models/*.php` | Main model, translation model, `fillable` / `getCustomTranslatedAttributes`, `scope`, delete side-effects |
10+
| `packages/{pkg}/config/{pkg}.php` | Existing config structure; add `audit` block before closing `];` |
11+
| `packages/{pkg}/src/{Pkg}ServiceProvider.php` | `packageBooted()` for registry |
12+
| `packages/{pkg}/src/Resources/*Resource.php` | Resource class for `filament` config |
13+
14+
### Draft packages (BaseDraftModel)
15+
16+
Typical pair:
17+
18+
- **Main model** → preset `draft_main`, track non-translated columns (`is_active`, `status`, `scope`, `parent_id`, styling fields, …)
19+
- **Translation model** → preset `draft_translation`, track `title`, `slug`, `description`, `content`, `translation_status`, `author_id`, `author_type`
20+
21+
Use the same `log_name` for both (e.g. `'tag'`).
22+
23+
**Attribute rule:** Only list columns that should appear in the audit diff. Omit internal morph `*_by_*` on translations (preset hides them). Include `scope` on the main model when present.
24+
25+
## 2. Config template
26+
27+
Add to `packages/{pkg}/config/{pkg}.php` (adjust imports at top):
28+
29+
```php
30+
use Moox\{Pkg}\Models\{MainModel};
31+
use Moox\{Pkg}\Models\{TranslationModel};
32+
use Moox\{Pkg}\Resources\{MainResource};
33+
34+
// ...
35+
36+
/*
37+
|--------------------------------------------------------------------------
38+
| Audit defaults
39+
|--------------------------------------------------------------------------
40+
|
41+
| Registered with moox/audit when installed. Override in config/audit.php.
42+
|
43+
*/
44+
45+
'audit' => [
46+
'enabled' => true,
47+
'models' => [
48+
{MainModel}::class => [
49+
'preset' => 'draft_main',
50+
'log_name' => '{package_key}',
51+
'attributes' => [
52+
// main-model columns from fillable / business relevance
53+
],
54+
],
55+
{TranslationModel}::class => [
56+
'preset' => 'draft_translation',
57+
'log_name' => '{package_key}',
58+
'attributes' => [
59+
'title',
60+
'slug',
61+
'description',
62+
'content',
63+
'translation_status',
64+
'author_id',
65+
'author_type',
66+
],
67+
],
68+
],
69+
'hooks' => [
70+
// optional — see decisions.md
71+
],
72+
'filament' => [
73+
{MainResource}::class => [
74+
'owner_model' => {MainModel}::class,
75+
'aggregate_subjects' => [
76+
{TranslationModel}::class => 'translations',
77+
],
78+
],
79+
],
80+
],
81+
```
82+
83+
## 3. ServiceProvider template
84+
85+
```php
86+
use Moox\Audit\Support\AuditPackageRegistry;
87+
88+
public function packageBooted(): void
89+
{
90+
// ... existing boot logic ...
91+
92+
if (class_exists(AuditPackageRegistry::class) && config('audit.enabled', true)) {
93+
AuditPackageRegistry::register('{package_key}', config('{package_key}.audit', []));
94+
}
95+
}
96+
```
97+
98+
## 4. Example: `moox/tag`
99+
100+
**Models:** `Tag` (main), `TagTranslation` (translation). `Tag` has `detachAllTaggables()` on `deleting` (like category + categorizables).
101+
102+
### `config/tag.php`
103+
104+
```php
105+
use Moox\Tag\Models\Tag;
106+
use Moox\Tag\Models\TagTranslation;
107+
use Moox\Tag\Resources\TagResource;
108+
109+
// inside return [ ... ]:
110+
111+
'audit' => [
112+
'enabled' => true,
113+
'models' => [
114+
Tag::class => [
115+
'preset' => 'draft_main',
116+
'log_name' => 'tag',
117+
'attributes' => [
118+
'is_active',
119+
'status',
120+
'scope',
121+
'color',
122+
'weight',
123+
'due_at',
124+
],
125+
],
126+
TagTranslation::class => [
127+
'preset' => 'draft_translation',
128+
'log_name' => 'tag',
129+
'attributes' => [
130+
'title',
131+
'slug',
132+
'permalink',
133+
'description',
134+
'content',
135+
'translation_status',
136+
'author_id',
137+
'author_type',
138+
],
139+
],
140+
],
141+
'hooks' => [
142+
Tag::class => [
143+
'deleting' => [
144+
'log_name' => 'tag',
145+
'entry_type' => 'log',
146+
'event' => 'taggables_detached',
147+
'description' => 'taggables_detached',
148+
],
149+
],
150+
],
151+
'filament' => [
152+
TagResource::class => [
153+
'owner_model' => Tag::class,
154+
'aggregate_subjects' => [
155+
TagTranslation::class => 'translations',
156+
],
157+
],
158+
],
159+
],
160+
```
161+
162+
No built-in `taggables_detached` handler exists — omit `handler` so `MooxActivityLogger::log()` runs (see `AuditHooks`). For category-style enriched properties, add a handler in `moox/audit` first, then reference it.
163+
164+
### `TagServiceProvider.php`
165+
166+
Same `AuditPackageRegistry::register('tag', config('tag.audit', []))` block as category.
167+
168+
## 5. Verification
169+
170+
1. `audit.enabled` is true (env `AUDIT_ENABLED` or default).
171+
2. `AuditPlugin` registered in the Filament panel (app install).
172+
3. Edit a tracked record → **Activity** tab shows `audit` entries on attribute change.
173+
4. Delete with pivot detach → `log` entry if hook configured.
174+
5. Global **Audit** resource lists entries filtered by `log_name`.
175+
176+
## 6. App overrides (optional)
177+
178+
Consumers can tune without editing the package via published `config/audit.php`:
179+
180+
```php
181+
'models' => [
182+
\Moox\Tag\Models\Tag::class => ['append_attributes' => ['count']],
183+
],
184+
```
185+
186+
Merge rules: `attributes` **replaces**; `append_attributes` **appends**; `enabled => false` disables. See package README.

.cursor/skills/registry.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# Packages with a Cursor skill — keep in sync after integrator-facing changes.
12
# Maps Moox package folders (packages/{name}) to Cursor skills (.cursor/skills/{skill}/).
23
# Only packages listed here require skill sync after package changes.
34
# See .cursor/rules/moox-package-skill-sync.mdc
@@ -12,3 +13,12 @@ packages:
1213
- installation.md
1314
- integration.md
1415
- decisions.md
16+
17+
audit:
18+
skill: moox-audit
19+
skill_path: .cursor/skills/moox-audit
20+
package_readme: packages/audit/README.md
21+
skill_files:
22+
- SKILL.md
23+
- integration.md
24+
- decisions.md

0 commit comments

Comments
 (0)