How to maintain edit log in Appian?

I have come across a requirement where we need to maintain a table where all the edit information needs to be shown. The requirement is as follows:

When someone edits anything in a Request form (has 9 inputs fields which can be edited), a new “Edit Log” read-only table should appear.

Columns in the Table should include:

      • Input Field Name that was changed

      • Initial Input Data (Data provided when creating a request first time)

      • Input Data that was provided during the edit (Current)

      • Date and Time of Edit

      • Name of the Editor

      • Status of the Request at the time of the Edit (Can be Pending, Approved, etc.)

It should look something similar to this:

Your open inputs are invited for handling this in database (how can we maintain this log in DB) and showing in Sail UI.

Thanks in advance

  Discussion posts and replies are publicly visible

Parents
  • 0
    Certified Lead Developer

    1.  I would urge you to express to your client the egregious cost that you are going to incur by doing this, and strongly recommend that they consider whether they really want to do this.

    2.  You can use a!writeToDataStoreEntity() as part of the saveInto of *this makes me cringe to type it* all 9 input fields.  This will write to the database every time the saveInto function is called. (Warning:  This may be even grossly more infeasible if it actually saves once every key press, which is likely.  You could be writing to the database hundreds of times rather than 9 times.)

    3.  To display this info on the screen, you then need to query the latest row from the database for each input once every time the variable that stores the contents of each of the nine inputs is changed.  Whichever query that runs again will pull the data, and then you need to display it in a separate read-only component beneath each input.

    4.  DON'T DO THIS!  Explain to your client what a terrible idea this is.  You don't need to log edits at the input, or more probable if you took this approach keypress, level.  You're going to wind up sending so much data to and getting so much data from that you will kill your connection thread pool.  If it somehow passed test, doing so with only a few users on the test system total, I promise you that you would crash your database in production with only a few users filling out this form at the same time.

    Under normal circumstances, under most reasonable design patterns, no data would go to the database, hence nothing would really be edited, and nothing need to be logged, until the form was submitted.  Then you can display another form with all the logging information you want.  One trip to the DB, one trip back, with everything.  One maybe two connection threads.  You don't need your logging to be more granular than that, because your updates to the data itself shouldn't be that granular.

Reply
  • 0
    Certified Lead Developer

    1.  I would urge you to express to your client the egregious cost that you are going to incur by doing this, and strongly recommend that they consider whether they really want to do this.

    2.  You can use a!writeToDataStoreEntity() as part of the saveInto of *this makes me cringe to type it* all 9 input fields.  This will write to the database every time the saveInto function is called. (Warning:  This may be even grossly more infeasible if it actually saves once every key press, which is likely.  You could be writing to the database hundreds of times rather than 9 times.)

    3.  To display this info on the screen, you then need to query the latest row from the database for each input once every time the variable that stores the contents of each of the nine inputs is changed.  Whichever query that runs again will pull the data, and then you need to display it in a separate read-only component beneath each input.

    4.  DON'T DO THIS!  Explain to your client what a terrible idea this is.  You don't need to log edits at the input, or more probable if you took this approach keypress, level.  You're going to wind up sending so much data to and getting so much data from that you will kill your connection thread pool.  If it somehow passed test, doing so with only a few users on the test system total, I promise you that you would crash your database in production with only a few users filling out this form at the same time.

    Under normal circumstances, under most reasonable design patterns, no data would go to the database, hence nothing would really be edited, and nothing need to be logged, until the form was submitted.  Then you can display another form with all the logging information you want.  One trip to the DB, one trip back, with everything.  One maybe two connection threads.  You don't need your logging to be more granular than that, because your updates to the data itself shouldn't be that granular.

Children
  •  I would echo 's comments. I guess my reaction is to ask you to wind back to what the objective is here? Usually this sort of requirements reflects a need to audit what a record looked like before a transaction was applied and what it looks like after a transaction was applied. In which case you're only really interested in actual changes applied to the database row in question, not all of the changes I started to make then undid then re-did at the form level - what value would there be in that? 

    For the audit-style requirement one common pattern is as follows:

    • database triggers - have a 'history' table that is a carbon-copy of the actual business data (which should hold who crated/updated the row and when), with its  own Primary Key and a Foreign Key pointing to the business data table's Primary Key. You can add 'after insert' and 'after update' style triggers. The benefit of this pattern is that you get carbon-copies of every single state your business data was ever in. The downside is, depending on the volumes of transactions, this table can get very big  very quickly
    • audit interface - this exposes the 'history' table to the application front-end, where it can be searched/filtered/locked down to a discrete set of Users who have the rights to view it

    So: the key question to ask is - what is the objective you're aiming for?