We have some complex sync requirements and I haven't been able to wrap my head around how to use the sync function.
The basic use case is that there is a group of mobile users from a company. The company's docs are in the same database as many other companies docs. Some company users will have access to all documents, others will only have access to some documents. Access can change along the way.
Maybe some example docs would help to illustrate and work through this.
Let's pretend this is a task management system and multiple notes can be added to each task. We have task documents, and note documents.
{
"id" : "1",
"name" : "task1",
"company" : "Acme",
"type" : "task",
"owners" : ["user1"],
}
{
"id" : "2",
"name" : "task2",
"company" : "Acme",
"type" : "task",
"owners" : ["user2"],
}
{
"id" : "3",
"name" : "task3",
"company" : "Different Company",
"type" : "task",
"owners" : ["user5"],
}
{
"id" : "4",
"name" : "note1",
"type" : "note",
"parent" : "1"
}
{
"id" : "5",
"name" : "note2",
"type" : "note",
"parent" : "1"
}
{
"id" : "6",
"name" : "note3",
"type" : "note",
"parent" : "2"
}
user1 is a "regular" user, so they should only have access to the tasks that they own (task 1) and their child notes (note1 and note2, but not note3)
user2 is an "manager" user, so they should have access to all tasks and all child notes for their company (not task3 or note3 because they're for another company)
1. I can envision one solution where I use a channels property in every document and our application logic can handle distinguishing between "regular" users and "manager" users. Thinking through the drawbacks to this approach:
- If a "regular" users gets promoted to a "manager", we would have to manually update the channels property for all of that company's documents. In our case, we'll have 10,000+ documents per company and even though nothing substantial will have changed, this will trigger re-syncing all documents to every mobile user.
One possible solution to this would be to have direct API access to manipulate channel access from our app servers. My theory is that by manipulating the "access control list" directly, it wouldn't cause each document to be updated and therefore wouldn't trigger unnecessary syncing to all of the mobile clients. I don't understand the internals well enough to know if 1) such an api exists or 2) manipulating it this way would trigger appropriate syncing or "unsyncing" in the case of reduced access.
2. Can sync() function logic be based on a users role? For example, if a user is a "manager" can we sync all documents regardless of the "owners" property? Then if the user gets demoted to a "regular" user, will sync_gateway know to remove their access to all of the documents that they aren't an "owner" on?
3. I don't have an "owners" property on the note documents and the parent "task" documents don't point to the child "note" documents, it's the other way around. When the sync() function comes across a note document, is there any way to have it grant access based on the referenced parent document's "owners" property? I think I know the answer to this but wanted to bring up the use case. Again, the "possible solution" for point #1 above would be helpful for something like this.
4. The other question this brings to mind is how well the channels concept scales. How many channels can we reasonably have? Hundreds of thousands, millions?
Sorry for the long post - I can only imagine that these use cases will be very common so solving them would be helpful.
fyi - we're currently solving this by running a separate CouchDB database per user, but with CouchDB not being our "master" database, keeping Couchbase and CouchDB in sync isn't very fun.
Nick