UBERF-9732: Use huly id as primary social id (#8499)

* uberf-9732: use huly id as primary social id
Signed-off-by: Alexey Zinoviev <alexey.zinoviev@xored.com>

* uberf-9732: fix person id filter
Signed-off-by: Alexey Zinoviev <alexey.zinoviev@xored.com>
This commit is contained in:
Alexey Zinoviev
2025-04-09 09:52:06 +07:00
committed by GitHub
parent 420b31d66f
commit 4cb1f3e411
29 changed files with 478 additions and 238 deletions
+15 -11
View File
@@ -13,7 +13,7 @@
// limitations under the License.
//
import calendar, { Calendar, Event, ExternalCalendar } from '@hcengineering/calendar'
import contactPlugin, { Employee, Person, SocialIdentity, pickPrimarySocialId } from '@hcengineering/contact'
import contactPlugin, { Employee, Person, SocialIdentity } from '@hcengineering/contact'
import core, {
Class,
concatLink,
@@ -33,12 +33,13 @@ import core, {
TxProcessor,
TxRemoveDoc,
TxUpdateDoc,
AccountUuid
AccountUuid,
pickPrimarySocialId
} from '@hcengineering/core'
import serverCalendar from '@hcengineering/server-calendar'
import { getMetadata, getResource } from '@hcengineering/platform'
import { TriggerControl } from '@hcengineering/server-core'
import { getPerson, getSocialStrings } from '@hcengineering/server-contact'
import { getPerson, getSocialStrings, getSocialIds } from '@hcengineering/server-contact'
import { getHTMLPresenter, getTextPresenter } from '@hcengineering/server-notification-resources'
import { generateToken } from '@hcengineering/server-token'
@@ -95,10 +96,10 @@ export async function OnEmployee (txes: Tx[], control: TriggerControl): Promise<
if (ctx.attributes?.active !== true) continue
if (await checkCalendarsExist(control, ctx.objectId)) continue
const socialIds = await getSocialStrings(control, ctx.objectId)
const socialIds = await getSocialIds(control, ctx.objectId)
if (socialIds.length === 0) continue
const socialId = pickPrimarySocialId(socialIds)
const socialId = pickPrimarySocialId(socialIds)._id
const employee = (
await control.findAll(
@@ -283,10 +284,12 @@ async function eventForNewParticipants (
const { _class, space, attachedTo, attachedToClass, collection, ...attr } = event
const data = attr as any as Data<Event>
for (const part of newParticipants) {
const socialStrings = await getSocialStrings(control, part)
if (socialStrings.length === 0) continue
const socialIds = await getSocialIds(control, part)
if (socialIds.length === 0) continue
const socialStrings = socialIds.map((si) => si._id)
if (socialStrings.includes(event.createdBy ?? event.modifiedBy)) continue
const primarySocialString = pickPrimarySocialId(socialStrings)
const primarySocialString = pickPrimarySocialId(socialIds)._id
const calendar = getCalendar(calendars, socialStrings)
if (calendar === undefined) continue
const innerTx = control.txFactory.createTxCreateDoc(
@@ -355,10 +358,11 @@ async function onEventCreate (ctx: TxCreateDoc<Event>, control: TriggerControl):
const calendars = await control.findAll(control.ctx, calendar.class.Calendar, { hidden: false })
const access = 'reader'
for (const part of event.participants) {
const socialStrings = await getSocialStrings(control, part as Ref<Person>)
if (socialStrings.length === 0) continue
const socialIds = await getSocialIds(control, part as Ref<Person>)
if (socialIds.length === 0) continue
const socialStrings = socialIds.map((si) => si._id)
if (socialStrings.includes(event.createdBy ?? event.modifiedBy)) continue
const primarySocialString = pickPrimarySocialId(socialStrings)
const primarySocialString = pickPrimarySocialId(socialIds)._id
const calendar = getCalendar(calendars, socialStrings)
if (calendar === undefined) continue
const innerTx = control.txFactory.createTxCreateDoc(
+9 -25
View File
@@ -14,14 +14,8 @@
//
import { TriggerControl } from '@hcengineering/server-core'
import contact, {
Employee,
type Person,
PersonSpace,
pickPrimarySocialId,
SocialIdentityRef
} from '@hcengineering/contact'
import { AccountUuid, parseSocialIdString, PersonId, type Ref, toIdMap } from '@hcengineering/core'
import contact, { Employee, type Person, PersonSpace, SocialIdentityRef } from '@hcengineering/contact'
import { AccountUuid, parseSocialIdString, PersonId, type Ref, SocialId, toIdMap } from '@hcengineering/core'
export async function getCurrentPerson (control: TriggerControl): Promise<Person | undefined> {
const { type, value } = parseSocialIdString(control.txFactory.account)
@@ -39,13 +33,16 @@ export async function getCurrentPerson (control: TriggerControl): Promise<Person
)[0]
}
export async function getSocialStrings (control: TriggerControl, person: Ref<Person>): Promise<PersonId[]> {
const socialIdentities = await control.findAll(control.ctx, contact.class.SocialIdentity, {
export async function getSocialIds (control: TriggerControl, person: Ref<Person>): Promise<SocialId[]> {
return await control.findAll(control.ctx, contact.class.SocialIdentity, {
attachedTo: person,
attachedToClass: contact.class.Person
attachedToClass: contact.class.Person,
verifiedOn: { $gt: 0 }
})
}
return socialIdentities.map((s) => s._id)
export async function getSocialStrings (control: TriggerControl, person: Ref<Person>): Promise<PersonId[]> {
return (await getSocialIds(control, person)).map((s) => s._id)
}
export async function getSocialStringsByPersons (
@@ -194,19 +191,6 @@ export async function getSocialIdsByAccounts (
}, {})
}
export async function getPrimarySocialIdsByAccounts (
control: TriggerControl,
accounts: AccountUuid[]
): Promise<Record<AccountUuid, PersonId>> {
return Object.entries(await getSocialIdsByAccounts(control, accounts)).reduce<Record<AccountUuid, PersonId>>(
(acc, [account, sids]) => {
acc[account as AccountUuid] = pickPrimarySocialId(sids)
return acc
},
{}
)
}
export async function getAccountBySocialId (control: TriggerControl, socialId: PersonId): Promise<AccountUuid | null> {
const contextAccount = control.ctx.contextData.socialStringsToUsers.get(socialId)
if (contextAccount != null) {
@@ -1,7 +1,7 @@
//
// Copyright © 2023-2024 Hardcore Engineering Inc.
//
import { Person, pickPrimarySocialId, type Employee } from '@hcengineering/contact'
import { Person, type Employee } from '@hcengineering/contact'
import core, {
AccountRole,
combineAttributes,
@@ -13,14 +13,15 @@ import core, {
TxCreateDoc,
TxFactory,
TxUpdateDoc,
systemAccountUuid,
pickPrimarySocialId,
type Doc,
type RolesAssignment,
type Timestamp,
type TxCUD,
systemAccountUuid
type TxCUD
} from '@hcengineering/core'
import { NotificationType } from '@hcengineering/notification'
import { getEmployees, getSocialStrings } from '@hcengineering/server-contact'
import { getEmployees, getSocialIds } from '@hcengineering/server-contact'
import { TriggerControl } from '@hcengineering/server-core'
import documents, {
@@ -130,9 +131,14 @@ async function createDocumentTrainingRequest (doc: ControlledDocument, control:
const dueDate: Timestamp | null =
documentTraining.dueDays === null ? null : doc.effectiveDate + documentTraining.dueDays * 24 * 60 * 60 * 1000
const ownerSocialStrings = await getSocialStrings(control, doc.owner)
const ownerSocialIds = await getSocialIds(control, doc.owner)
if (ownerSocialIds.length === 0) {
console.error(`Owner ${doc.owner} has no social ids`)
return []
}
// TODO: Encapsulate training request creation logic in training plugin?
const modifiedBy = pickPrimarySocialId(ownerSocialStrings)
const modifiedBy = pickPrimarySocialId(ownerSocialIds)._id
let trainees: Array<Ref<Employee>> = documentTraining.trainees
const roles = documentTraining.roles