Legacy API
This page documents the legacy @logic-bee/flow-query package, which has been superseded by @logic-bee/data-flow. See Writing documents and the migration guide for equivalents. New code should use the new API.
Insert
Inserting a document must be executed on a pre-defined flow document and sent to a cfpPath. The document body is validated against the form validators in the frontend and the Joi validator in the backend.
insertOne()
// -->Get: the flow collection
const flowCollection = bob.flowGlobal.getFlowCollection(bob.cfpPath);
// -->Insert: a new document using the payload sent by the user
const create = await flowCollection.docs.flowQuery()
.addPolicy('canCreate')
.user(bob.flowUser)
.flowOptions(bob.naoQueryOptions)
.insertOne(bob.dataPayload, bob.dbSession());
Setting a Status on Insert
// -->Insert: a document setting the status to active
await flowCollection.docs.flowQuery()
.addPolicy('canInsert')
.user(bob.flowUser)
.flowOptions(bob.naoQueryOptions)
.setStatus('active')
.insertOne(newData, bob.dbSession());
Returning the Inserted Document
Pass true as the third argument to insertOne to return the inserted document:
// -->Insert: a new document and return the document inserted
const create = await flowCollection.docs.flowQuery()
.addPolicy('canCreate')
.user(bob.flowUser)
.flowOptions(bob.naoQueryOptions)
.insertOne(bob.dataPayload, bob.dbSession(), true);
insertMany()
// -->Get: the flow collection
const flowCollection = bob.flowGlobal.getFlowCollection(bob.cfpPath);
// -->Set: array with all documents to import
const manyDocuments = [
{ name: 'Mark' },
...bob.dataPayload.documents
]
// -->Insert: many documents
const create = await flowCollection.docs.flowQuery()
.addPolicy('canCreate')
.user(bob.flowUser)
.flowOptions(bob.naoQueryOptions)
.insertMany(manyDocuments, bob.dbSession());
Best Practices
✅ DOs:
- Always use
bob.dbSession()for insert operations - Always add the
canCreatepolicy to the insert flow query
❌ DON'Ts:
- Do not run the query without
bob.dbSession()unless you know what you are doing
Full Example: Frontend to Backend
- Frontend
- Request Payload
- Request Configuration
- Action
- Response
// -->Get: data
const data = this.formGroup.getValues() as any;
// -->Create: new doc
this.naoFlowService.reqData({
cfpSlug: 'data',
action: 'data/create-new',
data,
naoQueryOptions: {docName: 'project', cfpPath: 'projects/projects'}
})
.execute()
.subscribe({
next: (res) => {
console.log(res)
},
error: (err) => {
this.status.error();
},
complete: () => {
//
},
});
{
"data": {
"naoQueryOptions": {
"docName": "project",
"cfpPath": "project/project"
},
"data": {
"documents": [
{ "name": "Mary" },
{ "name": "Jason" }
]
}
}
}
{
cfpPath: 'projects/projects',
slug: 'projects',
requestPresets: [
{
action: 'create-new',
dataType: 'data',
requestTypes: ['POST', 'manual'],
compatibleFlowDocs: [
{ docType: 'project' }
],
allowPublicRequests: false,
jobs: [
{ eventName: 'nao-app-data/nao-app-data.data.validateCrudRequest', setInitialPayload: true, options: { requestType: 'create' } },
{ eventName: 'nao-app-data/nao-app-data.data.formatCreateFlowDocument' },
{ eventName: 'nao-app-data/nao-app-data.crudHooks.createDocument', returnPayload: true },
]
},
]
}
/**
* Insert documents
*/
public static createDocument() {
return async (bob: BobRequest<{
data: {
data: { documents: any[] },
naoQueryOptions: NaoQueryOptions
}
}>) => {
let ok = true, error: any = null, data;
try {
// -->Validate: input
bob.validator.joi().validateData(bob.dataPayload, SuperJoi.object({
documents: SuperJoi.array().items(SuperJoi.any()).required(),
}), bob.flowUser.getUserInfo());
// -->Get: the flow collection
const flowCollection = bob.flowGlobal.getFlowCollection(bob.cfpPath);
// -->Set: array with all documents to import
const manyDocuments = [
{ name: 'Mark' },
...bob.dataPayload.documents
]
// -->Insert: many documents
const create = await flowCollection.docs.flowQuery()
.addPolicy('canCreate')
.user(bob.flowUser)
.flowOptions(bob.naoQueryOptions)
.insertMany(manyDocuments, bob.dbSession());
// -->Set: the output payload
ok = create.ok;
data = create;
} catch (err) {
error = err;
ok = false;
}
// -->Return: result
return returnEventResult(bob, {ok, error, data});
};
}
{
"ok": true,
"meta": {
"workerId": "worker-101",
"requestId": "YSJPi7iNiBh",
"events": [
{
"eventName": "nao-app-data/nao-app-data.data.validateCrudRequest",
"ms": 8.65775
},
{
"eventName": "nao-app-data/nao-app-data.data.formatCreateFlowDocument",
"ms": 12.015369999999999
},
{
"eventName": "nao-app-data/nao-app-data.crudHooks.createDocument",
"ms": 212.63528399999998
}
],
"request": {
"eventName": "request",
"ms": 234.604202
},
"mode": "active",
"total": 3,
"jobsLog": []
},
"returnType": "data",
"eventType": "data",
"data": {
"ok": true,
"docIds": [
"tm2Ota-HOxyEf5BfXLSrlnMb"
],
"hash": "Im3EL-aZh4tQU1iuSWRaD",
"transactionId": "nuwiSBgJruTWaw4t0YZhY"
}
}