I have the following use case / application:
a TODO app where users can: CRUD their on TODOs (I am using pouchdb/couchdb syncing). Pretty much based on Josh Morony\'
CouchDB does not offer a good way to do this, but if your backend has a facility for maintaining lots of shared databases (in addition to single-user ones) I think you could pull it off.
The initial impulse is to use continuous filtered replication to/from a central "master" hub, but this leaves you with two problems:
How is your sharing organized? What you might be able to do is set up a shared database for each "share" combination.
When user A wants to share document D with user B, "move" the document into a new database AB. Practically this means: copy the contents of D to a new document D' in database AB, and then delete the original D from database A.
How does this sync?
Keep in mind PouchDB clients can replicate to/from more than one source database, so user A will replicate from A and AB, while user B replicates from B and AB. The trick is to use filtered replication in the opposite direction, back to the server databases:
The now-shared document D' should never go to database A or database B, and likewise an unshared document X should never go to database AB. Something like this:
┌───────────────────────┐
│ server:5984/user_a │
└───┬───────────────▲───┘
└─┐ ┌─┘ ┌──────────────────────────────┐
│ ●──────│ if (doc.shared_with == null) │
┌─▼───────────┴─┐ └──────────────────────────────┘
│ local │
└──▲──────────┬─┘
┌─┘ └─┐ ┌──────────────────────────────┐
│ ●──────│ if (doc.shared_with == 'ab') │
┌───┴──────────────▼────┐ └──────────────────────────────┘
│ server:5984/shares_ab │
└───────────────────────┘
So, assuming the share database(s) are already set up, when the local client wants to share some data it actually adds _deleted:true
to the original (unshared) document and creates a new (shared) document. The deleted original propagates to the user_a database on the server and the created copy propagates to the shares_ab.
Unsharing then works pretty much the same: the client adds _deleted:true
to the shared document and recreates the data again in a new unshared copy. From B's perspective, the document had showed up once it was in shares_ab and now disappears because it is deleted from shares_ab.
(Instead of user "pairs" you could extend this to ad-hoc sets of users, or simplify it to specific groups that users are already in, or whatnot. The key idea is to create an actually shared database for each unique sharing context needed.)
So for this kind of project, per-user database is the recommended pattern for your databases.
So basically, you will have :
As for the central database, you need it to be read-only and you also need to allow shared documents only. You need some kind of application proxy for this. You can basically build an API on top of the central database and allow access to shared documents only.
Then, you can setup replications from each user database to the central database and persist de replication in the _replicator database.
I'm not sure that per-user database plugin is working at the moment with the version 2.X.X but you can do it yourself with some sort of application process (Create the user, then create the database, then manage permissions of the new database)