= V2 Inspector2 Specification = [[V2Master]] | [[V2HighLevelDesign]] <> = Introduction = = Development = See [[V2Inspector2Todo]] = Main Menu = * '''Home''' - * '''Inspection Records''' - Displays a list of ''Inspection Records'' * '''Inspection Items''' - Displays a list of ''Inspection Items'' * '''Synchronize''' - Displays counts of Inspection Records and Inspection Items. Buttons for ''Upload'' and ''Download'' data. * '''Preferences''' - * '''About Inspector''' - Displays Inspector version number and release date * '''Contact Us''' = Screens = * '''Home''' * '''Inspection Records''' (list) * '''Inspection Record Detail''' * '''Inspection Record New/Edit''' * '''Inspection Items''' (list) * '''Inspection Item Detail''' * '''Inspection Item New/Edit''' * '''Synchronize''' * '''Statistics''' * '''Preferences''' * '''About Inspector''' * '''Contact Us''' = Data Synchronization = Key data fields for synchronization: * ''local_id'' - Primary key in the device (local) database * ''local_is_dirty'' - If set to on-zero, then the record has been changed on the device * ''local_is_conflict'' - If set, then the record has been change on the device and the server, and cannot be uploaded * ''id'' - The server's primary key * ''update_count'' - The server's update count. The device should never change this field == Download == * Data in JSON format is download from the server, from the following tables: * '''tags''' - Inspection Items * '''scans''' - Inspection Records * '''photos''' - Inspection Photos (''not implemented yet'') === Download Algorithm === For a single downloaded record: {{{ table = name of the table being processed new_record = record downloaded from server old_record = db.getById(table, record.id) -- Record from client device database if ( old_record == null ) { new_record.local_is_dirty = 0; new_record.local_is_conflict = 0 db.insert(table, new_record) -- local_id is set by the database server } else { if ( new_record.update_count != old_record.update_count ) { // Server record was updated if ( old_record.local_is_dirty ) { db.updateById(table, old_record.id, {local_is_conflict: 1}) -- Set old_record.local_is_conflict = 1 } else { record.local_is_conflict = 0 db.updateById(table, new_record.id, new_record) -- Replace old_record with new_record (or delete & insert?) } } } }}} == Data Upload == === Upload Algorithm === 1. Only upload records records that meet one the following conditions: 1. ''local_is_dirty'' != 0 1. ''id'' == null 1. Do not upload records where ''local_is_conflict'' != 0 '''To Do''' What are the responses from the server in the following cases: 1. '''Success''' 1. '''Insert''' On a new record does the server respond with the new ''id'' value or path to access the new record? 1. '''Update''' Does the server respond with the updated ''update_count''. If not, can we always guarantee it is incremented by one 1. '''Conflict''' What is the response when the ''update_count'' of uploaded record doesn't not match that on the server Possible responses to an insert/update: inserted: id updated: update_count conflict: an error code For a single record to upload: {{{ table = name of the table being processed record = record to upload create a JSON string from the record, which does not include the following fields: local_id local_is_dirty local_is_conflict if ( record.id == null ) { // Insert a new record POST JSON to "http://{url}/{table}.json" record.id = id from server -- how to get the new id from server? record.local_is_dirty = 0 record.local_is_conflict = 0 record.update_count = 1 (or 0?) db.updateByLocalId(record.local_id, record) } else { // Update existing record PUT JSON to "http://{url}/{record.id}/{table}.json if (response == OK) { -- do nothing or download record again to get new update_at value? record.update_count = record.update_count + 1 db.updateByLocalId(record.local_id, record) } else if ( response == conflict ) { db.updateById(record.id, {local_is_conflict: 1}) -- Set old_record.local_is_conflict = 1 } else { report error } } }}}