Re-enable the graphql type pres_annotation_history_curr
to receive all annotations as incremental diff.
It will make the whiteboard more consistent and easier to merge the data.
This commit is contained in:
parent
c79637f21b
commit
60c15006f2
@ -4,7 +4,7 @@ import scala.collection.immutable.HashMap
|
|||||||
import org.bigbluebutton.common2.msgs.AnnotationVO
|
import org.bigbluebutton.common2.msgs.AnnotationVO
|
||||||
import org.bigbluebutton.core.apps.whiteboard.Whiteboard
|
import org.bigbluebutton.core.apps.whiteboard.Whiteboard
|
||||||
import org.bigbluebutton.SystemConfiguration
|
import org.bigbluebutton.SystemConfiguration
|
||||||
import org.bigbluebutton.core.db.{ PresAnnotationDAO, PresPageWritersDAO }
|
import org.bigbluebutton.core.db.{ PresAnnotationDAO, PresAnnotationHistoryDAO, PresPageWritersDAO }
|
||||||
|
|
||||||
class WhiteboardModel extends SystemConfiguration {
|
class WhiteboardModel extends SystemConfiguration {
|
||||||
private var _whiteboards = new HashMap[String, Whiteboard]()
|
private var _whiteboards = new HashMap[String, Whiteboard]()
|
||||||
@ -85,7 +85,9 @@ class WhiteboardModel extends SystemConfiguration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PresAnnotationDAO.insertOrUpdateMap(meetingId, annotationsAdded)
|
val annotationUpdatedAt = System.currentTimeMillis()
|
||||||
|
PresAnnotationHistoryDAO.insertOrUpdateMap(meetingId, annotationsDiffAdded, annotationUpdatedAt)
|
||||||
|
PresAnnotationDAO.insertOrUpdateMap(meetingId, annotationsAdded, annotationUpdatedAt)
|
||||||
|
|
||||||
val newWb = wb.copy(annotationsMap = newAnnotationsMap)
|
val newWb = wb.copy(annotationsMap = newAnnotationsMap)
|
||||||
saveWhiteboard(newWb)
|
saveWhiteboard(newWb)
|
||||||
@ -154,7 +156,9 @@ class WhiteboardModel extends SystemConfiguration {
|
|||||||
val updatedWb = wb.copy(annotationsMap = newAnnotationsMap)
|
val updatedWb = wb.copy(annotationsMap = newAnnotationsMap)
|
||||||
saveWhiteboard(updatedWb)
|
saveWhiteboard(updatedWb)
|
||||||
|
|
||||||
PresAnnotationDAO.delete(meetingId, userId, annotationsIdsRemoved)
|
val annotationUpdatedAt = System.currentTimeMillis()
|
||||||
|
PresAnnotationHistoryDAO.deleteAnnotations(meetingId, wb.id, userId, annotationsIdsRemoved, annotationUpdatedAt)
|
||||||
|
PresAnnotationDAO.deleteAnnotations(meetingId, userId, annotationsIdsRemoved, annotationUpdatedAt)
|
||||||
|
|
||||||
annotationsIdsRemoved
|
annotationsIdsRemoved
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,12 @@ import org.bigbluebutton.common2.msgs.AnnotationVO
|
|||||||
import slick.jdbc.PostgresProfile.api._
|
import slick.jdbc.PostgresProfile.api._
|
||||||
|
|
||||||
case class PresAnnotationDbModel(
|
case class PresAnnotationDbModel(
|
||||||
annotationId: String,
|
annotationId: String,
|
||||||
pageId: String,
|
pageId: String,
|
||||||
meetingId: String,
|
meetingId: String,
|
||||||
userId: String,
|
userId: String,
|
||||||
annotationInfo: String,
|
annotationInfo: String,
|
||||||
lastHistorySequence: Int,
|
lastUpdatedAt: java.sql.Timestamp = new java.sql.Timestamp(System.currentTimeMillis())
|
||||||
lastUpdatedAt: java.sql.Timestamp = new java.sql.Timestamp(System.currentTimeMillis())
|
|
||||||
)
|
)
|
||||||
|
|
||||||
class PresAnnotationDbTableDef(tag: Tag) extends Table[PresAnnotationDbModel](tag, None, "pres_annotation") {
|
class PresAnnotationDbTableDef(tag: Tag) extends Table[PresAnnotationDbModel](tag, None, "pres_annotation") {
|
||||||
@ -19,38 +18,13 @@ class PresAnnotationDbTableDef(tag: Tag) extends Table[PresAnnotationDbModel](ta
|
|||||||
val meetingId = column[String]("meetingId")
|
val meetingId = column[String]("meetingId")
|
||||||
val userId = column[String]("userId")
|
val userId = column[String]("userId")
|
||||||
val annotationInfo = column[String]("annotationInfo")
|
val annotationInfo = column[String]("annotationInfo")
|
||||||
val lastHistorySequence = column[Int]("lastHistorySequence")
|
|
||||||
val lastUpdatedAt = column[java.sql.Timestamp]("lastUpdatedAt")
|
val lastUpdatedAt = column[java.sql.Timestamp]("lastUpdatedAt")
|
||||||
// def whiteboard = foreignKey("whiteboard_fk", whiteboardId, Whiteboards)(_.whiteboardId, onDelete = ForeignKeyAction.Cascade)
|
def * = (annotationId, pageId, meetingId, userId, annotationInfo, lastUpdatedAt) <> (PresAnnotationDbModel.tupled, PresAnnotationDbModel.unapply)
|
||||||
def * = (annotationId, pageId, meetingId, userId, annotationInfo, lastHistorySequence, lastUpdatedAt) <> (PresAnnotationDbModel.tupled, PresAnnotationDbModel.unapply)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object PresAnnotationDAO {
|
object PresAnnotationDAO {
|
||||||
def insertOrUpdate(meetingId: String, annotation: AnnotationVO, annotationDiff: AnnotationVO) = {
|
|
||||||
// //TODO do it via trigger?
|
|
||||||
// PresAnnotationHistoryDAO.insert(meetingId, annotationDiff).onComplete {
|
|
||||||
// case Success(sequence) => {
|
|
||||||
// DatabaseConnection.logger.debug(s"Sequence generated to PresAnnotationHistory record: $sequence")
|
|
||||||
//
|
|
||||||
DatabaseConnection.enqueue(
|
|
||||||
TableQuery[PresAnnotationDbTableDef].insertOrUpdate(
|
|
||||||
PresAnnotationDbModel(
|
|
||||||
annotationId = annotation.id,
|
|
||||||
pageId = annotation.wbId,
|
|
||||||
meetingId = meetingId,
|
|
||||||
userId = annotation.userId,
|
|
||||||
annotationInfo = JsonUtils.mapToJson(annotation.annotationInfo).compactPrint,
|
|
||||||
lastHistorySequence = 0,
|
|
||||||
lastUpdatedAt = new java.sql.Timestamp(System.currentTimeMillis())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
// }
|
def prepareInsertOrUpdate(meetingId: String, annotation: AnnotationVO, annotationUpdatedAt: Long) = {
|
||||||
// case Failure(e) => DatabaseConnection.logger.error(s"Error inserting PresAnnotationHistory: $e")
|
|
||||||
}
|
|
||||||
|
|
||||||
def prepareInsertOrUpdate(meetingId: String, annotation: AnnotationVO) = {
|
|
||||||
TableQuery[PresAnnotationDbTableDef].insertOrUpdate(
|
TableQuery[PresAnnotationDbTableDef].insertOrUpdate(
|
||||||
PresAnnotationDbModel(
|
PresAnnotationDbModel(
|
||||||
annotationId = annotation.id,
|
annotationId = annotation.id,
|
||||||
@ -58,38 +32,27 @@ object PresAnnotationDAO {
|
|||||||
meetingId = meetingId,
|
meetingId = meetingId,
|
||||||
userId = annotation.userId,
|
userId = annotation.userId,
|
||||||
annotationInfo = JsonUtils.mapToJson(annotation.annotationInfo).compactPrint,
|
annotationInfo = JsonUtils.mapToJson(annotation.annotationInfo).compactPrint,
|
||||||
lastHistorySequence = 0,
|
lastUpdatedAt = new java.sql.Timestamp(annotationUpdatedAt)
|
||||||
lastUpdatedAt = new java.sql.Timestamp(System.currentTimeMillis())
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def insertOrUpdateMap(meetingId: String, annotations: Array[AnnotationVO]) = {
|
def insertOrUpdateMap(meetingId: String, annotations: Array[AnnotationVO], annotationUpdatedAt: Long) = {
|
||||||
DatabaseConnection.enqueue(
|
DatabaseConnection.enqueue(
|
||||||
DBIO.sequence(
|
DBIO.sequence(
|
||||||
annotations.map { annotation =>
|
annotations.map { annotation =>
|
||||||
prepareInsertOrUpdate(meetingId, annotation)
|
prepareInsertOrUpdate(meetingId, annotation, annotationUpdatedAt)
|
||||||
}.toVector
|
}.toVector
|
||||||
).transactionally
|
).transactionally
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def delete(wbId: String, meetingId: String, userId: String, annotationId: String) = {
|
def deleteAnnotations(meetingId: String, userId: String, annotationIds: Array[String], annotationUpdatedAt: Long) = {
|
||||||
// PresAnnotationHistoryDAO.delete(wbId, meetingId, userId, annotationId)
|
|
||||||
DatabaseConnection.enqueue(
|
|
||||||
TableQuery[PresAnnotationDbTableDef]
|
|
||||||
.filter(_.annotationId === annotationId)
|
|
||||||
.map(a => (a.annotationInfo, a.lastHistorySequence, a.meetingId, a.userId, a.lastUpdatedAt))
|
|
||||||
.update("", 0, meetingId, userId, new java.sql.Timestamp(System.currentTimeMillis()))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
def delete(meetingId: String, userId: String, annotationIds: Array[String]) = {
|
|
||||||
DatabaseConnection.enqueue(
|
DatabaseConnection.enqueue(
|
||||||
TableQuery[PresAnnotationDbTableDef]
|
TableQuery[PresAnnotationDbTableDef]
|
||||||
.filter(_.annotationId inSet annotationIds)
|
.filter(_.annotationId inSet annotationIds)
|
||||||
.map(a => (a.annotationInfo, a.lastHistorySequence, a.meetingId, a.userId, a.lastUpdatedAt))
|
.map(a => (a.annotationInfo, a.meetingId, a.userId, a.lastUpdatedAt))
|
||||||
.update("", 0, meetingId, userId, new java.sql.Timestamp(System.currentTimeMillis()))
|
.update("", meetingId, userId, new java.sql.Timestamp(annotationUpdatedAt))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,58 +4,85 @@ import org.bigbluebutton.common2.msgs.AnnotationVO
|
|||||||
import PostgresProfile.api._
|
import PostgresProfile.api._
|
||||||
|
|
||||||
case class PresAnnotationHistoryDbModel(
|
case class PresAnnotationHistoryDbModel(
|
||||||
sequence: Option[Int] = None,
|
|
||||||
annotationId: String,
|
annotationId: String,
|
||||||
pageId: String,
|
pageId: String,
|
||||||
meetingId: String,
|
meetingId: String,
|
||||||
userId: String,
|
userId: String,
|
||||||
annotationInfo: String
|
annotationInfo: String,
|
||||||
// lastUpdatedAt: java.sql.Timestamp = new java.sql.Timestamp(System.currentTimeMillis())
|
updatedAt: java.sql.Timestamp
|
||||||
)
|
)
|
||||||
|
|
||||||
class PresAnnotationHistoryDbTableDef(tag: Tag) extends Table[PresAnnotationHistoryDbModel](tag, None, "pres_annotation_history") {
|
class PresAnnotationHistoryDbTableDef(tag: Tag) extends Table[PresAnnotationHistoryDbModel](tag, None, "pres_annotation_history") {
|
||||||
val sequence = column[Option[Int]]("sequence", O.PrimaryKey, O.AutoInc)
|
|
||||||
val annotationId = column[String]("annotationId")
|
val annotationId = column[String]("annotationId")
|
||||||
val pageId = column[String]("pageId")
|
val pageId = column[String]("pageId")
|
||||||
val meetingId = column[String]("meetingId")
|
val meetingId = column[String]("meetingId")
|
||||||
val userId = column[String]("userId")
|
val userId = column[String]("userId")
|
||||||
val annotationInfo = column[String]("annotationInfo")
|
val annotationInfo = column[String]("annotationInfo")
|
||||||
// val lastUpdatedAt = column[java.sql.Timestamp]("lastUpdatedAt")
|
val updatedAt = column[java.sql.Timestamp]("updatedAt")
|
||||||
// def whiteboard = foreignKey("whiteboard_fk", whiteboardId, Whiteboards)(_.whiteboardId, onDelete = ForeignKeyAction.Cascade)
|
def * = (annotationId, pageId, meetingId, userId, annotationInfo, updatedAt) <> (PresAnnotationHistoryDbModel.tupled, PresAnnotationHistoryDbModel.unapply)
|
||||||
def * = (sequence, annotationId, pageId, meetingId, userId, annotationInfo) <> (PresAnnotationHistoryDbModel.tupled, PresAnnotationHistoryDbModel.unapply)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object PresAnnotationHistoryDAO {
|
object PresAnnotationHistoryDAO {
|
||||||
|
|
||||||
def insert(meetingId: String, annotationDiff: AnnotationVO) = {
|
def delete(wbId: String, meetingId: String, userId: String, annotationId: String, annotationUpdatedAt: Long) = {
|
||||||
DatabaseConnection.db.run(
|
DatabaseConnection.enqueue(
|
||||||
//TODO not being used for now
|
TableQuery[PresAnnotationHistoryDbTableDef].forceInsert(
|
||||||
TableQuery[PresAnnotationHistoryDbTableDef].returning(
|
PresAnnotationHistoryDbModel(
|
||||||
TableQuery[PresAnnotationHistoryDbTableDef].map(_.sequence)
|
// None,
|
||||||
) += PresAnnotationHistoryDbModel(
|
|
||||||
None,
|
|
||||||
annotationId = annotationDiff.id,
|
|
||||||
pageId = annotationDiff.wbId,
|
|
||||||
meetingId = meetingId,
|
|
||||||
userId = annotationDiff.userId,
|
|
||||||
annotationInfo = JsonUtils.mapToJson(annotationDiff.annotationInfo).compactPrint
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
def delete(wbId: String, meetingId: String, userId: String, annotationId: String) = {
|
|
||||||
DatabaseConnection.db.run(
|
|
||||||
//TODO not being used for now
|
|
||||||
TableQuery[PresAnnotationHistoryDbTableDef].returning(
|
|
||||||
TableQuery[PresAnnotationHistoryDbTableDef].map(_.sequence)
|
|
||||||
) += PresAnnotationHistoryDbModel(
|
|
||||||
None,
|
|
||||||
annotationId = annotationId,
|
annotationId = annotationId,
|
||||||
pageId = wbId,
|
pageId = wbId,
|
||||||
meetingId = meetingId,
|
meetingId = meetingId,
|
||||||
userId = userId,
|
userId = userId,
|
||||||
annotationInfo = ""
|
annotationInfo = "",
|
||||||
|
updatedAt = new java.sql.Timestamp(annotationUpdatedAt)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
def prepareInsertOrUpdate(meetingId: String, annotation: AnnotationVO, annotationUpdatedAt: Long) = {
|
||||||
|
TableQuery[PresAnnotationHistoryDbTableDef].forceInsert(
|
||||||
|
PresAnnotationHistoryDbModel(
|
||||||
|
annotationId = annotation.id,
|
||||||
|
pageId = annotation.wbId,
|
||||||
|
meetingId = meetingId,
|
||||||
|
userId = annotation.userId,
|
||||||
|
annotationInfo = JsonUtils.mapToJson(annotation.annotationInfo).compactPrint,
|
||||||
|
updatedAt = new java.sql.Timestamp(annotationUpdatedAt)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
def insertOrUpdateMap(meetingId: String, annotations: Array[AnnotationVO], annotationUpdatedAt: Long) = {
|
||||||
|
DatabaseConnection.enqueue(
|
||||||
|
DBIO.sequence(
|
||||||
|
annotations.map { annotation =>
|
||||||
|
prepareInsertOrUpdate(meetingId, annotation, annotationUpdatedAt)
|
||||||
|
}.toVector
|
||||||
|
).transactionally
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
def prepareDelete(meetingId: String, pageId: String, annotationId: String, userId: String, annotationUpdatedAt: Long) = {
|
||||||
|
TableQuery[PresAnnotationHistoryDbTableDef].forceInsert(
|
||||||
|
PresAnnotationHistoryDbModel(
|
||||||
|
annotationId = annotationId,
|
||||||
|
pageId = pageId,
|
||||||
|
meetingId = meetingId,
|
||||||
|
userId = userId,
|
||||||
|
annotationInfo = "",
|
||||||
|
updatedAt = new java.sql.Timestamp(annotationUpdatedAt)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
def deleteAnnotations(meetingId: String, pageId: String, userId: String, annotations: Array[String], annotationUpdatedAt: Long) = {
|
||||||
|
DatabaseConnection.enqueue(
|
||||||
|
DBIO.sequence(
|
||||||
|
annotations.map { annotationId =>
|
||||||
|
prepareDelete(meetingId, pageId, annotationId, userId, annotationUpdatedAt)
|
||||||
|
}.toVector
|
||||||
|
).transactionally
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1366,8 +1366,7 @@ CREATE TABLE "pres_annotation" (
|
|||||||
"meetingId" varchar(100),
|
"meetingId" varchar(100),
|
||||||
"userId" varchar(50),
|
"userId" varchar(50),
|
||||||
"annotationInfo" TEXT,
|
"annotationInfo" TEXT,
|
||||||
"lastHistorySequence" integer,
|
"lastUpdatedAt" timestamp with time zone
|
||||||
"lastUpdatedAt" timestamp with time zone DEFAULT now()
|
|
||||||
);
|
);
|
||||||
CREATE INDEX "idx_pres_annotation_pageId" ON "pres_annotation"("pageId");
|
CREATE INDEX "idx_pres_annotation_pageId" ON "pres_annotation"("pageId");
|
||||||
CREATE INDEX "idx_pres_annotation_updatedAt" ON "pres_annotation"("pageId","lastUpdatedAt");
|
CREATE INDEX "idx_pres_annotation_updatedAt" ON "pres_annotation"("pageId","lastUpdatedAt");
|
||||||
@ -1379,25 +1378,30 @@ CREATE TABLE "pres_annotation_history" (
|
|||||||
"pageId" varchar(100) REFERENCES "pres_page"("pageId") ON DELETE CASCADE,
|
"pageId" varchar(100) REFERENCES "pres_page"("pageId") ON DELETE CASCADE,
|
||||||
"meetingId" varchar(100),
|
"meetingId" varchar(100),
|
||||||
"userId" varchar(50),
|
"userId" varchar(50),
|
||||||
"annotationInfo" TEXT
|
"annotationInfo" TEXT,
|
||||||
-- "lastUpdatedAt" timestamp with time zone DEFAULT now()
|
"updatedAt" timestamp with time zone
|
||||||
);
|
);
|
||||||
CREATE INDEX "idx_pres_annotation_history_pageId" ON "pres_annotation"("pageId");
|
CREATE INDEX "idx_pres_annotation_history_pageId" ON "pres_annotation"("pageId");
|
||||||
create index "idx_pres_annotation_history_user_meeting" on "pres_annotation_history" ("userId", "meetingId");
|
create index "idx_pres_annotation_history_user_meeting" on "pres_annotation_history" ("userId", "meetingId");
|
||||||
|
CREATE INDEX "idx_pres_annotation_history_updatedAt" ON "pres_annotation_history"("pageId", "updatedAt");
|
||||||
|
|
||||||
CREATE VIEW "v_pres_annotation_curr" AS
|
CREATE VIEW "v_pres_annotation_curr" AS
|
||||||
SELECT p."meetingId", pp."presentationId", pa."annotationId", pa."pageId", pa."userId", pa."annotationInfo", pa."lastHistorySequence", pa."lastUpdatedAt"
|
SELECT p."meetingId", pp."presentationId", pa."annotationId", pa."pageId", pa."userId", pa."annotationInfo",
|
||||||
|
pa."lastUpdatedAt", "user"."isModerator" as "userIsModerator"
|
||||||
FROM pres_presentation p
|
FROM pres_presentation p
|
||||||
JOIN pres_page pp ON pp."presentationId" = p."presentationId"
|
JOIN pres_page pp ON pp."presentationId" = p."presentationId"
|
||||||
JOIN pres_annotation pa ON pa."pageId" = pp."pageId"
|
JOIN pres_annotation pa ON pa."pageId" = pp."pageId"
|
||||||
|
JOIN "user" on "user"."meetingId" = pa."meetingId" and "user"."userId" = pa."userId"
|
||||||
WHERE p."current" IS true
|
WHERE p."current" IS true
|
||||||
AND pp."current" IS true;
|
AND pp."current" IS true;
|
||||||
|
|
||||||
CREATE VIEW "v_pres_annotation_history_curr" AS
|
CREATE VIEW "v_pres_annotation_history_curr" AS
|
||||||
SELECT p."meetingId", pp."presentationId", pah."pageId", pah."userId", pah."annotationId", pah."annotationInfo", pah."sequence"
|
SELECT p."meetingId", pp."presentationId", pah."pageId", pah."userId", pah."annotationId", pah."annotationInfo",
|
||||||
|
pah."updatedAt", "user"."isModerator" as "userIsModerator"
|
||||||
FROM pres_presentation p
|
FROM pres_presentation p
|
||||||
JOIN pres_page pp ON pp."presentationId" = p."presentationId"
|
JOIN pres_page pp ON pp."presentationId" = p."presentationId"
|
||||||
JOIN pres_annotation_history pah ON pah."pageId" = pp."pageId"
|
JOIN pres_annotation_history pah ON pah."pageId" = pp."pageId"
|
||||||
|
JOIN "user" on "user"."meetingId" = pah."meetingId" and "user"."userId" = pah."userId"
|
||||||
WHERE p."current" IS true
|
WHERE p."current" IS true
|
||||||
AND pp."current" IS true;
|
AND pp."current" IS true;
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ select_permissions:
|
|||||||
- pageId
|
- pageId
|
||||||
- presentationId
|
- presentationId
|
||||||
- userId
|
- userId
|
||||||
- lastHistorySequence
|
|
||||||
- annotationInfo
|
- annotationInfo
|
||||||
- lastUpdatedAt
|
- lastUpdatedAt
|
||||||
filter:
|
filter:
|
||||||
@ -32,9 +31,8 @@ select_permissions:
|
|||||||
- meetingId:
|
- meetingId:
|
||||||
_eq: X-Hasura-MeetingId
|
_eq: X-Hasura-MeetingId
|
||||||
- _or:
|
- _or:
|
||||||
- user:
|
- userIsModerator:
|
||||||
isModerator:
|
_eq: true
|
||||||
_eq: true
|
|
||||||
- meetingId:
|
- meetingId:
|
||||||
_eq: X-Hasura-AnnotationsNotLockedInMeeting
|
_eq: X-Hasura-AnnotationsNotLockedInMeeting
|
||||||
- userId:
|
- userId:
|
||||||
|
@ -24,16 +24,15 @@ select_permissions:
|
|||||||
- pageId
|
- pageId
|
||||||
- presentationId
|
- presentationId
|
||||||
- userId
|
- userId
|
||||||
- sequence
|
- updatedAt
|
||||||
- annotationInfo
|
- annotationInfo
|
||||||
filter:
|
filter:
|
||||||
_and:
|
_and:
|
||||||
- meetingId:
|
- meetingId:
|
||||||
_eq: X-Hasura-MeetingId
|
_eq: X-Hasura-MeetingId
|
||||||
- _or:
|
- _or:
|
||||||
- user:
|
- userIsModerator:
|
||||||
isModerator:
|
_eq: true
|
||||||
_eq: true
|
|
||||||
- meetingId:
|
- meetingId:
|
||||||
_eq: X-Hasura-AnnotationsNotLockedInMeeting
|
_eq: X-Hasura-AnnotationsNotLockedInMeeting
|
||||||
- userId:
|
- userId:
|
||||||
|
Loading…
Reference in New Issue
Block a user