mit einem Klick
review-multi-tenancy
// Step-by-step tenant isolation audit for OpenAEV pull requests. Use when reviewing PRs that touch entities, repositories, native queries, or migrations.
// Step-by-step tenant isolation audit for OpenAEV pull requests. Use when reviewing PRs that touch entities, repositories, native queries, or migrations.
| name | review-multi-tenancy |
| description | Step-by-step tenant isolation audit for OpenAEV pull requests. Use when reviewing PRs that touch entities, repositories, native queries, or migrations. |
# List all entity classes modified in the PR
git diff --name-only HEAD~1 | grep -E "openaev-model/.*\.java$"
For each modified entity, determine:
TenantBase? → tenant-scopedBase only? → platform-levelgrep -rn "extends TenantBase" --include="*.java" -l openaev-model/ | while read f; do
echo "=== $f ==="
grep -c "tenantFilter" "$f"
done
Expected: every TenantBase entity has @Filter(name = "tenantFilter").
Missing @Filter = 🔴 CRITICAL — Hibernate won't apply tenant filtering.
grep -rn "nativeQuery = true" --include="*.java" openaev-model/ openaev-api/
For each native query:
WHERE tenant_id = :tenantId? ✅WHERE tenant_id = :#{#tenantContext.currentTenant}? ✅git diff --name-only HEAD~1 | grep "migration"
For each migration touching a tenant-scoped table, verify:
tenant_id VARCHAR(255) NOT NULL columntenants(tenant_id) ON DELETE CASCADEtenant_idtenant_idgrep -rn "@Async\|@Scheduled\|CompletableFuture\|ExecutorService\|@EventListener" --include="*.java" openaev-api/src/main/java/ | grep -v "test"
For each async entry point:
TenantContext.setCurrentTenant() called before any DB access?grep -rn "tenantId\|tenant_id\|getTenant" --include="*.java" openaev-api/src/main/java/io/openaev/api/ openaev-api/src/main/java/io/openaev/rest/ | grep -v "@JsonIgnore" | grep -v "test"
Any tenant reference in API layer without @JsonIgnore = 🟠 HIGH.
grep -rn "@Cacheable\|@CachePut\|@CacheEvict" --include="*.java" openaev-api/src/main/java/
For each cached method:
Dual-scope entities (Settings, User, Role, Group) implement DualScopeBase and have nullable tenant_id:
# Check that dual-scope repos extend DualScopeRepository
grep -rn "DualScopeRepository\|DualScopeBase" --include="*.java" openaev-model/src/main/java/
For each dual-scope entity:
DualScopeBaseDualScopeRepository (blocks unscoped findAll(), findById())PlatformXxxService + TenantXxxServicePlatformXxxApi + TenantXxxApifindByTenantIsNull, findByTenantId)PlatformXxxService never receives tenantId; TenantXxxService always receives tenantIdDualScopeBase = 🟠 HIGHDualScopeRepository = 🟠 HIGHGenerate the Multi-Tenancy Review Summary following the output format
defined in multi-tenancy-reviewer.agent.md.
Creates tests for an existing feature following OpenAEV patterns: fixture class, composer, integration test with @Nested groups, and optionally unit tests. Use when asked to add tests or improve test coverage.
Scaffolds a complete feature end-to-end: JPA entity, repository, service, DTOs, mapper, controller, migration, tests (fixture + composer + integration test), and frontend actions/page. Use when asked to create a new feature or module.
Step-by-step general code review procedure for OpenAEV pull requests. Covers architecture, conventions, code quality, and delegation to specialized agents.
Frontend review checklist for OpenAEV React/TypeScript code: component patterns, forms, MUI usage, permissions, i18n, state management, dead code. Use when reviewing PRs or auditing frontend features.
Creates a Flyway Java-based migration for schema changes. Handles table creation, column additions, tenant isolation, and ES reindex. Use when asked to modify the database schema.
Performance review checklist for OpenAEV code: N+1 queries, fetch strategy, pagination, indexing, memory usage. Use when reviewing PRs or auditing performance of a feature.