diff --git a/dev/prod/public/huly/site.webmanifest b/dev/prod/public/huly/site.webmanifest index 3d240ef504..174bdb93de 100644 --- a/dev/prod/public/huly/site.webmanifest +++ b/dev/prod/public/huly/site.webmanifest @@ -5,5 +5,7 @@ { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" }, { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }, { "src": "/icon-1024.png", "type": "image/png", "sizes": "1024x1024" } - ] + ], + "start_url": "/", + "scope": "/" } \ No newline at end of file diff --git a/dev/prod/src/analytics.ts b/dev/prod/src/analytics.ts index ac19bdf2d9..3a040258aa 100644 --- a/dev/prod/src/analytics.ts +++ b/dev/prod/src/analytics.ts @@ -3,7 +3,6 @@ // import { type AnalyticProvider, Analytics } from "@hcengineering/analytics" -import { AnalyticsCollectorProvider } from './analytics/analyticsCollector' import { PosthogAnalyticProvider } from "./analytics/posthog" import { SentryAnalyticProvider } from "./analytics/sentry" import { type Config } from "./platform" @@ -11,8 +10,7 @@ import { type Config } from "./platform" export function configureAnalytics (config: Config) { const providers: AnalyticProvider[] = [ new SentryAnalyticProvider, - new PosthogAnalyticProvider, - new AnalyticsCollectorProvider + new PosthogAnalyticProvider ] for (const provider of providers) { Analytics.init(provider, config) diff --git a/packages/api-client/src/rest/rest.ts b/packages/api-client/src/rest/rest.ts index a483c94c1f..fb2995eb9c 100644 --- a/packages/api-client/src/rest/rest.ts +++ b/packages/api-client/src/rest/rest.ts @@ -39,7 +39,7 @@ import { PlatformError, unknownError } from '@hcengineering/platform' import type { RestClient } from './types' import { extractJson, withRetry } from './utils' -export async function createRestClient (endpoint: string, workspaceId: string, token: string): Promise { +export function createRestClient (endpoint: string, workspaceId: string, token: string): RestClient { return new RestClientImpl(endpoint, workspaceId, token) } diff --git a/server/workspace-service/src/service.ts b/server/workspace-service/src/service.ts index 9971ed683f..58a3fc6fb9 100644 --- a/server/workspace-service/src/service.ts +++ b/server/workspace-service/src/service.ts @@ -70,6 +70,8 @@ import { import { buildStorageFromConfig, storageConfigFromEnv } from '@hcengineering/server-storage' import { createWorkspace, upgradeWorkspace } from './ws-operations' +const dbCleanTreshold = 256 // Cleanup workspaces if less 256mb + export interface WorkspaceOptions { errorHandler: (workspace: BaseWorkspaceInfo, error: any) => Promise force: boolean @@ -372,15 +374,19 @@ export class WorkspaceWorker { /** * If onlyDrop is true, will drop workspace from database, overwize remove only indexes and do full reindex. */ - async doCleanup (ctx: MeasureContext, workspace: BaseWorkspaceInfo, onlyDrop: boolean): Promise { + async doCleanup (ctx: MeasureContext, workspace: BaseWorkspaceInfo, cleanIndexes: boolean): Promise { const { dbUrl } = prepareTools([]) const adapter = getWorkspaceDestroyAdapter(dbUrl) await adapter.deleteWorkspace(ctx, sharedPipelineContextVars, { name: workspace.workspace, uuid: workspace.uuid }) - await this.doReindexFulltext(ctx, workspace, onlyDrop) + await this.doReindexFulltext(ctx, workspace, cleanIndexes) } - private async doReindexFulltext (ctx: MeasureContext, workspace: BaseWorkspaceInfo, onlyDrop: boolean): Promise { + private async doReindexFulltext ( + ctx: MeasureContext, + workspace: BaseWorkspaceInfo, + clearIndexes: boolean + ): Promise { if (this.fulltextUrl !== undefined) { const token = generateToken(systemAccountEmail, { name: workspace.workspace }, { service: 'workspace' }) @@ -390,7 +396,7 @@ export class WorkspaceWorker { headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ token, onlyDrop }) + body: JSON.stringify({ token, onlyDrop: clearIndexes }) }) if (!res.ok) { throw new Error(`HTTP Error ${res.status} ${res.statusText}`) @@ -491,11 +497,15 @@ export class WorkspaceWorker { // We should remove DB, not storages. await sendEvent('migrate-clean-started', 0) await this.sendTransactorMaitenance(token, { name: workspace.workspace }) - try { - await this.doCleanup(ctx, workspace, false) - } catch (err: any) { - Analytics.handleError(err) - return + + const sz = workspace.backupInfo?.backupSize ?? 0 + if (sz <= dbCleanTreshold) { + try { + await this.doCleanup(ctx, workspace, false) + } catch (err: any) { + Analytics.handleError(err) + return + } } await sendEvent('migrate-clean-done', 0) break diff --git a/server/ws/src/__tests__/rest.test.ts b/server/ws/src/__tests__/rest.test.ts index 0e527efb40..edcca6a125 100644 --- a/server/ws/src/__tests__/rest.test.ts +++ b/server/ws/src/__tests__/rest.test.ts @@ -149,9 +149,9 @@ describe('rest-server', () => { await shutdown() }) - async function connect (): Promise { + function connect (): RestClient { const token: string = generateToken('user1@site.com', getWorkspaceId('test-ws')) - return await createRestClient(`http://localhost:${port}`, 'test-ws', token) + return createRestClient(`http://localhost:${port}`, 'test-ws', token) } async function connectTx (): Promise { @@ -160,7 +160,7 @@ describe('rest-server', () => { } it('get account', async () => { - const conn = await connect() + const conn = connect() const account = await conn.getAccount() expect(account.email).toBe('user1@site.com') @@ -175,7 +175,7 @@ describe('rest-server', () => { }) it('find spaces', async () => { - const conn = await connect() + const conn = connect() const spaces = await conn.findAll(core.class.Space, {}) expect(spaces.length).toBe(2) expect(spaces[0].name).toBe('Sp1') @@ -183,7 +183,7 @@ describe('rest-server', () => { }) it('find avg', async () => { - const conn = await connect() + const conn = connect() let ops = 0 let total = 0 const attempts = 1000 @@ -204,7 +204,7 @@ describe('rest-server', () => { }) it('add space', async () => { - const conn = await connect() + const conn = connect() const account = await conn.getAccount() const tx: TxCreateDoc = { _class: core.class.TxCreateDoc, diff --git a/ws-tests/api-tests/src/__tests__/rest.test.ts b/ws-tests/api-tests/src/__tests__/rest.test.ts index 74e1f21930..fd38e7af75 100644 --- a/ws-tests/api-tests/src/__tests__/rest.test.ts +++ b/ws-tests/api-tests/src/__tests__/rest.test.ts @@ -44,9 +44,9 @@ describe('rest-api-server', () => { }) }) - async function connect (ws?: WorkspaceToken): Promise { + function connect (ws?: WorkspaceToken): RestClient { const tok = ws ?? apiWorkspace1 - return await createRestClient(tok.endpoint, tok.workspaceId, tok.token) + return createRestClient(tok.endpoint, tok.workspaceId, tok.token) } async function connectTx (ws?: WorkspaceToken): Promise { @@ -55,7 +55,7 @@ describe('rest-api-server', () => { } it('get account', async () => { - const conn = await connect() + const conn = connect() const account = await conn.getAccount() expect(account.email).toBe('user1') @@ -69,7 +69,7 @@ describe('rest-api-server', () => { }) it('find spaces', async () => { - const conn = await connect() + const conn = connect() const spaces = await conn.findAll(core.class.Space, {}) expect(spaces.length).toBeGreaterThanOrEqual(20) const personSpace = spaces.find((it) => it.name === 'Pesonal space' && it.private) @@ -77,12 +77,12 @@ describe('rest-api-server', () => { }) it('find spaces limit', async () => { - const conn = await connect() + const conn = connect() const spaces = await conn.findAll(core.class.Space, {}, { limit: 5 }) expect(spaces.length).toBe(5) }) it('find spaces by-name', async () => { - const conn = await connect() + const conn = connect() const spaces = await conn.findAll( contact.class.PersonSpace, { name: 'Personal space' }, @@ -98,24 +98,24 @@ describe('rest-api-server', () => { }) it('find channels', async () => { - const conn = await connect() + const conn = connect() const spaces = await conn.findAll(chunter.class.Channel, {}) expect(spaces.length).toBeGreaterThanOrEqual(2) expect(spaces.find((it) => it._id === 'chunter:space:General')).not.toBeNull() }) it('find avg', async () => { - const conn = await connect() + const conn = connect() await checkFindPerformance(conn) // 5ms max per operation }) it('find avg-europe', async () => { - const conn = await connect(apiWorkspace2) + const conn = connect(apiWorkspace2) await checkFindPerformance(conn) // 5ms max per operation }) it('add space', async () => { - const conn = await connect() + const conn = connect() const account = await conn.getAccount() const spaceName = generateId() const tx: TxCreateDoc = { @@ -142,7 +142,7 @@ describe('rest-api-server', () => { }) it('get-model', async () => { - const conn = await connect() + const conn = connect() const { hierarchy, model } = await conn.getModel() const dsc = hierarchy.getDescendants(core.class.Space)