DuncanTPerkins / SE1-Sprint1-Group3

Class Project for Software Engineering 1 Group 3
0 stars 0 forks source link

Implementation Discussion #27

Open woodardc opened 8 years ago

woodardc commented 8 years ago

Discuss and store implementation details for Sprint 2 here. We cannot use Slack for this purpose because we actively use Slack and the discussions will eventually become tedious to find.

woodardc commented 8 years ago

Duncan Perkins [12:48 PM] Hey guys, I pushed the initial database design to the "DatabaseDesign" branch, I THINK it should work, but look at it and point out the glaring errors that I didn't notice, thanks!

It looks pretty straightforward code wise, but i'd like to suggest that you switch from booleans to one enum variable with the created enum type in its own source file. for the forms, and for generally everything that requires multiple types of state changes. More often than not I have found the use of booleans in my code creates an AntiPattern.

For a form to be accepted by an admin, they'd probably want the form to be completed first. Have I got that right? This also removes a variable to think about in forms, which is better from an efficiency standpoint.

In fact, the following would suffice as states:

NEW - A user saved (and thus created) a new form, it's in limbo to be confirmed as completed, an initial state. ACCEPTED - An admin accepted a form. DEFERRED - An admin deferred a form, as it is not acceptable yet, but it's almost there. CANCELLED - An admin cancelled a form, it's a notification to remove the form completely. COMPLETED - A user has confirmed that the form is filled out and completed, to the best of their knowledge.

woodardc commented 8 years ago

also, the DEFERRED state is really dependent upon the type of form the user filled out. An example would be applying to a University, which may require data that gets delayed past the due date of all the applications. (something that the user can't just "fill out"). Also, looking at the project overview, the "workflow" portion:

For example, Form Type A may require the Department Chair and College Dean to sign off before a form is considered “processed".

It also would perform that role. A particular type of form that gets deferred instead of completed due to a form specific reason.

woodardc commented 8 years ago

two more things: when a form is given a DEFERRED state, it will always be waiting to have a COMPLETED state, so what you have in essence is a pushdown automata.

In short, when forms are given a DEFERRED state, the form must have a stack which puts COMPLETED on the stack first, and then DEFERRED. The last thing to be pushed on the stack is the current state. Popping the stack once will immediately change its state to COMPLETED. A Pushdown automata will assert a simple and elegant state transition for forms.

The implementation details are not involved, but the data structure should probably be separated from the C# form object as data structure data for every specific instance of a form object is not something we would want to store in a database. What it would require is a subsystem that handles deferred forms, that would be where the data structure is. A Map data structure would have a form entry that holds a reference to a stack data structure which maintains their state transitions. And also after form objects are entered in a database they should be removed from the server's memory. I can't remember if we talked about how form objects are handled by the server, are they persistent in memory or are they removed? Ideally they're removed and form objects are never created, you're just using objects from an object pool. These objects just need to be constantly reused, they don't warrant being created more than the initial start up of the system.

lastly, a state machine often benefits from the use of the command pattern and you all may find it extremely useful for writing code that processes state transitions. see: http://www.dofactory.com/net/command-design-pattern

Just trying to help.

woodardc commented 8 years ago

Ariel Rowland [3:27 PM] hmm, should we divide that into two user stories? One for inserting the things in the database and another for pulling that information back out when the user next opens that page?

Christopher Woodard [3:29 PM] If they can be done separately and aren't reliant on each other's code (tightly coupled), I would go ahead and split them up and give them half the story points of the original user story.

Duncan Perkins [3:33 PM] @shind1: The save functionality is kind of built into how the database is designed and should probably just be part of the page that Haley is doing. A better thing to work on would be the "filling out a form" page for users

Ariel Rowland [3:34 PM] the save function is for users filling out a form that might need to finish it later

[3:34] I don't think it has anything to do with what Haley is doing beyond using the same db

Duncan Perkins [3:35 PM] You're right, I'm getting the forms mixed up in my head.

[3:35] But still, wouldn't the "save for later" functionality just be a button on the "filling out a form" page

Christopher Woodard [3:35 PM] To rephrase that, if parts of the user story can be written so that they are modular and loosely coupled, you can split them up again. And I still think it's beneficial to us as of right now to split up user stories so that we have less work to do per user story, so that we can get done with the sprint faster, because, in general, the less work you have to do for a user story the less likely you're going to get an impediment in your way.

Ariel Rowland [3:36 PM] yes, it's more or less doing the same thing as the submit button, it's just sticking a different status into the database

[3:38] the tricky part would be calling in that information from the database and prepopulating the fields that already have an input the next time that user viewed that form

Duncan Perkins [3:39 PM] I dont think it should be that bad. It's referenced by the formid right? So just "for every form in the database that is a draft that has my ID, list it here" for the in progress list, and then on a specific form view "thisid.name thisid.html"

Haley Hughes [3:40 PM] here's where I am with the form generator: http://codepen.io/hugheshe1/pen/eZWqYy CodePen eZWqYy ...

[3:41] currently trying to figure out how to allow the user to dynamically add options to the dropdown, checkbox, and radio elements.

Duncan Perkins [3:41 PM] I think it might have to be done differently than the other options because the user could want 1 to n options in a radio selection

Haley Hughes [3:42 PM] yeah, I think I'm going to provide another button allowing them to add as many options as needed for each element

Duncan Perkins [3:43 PM] I know in dynamic javascript frameworks you can hide or showelements based upon what option in a dropdown is selected. so if radio is selected you could show a different set of options, I don't know how to do something like that in vanilla javascript however

Christopher Woodard [3:44 PM] It looks good so far, but you can get rid of that ugly case statement by using the command pattern which is probably a cleaner way to write this.

Haley Hughes [3:44 PM] at this point I am just trying to provide us with a functioning form generator.

[3:45] it can be cleaned up later.

Christopher Woodard [3:46 PM] yeah, we can refactor things later, I understand. this is merely part of the scrum master's role.

[3:47] However, we should do it because it allow allows us to use a two way pointer of commands, which allows us to undo and redo actions.

[3:47](This means that the user making their form has an undo and redo button)

Ariel Rowland [3:49 PM] useful as it would be to be able to remove form elements, at this point it would probably be better to get it actually working first

Haley Hughes [3:50 PM] I agree. we have to have a functional generator before we can think about its features. lol

Duncan Perkins [3:50 PM] I think we need to focus on A) the form generator B) submitting forms to the database C) Users filling out those forms

[3:51] If we can get those 3 things done by monday that would be passable.

Christopher Woodard [3:55 PM] I'm trying to understand the functionality of the code you sent me, is the HTML being parsed or is the HTML being generated by the javascript?

Duncan Perkins [4:00 PM] The javascript is using templates in the HTML to generate HTML

Christopher Woodard [4:00 PM] okay, that makes a lot of sense, lol.

Duncan Perkins [4:00 PM] the frontend form generator creates the html layout for the page, which is then submitted to the controller, in C#, which will parse the html into seperate input elements, which will be stored in a collection in the form class

Haley Hughes [4:01 PM] https://lodash.com/ is the template language

Duncan Perkins [4:04 PM] Can I get an opinion? Should I add another state to the enum in the form class for forms that have been generated by the admin, the kind that gets copied and then the copy actually gets filled out? Because otherwise the default will be called "draft", should forms by default be generated as "template" or something?

Ariel Rowland [4:04 PM] yes

[4:05] we could set the user list view up to search for templates that way

Duncan Perkins [4:05 PM] Yeah, only show template forms.

Ariel Rowland [4:06 PM] although if we do that, we're going to need to add some sort way for it to differentiate between forms that the user has not filled out at all and forms that the user has drafts in

[4:06] or forms that the user has already completed

Duncan Perkins [4:08 PM] I suppose another table containing FormIDs that the user has filled out.

Ariel Rowland [4:08 PM] so maybe each new form type gets its own form id, and all ensuing copies of that form created by users have that same form id, so then it only has to see whether the user id has a form containing that form id associated with them

Duncan Perkins [4:09 PM] The form ID can't be the same though, because it's the primary key, right? I could just add a list to the User class called "UsedForms" or something and add the form ID of all forms the user has filled out

[4:10] and then a nullable ParentId to the Form class that is null if it's a template, and when a new form is created from a template, that ID is changed from null to the ID of the template that it's copied from. That way we'd have a reference to what form to delete from the User's UsedForm list if they delete their filled out form.

Ariel Rowland [4:10 PM] or we could do it by formName

[4:11] if a userId already has that formName in the database, then it pulls that up instead of the template

Duncan Perkins [4:11 PM] Do we want to force the name of the form to be unique?

[4:12] I guess I don't see why not

Duncan Perkins [4:18 PM] But then we would have to put name validation in the frontend, it might be easier to use the parentID thing

[4:18] not sure

Christopher Woodard [4:22 PM] I can't really comment on some of this, it's not my area of expertise but I think you should leave the primary key alone, just store the drafts on disk, can you associate a database entry with a markup language file on disk somewhere?

[4:23] you'd then parse the markup language of your choice into strings which would go back into their respective fields

[4:24] have I understood the problem correctly?

Christopher Woodard [4:32 PM] this then means, every time a user makes a form it is placed on the disk of the server someplace, if the user fills nothing out, we don't need to store it, if they only filled one thing out, we only need to store that one thing, and it'd be a tiny amount to store.

[4:34] The database entry of the draft would then be, an identifier and a string to the location of the draft?

Duncan Perkins [4:34 PM] That's how it works right now. The database is designed so that the html is stored in the form table. And the Database entry is only created once the user clicks save. So if they don't type anything nothing is created.

[4:36] and the html is stored as a string in C#, I don't know what EntityFramework maps that to in MSSQL but yeah.

[4:36] You've basically described the database design lol

Christopher Woodard [4:36 PM] welp lol

Duncan Perkins [4:41 PM] Should I use inheritance? That would probably be better than making nullable variables.

[4:41] public class Form : FormTemplate

[4:41] where form has UserID and ParentID and FormTemplate just has the regular stuff

[4:42] I apologize for asking so many questions I'm just wanting opinions other than my own

Christopher Woodard [4:43 PM] will there be forms with the same formID?

Duncan Perkins [4:44 PM] No. FormID is auto incremented by the database. Different for every entity

Ariel Rowland [4:45 PM] so just to be clear, the form table will only have the two IDs, and everything else will be stored in the formtemplate table that inherits from it?

[4:46] well, three ID's I suppose since there'll be FormId as well

Duncan Perkins [4:46 PM] the enum would probably go in the inherited class too.

Ariel Rowland [4:46 PM] okay

Duncan Perkins [4:46 PM] FormId would go in FormTemplate, since the FormTemplate class isn't being used as an abstract class. It would be used to show users what forms are available to fill out.

[4:47] This might be more hassle than it's worth

Ariel Rowland [4:51 PM] is it going to make our lives easier in the long run?

Duncan Perkins [4:53 PM] Honestly I don't think so. I just looked up how entity framework maps inherited classes and it looks like the database tables basically extract the inherited properties into different tables anyway. I'm just going to put it all into one class.