Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UBER-937: Extensibility changes #3874

Merged
merged 4 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ It may also be necessary to upgrade the running database.

```bash
cd ./dev/tool
rushx upgrade
rushx upgrade -f
```

In cases where the project fails to build for any logical reason, try the following steps:
Expand Down
3 changes: 2 additions & 1 deletion dev/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ services:
- SERVER_SECRET=secret
- ELASTIC_URL=http://elastic:9200
- MONGO_URL=mongodb://mongodb:27017
- METRICS_CONSOLE=true
- METRICS_CONSOLE=false
- METRICS_FILE=metrics.txt
- MINIO_ENDPOINT=minio
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
Expand Down
19 changes: 14 additions & 5 deletions dev/tool/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import { diffWorkspace } from './workspace'

import { Data, getWorkspaceId, RateLimitter, Tx, Version } from '@hcengineering/core'
import { MinioService } from '@hcengineering/minio'
import { MigrateOperation } from '@hcengineering/model'
import { consoleModelLogger, MigrateOperation } from '@hcengineering/model'
import { openAIConfigDefaults } from '@hcengineering/openai'
import path from 'path'
import { benchmark } from './benchmark'
Expand Down Expand Up @@ -237,17 +237,24 @@ export function devTool (
.option('-p|--parallel <parallel>', 'Parallel upgrade', '0')
.option('-l|--logs <logs>', 'Default logs folder', './logs')
.option('-r|--retry <retry>', 'Number of apply retries', '0')
.option(
'-c|--console',
'Display all information into console(default will create logs folder with {workspace}.log files',
false
)
.option('-f|--force [force]', 'Force update', false)
.action(async (cmd: { parallel: string, logs: string, retry: string, force: boolean }) => {
.action(async (cmd: { parallel: string, logs: string, retry: string, force: boolean, console: boolean }) => {
const { mongodbUri, version, txes, migrateOperations } = prepareTools()
return await withDatabase(mongodbUri, async (db) => {
const workspaces = await listWorkspaces(db, productId)
const withError: string[] = []

async function _upgradeWorkspace (ws: WorkspaceInfoOnly): Promise<void> {
const t = Date.now()
const logger = new FileModelLogger(path.join(cmd.logs, `${ws.workspace}.log`))
console.log('---UPGRADING----', ws.workspace, logger.file)
const logger = cmd.console
? consoleModelLogger
: new FileModelLogger(path.join(cmd.logs, `${ws.workspace}.log`))
console.log('---UPGRADING----', ws.workspace, !cmd.console ? (logger as FileModelLogger).file : '')
try {
await upgradeWorkspace(version, txes, migrateOperations, productId, db, ws.workspace, logger, cmd.force)
console.log('---UPGRADING-DONE----', ws.workspace, Date.now() - t)
Expand All @@ -256,7 +263,9 @@ export function devTool (
logger.log('error', JSON.stringify(err))
console.log('---UPGRADING-FAILED----', ws.workspace, Date.now() - t)
} finally {
logger.close()
if (!cmd.console) {
;(logger as FileModelLogger).close()
}
}
}
if (cmd.parallel !== '0') {
Expand Down
225 changes: 119 additions & 106 deletions models/contact/src/migration.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
//

import { Class, DOMAIN_TX, Doc, Domain, Ref, TxOperations } from '@hcengineering/core'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@hcengineering/model'
import {
MigrateOperation,
MigrationClient,
MigrationUpgradeClient,
ModelLogger,
tryMigrate
} from '@hcengineering/model'
import { DOMAIN_COMMENT } from '@hcengineering/model-chunter'
import core from '@hcengineering/model-core'
import { DOMAIN_VIEW } from '@hcengineering/model-view'
import contact, { DOMAIN_CONTACT } from './index'
import contact, { DOMAIN_CONTACT, contactId } from './index'

async function createSpace (tx: TxOperations): Promise<void> {
const current = await tx.findOne(core.class.Space, {
Expand Down Expand Up @@ -76,118 +82,125 @@ async function createEmployeeEmail (client: TxOperations): Promise<void> {
}

export const contactOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
await client.update(
DOMAIN_TX,
{
objectClass: 'contact:class:EmployeeAccount'
},
{
$rename: { 'attributes.employee': 'attributes.person' },
$set: { objectClass: contact.class.PersonAccount }
}
)
async migrate (client: MigrationClient, logger: ModelLogger): Promise<void> {
await tryMigrate(client, contactId, [
{
state: 'employees',
func: async (client) => {
await client.update(
DOMAIN_TX,
{
objectClass: 'contact:class:EmployeeAccount'
},
{
$rename: { 'attributes.employee': 'attributes.person' },
$set: { objectClass: contact.class.PersonAccount }
}
)

await client.update(
DOMAIN_TX,
{
objectClass: 'contact:class:Employee'
},
{
$set: { objectClass: contact.mixin.Employee }
}
)
await client.update(
DOMAIN_TX,
{
objectClass: 'contact:class:Employee'
},
{
$set: { objectClass: contact.mixin.Employee }
}
)

await client.update(
DOMAIN_TX,
{
'tx.attributes.backlinkClass': 'contact:class:Employee'
},
{
$set: { 'tx.attributes.backlinkClass': contact.mixin.Employee }
}
)
await client.update(
DOMAIN_TX,
{
'tx.attributes.backlinkClass': 'contact:class:Employee'
},
{
$set: { 'tx.attributes.backlinkClass': contact.mixin.Employee }
}
)

await client.update(
DOMAIN_TX,
{
'tx.attributes.backlinkClass': 'contact:class:Employee'
},
{
$set: { 'tx.attributes.backlinkClass': contact.mixin.Employee }
}
)
await client.update(
DOMAIN_TX,
{
'tx.attributes.backlinkClass': 'contact:class:Employee'
},
{
$set: { 'tx.attributes.backlinkClass': contact.mixin.Employee }
}
)

await client.update(
DOMAIN_TX,
{
objectClass: core.class.Attribute,
'attributes.type.to': 'contact:class:Employee'
},
{
$set: { 'attributes.type.to': contact.mixin.Employee }
}
)
await client.update(
DOMAIN_TX,
{
objectClass: core.class.Attribute,
'operations.type.to': 'contact:class:Employee'
},
{
$set: { 'operations.type.to': contact.mixin.Employee }
}
)
await client.update(
DOMAIN_TX,
{
objectClass: core.class.Attribute,
'attributes.type.to': 'contact:class:Employee'
},
{
$set: { 'attributes.type.to': contact.mixin.Employee }
}
)
await client.update(
DOMAIN_TX,
{
objectClass: core.class.Attribute,
'operations.type.to': 'contact:class:Employee'
},
{
$set: { 'operations.type.to': contact.mixin.Employee }
}
)

await client.update(
DOMAIN_TX,
{
'attributes.extends': 'contact:class:Employee'
},
{
$set: { 'attributes.extends': contact.mixin.Employee }
}
)
await client.update(
DOMAIN_TX,
{
'attributes.extends': 'contact:class:Employee'
},
{
$set: { 'attributes.extends': contact.mixin.Employee }
}
)

for (const d of client.hierarchy.domains()) {
await client.update(
d,
{ attachedToClass: 'contact:class:Employee' },
{ $set: { attachedToClass: contact.mixin.Employee } }
)
}
await client.update(
DOMAIN_COMMENT,
{ backlinkClass: 'contact:class:Employee' },
{ $set: { backlinkClass: contact.mixin.Employee } }
)
await client.update(
'tags' as Domain,
{ targetClass: 'contact:class:Employee' },
{ $set: { targetClass: contact.mixin.Employee } }
)
await client.update(
DOMAIN_VIEW,
{ filterClass: 'contact:class:Employee' },
{ $set: { filterClass: contact.mixin.Employee } }
)
await client.update(
DOMAIN_CONTACT,
{
_class: 'contact:class:Employee' as Ref<Class<Doc>>
},
{
$rename: {
active: `${contact.mixin.Employee as string}.active`,
statuses: `${contact.mixin.Employee as string}.statuses`,
displayName: `${contact.mixin.Employee as string}.displayName`,
position: `${contact.mixin.Employee as string}.position`
},
$set: {
_class: contact.class.Person
for (const d of client.hierarchy.domains()) {
await client.update(
d,
{ attachedToClass: 'contact:class:Employee' },
{ $set: { attachedToClass: contact.mixin.Employee } }
)
}
await client.update(
DOMAIN_COMMENT,
{ backlinkClass: 'contact:class:Employee' },
{ $set: { backlinkClass: contact.mixin.Employee } }
)
await client.update(
'tags' as Domain,
{ targetClass: 'contact:class:Employee' },
{ $set: { targetClass: contact.mixin.Employee } }
)
await client.update(
DOMAIN_VIEW,
{ filterClass: 'contact:class:Employee' },
{ $set: { filterClass: contact.mixin.Employee } }
)
await client.update(
DOMAIN_CONTACT,
{
_class: 'contact:class:Employee' as Ref<Class<Doc>>
},
{
$rename: {
active: `${contact.mixin.Employee as string}.active`,
statuses: `${contact.mixin.Employee as string}.statuses`,
displayName: `${contact.mixin.Employee as string}.displayName`,
position: `${contact.mixin.Employee as string}.position`
},
$set: {
_class: contact.class.Person
}
}
)
}
}
)
])
},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
Expand Down
40 changes: 34 additions & 6 deletions models/presentation/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,28 @@
// limitations under the License.
//

import { DOMAIN_MODEL } from '@hcengineering/core'
import { Builder, Model } from '@hcengineering/model'
import { Class, DOMAIN_MODEL, Doc, Ref } from '@hcengineering/core'
import { Builder, Model, Prop, TypeRef } from '@hcengineering/model'
import core, { TDoc } from '@hcengineering/model-core'
import { Asset, IntlString, Resource } from '@hcengineering/platform'
// Import types to prevent .svelte components to being exposed to type typescript.
import { PresentationMiddlewareCreator, PresentationMiddlewareFactory } from '@hcengineering/presentation'
import {
ComponentPointExtension,
CreateExtensionKind,
DocAttributeRule,
DocRules,
DocCreateExtension,
DocCreateFunction,
ObjectSearchCategory,
ObjectSearchFactory
} from '@hcengineering/presentation/src/types'
import presentation from './plugin'
import { PresentationMiddlewareCreator, PresentationMiddlewareFactory } from '@hcengineering/presentation'
import { AnyComponent, ComponentExtensionId } from '@hcengineering/ui'
import presentation from './plugin'

export { presentationId } from '@hcengineering/presentation/src/plugin'
export { default } from './plugin'
export { ObjectSearchCategory, ObjectSearchFactory }
export { CreateExtensionKind, DocCreateExtension, DocCreateFunction, ObjectSearchCategory, ObjectSearchFactory }

@Model(presentation.class.ObjectSearchCategory, core.class.Doc, DOMAIN_MODEL)
export class TObjectSearchCategory extends TDoc implements ObjectSearchCategory {
Expand All @@ -53,6 +58,29 @@ export class TComponentPointExtension extends TDoc implements ComponentPointExte
order!: number
}

@Model(presentation.class.DocCreateExtension, core.class.Doc, DOMAIN_MODEL)
export class TDocCreateExtension extends TDoc implements DocCreateExtension {
@Prop(TypeRef(core.class.Class), core.string.Class)
ofClass!: Ref<Class<Doc>>

components!: Record<CreateExtensionKind, AnyComponent>
apply!: Resource<DocCreateFunction>
}

@Model(presentation.class.DocRules, core.class.Doc, DOMAIN_MODEL)
export class TDocRules extends TDoc implements DocRules {
@Prop(TypeRef(core.class.Class), core.string.Class)
ofClass!: Ref<Class<Doc>>

fieldRules!: DocAttributeRule[]
}

export function createModel (builder: Builder): void {
builder.createModel(TObjectSearchCategory, TPresentationMiddlewareFactory, TComponentPointExtension)
builder.createModel(
TObjectSearchCategory,
TPresentationMiddlewareFactory,
TComponentPointExtension,
TDocCreateExtension,
TDocRules
)
}
10 changes: 9 additions & 1 deletion models/recruit/src/migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,15 @@ export const recruitOperation: MigrateOperation = {
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await createDefaults(tx)
await fixTemplateSpace(tx)

await tryUpgrade(client, recruitId, [
{
state: 'fix-template-space',
func: async (client) => {
await fixTemplateSpace(tx)
}
}
])

await tryUpgrade(client, recruitId, [
{
Expand Down
Loading