diff --git a/packages/core/src/operations.ts b/packages/core/src/operations.ts
index d3271ecc3a..94e45c3ec9 100644
--- a/packages/core/src/operations.ts
+++ b/packages/core/src/operations.ts
@@ -453,7 +453,7 @@ export class ApplyOperations extends TxOperations {
       findAll: (_class, query, options?) => ops.client.findAll(_class, query, options),
       searchFulltext: (query, options) => ops.client.searchFulltext(query, options),
       tx: async (tx): Promise<TxResult> => {
-        if (ops.getHierarchy().isDerived(tx._class, core.class.TxCUD)) {
+        if (TxProcessor.isExtendsCUD(tx._class)) {
           this.txes.push(tx as TxCUD<Doc>)
         }
         return {}
@@ -518,7 +518,7 @@ export class TxBuilder extends TxOperations {
       findAll: async (_class, query, options?) => toFindResult([]),
       searchFulltext: async (query, options) => ({ docs: [] }),
       tx: async (tx): Promise<TxResult> => {
-        if (this.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
+        if (TxProcessor.isExtendsCUD(tx._class)) {
           this.txes.push(tx as TxCUD<Doc>)
         }
         return {}
diff --git a/packages/core/src/tx.ts b/packages/core/src/tx.ts
index d14d85704c..8d5d24ff9c 100644
--- a/packages/core/src/tx.ts
+++ b/packages/core/src/tx.ts
@@ -438,6 +438,16 @@ export abstract class TxProcessor implements WithTx {
     return doc as D
   }
 
+  static isExtendsCUD (_class: Ref<Class<Doc>>): boolean {
+    return (
+      _class === core.class.TxCreateDoc ||
+      _class === core.class.TxUpdateDoc ||
+      _class === core.class.TxRemoveDoc ||
+      _class === core.class.TxCollectionCUD ||
+      _class === core.class.TxMixin
+    )
+  }
+
   static extractTx (tx: Tx): Tx {
     if (tx._class === core.class.TxCollectionCUD) {
       const ctx = tx as TxCollectionCUD<Doc, AttachedDoc>
diff --git a/packages/presentation/src/utils.ts b/packages/presentation/src/utils.ts
index 37e195e6d3..1b8f61d333 100644
--- a/packages/presentation/src/utils.ts
+++ b/packages/presentation/src/utils.ts
@@ -200,7 +200,7 @@ class UIClient extends TxOperations implements Client, OptimisticTxes {
       return
     }
 
-    if (!this.getHierarchy().isDerived(tx._class, core.class.TxCUD)) {
+    if (!TxProcessor.isExtendsCUD(tx._class)) {
       return
     }
 
diff --git a/plugins/view-resources/src/middleware.ts b/plugins/view-resources/src/middleware.ts
index 09d1f10f82..94201e46c2 100644
--- a/plugins/view-resources/src/middleware.ts
+++ b/plugins/view-resources/src/middleware.ts
@@ -303,7 +303,7 @@ export class AnalyticsMiddleware extends BasePresentationMiddleware implements P
         const applyIf = etx as TxApplyIf
         void this.handleTx(...applyIf.txes)
       }
-      if (this.client.getHierarchy().isDerived(etx._class, core.class.TxCUD)) {
+      if (TxProcessor.isExtendsCUD(etx._class)) {
         const cud = etx as TxCUD<Doc>
         const _class = this.client.getHierarchy().getClass(cud.objectClass)
         if (_class.label !== undefined) {
diff --git a/server-plugins/openai/src/resources.ts b/server-plugins/openai/src/resources.ts
index 8ad7929dc9..359ef7e20f 100644
--- a/server-plugins/openai/src/resources.ts
+++ b/server-plugins/openai/src/resources.ts
@@ -115,7 +115,7 @@ async function performCompletion (
 export async function AsyncOnGPTRequest (tx: Tx, tc: TriggerControl): Promise<Tx[]> {
   const actualTx = TxProcessor.extractTx(tx)
 
-  if (tc.hierarchy.isDerived(actualTx._class, core.class.TxCUD) && actualTx.modifiedBy !== openai.account.GPT) {
+  if (TxProcessor.isExtendsCUD(actualTx._class) && actualTx.modifiedBy !== openai.account.GPT) {
     const cud: TxCUD<Doc> = actualTx as TxCUD<Doc>
     //
     if (tc.hierarchy.isDerived(cud.objectClass, chunter.class.ChatMessage)) {
diff --git a/server/core/src/fulltext.ts b/server/core/src/fulltext.ts
index 358c6fc0e9..9e18f1c55f 100644
--- a/server/core/src/fulltext.ts
+++ b/server/core/src/fulltext.ts
@@ -33,6 +33,7 @@ import core, {
   type TxCUD,
   type TxCollectionCUD,
   TxFactory,
+  TxProcessor,
   type TxResult,
   type WorkspaceId,
   docKey,
@@ -84,7 +85,7 @@ export class FullTextIndex implements WithFind {
         attachedToClass = txcol.objectClass
         tx = txcol.tx
       }
-      if (this.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
+      if (TxProcessor.isExtendsCUD(tx._class)) {
         const cud = tx as TxCUD<Doc>
 
         if (!isClassIndexable(this.hierarchy, cud.objectClass)) {
diff --git a/server/core/src/server/storage.ts b/server/core/src/server/storage.ts
index 5d2fc7e3ce..9e17fa77e0 100644
--- a/server/core/src/server/storage.ts
+++ b/server/core/src/server/storage.ts
@@ -255,7 +255,7 @@ export class TServerStorage implements ServerStorage {
 
     for (const tx of txes) {
       const txCUD = TxProcessor.extractTx(tx) as TxCUD<Doc>
-      if (!this.hierarchy.isDerived(txCUD._class, core.class.TxCUD)) {
+      if (!TxProcessor.isExtendsCUD(txCUD._class)) {
         // Skip unsupported tx
         ctx.error('Unsupported transaction', tx)
         continue
@@ -444,6 +444,9 @@ export class TServerStorage implements ServerStorage {
     if (query?.$search !== undefined) {
       return await ctx.with(p + '-fulltext-find-all', {}, (ctx) => this.fulltext.findAll(ctx, clazz, query, options))
     }
+    if (domain === DOMAIN_MODEL) {
+      return this.modelDb.findAllSync(clazz, query, options)
+    }
     const st = Date.now()
     const result = await ctx.with(
       p + '-find-all',
@@ -656,11 +659,11 @@ export class TServerStorage implements ServerStorage {
     ): Promise<void> => {
       const classes = new Set<Ref<Class<Doc>>>()
       for (const dtx of derived) {
-        if (this.hierarchy.isDerived(dtx._class, core.class.TxCUD)) {
+        if (TxProcessor.isExtendsCUD(dtx._class)) {
           classes.add((dtx as TxCUD<Doc>).objectClass)
         }
         const etx = TxProcessor.extractTx(dtx)
-        if (this.hierarchy.isDerived(etx._class, core.class.TxCUD)) {
+        if (TxProcessor.isExtendsCUD(etx._class)) {
           classes.add((etx as TxCUD<Doc>).objectClass)
         }
       }
@@ -876,7 +879,7 @@ export class TServerStorage implements ServerStorage {
     for (const tx of txes) {
       if (!this.hierarchy.isDerived(tx._class, core.class.TxApplyIf)) {
         if (tx.space !== core.space.DerivedTx) {
-          if (this.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
+          if (TxProcessor.isExtendsCUD(tx._class)) {
             const objectClass = (tx as TxCUD<Doc>).objectClass
             if (
               objectClass !== core.class.BenchmarkDoc &&
diff --git a/server/middleware/src/configuration.ts b/server/middleware/src/configuration.ts
index 97a3a62e6e..21411b83d2 100644
--- a/server/middleware/src/configuration.ts
+++ b/server/middleware/src/configuration.ts
@@ -25,7 +25,8 @@ import core, {
   MeasureContext,
   Ref,
   Tx,
-  TxCUD
+  TxCUD,
+  TxProcessor
 } from '@hcengineering/core'
 import platform, { PlatformError, Severity, Status } from '@hcengineering/platform'
 import { Middleware, SessionContext, TxMiddlewareResult, type ServerStorage } from '@hcengineering/server-core'
@@ -51,7 +52,7 @@ export class ConfigurationMiddleware extends BaseMiddleware implements Middlewar
   }
 
   async tx (ctx: SessionContext, tx: Tx): Promise<TxMiddlewareResult> {
-    if (this.storage.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
+    if (TxProcessor.isExtendsCUD(tx._class)) {
       const txCUD = tx as TxCUD<Doc>
       const domain = this.storage.hierarchy.getDomain(txCUD.objectClass)
       if (this.targetDomains.includes(domain)) {
diff --git a/server/middleware/src/private.ts b/server/middleware/src/private.ts
index 1e76eeaf3d..f7659cddac 100644
--- a/server/middleware/src/private.ts
+++ b/server/middleware/src/private.ts
@@ -26,6 +26,7 @@ import core, {
   Ref,
   Tx,
   TxCUD,
+  TxProcessor,
   systemAccountEmail
 } from '@hcengineering/core'
 import platform, { PlatformError, Severity, Status } from '@hcengineering/platform'
@@ -50,7 +51,7 @@ export class PrivateMiddleware extends BaseMiddleware implements Middleware {
 
   async tx (ctx: SessionContext, tx: Tx): Promise<TxMiddlewareResult> {
     let target: string[] | undefined
-    if (this.storage.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
+    if (TxProcessor.isExtendsCUD(tx._class)) {
       const txCUD = tx as TxCUD<Doc>
       const domain = this.storage.hierarchy.getDomain(txCUD.objectClass)
       if (this.targetDomains.includes(domain)) {
@@ -98,7 +99,7 @@ export class PrivateMiddleware extends BaseMiddleware implements Middleware {
         )
         ;(findResult as FindResult<Doc> as FindResult<Tx>).filter(
           (p) =>
-            !hierarchy.isDerived(p._class, core.class.TxCUD) ||
+            !TxProcessor.isExtendsCUD(p._class) ||
             !targetClasses.has((p as TxCUD<Doc>).objectClass) ||
             p.createdBy === account._id
         )
diff --git a/server/middleware/src/spacePermissions.ts b/server/middleware/src/spacePermissions.ts
index 951a5e8852..abc3a13d51 100644
--- a/server/middleware/src/spacePermissions.ts
+++ b/server/middleware/src/spacePermissions.ts
@@ -250,9 +250,8 @@ export class SpacePermissionsMiddleware extends BaseMiddleware implements Middle
       return
     }
 
-    const h = this.storage.hierarchy
     const actualTx = TxProcessor.extractTx(tx)
-    if (!h.isDerived(actualTx._class, core.class.TxCUD)) {
+    if (!TxProcessor.isExtendsCUD(actualTx._class)) {
       return
     }
 
@@ -322,8 +321,7 @@ export class SpacePermissionsMiddleware extends BaseMiddleware implements Middle
   }
 
   private async processPermissionsUpdatesFromTx (ctx: SessionContext, tx: Tx): Promise<void> {
-    const h = this.storage.hierarchy
-    if (!h.isDerived(tx._class, core.class.TxCUD)) {
+    if (!TxProcessor.isExtendsCUD(tx._class)) {
       return
     }
 
diff --git a/server/middleware/src/spaceSecurity.ts b/server/middleware/src/spaceSecurity.ts
index 3084bef302..fd42b700a1 100644
--- a/server/middleware/src/spaceSecurity.ts
+++ b/server/middleware/src/spaceSecurity.ts
@@ -328,7 +328,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
     const h = this.storage.hierarchy
     let targets: string[] | undefined
 
-    if (h.isDerived(tx._class, core.class.TxCUD)) {
+    if (TxProcessor.isExtendsCUD(tx._class)) {
       const account = await getUser(this.storage, ctx)
       if (tx.objectSpace === (account._id as string)) {
         targets = [account.email, systemAccountEmail]
@@ -384,7 +384,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
 
   private async processTx (ctx: SessionContext, tx: Tx): Promise<void> {
     const h = this.storage.hierarchy
-    if (h.isDerived(tx._class, core.class.TxCUD)) {
+    if (TxProcessor.isExtendsCUD(tx._class)) {
       const cudTx = tx as TxCUD<Doc>
       const isSpace = h.isDerived(cudTx.objectClass, core.class.Space)
       if (isSpace) {
@@ -429,8 +429,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
     exclude?: string[] | undefined
   ): Promise<void> {
     for (const tx of txes) {
-      const h = this.storage.hierarchy
-      if (h.isDerived(tx._class, core.class.TxCUD)) {
+      if (TxProcessor.isExtendsCUD(tx._class)) {
         // TODO: Do we need security check here?
         const cudTx = tx as TxCUD<Doc>
         await this.processTxSpaceDomain(cudTx)
diff --git a/server/tool/src/index.ts b/server/tool/src/index.ts
index aa6c6da530..2708e5488f 100644
--- a/server/tool/src/index.ts
+++ b/server/tool/src/index.ts
@@ -28,6 +28,8 @@ import core, {
   MeasureContext,
   MigrationState,
   ModelDb,
+  systemAccountEmail,
+  toWorkspaceString,
   Tx,
   WorkspaceId,
   type Doc,
@@ -44,6 +46,7 @@ import toolPlugin from './plugin'
 import { MigrateClientImpl } from './upgrade'
 
 import { getMetadata } from '@hcengineering/platform'
+import { generateToken } from '@hcengineering/server-token'
 import fs from 'fs'
 import path from 'path'
 
@@ -411,6 +414,20 @@ export async function upgradeModel (
           i++
         }
       })
+
+      if (connection === undefined) {
+        // We need to send reboot for workspace
+        console.info('send force close')
+        const serverEndpoint = transactorUrl.replaceAll('wss://', 'https://').replace('ws://', 'http://')
+        const token = generateToken(systemAccountEmail, workspaceId, { admin: 'true' })
+        await fetch(
+          serverEndpoint +
+            `/api/v1/manage?token=${token}&operation=force-close&wsId=${toWorkspaceString(workspaceId, '@')}`,
+          {
+            method: 'PUT'
+          }
+        )
+      }
     } finally {
       await connection?.sendForceClose()
       await connection?.close()
diff --git a/server/ws/src/client.ts b/server/ws/src/client.ts
index 204885a0b6..789960c71c 100644
--- a/server/ws/src/client.ts
+++ b/server/ws/src/client.ts
@@ -305,11 +305,11 @@ export class ClientSession implements Session {
   ): Promise<void> {
     const classes = new Set<Ref<Class<Doc>>>()
     for (const dtx of derived) {
-      if (this._pipeline.storage.hierarchy.isDerived(dtx._class, core.class.TxCUD)) {
+      if (TxProcessor.isExtendsCUD(dtx._class)) {
         classes.add((dtx as TxCUD<Doc>).objectClass)
       }
       const etx = TxProcessor.extractTx(dtx)
-      if (this._pipeline.storage.hierarchy.isDerived(etx._class, core.class.TxCUD)) {
+      if (TxProcessor.isExtendsCUD(etx._class)) {
         classes.add((etx as TxCUD<Doc>).objectClass)
       }
     }