Rework Attachments as a bag (#193)

Signed-off-by: Andrey Platov <andrey@hardcoreeng.com>
This commit is contained in:
Andrey Platov 2021-09-15 19:03:34 +02:00 committed by GitHub
parent 74d46558f1
commit bf9f479500
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 923 additions and 833 deletions

View File

@ -1,2 +1,2 @@
helm upgrade dev --set master.persistence.size=10Gi,data.persistence.size=10Gi,image.repository=anticrm/elasticsearch,ingest.enabled=true,data.heapSize=4096m,master.heapSize=256m,coordinating.heapSize=256m bitnami/elasticsearch
helm upgrade dev --set master.persistence.size=10Gi,data.persistence.size=10Gi,image.repository=anticrm/elasticsearch,ingest.enabled=true,data.heapSize=8192m,master.heapSize=1024m,coordinating.heapSize=1024m bitnami/elasticsearch

View File

@ -2,6 +2,6 @@
CLIENT_TYPE=dev
ACCOUNTS_URL=/account
UPLOAD_URL=/upload
LOGIN_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InJvc2FtdW5kQGhjLmVuZ2luZWVyaW5nIiwid29ya3NwYWNlIjoid3MxIn0.crxqT7QUkpZiTmmxouB40LpMwK2CfTf76XqPFWIMyic
LOGIN_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InJvc2FtdW5kQGhjLmVuZ2luZWVyaW5nIiwid29ya3NwYWNlIjoidHJ4NDAifQ.dYsCF2VRbuc-zmRt0yLAww1_--xtX4P1EqPFREEzCjQ
# LOGIN_ENDPOINT=ws://localhost:3333
LOGIN_ENDPOINT=wss://transactor.hc.engineering/

View File

@ -18,7 +18,7 @@ import { start } from '.'
import { encode } from 'jwt-simple'
const token = encode({ email: 'rosamund@hc.engineering', workspace: 'ws1' }, 'secret')
const token = encode({ email: 'rosamund@hc.engineering', workspace: 'trx40' }, 'secret')
console.log(token)
// eslint-disable-next-line @typescript-eslint/no-floating-promises

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@ import type { IntlString } from '@anticrm/platform'
import { Builder, Model, Prop, UX, TypeString, Index } from '@anticrm/model'
import type { Ref, Doc, Class, Domain } from '@anticrm/core'
import { IndexKind } from '@anticrm/core'
import core, { TSpace, TDoc } from '@anticrm/model-core'
import core, { TSpace, TDoc, TObj } from '@anticrm/model-core'
import type { Backlink, Channel, Message, Comment, Attachment } from '@anticrm/chunter'
import type { AnyComponent } from '@anticrm/ui'
@ -55,10 +55,8 @@ export class TBacklink extends TComment implements Backlink {
backlinkClass!: Ref<Class<Doc>>
}
@Model(chunter.class.Attachment, core.class.Doc, DOMAIN_ATTACHMENT)
export class TAttachment extends TDoc implements Attachment {
attachedTo!: Ref<Doc>
collection!: string
@Model(chunter.class.Attachment, core.class.Obj, DOMAIN_ATTACHMENT)
export class TAttachment extends TObj implements Attachment {
name!: string
file!: string
size!: number

View File

@ -17,7 +17,7 @@ import { Builder } from '@anticrm/model'
import core from './component'
import { TAttribute, TClass, TDoc, TMixin, TObj, TType, TTypeString } from './core'
import { TSpace, TAccount, TState } from './security'
import { TTx, TTxCreateDoc, TTxMixin, TTxUpdateDoc, TTxCUD } from './tx'
import { TTx, TTxCreateDoc, TTxMixin, TTxUpdateDoc, TTxCUD, TTxPutBag } from './tx'
export * from './core'
export * from './security'
@ -33,6 +33,7 @@ export function createModel (builder: Builder): void {
TTx,
TTxCUD,
TTxCreateDoc,
TTxPutBag,
TTxMixin,
TTxUpdateDoc,
TSpace,

View File

@ -27,7 +27,9 @@ import type {
TxUpdateDoc,
TxMixin,
Mixin,
ExtendedAttributes
ExtendedAttributes,
PropertyType,
TxPutBag
} from '@anticrm/core'
import { DOMAIN_TX } from '@anticrm/core'
import { Model } from '@anticrm/model'
@ -52,6 +54,13 @@ export class TTxCreateDoc<T extends Doc> extends TTxCUD<T> implements TxCreateDo
attributes!: Data<T>
}
@Model(core.class.TxPutBag, core.class.TxCUD)
export class TTxPutBag<T extends PropertyType> extends TTxCUD<Doc> implements TxPutBag<T> {
bag!: string
key!: string
value!: T
}
@Model(core.class.TxMixin, core.class.TxCUD)
export class TTxMixin<D extends Doc, M extends D> extends TTxCUD<D> implements TxMixin<D, M> {
mixin!: Ref<Mixin<M>>

View File

@ -46,7 +46,8 @@ export function createDemo (builder: Builder): void {
provider: contact.channelProvider.Email,
value: 'andrey@hc.engineering'
}
]
],
attachments: {}
})
builder.createDoc(recruit.class.Candidate, recruit.space.CandidatesPublic, {
@ -58,6 +59,7 @@ export function createDemo (builder: Builder): void {
provider: contact.channelProvider.Email,
value: 'marina@hc.engineering'
}
]
],
attachments: {}
})
}

View File

@ -14,8 +14,8 @@
//
import type { IntlString } from '@anticrm/platform'
import { Builder, Model, UX, Prop, TypeString } from '@anticrm/model'
import type { Ref, FindOptions, Doc, Domain, State } from '@anticrm/core'
import { Builder, Model, UX, Prop, TypeString, Bag as TypeBag } from '@anticrm/model'
import type { Ref, FindOptions, Doc, Domain, State, Bag } from '@anticrm/core'
import core, { TSpace, TDoc } from '@anticrm/model-core'
import type { Vacancy, Candidates, Candidate, Applicant } from '@anticrm/recruit'
import type { Attachment } from '@anticrm/chunter'
@ -25,8 +25,6 @@ import workbench from '@anticrm/model-workbench'
import view from '@anticrm/model-view'
import contact, { TPerson } from '@anticrm/model-contact'
import recruit from './plugin'
import chunter from '@anticrm/chunter'
import type { Person } from '@anticrm/contact'
export const DOMAIN_RECRUIT = 'recruit' as Domain
@ -41,17 +39,17 @@ export class TCandidates extends TSpace implements Candidates {}
@Model(recruit.class.Candidate, contact.class.Person)
@UX('Candidate' as IntlString)
export class TCandidate extends TPerson implements Candidate {
@Prop(TypeString(), 'Resume' as IntlString)
resume?: Ref<Attachment>
@Prop(TypeString(), 'Title' as IntlString)
title?: Ref<Attachment>
title?: string
@Prop(TypeBag(), 'Attachments' as IntlString)
attachments!: Bag<Attachment>
}
@Model(recruit.class.Applicant, core.class.Doc, DOMAIN_RECRUIT)
export class TApplicant extends TDoc implements Applicant {
@Prop(TypeString(), 'Candidate' as IntlString)
candidate!: Ref<Person>
candidate!: Ref<Candidate>
@Prop(TypeString(), 'State' as IntlString)
state!: Ref<State>
@ -107,11 +105,11 @@ export function createModel (builder: Builder): void {
open: recruit.component.EditCandidate,
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
options: {
lookup: {
resume: chunter.class.Attachment
}
// lookup: {
// resume: chunter.class.Attachment
// }
} as FindOptions<Doc>, // TODO: fix
config: ['', '#' + recruit.component.CreateApplicationPresenter + '/Action', 'city', '$lookup.resume', 'channels']
config: ['', '#' + recruit.component.CreateApplicationPresenter + '/Action', 'city', 'channels']
})
builder.createDoc(view.class.Viewlet, core.space.Model, {

View File

@ -38,7 +38,8 @@ export default plugin(coreId, {
Space: '' as Ref<Class<Space>>,
Account: '' as Ref<Class<Account>>,
State: '' as Ref<Class<State>>,
TypeString: '' as Ref<Class<Type<string>>>
TypeString: '' as Ref<Class<Type<string>>>,
Bag: '' as Ref<Class<Type<Record<string, PropertyType>>>>
},
space: {
Tx: '' as Ref<Space>,

View File

@ -266,7 +266,7 @@ export class TxFactory {
): TxPutBag<P> {
return {
_id: generateId(),
_class: core.class.TxUpdateDoc,
_class: core.class.TxPutBag,
space: core.space.Tx,
modifiedBy: this.account,
modifiedOn: Date.now(),

View File

@ -272,3 +272,10 @@ export class Builder {
export function TypeString (): Type<string> {
return { _class: core.class.TypeString }
}
/**
* @public
*/
export function Bag (): Type<Record<string, PropertyType>> {
return { _class: core.class.Bag }
}

View File

@ -87,8 +87,22 @@ export class LiveQuery extends TxProcessor implements Client {
}
}
protected txPutBag (tx: TxPutBag<any>): Promise<void> {
throw new Error('Method not implemented.')
protected override async txPutBag (tx: TxPutBag<any>): Promise<void> {
for (const q of this.queries) {
if (q.result instanceof Promise) {
q.result = await q.result
}
const updatedDoc = q.result.find(p => p._id === tx.objectId)
if (updatedDoc !== undefined) {
const doc = updatedDoc as any
let bag = doc[tx.bag]
if (bag === undefined) {
doc[tx.bag] = bag = {}
}
bag[tx.key] = tx.value
await this.callback(updatedDoc, q)
}
}
}
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<void> {

View File

@ -53,6 +53,7 @@ export { default as Row } from './components/Row.svelte'
// export { default as CheckBoxList } from './components/CheckBoxList.svelte.txt'
export { default as EditWithIcon } from './components/EditWithIcon.svelte'
export { default as Loading } from './components/Loading.svelte'
export { default as Spinner } from './components/Spinner.svelte'
export { default as Popup } from './components/Popup.svelte'
export { default as CircleButton } from './components/CircleButton.svelte'
export { default as Link } from './components/Link.svelte'

View File

@ -15,7 +15,7 @@
import { plugin } from '@anticrm/platform'
import type { Asset, Plugin } from '@anticrm/platform'
import type { Space, Doc, Ref, Class, AttachedDoc } from '@anticrm/core'
import type { Space, Obj, Doc, Ref, Class, AttachedDoc } from '@anticrm/core'
/**
* @public
@ -47,8 +47,7 @@ export interface Backlink extends Comment {
/**
* @public
*/
export interface Attachment extends AttachedDoc {
collection: string
export interface Attachment extends Obj {
name: string
file: string
size: number

View File

@ -29,7 +29,7 @@ async function onClick() {
const clazz = hierarchy.getClass(value._class)
const editorMixin = hierarchy.as(clazz, view.mixin.ObjectEditor)
const editor = await getResource(editorMixin.editor)
showPopup(editor, { object: value }, 'full')
showPopup(editor, { _id: value._id }, 'full')
}
</script>

View File

@ -14,9 +14,10 @@
-->
<script lang="ts">
import { CircleButton, IconAdd, showPopup } from '@anticrm/ui'
import { CircleButton, IconAdd, showPopup, Spinner } from '@anticrm/ui'
import type { Doc, Ref, Space } from '@anticrm/core'
import type { Doc, Ref, Space, Class, Bag } from '@anticrm/core'
import { setPlatformStatus, unknownError } from '@anticrm/platform'
import { generateId } from '@anticrm/core'
import { createQuery, getClient } from '@anticrm/presentation'
import type { Attachment } from '@anticrm/chunter'
@ -26,13 +27,14 @@
import chunter from '@anticrm/chunter'
export let object: Doc
// export let space: Ref<Space>
export let objectId: Ref<Doc & { attachments: Bag<Attachment> }>
export let space: Ref<Space>
export let _class: Ref<Class<Doc & { attachments: Bag<Attachment> }>>
let files: Attachment[] = []
export let object: Doc & { attachments: Bag<Attachment> } | undefined = undefined
const query = createQuery()
$: query.query(chunter.class.Attachment, { attachedTo: object._id }, result => { files = result})
// const query = createQuery()
// $: query.query(_class, { _id: objectId }, result => { object = result[0] })
let inputFile: HTMLInputElement
let loading = false
@ -40,20 +42,19 @@
const client = getClient()
async function createAttachment(file: File) {
console.log('CREATE ATTACHMENT')
loading = true
try {
const id = generateId<Attachment>()
const uuid = await uploadFile(id, object.space, file, object._id)
const uuid = await uploadFile(space, file, objectId)
console.log('uploaded file uuid', uuid)
client.createDoc(chunter.class.Attachment, object.space, {
attachedTo: object._id,
collection: 'attachment',
client.putBag(_class, space, objectId, 'attachments', encodeURIComponent(uuid), {
_class: chunter.class.Attachment,
name: file.name,
file: uuid,
type: file.type,
size: file.size,
})
})
} catch (err: any) {
setPlatformStatus(unknownError(err))
} finally {
loading = false
}
@ -70,10 +71,14 @@
<div class="attachments-container">
<div class="flex-row-center">
<span class="title">Attachments</span>
<a href={'#'} on:click={ () => { inputFile.click() } }><CircleButton icon={IconAdd} size={'small'} /></a>
{#if loading}
<Spinner/>
{:else}
<a href={'#'} on:click={ () => { inputFile.click() } }><CircleButton icon={IconAdd} size={'small'} /></a>
{/if}
<input bind:this={inputFile} type="file" name="file" id="file" style="display: none" on:change={fileSelected}/>
</div>
{#if files.length > 0}
{#if object?.attachments !== undefined}
<table class="table-body">
<thead>
<tr class="tr-head">
@ -82,7 +87,7 @@
</tr>
</thead>
<tbody>
{#each files as file}
{#each Object.values(object.attachments) as file}
<tr class="tr-body">
<td class="item flex-row-center">
<div class="flex-center file-icon">pdf</div>

View File

@ -15,8 +15,9 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import type { Ref, Space } from '@anticrm/core'
import type { Ref, Space, Data } from '@anticrm/core'
import { generateId } from '@anticrm/core'
import { setPlatformStatus, unknownError } from '@anticrm/platform'
import { getClient, Card, Channels } from '@anticrm/presentation'
import { uploadFile } from '../utils'
@ -26,7 +27,7 @@
import type { Candidate } from '@anticrm/recruit'
import type { Attachment } from '@anticrm/chunter'
import { EditBox, Link, showPopup, Component, CircleButton, IconFile as FileIcon } from '@anticrm/ui'
import { EditBox, Link, showPopup, Component, CircleButton, IconFile as FileIcon, Spinner } from '@anticrm/ui'
import FileUpload from './icons/FileUpload.svelte'
import Avatar from './icons/Avatar.svelte'
import Edit from './icons/Edit.svelte'
@ -49,7 +50,6 @@
} as Candidate
let resume = {} as {
id: Ref<Attachment> | undefined
name: string
uuid: string
size: number
@ -58,36 +58,46 @@
const dispatch = createEventDispatcher()
const client = getClient()
const candidateId = generateId<Candidate>()
const candidateId = generateId()
async function createCandidate() {
console.log(_space)
// create candidate
await client.createDoc(recruit.class.Candidate, _space, {
const candidate: Data<Candidate> = {
firstName: object.firstName,
lastName: object.lastName,
city: object.city,
channels: object.channels,
}, candidateId)
attachments: {}
}
if (resume.uuid !== undefined) {
candidate.attachments[encodeURIComponent(resume.uuid)] = {
_class: chunter.class.Attachment,
name: resume.name,
file: resume.uuid,
size: resume.size,
type: resume.type
}
}
await client.createDoc(recruit.class.Candidate, _space, candidate, candidateId)
console.log('resume name', resume.name)
if (resume.id !== undefined) {
// create attachment
console.log('creaing attachment space', _space)
client.createDoc(chunter.class.Attachment, _space, {
attachedTo: candidateId,
collection: 'resume',
name: resume.name,
file: resume.uuid,
type: resume.type,
size: resume.size,
}, resume.id)
// if (resume.id !== undefined) {
// // create attachment
// console.log('creaing attachment space', _space)
// client.createDoc(chunter.class.Attachment, _space, {
// attachedTo: candidateId,
// collection: 'resume',
// name: resume.name,
// file: resume.uuid,
// type: resume.type,
// size: resume.size,
// }, resume.id)
client.updateDoc(recruit.class.Candidate, _space, candidateId, {
resume: resume.id
})
}
// client.updateDoc(recruit.class.Candidate, _space, candidateId, {
// resume: resume.id
// })
// }
dispatch('close')
}
@ -98,17 +108,14 @@
async function createAttachment(file: File) {
loading = true
try {
const id = generateId<Attachment>()
resume.uuid = await uploadFile(id, space, file, candidateId)
resume.id = id
resume.uuid = await uploadFile(space, file, candidateId)
resume.name = file.name
resume.size = file.size
resume.type = file.type
object.resume = id
console.log('uploaded file uuid', resume.uuid)
} catch (err: any) {
setPlatformStatus(unknownError(err))
} finally {
loading = false
}
@ -154,10 +161,15 @@
<div class="name"><EditBox placeholder="Appleseed" maxWidth="9.5rem" bind:value={object.lastName}/></div>
<div class="city"><EditBox placeholder="Location" maxWidth="9.5rem" bind:value={object.city}/></div>
<div class="flex resume">
{#if resume.id}
{#if resume.uuid}
<Link label={resume.name} href={'#'} icon={FileIcon} on:click={ () => { showPopup(PDFViewer, { file: resume.uuid }, 'right') } }/>
{:else}
<a href={'#'} on:click={ () => { inputFile.click() } }>Upload resume</a>
{#if loading}
<Spinner/> Uploading...
{:else}
<FileUpload size='small'/>
<a href={'#'} on:click={ () => { inputFile.click() } }>Upload resume</a>
{/if}
<input bind:this={inputFile} type="file" name="file" id="file" style="display: none" on:change={fileSelected}/>
{/if}
</div>

View File

@ -15,14 +15,14 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import type { Ref, Space, Doc } from '@anticrm/core'
import type { Ref, Space, Doc, Class } from '@anticrm/core'
import { CircleButton, EditBox, Link, showPopup, IconFile as FileIcon } from '@anticrm/ui'
import type { Attachment } from '@anticrm/chunter'
import FileUpload from './icons/FileUpload.svelte'
import PDFViewer from './PDFViewer.svelte'
import { getClient, Channels, AttributeEditor } from '@anticrm/presentation'
import { getClient, createQuery, Channels, AttributeEditor } from '@anticrm/presentation'
import { Panel } from '@anticrm/panel'
import type { Candidate } from '@anticrm/recruit'
import type { Candidate, Candidate } from '@anticrm/recruit'
import DialogHeader from './DialogHeader.svelte'
import Contact from './icons/Contact.svelte'
import Avatar from './icons/Avatar.svelte'
@ -34,10 +34,14 @@
import recruit from '../plugin'
export let object: Candidate
export let _id: Ref<Candidate>
let object: Candidate
const client = getClient()
const query = createQuery()
$: query.query(recruit.class.Candidate, { _id }, result => { object = result[0] })
const dispatch = createEventDispatcher()
function saveChannels(result: any) {
@ -47,6 +51,7 @@
</script>
{#if object !== undefined}
<Panel icon={Contact} title={object.firstName + ' ' + object.lastName} {object} on:close={() => { dispatch('close') }}>
<svelte:fragment slot="subtitle">
<div class="flex-between flex-reverse" style="width: 100%">
@ -69,10 +74,11 @@
</div>
<div class="attachments">
<Attachments {object}/>
<Attachments objectId={object._id} _class={object._class} space={object.space} {object}/>
</div>
</Panel>
{/if}
<style lang="scss">
@import '../../../../packages/theme/styles/mixins.scss';

View File

@ -15,18 +15,18 @@
//
import type { Ref, Doc, Space } from '@anticrm/core'
import { getMetadata } from '@anticrm/platform'
import { getMetadata, PlatformError } from '@anticrm/platform'
import login from '@anticrm/login'
export async function uploadFile(id: Ref<Doc>, space: Ref<Space>, file: File, attachedTo: Ref<Doc>): Promise<string> {
export async function uploadFile(space: Ref<Space>, file: File, attachedTo: Ref<Doc>): Promise<string> {
console.log(file)
const uploadUrl = getMetadata(login.metadata.UploadUrl)
const data = new FormData()
data.append('file', file)
const url = `${uploadUrl}?id=${id}&space=${space}&attachedTo=${attachedTo}`
const url = `${uploadUrl}?space=${space}&name=${encodeURIComponent(file.name)}&attachedTo=${attachedTo}`
const resp = await fetch(url, {
method: 'POST',
headers: {
@ -34,6 +34,9 @@ export async function uploadFile(id: Ref<Doc>, space: Ref<Space>, file: File, at
},
body: data
})
if (resp.status !== 200) {
throw new Error('Can\t upload file.')
}
const uuid = await resp.text()
console.log(uuid)
return uuid

View File

@ -15,7 +15,7 @@
import { plugin } from '@anticrm/platform'
import type { Plugin, Asset } from '@anticrm/platform'
import type { Space, Doc, Ref, State } from '@anticrm/core'
import type { Space, Doc, Ref, State, Bag } from '@anticrm/core'
import type { Person } from '@anticrm/contact'
import type { Attachment } from '@anticrm/chunter'
@ -33,8 +33,8 @@ export interface Candidates extends Space {}
* @public
*/
export interface Candidate extends Person {
resume?: Ref<Attachment>
title?: string
attachments: Bag<Attachment>
}
/**

View File

@ -33,8 +33,8 @@ export class FullTextIndex extends TxProcessor implements Storage {
super()
}
protected txPutBag (tx: TxPutBag<any>): Promise<void> {
throw new Error('Method not implemented.')
protected override async txPutBag (tx: TxPutBag<any>): Promise<void> {
console.log('FullTextIndex.txPutBag: Method not implemented.')
}
protected txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<void> {

View File

@ -34,7 +34,7 @@ export interface Trigger extends Doc {
* @public
*/
export interface IndexedDoc {
id: Ref<Doc>
id: string
_class: Ref<Class<Doc>>
space: Ref<Space>
modifiedOn: Timestamp

View File

@ -92,8 +92,10 @@ abstract class MongoAdapterBase extends TxProcessor {
}
class MongoAdapter extends MongoAdapterBase {
protected txPutBag (tx: TxPutBag<any>): Promise<void> {
throw new Error('Method not implemented.')
protected override async txPutBag (tx: TxPutBag<any>): Promise<void> {
const domain = this.hierarchy.getDomain(tx.objectClass)
console.log('mongo', { $set: { [tx.bag + '.' + tx.key]: tx.value } })
await this.db.collection(domain).updateOne({ _id: tx.objectId }, { $set: { [tx.bag + '.' + tx.key]: tx.value } })
}
protected txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<void> {
@ -112,8 +114,7 @@ class MongoAdapter extends MongoAdapterBase {
protected override async txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<void> {
const domain = this.hierarchy.getDomain(tx.objectClass)
const result = await this.db.collection(domain).updateOne({ _id: tx.objectId }, { $set: tx.operations })
console.log('update result', result)
await this.db.collection(domain).updateOne({ _id: tx.objectId }, { $set: tx.operations })
}
}

View File

@ -20,7 +20,7 @@ import cors from 'cors'
import { v4 as uuid } from 'uuid'
import { decode } from 'jwt-simple'
import type { Space, Ref, Doc, Account } from '@anticrm/core'
import { Space, Ref, Doc, Account, generateId } from '@anticrm/core'
// import { TxFactory } from '@anticrm/core'
import type { Token, IndexedDoc } from '@anticrm/server-core'
import { createElasticAdapter } from '@anticrm/elastic'
@ -131,7 +131,7 @@ export function start (transactorEndpoint: string, elasticUrl: string, minio: Cl
const uuid = await minioUpload(minio, payload.workspace, file)
console.log('uploaded uuid', uuid)
const id = req.query.id as Ref<Doc>
const name = req.query.name as string
const space = req.query.space as Ref<Space>
const attachedTo = req.query.attachedTo as Ref<Doc>
// const name = req.query.name as string
@ -150,7 +150,7 @@ export function start (transactorEndpoint: string, elasticUrl: string, minio: Cl
const elastic = await createElasticAdapter(elasticUrl, payload.workspace)
const indexedDoc: IndexedDoc = {
id,
id: generateId() + '/attachments/' + name,
_class: chunter.class.Attachment,
space,
modifiedOn: Date.now(),

File diff suppressed because it is too large Load Diff