BLOCKER: wire Hibernate multi-tenancy
- application.yaml: set hibernate.tenant_identifier_resolver and
hibernate.multiTenancy=DISCRIMINATOR so HibernateTenantResolver is
actually installed into the SessionFactory
- AuditedJpaEntity.tenantId: add @org.hibernate.annotations.TenantId so
every PBC entity inherits the discriminator
- AuditedJpaEntityListener.onCreate: throw if a caller pre-set tenantId
to a different value than the current TenantContext, instead of
silently overwriting (defense against cross-tenant write bugs)
IMPORTANT: dependency hygiene
- pbc-identity no longer depends on platform-bootstrap (wrong direction;
bootstrap assembles PBCs at the top of the stack)
- root build.gradle.kts: tighten the architectural-rule enforcement to
also reject :pbc:* -> platform-bootstrap; switch plug-in detection
from a fragile pathname heuristic to an explicit
extra["vibeerp.module-kind"] = "plugin" marker; reference plug-in
declares the marker
IMPORTANT: api.v1 surface additions (all non-breaking)
- Repository: documented closed exception set; new
PersistenceExceptions.kt declares OptimisticLockConflictException,
UniqueConstraintViolationException, EntityValidationException, and
EntityNotFoundException so plug-ins never see Hibernate types
- TaskContext: now exposes tenantId(), principal(), locale(),
correlationId() so workflow handlers (which run outside an HTTP
request) can pass tenant-aware calls back into api.v1
- EventBus: subscribe() now returns a Subscription with close() so
long-lived subscribers can deregister explicitly; added a
subscribe(topic: String, ...) overload for cross-classloader event
routing where Class<E> equality is unreliable
- IdentityApi.findUserById: tightened from Id<*> to PrincipalId so the
type system rejects "wrong-id-kind" mistakes at the cross-PBC boundary
NITs:
- HealthController.kt -> MetaController.kt (file name now matches the
class name); added TODO(v0.2) for reading implementationVersion from
the Spring Boot BuildProperties bean