We have an Android app written as a Cordova AngularJS SPA which has now grown so that we need to add some work to it meaning we have to improve the synchronization part of the app. The app is mainly used offline. I can't give details of the business use but data structure and constraints can be illustrated with an over simplified car mechanic's business!
Claims are at Company, Garages and Car level, so in other words Jack may be able to see all garages and all cars in company A, Jill may be able to see all garages in Company A and only some cars in each garage, Jo may be able to see only one garage and only some of the cars in that garage. - you get the idea.
- The app downloads information that the mechanic can see about their jobs. They are able to see all jobs assigned to them and any other jobs that the claims they have allow them to see, so that they can pick those jobs up. A job is a grouping of Checkpoints that need to be completed on a car.
- The garage workshop has no data connection, the mechanic can only sync when they go back to the office. This may need to be user initiated, not entirely sure yet though.
- More than one mechanic can work on a job, if the same data item gets updated by both mechanics the last item synchronised wins.
- If a data item has been updated on the server since the mechanic downloaded it to the tablet app, they then updated it and uploaded it, the mechanic's change wins.
- Jobs may only be partially complete at time of synchronisation.
- When the app synchronises it needs to apply the changes it holds and update what data is held locally with the most up to date information from the SQL database. It may need to remove data from the app that is no longer relevant to the jobs being worked on currently or in the future.
The backend is hosted on Azure, data stored in an Azure SQL database. There is an OData API we're phasing out and a Web API that can be used / added to. The complex authorisation happens within a shared module in the APIs, the only data taken down to an app would be data the user is allowed to see.
The data will get fairly large over time.
This needs to be transactional – ie. If there is a problem with the sync we want a whole job to have been synchronized at a time, not entity type at a time.
The app has been written as a SPA Cordova application so, unless there is a compelling reason not to, it has to remain this way.
Ideas we've considered so far :
BreezeJS has been used to track changes. We could send just those changes up to the server, wait for a process on the server to apply those changes to the database and then start the download of any changes and new data required. However this could mean that the sync will take a long time to complete if lots of people are syncing at the same time and things get clogged up in a queue of some sort.
Using CouchDb/PouchDB - I know very little about this, would this work with the authorisation model we have? And how would it work getting the changes to/from the master SQL database?
Azure offline data sync (https://docs.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-offline-data-sync) - As far as I can see this is pretty similar to using CouchDb, or have I misunderstood?
The required authorisation model is the part that seems to be the blocker to several solutions being viable, we need different users to have different sets of common data at a given time, this is imperative.