This commit is contained in:
@@ -70,22 +70,13 @@ CURRENT TODOs
|
|||||||
@@@@@@@@@@@ ROADMAP STAGE 2:
|
@@@@@@@@@@@ ROADMAP STAGE 2:
|
||||||
|
|
||||||
CURRENT ITEM:
|
CURRENT ITEM:
|
||||||
|
|
||||||
Add tests as I go while adding all the structure of the workorder and all ops
|
|
||||||
TBD: Does a labor and other grandchild objects record really have an attachment, wiki, and custom fields?
|
|
||||||
doesn't matter for our purposes at this point, it's all boilerplate anyway can remove it later
|
|
||||||
UI? Will it be a table or a whole form or...??
|
|
||||||
|
|
||||||
Do tests for every operation on workorder and structure
|
|
||||||
(implementing all bits in object as required)
|
|
||||||
|
|
||||||
TEST: Proposed workorder structure and routes
|
|
||||||
RESULT: Basically they work, now need to INTEGRATION TEST
|
|
||||||
|
|
||||||
MAKE THESE INTEGRATION TESTS FTW!
|
MAKE THESE INTEGRATION TESTS FTW!
|
||||||
test: concurrency exception handling in workorder PUT route
|
test: concurrency exception handling in workorder PUT route
|
||||||
test: biz rules
|
test: biz rules
|
||||||
test: does duplicate workorder return full workorder graph (i.e. does the CopyObject function actually copy the entire object and descendents? Or do I need to iterate it)
|
test: does duplicate workorder return full workorder graph (i.e. does the CopyObject function actually copy the entire object and descendents? Or do I need to iterate it)
|
||||||
|
Do tests for every operation on workorder and structure
|
||||||
|
(implementing all bits in object as required)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
update: v8Export to use new routes for workorder properly
|
update: v8Export to use new routes for workorder properly
|
||||||
@@ -99,128 +90,6 @@ Finish off the v8 test export then get the below shit done so can move to stage
|
|||||||
todo: Release AyaNova 7.x (bump version numbers)
|
todo: Release AyaNova 7.x (bump version numbers)
|
||||||
|
|
||||||
|
|
||||||
todo: ***CLEAN UP OR DELETE***
|
|
||||||
PLANNING WORKORDER considerations:
|
|
||||||
QUESTIONS:
|
|
||||||
Why do I need to make a wo first before I can update it? (i.e. why did I make a CREATE route?)
|
|
||||||
still no idea after lot's of planning, answer is probably not needed at all
|
|
||||||
|
|
||||||
How can I avoid concurrency issues?
|
|
||||||
concurrency check each record in graph, not entire workorder from top
|
|
||||||
|
|
||||||
How to minimize data sent, make fast saves?
|
|
||||||
I'm leaning towards the tons of routes option, need to test it out
|
|
||||||
|
|
||||||
PATCH, send all changes in graph in one go
|
|
||||||
most efficient, sends all changes in one go
|
|
||||||
if any part fails it all fails
|
|
||||||
requires second copy of wo for diffing
|
|
||||||
UPDATE (PATCH): Send only changes in whole graph from client with an OP (for "operation") flag at each level indicating to change that part or not, a flag?
|
|
||||||
WO (OP flag=no change, no concurrency token, basically empty but for the fields that hold the descendents that are changed)
|
|
||||||
woitem 0 (OP flag="Delete" and concurrency token, no other data with it, just the id and flag and ctoken)
|
|
||||||
woitem 1 (OP flag ="update", all fields as in a "put" operation, nothing left out, assumed all are changed)
|
|
||||||
woitem2 (OP flag="no OP", just a placeholder for children with changes)
|
|
||||||
labor 2 (OP flag = "update" with all data)
|
|
||||||
labor 3 (OP flag="delete" with concurrency token and nothing else)
|
|
||||||
labor 4 (OP flag="Add", with all PUT data)
|
|
||||||
issues with patch:
|
|
||||||
how to post a whole object leaving blank when so many fields will be required?
|
|
||||||
maybe we don't make them required at the object field annotation level but only at the db level and as a biz rule?
|
|
||||||
how to synchronize objects and id's?
|
|
||||||
i.e. reverse patch back again
|
|
||||||
for example, you add two woitems, save, you have two now that are not id'd and don't know which is which
|
|
||||||
server has to return something identifying which is which and assigned ID, plus it might add data back or change data due to rules or whatever
|
|
||||||
Maybe server sends back entire saved objects?
|
|
||||||
issues:
|
|
||||||
how to update client end with update back from server when saved (server will add id and may change fields or even add things)
|
|
||||||
|
|
||||||
* TONS OF ROUTES: Update individual portions as seperate objects to their own routes sequentially
|
|
||||||
i.e. client traverses and diffs virgin copy and edited copy of wo
|
|
||||||
determines what's different, only sends an update for each object to it's own route as appropriate
|
|
||||||
on successful update fixes up the edited copy of that object
|
|
||||||
on all updates done, the edited copy becomes the virgin copy (or do we need 3 objects at one point in case of fail?)
|
|
||||||
|
|
||||||
requires second copy of wo for diffing
|
|
||||||
goes over workorder, looks for changes, sends update for each object individually and patches up local from result
|
|
||||||
so if a workorderitempart has changed then it sends only that for update individually
|
|
||||||
Example routes:
|
|
||||||
Post: Workorder/1/WorkorderItem/2/Labor/4 {updated object}
|
|
||||||
WorkOrder/{woid} <-entire workorder, get for all, post for entire, put to update entire (not likely to use but?)
|
|
||||||
WorkOrder/{woid}/WorkorderItems <- all workorderitems, post to add new, put to update all as a collection
|
|
||||||
WorkOrder/{woid}/WorkOrderItems/{woitemid} <- CRUD single woitemid
|
|
||||||
WorkOrder/{woid}/WorkOrderItems/{woitemid}/Labors <- entire labor collection CRUD ops over all collection (also ADD new labor here (POST))
|
|
||||||
WorkOrder/{woid}/WorkOrderItems/{woitemid}/Labors/{laborid} <- Crud on individual item
|
|
||||||
https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design#define-operations-in-terms-of-http-methods
|
|
||||||
This way is pretty solid, will result in a lot of routes but a lot of the code can be shared in the biz object, so for example if updating a labor or a collection of labor most code the same
|
|
||||||
Efficiency:
|
|
||||||
Since there is a route for every bit of the workorder the client can pick how high up to update based on diff check
|
|
||||||
so if only one single bit of a header has changed then only update that bit (or will it need the collection to not remove it? No because collection route is where you remove an item)
|
|
||||||
or if only a deeply nested labor has changed, just PUTS it to that exact route and udpates concurrency token on result
|
|
||||||
since the workorder is not really influenced as a whole by updates to portions this could work and be a bit less problematic than JSONPATCH which really seems to be a bit of a stretch
|
|
||||||
|
|
||||||
|
|
||||||
NOTE: can put part of the route in the controller, so for example if every route in that controller needs to identify a workorder then this kind of thing is possible, not sure if helpful or not yet:
|
|
||||||
[Route("api/campus/{campusId:int}/building")]
|
|
||||||
public class BuildingController : Controller {
|
|
||||||
//...
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
[Route("{buildingId:int}")] // Matches GET api/campus/123/building/456
|
|
||||||
public IActionResult GetBuilding ([FromRoute]int campusId, [FromRoute]int buildingId) {
|
|
||||||
//... validate campus id along with building id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issues:
|
|
||||||
very chatty, could be slow
|
|
||||||
|
|
||||||
PUT, update entire workorder on every save
|
|
||||||
Very easy to code, basically send it all and see what happens
|
|
||||||
Very clean, no need to worry about bits and pieces being tracked etc
|
|
||||||
issues:
|
|
||||||
not very efficient, needs to send entire graph on every save even if user just changed one character
|
|
||||||
|
|
||||||
|
|
||||||
How to support undo?
|
|
||||||
How to show what's dirty on form?
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BUSINESS RULES (v7)
|
|
||||||
In reality there are almost no business rules in v7 workorder graph.
|
|
||||||
Only serious one is woitempart requires serial if serialized
|
|
||||||
Rest are all related to length of fields, required fields, date order etc and only a few of those to boot
|
|
||||||
Looks like this is not an issue regarding v7 stuff at all
|
|
||||||
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
Workorder is not dependent on it's children for anything
|
|
||||||
WoItem is not dependent on any of it's children
|
|
||||||
In fact nothing in any part of the wo is dependent on anything else during normal ops
|
|
||||||
|
|
||||||
CONCURRENCY
|
|
||||||
If the client updates part of the wo graph, only that exact record really needs dependency checking.
|
|
||||||
There *is* however business rules that might take hold but that's all at the server and not related to concurrency directly
|
|
||||||
For example, on any change to the wo graph the server has to see if the wo is still editable and hasn't been locked or user's rights changed
|
|
||||||
But that's not strictly concurrency related in teh sense that another user change the *same* record being updated
|
|
||||||
So, for v8 as long as it can handle a portional update to part of the graph and uses the concurrency of that exact record to check then it sidesteps a lot of multi-user scenarios
|
|
||||||
This was only an issue in v7 due to it using only the wo header itself as the source of concurrency checking which would *always* involve the whole graph in any change anywhere
|
|
||||||
|
|
||||||
for example:
|
|
||||||
WOHEADER (concurrency id, dirty flag at client)
|
|
||||||
WOITEM (concurrency id, dirty flag at client)
|
|
||||||
woitempart (concurrencyid dirty flag at client)
|
|
||||||
woitemlabor (concurrencyid, dirty flag at client)
|
|
||||||
WOITEM (concurrency id, dirty flag at client)
|
|
||||||
woitemscheduser (own concurrency, dirty flag etc)
|
|
||||||
woitempart (concurrencyid dirty flag at client)
|
|
||||||
woitemlabor (concurrencyid, dirty flag at client)
|
|
||||||
|
|
||||||
ROUTES
|
|
||||||
In light of dependencies and concurrency it is ideal if the server can handle updates to any portion of the graph independently
|
|
||||||
But, do we really want CRUD routes for every descendent of the workorder graph? (maybe, just not sure)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TEST
|
TEST
|
||||||
Do a practical test of a mocked wo, woitem, woitemlabor or whatever, see how it would be updated, fetched concurrency checking etc
|
Do a practical test of a mocked wo, woitem, woitemlabor or whatever, see how it would be updated, fetched concurrency checking etc
|
||||||
@@ -254,80 +123,7 @@ public class BuildingController : Controller {
|
|||||||
Test how to delete graph without ref. integrity errors
|
Test how to delete graph without ref. integrity errors
|
||||||
|
|
||||||
|
|
||||||
UI
|
|
||||||
Only send the bits that are altered to save bandwidth
|
|
||||||
All updates are technically a PATCH operation
|
|
||||||
Because it starts with a wo object provided by the server?
|
|
||||||
or is this even necessary now?
|
|
||||||
think Patch
|
|
||||||
CONCURRENCY:
|
|
||||||
if any part of the patch fails the whole patch fails
|
|
||||||
|
|
||||||
idea: UI reflects tentativeness state of object:
|
|
||||||
The UI doesn't imply something is done by changing it fully until the save is completed.
|
|
||||||
This serves two purposes:
|
|
||||||
1) user knows at a glance what isn't saved yet and will know it's waiting for save clearly, hopefully leading them to save more often,
|
|
||||||
2) client doesn't need to track invisible shit behind the scenes, can more easily do patch updates right off UI source
|
|
||||||
|
|
||||||
e.g.:
|
|
||||||
if deleted a row in parts, that row doesn't disappear but rather shows crossed out, maybe grayed out but still there until save to indicate it's tentative status
|
|
||||||
if added a row, shows green or something or bold or asterisk, (can style with css based on state) until saved
|
|
||||||
problems:
|
|
||||||
how to handle regular fields that are changed (that's a lot of field data to track for changes)?
|
|
||||||
Maybe client keeps a virgin copy of the original wo for comparison
|
|
||||||
periodically does a compare and flags differences on updates?
|
|
||||||
(this would also help to serve as an Undo maybe?)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
A biz object for each one?
|
|
||||||
probably need the parent for biz rules and shit so likely best to keep in one file
|
|
||||||
Controller - all in root controller or seperate controllers?
|
|
||||||
likely follows biz object decision
|
|
||||||
case 1714 re-rises the question about concurrency and mutiple editors of a workorder
|
|
||||||
Look into how independent changes can be from each other, i.e. is it safe to have two users editing two different woitems on a workorder?
|
|
||||||
This might make people happier.
|
|
||||||
Like, what exactly affects what else on a workorder. Do you save the whole wo to the route at once even though you just added a woitem or..?
|
|
||||||
If I code it to send the whole wo on a change to even a grandchild then that's heavy traffic for a minor change
|
|
||||||
- actually no, it's not really that heavy, even a fairly fat workorder will be way under 100kb, most probably under 1kb
|
|
||||||
should really only send the minimum data required to fulfil the change.
|
|
||||||
Maybe need two copies of wo at client so can tell what has changed and then only send that bit.
|
|
||||||
But then need routes to handle that?
|
|
||||||
Or can the wo route just accept a blank header with items hanging off it that have changed only? (like a patch?)
|
|
||||||
|
|
||||||
Use foreign keys!!
|
|
||||||
Consider UI in this as well, will need to decide at least what is visible when
|
|
||||||
Workorder UI good ideas here: https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3475
|
|
||||||
How to add items, like new woitem?
|
|
||||||
send to server get back new object?
|
|
||||||
lots of biz rules and stuff need to happen, want to minimize load at client
|
|
||||||
but lots of data back and forth is not ideal
|
|
||||||
maybe request a woitem and get it back?
|
|
||||||
what exactly needs to be processed in the wo when items are added / removed?
|
|
||||||
math / totalling?
|
|
||||||
simple calcs sb client doable
|
|
||||||
this will drive what has to happen.
|
|
||||||
Need to go over all wo features and factor them into this decision properly
|
|
||||||
The whole idea of a completed section of a wo and stuff, is that dropped due to TTM or still viable?
|
|
||||||
maybe can pick out the best new features of that which can be integrated into existing design rather than re-inventing the wheel
|
|
||||||
Here is an overview: https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3412
|
|
||||||
How best to be able to service LoanUnits on a workorder?
|
|
||||||
Just make them Units with extra properties exposed if type of loaner?
|
|
||||||
This seems simplest, but what will it effect?
|
|
||||||
Hard to make them serviceable if they are an alternate table of source for what's being repaired as that breaks a lot of other code or adds exceptions
|
|
||||||
Customer is then who exactly because it's fundamental to a lot of wo functionality?
|
|
||||||
from a biz perspective isn't it like you are your own customer when you service your own equipment that you loan out?
|
|
||||||
Does Serial field need to be numeric, could it be text instead?
|
|
||||||
prompted by case 3428 saying that it's hard to deal with constant conversion to text for UI etc
|
|
||||||
plus, I'm thinking it opens door to textual scheme like appending -A or whatever to a wo.
|
|
||||||
or, is that a display issue?
|
|
||||||
Calling something "serial" implies it's unique but it isn't, maybe I should call it "number" instead or "ID" or something?
|
|
||||||
INFO: did a test workorder with ALL fields filled out heavily and one woitem, exported from db entire graph based on detailed report so every line was every item repeated
|
|
||||||
still only 84kb and it's a lot bigger than any typical wo in v8 would be as it will be far more efficient without having to repeat lines flatly
|
|
||||||
so I think size of object is a non-issue really from a practical standpoint.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
@@ -944,49 +740,57 @@ todo: workorder UI layout stuff (TTM!! Don't re-invent the wheel!)
|
|||||||
Kind of like two views, tiny phone and anything larger
|
Kind of like two views, tiny phone and anything larger
|
||||||
On a PC people will want and expect it to look as much like v7 workorder as possible, maybe that's still a valid layout
|
On a PC people will want and expect it to look as much like v7 workorder as possible, maybe that's still a valid layout
|
||||||
just tweaked to work better as a web app a bit but theoretically I could almost duplicate that layout with the tools I have
|
just tweaked to work better as a web app a bit but theoretically I could almost duplicate that layout with the tools I have
|
||||||
|
|
||||||
WORKORDER BACKEND THOUGHTS
|
|
||||||
=-=-=-=-
|
|
||||||
Workorder routes
|
|
||||||
Workorder is a "heavy" object so need to be careful how this is split out
|
|
||||||
Avoid full transfer of wo where possible but don't avoid it when it's the best solution
|
|
||||||
Don't make the client do too much work, the server has a lot of stuff it can do
|
|
||||||
Task oriented routes are important for the wo beyond the basic crud ops there are a lot of other tasks at hand not involving moving data (i.e. set all parts closed etc)
|
|
||||||
Shadow properties
|
|
||||||
- will need shadow properties not persisted but that tell teh UI stuff like "canDelete" for a workorderitem etc
|
|
||||||
- this will save a lot of business rule checking at the client end
|
|
||||||
|
|
||||||
|
|
||||||
One workorder route for entire graph of workorder object (i.e. not a woitem route or a woitempart route etc)
|
Consider UI in this as well, will need to decide at least what is visible when
|
||||||
GET/id - gets the whole workorder and all descendents in a full graph
|
Workorder UI good ideas here: https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3475
|
||||||
PUT - Put's the whole wo and all descendents in a full graph
|
How to add items, like new woitem?
|
||||||
DELETE - this one is different, can specify all wo or a descendent
|
send to server get back new object?
|
||||||
is basically a request and may return broken rule error but if it works then it returns no-content
|
lots of biz rules and stuff need to happen, want to minimize load at client
|
||||||
MISC ROUTES for exact tasks, such as closing or whatever the UI needs to do
|
but lots of data back and forth is not ideal
|
||||||
When it doesn't need to return teh whole workorder it will endeavour to avoid it but not shy away from it where necessary
|
maybe request a woitem and get it back?
|
||||||
don't want the client to have to do too much work
|
what exactly needs to be processed in the wo when items are added / removed?
|
||||||
Routes that won't affect the workorder as a whole don't need to return the whole workorder, maybe just the "delta" of the descendent or object in question
|
math / totalling?
|
||||||
i.e. if you add a new woitem there's no need to return all teh workorder if nothing has changed, just acknowledge it and return the id for the new row
|
simple calcs sb client doable
|
||||||
|
this will drive what has to happen.
|
||||||
|
Need to go over all wo features and factor them into this decision properly
|
||||||
|
The whole idea of a completed section of a wo and stuff, is that dropped due to TTM or still viable?
|
||||||
|
maybe can pick out the best new features of that which can be integrated into existing design rather than re-inventing the wheel
|
||||||
|
Here is an overview: https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3412
|
||||||
|
How best to be able to service LoanUnits on a workorder?
|
||||||
|
Just make them Units with extra properties exposed if type of loaner?
|
||||||
|
This seems simplest, but what will it effect?
|
||||||
|
Hard to make them serviceable if they are an alternate table of source for what's being repaired as that breaks a lot of other code or adds exceptions
|
||||||
|
Customer is then who exactly because it's fundamental to a lot of wo functionality?
|
||||||
|
from a biz perspective isn't it like you are your own customer when you service your own equipment that you loan out?
|
||||||
|
Does Serial field need to be numeric, could it be text instead?
|
||||||
|
prompted by case 3428 saying that it's hard to deal with constant conversion to text for UI etc
|
||||||
|
plus, I'm thinking it opens door to textual scheme like appending -A or whatever to a wo.
|
||||||
|
or, is that a display issue?
|
||||||
|
Calling something "serial" implies it's unique but it isn't, maybe I should call it "number" instead or "ID" or something?
|
||||||
|
INFO: did a test workorder with ALL fields filled out heavily and one woitem, exported from db entire graph based on detailed report so every line was every item repeated
|
||||||
|
still only 84kb and it's a lot bigger than any typical wo in v8 would be as it will be far more efficient without having to repeat lines flatly
|
||||||
|
so I think size of object is a non-issue really from a practical standpoint.
|
||||||
|
|
||||||
|
|
||||||
Has routes for delete / add descdendents, returns whole wo object after they are executed
|
UI
|
||||||
- When Add or Delete descendent is called at client, the whole wo is saved first if dirty, then after it's updated a delete / add route is triggered which returns whole wo again
|
|
||||||
this seems like a lot but, due to business rules and automaticicty of certain ops it needs to process the whole thing at the server
|
idea: UI reflects tentativeness state of object:
|
||||||
|
The UI doesn't imply something is done by changing it fully until the save is completed.
|
||||||
|
This serves two purposes:
|
||||||
|
1) user knows at a glance what isn't saved yet and will know it's waiting for save clearly, hopefully leading them to save more often,
|
||||||
|
2) client doesn't need to track invisible shit behind the scenes, can more easily do patch updates right off UI source
|
||||||
|
|
||||||
|
e.g.:
|
||||||
|
if deleted a row in parts, that row doesn't disappear but rather shows crossed out, maybe grayed out but still there until save to indicate it's tentative status
|
||||||
|
if added a row, shows green or something or bold or asterisk, (can style with css based on state) until saved
|
||||||
|
problems:
|
||||||
|
how to handle regular fields that are changed (that's a lot of field data to track for changes)?
|
||||||
|
Maybe client keeps a virgin copy of the original wo for comparison
|
||||||
|
periodically does a compare and flags differences on updates?
|
||||||
|
(this would also help to serve as an Undo maybe?)
|
||||||
|
|
||||||
- NOTE: not a seperate route for each type, instead, a single route that takes a type and id and parent wo id and handles deletion and returning updated wo
|
|
||||||
- client updates entire wo locally when it gets back the wo result of the delete
|
|
||||||
|
|
||||||
- This is important because we need a way to deal with delete add descdendents as rules need to be applied and also applied to header / totals etc
|
|
||||||
- e.g. workorderitem, in v7 you called delete on the woitems collection which in turn marked a woitem for deletion, but only the db update actually deleted it
|
|
||||||
- since v8 is disconnected need a route to do that so call delete on an item
|
|
||||||
still split in db just using proper linking and stuff to work
|
|
||||||
start with wo->woitem and move outwards from there as that structure is basically all that's required to do the rest once figured out
|
|
||||||
workorder descendant types are still their own biz objects because of searching and in some cases attachments too.
|
|
||||||
- Not sure how deep to support attaching and custom fields, it's going to impact the UI a lot if I get too crazy with it, but maybe keep it as an idea
|
|
||||||
- Add CUSTOM FIELDS to top level as the new thing (previously only woitem in v7)?
|
|
||||||
- Add wiki and attachments to woITEM level (new thing, previously only header)?
|
|
||||||
- going to need a lot more aytypes for the full graph of each type of workorder basically or whatever it supports
|
|
||||||
=-=-=-=-=-
|
|
||||||
|
|
||||||
todo: Documentation
|
todo: Documentation
|
||||||
Need to think this through carefully
|
Need to think this through carefully
|
||||||
|
|||||||
Reference in New Issue
Block a user