Miisiiks: Difference between revisions

From ICO wiki
Jump to navigationJump to search
Caruste (talk | contribs)
Caruste (talk | contribs)
 
(26 intermediate revisions by 2 users not shown)
Line 43: Line 43:
<source lang="xml">
<source lang="xml">
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<ApplicationUsers>
  <ApplicationUserDTO UserId="296a7683-be8d-45e1-9b9d-6b7e1aa4657d">
    <UserName><![CDATA[workers@hotmail.com]]></UserName>
    <Advertisements>
      <AdvertisementDTO AdId="1">
        <AdName><![CDATA[Looking for a truck driver]]></AdName>
        <AdDescription><![CDATA[I am looking for a truck driver to help me move to another town. For more information send a message.]]></AdDescription>
        <UserName><![CDATA[workers@hotmail.com]]></UserName>
        <Location><![CDATA[Tallinn, Mustamäe]]></Location>
        <JobCategory> Driving </JobCategory>
        <CreationDate> 01.06.2018 </CreationDate>
        <AdvertisementPictureDTO PictureId="1">
          <Location><![CDATA[https://i1.wp.com/movingtips.wpengine.com/wp-content/uploads/2017/10/large-moving-truck.jpg?fit=1024%2C683&ssl=1]]></Location>
          <AdvertisementId> 1 </AdvertisementId>
        </AdvertisementPictureDTO>


<ApplicationUsers>
        <AdvertisementPictureDTO PictureId="2">
<ApplicationUserDTO>
          <Location><![CDATA[https://www.southernoak.com/v2/wp-content/uploads/2016/05/Moving-Day.jpg]]></Location>
<UserId> 296a7683-be8d-45e1-9b9d-6b7e1aa4657d </UserId>
          <AdvertisementId> 1 </AdvertisementId>
<UserName><![CDATA[workers@hotmail.com]]></UserName>
        </AdvertisementPictureDTO>
<Advertisements>
      </AdvertisementDTO>
<AdvertisementDTO>
    </Advertisements>
<AdId>1</AdId>
    <Contacts>
<AdName><![CDATA[Looking for a truck driver]]></AdName>
      <ContactDTO Id="1">
<AdDescription><![CDATA[I am looking for a truck driver to help me move to another town. For more information send a message.]]></AdDescription>
        <ContactValue><![CDATA[Miisiks]]></ContactValue>
<UserName><![CDATA[workers@hotmail.com]]></UserName>
        <UserName><![CDATA[workers@hotmail.com]]></UserName>
<Location><![CDATA[Tallinn, Mustamäe]]></Location>
        <ContactTypeName> Skype </ContactTypeName>
<JobCategory> Driving </JobCategory>
      </ContactDTO>
<CreationDate> 01.06.2018 </CreationDate>
    </Contacts>
<AdvertisementPictureDTO>
  </ApplicationUserDTO>
<PictureId>1</PictureId>
 
<Location><![CDATA[https://i1.wp.com/movingtips.wpengine.com/wp-content/uploads/2017/10/large-moving-truck.jpg?fit=1024%2C683&ssl=1]]></Location>
  <ApplicationUserDTO UserId="2460d33a-3505-4844-b8c8-2b7e0ece6a70">
<AdvertisentId> 1 </AdvertisentId>
    <UserName><![CDATA[homeforyou@gmail.com]]></UserName>
</AdvertisementPictureDTO>
    <Advertisements>
      <AdvertisementDTO AdId="3">
<AdvertisementPictureDTO>
        <AdName><![CDATA[Need a home assistant]]></AdName>
<PictureId>2</PictureId>
        <AdDescription><![CDATA[Need help with a big spring cleaning at countryside house. There’s a lot to clean from inside the house to the garden. Please message for more information]]></AdDescription>
<Location><![CDATA[https://www.southernoak.com/v2/wp-content/uploads/2016/05/Moving-Day.jpg]]></Location>
        <UserName><![CDATA[homeforyou@gmail.com]]></UserName>
<AdvertisentId> 1 </AdvertisentId>
        <Location><![CDATA[Pärnumaa, Sauga]]></Location>
</AdvertisementPictureDTO>
        <JobCategory> Cleaning</JobCategory>
</AdvertisementDTO>
        <CreationDate> 12.02.2018 </CreationDate>
</Advertisements>
        <AdvertisementPictureDTO PictureId="3">
<Contacts>
          <Location><![CDATA[https://s3-media4.fl.yelpcdn.com/bphoto/fWxU8tYpD3ddC7UtSKXA7A/o.jpg]]></Location>
<ContactDTO>
          <AdvertisementId> 3 </AdvertisementId>
<Id> 1 </Id>
        </AdvertisementPictureDTO>
<ContactValue><![CDATA[Miisiks]]></ContactValue>
 
<UserName><![CDATA[workers@hotmail.com]]></UserName>
        <AdvertisementPictureDTO PictureId="4">
<ContactTypeName> Skype </ContactTypeName>
          <Location><![CDATA[http://whatdoimakenow.com/wp-content/uploads/2017/05/Messy-House-Project-Kitchen-Before-Stove-e1495030958246.jpg]]></Location>
</ContactDTO>
          <AdvertisementId> 3 </AdvertisementId>
        </Contacts>
        </AdvertisementPictureDTO>
</ApplicationUserDTO>
 
        <AdvertisementPictureDTO PictureId="5">
<ApplicationUserDTO>
          <Location><![CDATA[http://www.gardenplansireland.com/forum/files/garden_123.jpg]]></Location>
<UserId> 2460d33a-3505-4844-b8c8-2b7e0ece6a70 </UserId>
          <AdvertisementId> 3 </AdvertisementId>
<UserName><![CDATA[homeforyou@gmail.com]]></UserName>
        </AdvertisementPictureDTO>
<Advertisements>
<AdvertisementDTO>
<AdId>3</AdId>
<AdName><![CDATA[Need a home assistant]]></AdName>
<AdDescription><![CDATA[Need help with a big spring cleaning at countryside house. There’s a lot to clean from inside the house to the garden. Please message for more information]]></AdDescription>
<UserName><![CDATA[homeforyou@gmail.com]]></UserName>
<Location><![CDATA[Pärnumaa, Sauga]]></Location>
<JobCategory> Cleaning</JobCategory>
<CreationDate> 12.02.2018 </CreationDate>
<AdvertisementPictureDTO>
<PictureId>3</PictureId>
<Location><![CDATA[https://s3-media4.fl.yelpcdn.com/bphoto/fWxU8tYpD3ddC7UtSKXA7A/o.jpg]]></Location>
<AdvertisementId> 3 </AdvertisementId>
</AdvertisementPictureDTO>
<AdvertisementPictureDTO>
<PictureId>4</PictureId>
<Location><![CDATA[http://whatdoimakenow.com/wp-content/uploads/2017/05/Messy-House-Project-Kitchen-Before-Stove-e1495030958246.jpg]]></Location>
<AdvertisentId> 3 </AdvertisentId>
</AdvertisementPictureDTO>


<AdvertisementPictureDTO>
        <AdvertisementPictureDTO PictureId="6">
<PictureId>5</PictureId>
          <Location><![CDATA[https://wshg.net/wp-content/uploads/2014/05/GardenDilemmas_B_WHG13A.jpg]]></Location>
<Location><![CDATA[http://www.gardenplansireland.com/forum/files/garden_123.jpg]]></Location>
          <AdvertisementId> 3 </AdvertisementId>
<AdvertisentId> 3 </AdvertisentId>
        </AdvertisementPictureDTO>
</AdvertisementPictureDTO>
      </AdvertisementDTO>
      <AdvertisementDTO AdId="4">
<AdvertisementPictureDTO>
        <AdName><![CDATA[Fixing a roof]]></AdName>
<PictureId>6</PictureId>
        <AdDescription><![CDATA[Need help with fixing a roof. Please message for more information]]></AdDescription>
<Location><![CDATA[https://wshg.net/wp-content/uploads/2014/05/GardenDilemmas_B_WHG13A.jpg]]></Location>
        <UserName><![CDATA[homeforyou@gmail.com]]></UserName>
<AdvertisentId> 3 </AdvertisentId>
        <Location><![CDATA[Pärnumaa, Sauga]]></Location>
</AdvertisementPictureDTO>
        <JobCategory>Construction</JobCategory>
</AdvertisementDTO>
        <CreationDate> 01.06.2018 </CreationDate>
<AdvertisementDTO>
      </AdvertisementDTO>
        <AdId>4</AdId>
        <AdName><![CDATA[Fixing a roof]]></AdName>
        <AdDescription><![CDATA[Need help with fixing a roof. Please message for more information]]></AdDescription>
        <UserName><![CDATA[homeforyou@gmail.com]]></UserName>
        <Location><![CDATA[Pärnumaa, Sauga]]></Location>
        <JobCategory>Construction</JobCategory>
        <CreationDate> 01.06.2018 </CreationDate>
      </AdvertisementDTO>


</Advertisements>
    </Advertisements>
<Contacts>
    <Contacts>
<ContactDTO>
      <ContactDTO Id="2">
<Id> 2 </Id>
        <ContactValue><![CDATA[homeforyou]]></ContactValue>
<ContactValue><![CDATA[homeforyou]]></ContactValue>
        <UserName><![CDATA[homeforyou@gmail.com]]></UserName>
<UserName><![CDATA[homeforyou@gmail.com]]></UserName>
        <ContactTypeName> Skype </ContactTypeName>
<ContactTypeName> Skype </ContactTypeName>
      </ContactDTO>
</ContactDTO>
    </Contacts>
</Contacts>
  </ApplicationUserDTO>
</ApplicationUserDTO>
</ApplicationUsers>
</ApplicationUsers>
</source>
</source>
Line 150: Line 136:
           <xs:complexType>
           <xs:complexType>
             <xs:sequence>
             <xs:sequence>
              <xs:element name="UserId" type="xs:string" />
               <xs:element name="UserName" type="xs:string" />
               <xs:element name="UserName" type="xs:string" />
               <xs:element name="Advertisements">
               <xs:element name="Advertisements">
Line 158: Line 143:
                       <xs:complexType>
                       <xs:complexType>
                         <xs:sequence>
                         <xs:sequence>
                          <xs:element name="AdId" type="xs:int" />
                           <xs:element name="AdName" type="xs:string" />
                           <xs:element name="AdName" type="xs:string" />
                           <xs:element name="AdDescription" type="xs:string" />
                           <xs:element name="AdDescription" type="xs:string" />
Line 168: Line 152:
                             <xs:complexType>
                             <xs:complexType>
                               <xs:sequence>
                               <xs:sequence>
                                <xs:element name="PictureId" type="xs:int" />
                                 <xs:element name="Location" type="xs:string" />
                                 <xs:element name="Location" type="xs:string" />
                                 <xs:element name="AdvertisentId" type="xs:int" />
                                 <xs:element name="AdvertisementId" type="xs:int" />
                               </xs:sequence>
                               </xs:sequence>
                              <xs:attribute name="PictureId" type="xs:int" />
                             </xs:complexType>
                             </xs:complexType>
                           </xs:element>
                           </xs:element>
                         </xs:sequence>
                         </xs:sequence>
                        <xs:attribute name="AdId" type="xs:int" />
                       </xs:complexType>
                       </xs:complexType>
                     </xs:element>
                     </xs:element>
Line 186: Line 171:
                       <xs:complexType>
                       <xs:complexType>
                         <xs:sequence>
                         <xs:sequence>
                          <xs:element name="Id" type="xs:int" />
                           <xs:element name="ContactValue" type="xs:string" />
                           <xs:element name="ContactValue" type="xs:string" />
                           <xs:element name="UserName" type="xs:string" />
                           <xs:element name="UserName" type="xs:string" />
                           <xs:element name="ContactTypeName" type="xs:string" />
                           <xs:element name="ContactTypeName" type="xs:string" />
                         </xs:sequence>
                         </xs:sequence>
                        <xs:attribute name="Id" type="xs:int" />
                       </xs:complexType>
                       </xs:complexType>
                     </xs:element>
                     </xs:element>
Line 197: Line 182:
               </xs:element>
               </xs:element>
             </xs:sequence>
             </xs:sequence>
            <xs:attribute name="UserId" type="xs:string" />
           </xs:complexType>
           </xs:complexType>
         </xs:element>
         </xs:element>
Line 284: Line 270:
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
>
<xsl:output method="xml" indent="yes"/>
  <xsl:output method="xml" indent="yes"/>


<xsl:template match="/">
  <xsl:template match="/">
     <xsl:element name="ApplicationUsers">
     <xsl:element name="ApplicationUsers">
<xsl:for-each select="/ApplicationUsers/ApplicationUserDTO">
      <xsl:for-each select="/ApplicationUsers/ApplicationUserDTO">
<xsl:variable name="ApplicationUser" select="."/>
        <xsl:variable name="ApplicationUser" select="."/>
<xsl:element name="ApplicationUser">
        <xsl:element name="ApplicationUser">
<xsl:attribute name="UserId">
          <xsl:attribute name="UserId">
<xsl:value-of select="@id"/>
            <xsl:value-of select="@UserId"/>
</xsl:attribute>
          </xsl:attribute>
<xsl:element name="UserName">
          <xsl:element name="UserName">
<xsl:value-of select="UserName" />
            <xsl:value-of select="UserName" />
</xsl:element>
          </xsl:element>
<xsl:element name="Advertisements">
          <xsl:element name="Advertisements">
<xsl:for-each select="$ApplicationUser/Advertisements/AdvertisementDTO">
            <xsl:for-each select="$ApplicationUser/Advertisements/AdvertisementDTO">
<xsl:variable name="AdvertisementDTO" select="."/>
              <xsl:variable name="AdvertisementDTO" select="."/>
<xsl:element name="Advertisement">
              <xsl:element name="Advertisement">
<xsl:attribute name="AdId">
                <xsl:attribute name="AdId">
<xsl:value-of select="AdId"/>
                  <xsl:value-of select="@AdId"/>
</xsl:attribute>
                </xsl:attribute>
<xsl:element name="AdName">
                <xsl:element name="AdName">
<xsl:value-of select="AdName"/>
                  <xsl:value-of select="AdName"/>
</xsl:element>
                </xsl:element>
<xsl:element name="AdDescription">
                <xsl:element name="AdDescription">
<xsl:value-of select="AdDescription"/>
                  <xsl:value-of select="AdDescription"/>
</xsl:element>
                </xsl:element>
<xsl:element name="UserName">
                <xsl:element name="UserName">
<xsl:value-of select="UserName"/>
                  <xsl:value-of select="UserName"/>
</xsl:element>
                </xsl:element>
<xsl:element name="Location">
                <xsl:element name="Location">
<xsl:value-of select="Location"/>
                  <xsl:value-of select="Location"/>
</xsl:element>
                </xsl:element>
<xsl:element name="JobCategory">
                <xsl:element name="JobCategory">
<xsl:value-of select="JobCategory"/>
                  <xsl:value-of select="JobCategory"/>
</xsl:element>
                </xsl:element>
<xsl:element name="CreationDate">
                <xsl:element name="CreationDate">
<xsl:value-of select="CreationDate"/>
                  <xsl:value-of select="CreationDate"/>
</xsl:element>
                </xsl:element>
<xsl:for-each select="$ApplicationUser/Advertisements/AdvertisementDTO/AdvertisementPictureDTO">
                <xsl:for-each select="$ApplicationUser/Advertisements/AdvertisementDTO/AdvertisementPictureDTO">
<xsl:attribute name="PictureId">
                  <xsl:variable name="Advertisement" select="."/>
<xsl:value-of select="PictureId"/>
                  <xsl:element name="Picture">
</xsl:attribute>
                    <xsl:attribute name="PictureId">
<xsl:element name="Location">
                      <xsl:value-of select="@PictureId"/>
<xsl:value-of select="Location"/>
                    </xsl:attribute>
</xsl:element>
                    <xsl:element name="Location">
<xsl:element name="AdvertisementId">
                      <xsl:value-of select="Location"/>
<xsl:value-of select="AdvertisementId"/>
                    </xsl:element>
</xsl:element>
                    <xsl:element name="AdvertisementId">
</xsl:for-each>
                      <xsl:value-of select="AdvertisementId"/>
</xsl:element>
                    </xsl:element>
</xsl:for-each>
                  </xsl:element>
</xsl:element>
                </xsl:for-each>
<xsl:for-each select="$ApplicationUser">
              </xsl:element>
<xsl:variable name="ContactDTO" select="."/>
            </xsl:for-each>
<xsl:element name="Contact">
          </xsl:element>
<xsl:element name="Id">
          <xsl:element name="Contacts">
<xsl:value-of select="Id"/>
            <xsl:for-each select="$ApplicationUser/Contacts/ContactDTO">
</xsl:element >
              <xsl:variable name="Contact" select="."/>
<xsl:element name="ContactValue">
              <xsl:element name="Contact">
<xsl:value-of select="ContactValue"/>
                <xsl:attribute name="Id">
</xsl:element>
                  <xsl:value-of select="@Id"/>
<xsl:element name="UserName">
                </xsl:attribute>
<xsl:value-of select="UserName"/>
 
</xsl:element>
                <xsl:element name="ContactValue">
<xsl:element name="ContactTypeName">
                  <xsl:value-of select="ContactValue" />
<xsl:value-of select="ContactTypeName"/>
                </xsl:element>
</xsl:element>
 
</xsl:element>
                <xsl:element name="UserName">
</xsl:for-each>
                  <xsl:value-of select="UserName" />
</xsl:element>
                </xsl:element>
</xsl:for-each>
 
                <xsl:element name="ContactTypeName">
                  <xsl:value-of select="ContactTypeName" />
                </xsl:element>
              </xsl:element>
            </xsl:for-each>
          </xsl:element>
        </xsl:element>
      </xsl:for-each>
     </xsl:element>
     </xsl:element>
</xsl:template>
  </xsl:template>
</xsl:stylesheet>
</xsl:stylesheet>


</source>
</source>
===Veebiteenuse retsensioon===
Meeskonnale: [https://wiki.itcollege.ee/index.php/Meeskond_Raavo_V2%E2%84%A2 Raavo V2™]
Antud töö on ilusti kirjutatud ning ei oma suuremaid vigu ning kõik Must Have eesmärgid on edukalt saavutatud. Nice to Have eesmärgid on kahjuks kõik jäänud tegemata. Kogu projekt on ilusti kommenteeritud ning ei oma vigu, mis jäävad koheselt silma. Projekti struktuur on ilusti püsti pandud ning ükski klass ei ole suvalises kaustas. Projekti sees on tehtud eraldi lisaks WebAppile veel viis eraldi väiksemat projekti, kus hoitakse domeene, liideseid ning Entity Frameworkiga seostuvaid klasse.
Veebiteenuses on täidetud kõik nõuded peale kasutaja statistika. Seda nõuet saab küll täita mitut moodi ning kasutaja statistikat on ka võimalik võtta broneeringutest seega võib seda tehniliselt lugeda täidetuks.
Kõik klassid, millele on mõttekas luua liides, on see ka tehtud. Domeenidel on kõik vajalikud väljad piiratud ning on ära märgitud, mida on vaja ära täita, mis on välisvõti, mis on võti ning väljastatakse ka veateated, kui ületab limiiti.
Projektile on lisatud UnitOfWork meetod ning startupis on ka olemas vajalikud sisendid, et seda kasutada, kuid mitte kordagi ei ole seda projekti vältel kasutatud. UnitOfWork lisab antud projekti palju üleliigset koodi, ilma milleta saaks edukalt hakkama. UnitOfWorki on lisatud ka kõik domeenid seega mingiaeg on mõeldud selle kasutamise peale.
Kontrolleritele ei ole tehtud eraldi teenuseid, seega seda võib-olla hiljem keeruline muuta ja testida. Kõik kontrollerid nõuavad autoriseerimist seega ei tohiks keegi pääseda ligi informatsioonile, millele tal pole õigust. Kahjuks tundub, et autoriseerimine on mingilt maalt jäänud pooleli ning muutmise meetodid pole avatud tavakasutajale. Näiteks kui soovib kasutaja muuta auto informatsiooni, siis ta peab selle hoopis ära kustutama ja uuesti lisama, kuna PUT meetodile on lubatud ligipääs vaid administraatoril. API’de juures oleks võinud kommentaari „summary“ osasse panna täpsema info, et millega antud meetod tegeleb. Hetkel on seal lihtsalt kuidas meetodile ligi pääseda, mis oli automaatselt genereeritud. Igast kontrolleri meetodist ei tule ka tagasi IActionResult, mille tõttu võivad mõned meetodid tagastada vale koodi.
Antud töös ei ole kasutatud Data Transfer Objecteid (DTO’sid), seega kui kasutada API’t, siis saavad kasutajad palju informatsiooni tagasi, kui nemad peaksid saama. Kuna DTO puudub, siis võib ka läbi API saada ligi konfidentsiaalsele informatsioonile, kui ei ole ettevaatlik.
Kuigi kõik kontrollerid on ilusti ära kommenteeritud ning autorisatsioon on kõikidel meetoditel olemas, siis väga tihti on autoriseeritud roll ainult administraatoril, kuigi peaks olema ka teistel. Samuti on näiteks kasutaja lisamine läbi API lubatud ainult administraatoril ja seda tehakse valesti. Kasutaja informatsioon lisatakse otse andmebaasi läbi ApplicationDbContexti, paroole ei hashita ja informatsiooni üle ei kontrollita. Selle jaoks oleks võinud kasutada userManageri, kus on kõik vajalikud meetodid ja kontrollid juba sisse ehitatud.
Klientrakendus ja API ei ole ka väga kooskõlas. Näiteks saab klientrakenduses vahetada kasutajainformatsiooni ka kasutajana, kuid kui teha seda läbi API, siis peab olema administraator, et muuta kasutaja informatsiooni.
BookingArchive ei saa ka töötaja vaadata läbi API, see informatsioon peaks olema neile kindlasti ligipääsetav.
Kasutajatele ei ole kuidagi võimalik läbi API lisada kasutajarolle, rolle on küll ennast võimalik lisada, muuta ja kustutada, kuid nende ühendamist kasutajakontodega ei ole veel lisatud (läbi API).
Projekti käivitades luuakse andmebaasi kohe kolm erinevat rolli, Admin, worker ja User ning kõikidel neil on erinevad õigused teenuse kasutamisel. Ükski roll ei ole ülearu, kuid näiteks worker ei saa lisada teenuse tüüpe ja teenuseid seega mõndade rollide õigused tunduvad algselt poolikud. Kohe alguses luuakse ka administraator, mille parooli vahetamist peaks kasutajalt sisse logides nõudma, et muudaks. Selle jaoks võib ka teha teavituse ülesse serva, kui on algne parool, siis tuletaks meelde, et muutke ära. Igat kasutajat on ka võimalik deaktiveerida, sellehulgas ka administraatori oma. Administraatori kasutaja on ainuke, kelle oma ei tohiks deaktiveerida, kui ta on ainuke administraator. Ehk teha selle jaoks test, kui on ainult 1 isik administraatori rollidega, siis teda deaktiveerida ei saa.
Antud programm on hästi tehtud ning kommenteeritud. Kõik liidesed, mida oleks vaja on olemas, kuid puudavad Data Transfer Objekt klassid, mis ei ole küll nõutud, kuid API vastusteks sobiksid palju paremini. UnitOfWork tundub olevat antud projektis üleliigne ja API peale ei ole täielikult läbi mõeldud. API'le ei pääse ligi kuna ei ole tehtud viisi tokenite küsimiseks ega loomiseks. Kuna veebiteenus ja klientrakendus töötavad ilusti koos, siis see ei ole API absoluutselt vajalik, kuid kui juba tehtud on, siis võiks olla töötav. Kuna API ei ole hetkel kasutatav, siis ei ole antud projekt väärt maksimum punkte.
===Klientrakenduse retsensioon===
Meeskonnale: [https://wiki.itcollege.ee/index.php/Meeskond_Raavo_V2%E2%84%A2 Raavo V2™]
Klientrakenduses on olemas kõik Must have funktsionaalsused. Analüüsis välja toodud Nice to have funktsionaalsusi sinna lisatud ei ole. Rakenduses saab registreerida kasutajaid, muuta kasutajainfot, vaadata pakutavaid teenuseid, vaadata ning teha broneeringuid. Administraator saab broneeringuid hallata. Ka töötajatel võiks olla broneeringute haldamise võimalus. Vastaval lehel on olemas nupud broneeringute kinnitamiseks ja kustutamiseks, kuid töötaja kontoga sisenedes need nupud ei tööta. Töötaja saab rakenduses ainult broneeringuid vaadata. Võimalused teenuste lisamiseks või muutmiseks puuduvad.
Kõikjal kus toimub info sisestamine võiks pärast edukat lisamist väljad tühjendada, mõnes kohas seda tehakse, mõnes kohas mitte. Niimoodi on palju mugavam järjest asju lisada, siis ei pea enne sisestamist välju ise tühjendama.
Kasutajale tagastatavaid teateid võiks paremaks teha. Näiteks kohas, kus kasutaja saab autot lisada, kuvatakse pärast auto lisamist teade: „added new car type“. See teade võib kasutajas segadust tekitada, sest lisati ju uus auto, mitte auto tüüp.
Broneeringute lisamise kõrval on väga oluline ka võimalus neid muuta ja kustutada. Sellist võimalust kasutajal kahjuks ei ole. Sarnane probleem on ka administraatori kasutajal. Seal ei ole näiteks võimalust teenuseid ja garaaže muuta. Neid saab ainult juurde lisada või kustutada. Garaažide majandamine on üldiselt puudulik funktsioon. Garaaži info on piiratud nime, ühe aadressi ja ühe telefoninumbriga. Usun et reaalne firma tahab rohkem vabadust oma info määramisel. Samuti tundub et töötaja tüüpi kasutajad peaksid olema seotud erinevate garaažide, mida praegu ei ole näha ehk veel üks koht kus tundub töötaja unarusse jäetud.
Teenuste lehel võiks olla teenuse otsimise võimalus. Kui teenuseid on nimekirjas palju, siis on kasutajal raske endale sobivat teenust üles leida. Kahtlane on ka see et admin kasutaja peab erinevatele garaažidele teenuseid lisama, kuna admin kasutajal on väga lai võimekus kõige üle. Seega kui mõni garaaž peaks tahtma oma teenuseid muuta siis peab see tegevus käima läbi mõne lehe admini kuna igale lehel olevale garaažile ei või ilmselt anda kätte administraator kasutajat. Lisaks on teenuste lisamisel hinna piirang 1-100 vahel, kuna seal on ka võimalus määrata hinna ühik siis on erinvaid valuutasid arvestades tegu väga suure piiranguga. Valuuta tüüpide valimisel on probleemne ka vaba teksti kast mis lubab ühikuid ise välja mõelda. Samuti kui mingile teenusele määrata ühik siis broneeringu all näitab hinda eurodes aga üld nimekirjas kasutab teenuse registreerimisel määratud ühikut.
Autode lisamisel on väljalaske aeg väga täpselt pandud (päev, kuu ja aasta), kuigi peaks piisama ainult aastast. Hea on see, et tuleviku kuupäevade lisamine on ära keelatud.
Administraator kasutajaga on pisut liiast anda võimalus deaktiveerida see kasutaja millega ollakse sisse logitud. Kasutajate haldamise lehel tundub ka puudu olevat võimalus muuta teiste kasutajate rolle või siis luua uusi administraator või töötaja kasutajaid. Hetkel ei ole seega võimalik läbi kasutaja liidese uusi töötaja või administraator rollis kasutajaid luua.
Javascripti kood on jaotatud funktsioonidesse, mis teeb selle paremini loetavaks. Funktsioonidel on asjakohased nimed ning kommentaarid.
Lehel on ilusti lisatud erinevad vaated iga kasutaja õiguse kohta, nii et iga kasutaja saab oma õiguste tasemel funktsionaalsusele ligi. Kuigi pisut üleliigne on kõigile kuvatud menüüvalikutest hoida kõrvuti nuppe “garagefy” ja “home” mis mõlemad teevad täpselt sama asja.
Klientrakendus oleks võinud olla eraldi projektis, mitte veebiteenusega samas kohas. Muidu on vajalik funktsionaalsus olemas. Omajagu kohtab küll poolikuid lehti või lihtsalt kohatäitvat funktsionaalsust, eriti töötaja tüüpi kasutajate juures.
===XML retsensioon===
Kõik esitatud XML failid valideeruvad. XML andmefailile esitatud nõuded on täidetud, ehk 4 dimensiooniline, mõne koha peal näeb isegi vähemalt 5 dimensioonini minemist ja neile dimensioonidele on ka jaotatud mõistlike andmeid. Näiteks kasutaja nimi, email, automudel, auto tüübi nimi jne. Andmefailil on loogiline ja selge ülesehitus. Vajalikud teksti väärtused on ümbritsetud CDATA märgistusega, mis keelab selle sisu tõlgendada XML-ina. Samas on ka näha kuupäevade kasutamist ja isegi valuuta väärtuse sidumist euroga.
HTML-i transformatsiooni faili nõuded on ka täidetud. Lisaks for-each-ile on kasutatud choose-i. Pärast transformatsiooni on kõik broneeringud ja nendega seotud andmed esitatud listi kujul. Arusaamatuks jääb miks on kasutatud osades kohtades id järgi sorteerimist <xsl:sort select="@id"/>, sest väärtustel, millele sorteerimist rakendatakse, puuduvad id-d.
XML-i transformatsioon on ka olemas. HTMLi viies on ilusti selgelt näha kolm broneeringut, millest esimene ja viimane on “pending” ja teine on vastu võetud. Siin puhul on ka ilusti värvi kasutatud kus vastuvõetud broneering on tähistatud roheliselt ja ootel olevad punaselt. Ülejäänu on väga standartselt grupeeritud nii et on pealkiri (N: Klient, Auto) ja siis selle all on tabuleeritult toodud täpsem info selle osa kohta. Selgelt on kõik eristatav ja arusaadav, midagi kurta pole.
XSLis on sisse tulnud väikene kirjaviga, kus iga Booking on kirjutatud kolme o’ga. Elementide nimedeks ei ole kasutatud “xsl:element-name” vaid on otse pandud nimetuis, mis ei tundu küll otseselt vigane olevat kuid siiski XLS’is võiksid need olemas olla. XLS’is ei ole samuti kasutatud atribuute, näiteks kaovad kõik ID’d ära. Need oleksid võinud tuua välja atribuutidena või elementidena iga elemendi juures. Kuna ID’d kaovad transformeerimisel ära, siis võib sellest tulla probleeme hiljem terviklikkusega.

Latest revision as of 21:45, 5 June 2018

Meeskond

  • Christo Aruste
  • Heleriin Malkov
  • Tõnis Prants

Analüüs

Idee

Juhutööde pakkumise ja otsimise veebiteenus ja veebikeskkond

Kirjeldus

Loome veebiteenuse ning veebikeskkonna, mille kaudu inimesed saavad vaadata ja lisada juhutöö otsimise ning pakkumise kuulutusi. Kuulutustel on võimalik ära märkida piirkond, kus otsitakse tööd/töötajat. Veebilehel on võimalik hinnata kasutajakontosid ja lisada kommentaare. Kuulutuse vastuvõtmisel saadetakse kuulutuse loojale teade kontaktandmetega. Kuulutuse lisamisel on võimalik märkida ära, kas antud töö eest pakutakse tasu või mitte.

Funktsionaalsus

Must have:

  • Kuulutuste vaatamine
  • Kuulutuste lisamine
  • Kuulutuste kustutamine
  • Kuulutuste otsimine
  • Kasutajate haldamine
  • Kasutajatele teadete saatmine
  • Teadete vaatamine

Nice to have:

  • Kasutajakontode hindamine
  • Kuulutuse aegumine
  • Kuulutuse sulgemine
  • Kasutajate kommenteerimine
  • Kuulutuse aadress
  • Kuulutuse asukoha kaugus sinu asukohast
  • Anonüümselt kuulutustele vastamine
  • Mitme kontaktandme valikuline sidumine kuulutusega

Veebiteenus

https://www.dropbox.com/s/e2vu3ukgckyc2x5/MiisiiksWS.zip?dl=0

Klientrakendus

https://www.dropbox.com/s/iwtheohp5mn0lek/MiisiiksC.zip?dl=0

XML

<?xml version="1.0" encoding="utf-8" ?>
<ApplicationUsers>
  <ApplicationUserDTO UserId="296a7683-be8d-45e1-9b9d-6b7e1aa4657d">
    <UserName><![CDATA[workers@hotmail.com]]></UserName>
    <Advertisements>
      <AdvertisementDTO AdId="1">
        <AdName><![CDATA[Looking for a truck driver]]></AdName>
        <AdDescription><![CDATA[I am looking for a truck driver to help me move to another town. For more information send a message.]]></AdDescription>
        <UserName><![CDATA[workers@hotmail.com]]></UserName>
        <Location><![CDATA[Tallinn, Mustamäe]]></Location>
        <JobCategory> Driving </JobCategory>
        <CreationDate> 01.06.2018 </CreationDate>
        <AdvertisementPictureDTO PictureId="1">
          <Location><![CDATA[https://i1.wp.com/movingtips.wpengine.com/wp-content/uploads/2017/10/large-moving-truck.jpg?fit=1024%2C683&ssl=1]]></Location>
          <AdvertisementId> 1 </AdvertisementId>
        </AdvertisementPictureDTO>

        <AdvertisementPictureDTO PictureId="2">
          <Location><![CDATA[https://www.southernoak.com/v2/wp-content/uploads/2016/05/Moving-Day.jpg]]></Location>
          <AdvertisementId> 1 </AdvertisementId>
        </AdvertisementPictureDTO>
      </AdvertisementDTO>
    </Advertisements>
    <Contacts>
      <ContactDTO Id="1">
        <ContactValue><![CDATA[Miisiks]]></ContactValue>
        <UserName><![CDATA[workers@hotmail.com]]></UserName>
        <ContactTypeName> Skype </ContactTypeName>
      </ContactDTO>
    </Contacts>
  </ApplicationUserDTO>

  <ApplicationUserDTO UserId="2460d33a-3505-4844-b8c8-2b7e0ece6a70">
    <UserName><![CDATA[homeforyou@gmail.com]]></UserName>
    <Advertisements>
      <AdvertisementDTO AdId="3">
        <AdName><![CDATA[Need a home assistant]]></AdName>
        <AdDescription><![CDATA[Need help with a big spring cleaning at countryside house. There’s a lot to clean from inside the house to the garden. Please message for more information]]></AdDescription>
        <UserName><![CDATA[homeforyou@gmail.com]]></UserName>
        <Location><![CDATA[Pärnumaa, Sauga]]></Location>
        <JobCategory> Cleaning</JobCategory>
        <CreationDate> 12.02.2018 </CreationDate>
        <AdvertisementPictureDTO PictureId="3">
          <Location><![CDATA[https://s3-media4.fl.yelpcdn.com/bphoto/fWxU8tYpD3ddC7UtSKXA7A/o.jpg]]></Location>
          <AdvertisementId> 3 </AdvertisementId>
        </AdvertisementPictureDTO>

        <AdvertisementPictureDTO PictureId="4">
          <Location><![CDATA[http://whatdoimakenow.com/wp-content/uploads/2017/05/Messy-House-Project-Kitchen-Before-Stove-e1495030958246.jpg]]></Location>
          <AdvertisementId> 3 </AdvertisementId>
        </AdvertisementPictureDTO>

        <AdvertisementPictureDTO PictureId="5">
          <Location><![CDATA[http://www.gardenplansireland.com/forum/files/garden_123.jpg]]></Location>
          <AdvertisementId> 3 </AdvertisementId>
        </AdvertisementPictureDTO>

        <AdvertisementPictureDTO PictureId="6">
          <Location><![CDATA[https://wshg.net/wp-content/uploads/2014/05/GardenDilemmas_B_WHG13A.jpg]]></Location>
          <AdvertisementId> 3 </AdvertisementId>
        </AdvertisementPictureDTO>
      </AdvertisementDTO>
      <AdvertisementDTO AdId="4">
        <AdName><![CDATA[Fixing a roof]]></AdName>
        <AdDescription><![CDATA[Need help with fixing a roof. Please message for more information]]></AdDescription>
        <UserName><![CDATA[homeforyou@gmail.com]]></UserName>
        <Location><![CDATA[Pärnumaa, Sauga]]></Location>
        <JobCategory>Construction</JobCategory>
        <CreationDate> 01.06.2018 </CreationDate>
      </AdvertisementDTO>

    </Advertisements>
    <Contacts>
      <ContactDTO Id="2">
        <ContactValue><![CDATA[homeforyou]]></ContactValue>
        <UserName><![CDATA[homeforyou@gmail.com]]></UserName>
        <ContactTypeName> Skype </ContactTypeName>
      </ContactDTO>
    </Contacts>
  </ApplicationUserDTO>
</ApplicationUsers>

XML skeem

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="ApplicationUsers">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" name="ApplicationUserDTO">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="UserName" type="xs:string" />
              <xs:element name="Advertisements">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="AdvertisementDTO">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="AdName" type="xs:string" />
                          <xs:element name="AdDescription" type="xs:string" />
                          <xs:element name="UserName" type="xs:string" />
                          <xs:element name="Location" type="xs:string" />
                          <xs:element name="JobCategory" type="xs:string" />
                          <xs:element name="CreationDate" type="xs:string" />
                          <xs:element maxOccurs="unbounded" minOccurs="0" name="AdvertisementPictureDTO">
                            <xs:complexType>
                              <xs:sequence>
                                <xs:element name="Location" type="xs:string" />
                                <xs:element name="AdvertisementId" type="xs:int" />
                              </xs:sequence>
                              <xs:attribute name="PictureId" type="xs:int" />
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                        <xs:attribute name="AdId" type="xs:int" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element name="Contacts">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="ContactDTO">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="ContactValue" type="xs:string" />
                          <xs:element name="UserName" type="xs:string" />
                          <xs:element name="ContactTypeName" type="xs:string" />
                        </xs:sequence>
                        <xs:attribute name="Id" type="xs:int" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="UserId" type="xs:string" />
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

XLS to HTML

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="html" indent="yes"/>
  <xsl:template match="/ApplicationUsers">
    <html>
      <head>
        <title>Miisiiks</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous"/>
      </head>
      <body>
        <h1>Advertisements</h1>
        <table border="1">
          <tr>
            <th>User</th>
            <th>Title</th>
            <th>Description</th>
            <th>Location</th>
            <th>Job Category</th>
            <th>Date Created</th>            
            <th>Pictures</th>
          </tr>
          <xsl:for-each select="ApplicationUserDTO/Advertisements/AdvertisementDTO">
            <tr>
              <td>
                <xsl:value-of select="UserName"/>
              </td>
              <td>
                <xsl:value-of select="AdName"/>
              </td>
              <td>
                <xsl:value-of select="AdDescription"/>
              </td>
              <td>
                <xsl:value-of select="Location"/>
              </td>
              <td>
                <xsl:value-of select="JobCategory"/>
              </td>
              <td>
                <xsl:value-of select="CreationDate"/>
              </td>
              <td>
                <xsl:choose>
                  <xsl:when test="0 = count(AdvertisementPictureDTO)">
                    No pictures
                  </xsl:when>
                  <xsl:otherwise>
                    <img alt="Advertisement picture" height="50" width="60">
                      <xsl:attribute name="src">
                        <xsl:value-of select="AdvertisementPictureDTO/Location"/>
                      </xsl:attribute>
                    </img>
                  </xsl:otherwise>
                </xsl:choose>
              </td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

XLS to XML

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
		xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <xsl:element name="ApplicationUsers">
      <xsl:for-each select="/ApplicationUsers/ApplicationUserDTO">
        <xsl:variable name="ApplicationUser" select="."/>
        <xsl:element name="ApplicationUser">
          <xsl:attribute name="UserId">
            <xsl:value-of select="@UserId"/>
          </xsl:attribute>
          <xsl:element name="UserName">
            <xsl:value-of select="UserName" />
          </xsl:element>
          <xsl:element name="Advertisements">
            <xsl:for-each select="$ApplicationUser/Advertisements/AdvertisementDTO">
              <xsl:variable name="AdvertisementDTO" select="."/>
              <xsl:element name="Advertisement">
                <xsl:attribute name="AdId">
                  <xsl:value-of select="@AdId"/>
                </xsl:attribute>
                <xsl:element name="AdName">
                  <xsl:value-of select="AdName"/>
                </xsl:element>
                <xsl:element name="AdDescription">
                  <xsl:value-of select="AdDescription"/>
                </xsl:element>
                <xsl:element name="UserName">
                  <xsl:value-of select="UserName"/>
                </xsl:element>
                <xsl:element name="Location">
                  <xsl:value-of select="Location"/>
                </xsl:element>
                <xsl:element name="JobCategory">
                  <xsl:value-of select="JobCategory"/>
                </xsl:element>
                <xsl:element name="CreationDate">
                  <xsl:value-of select="CreationDate"/>
                </xsl:element>
                <xsl:for-each select="$ApplicationUser/Advertisements/AdvertisementDTO/AdvertisementPictureDTO">
                  <xsl:variable name="Advertisement" select="."/>
                  <xsl:element name="Picture">
                    <xsl:attribute name="PictureId">
                      <xsl:value-of select="@PictureId"/>
                    </xsl:attribute>
                    <xsl:element name="Location">
                      <xsl:value-of select="Location"/>
                    </xsl:element>
                    <xsl:element name="AdvertisementId">
                      <xsl:value-of select="AdvertisementId"/>
                    </xsl:element>
                  </xsl:element>
                </xsl:for-each>
              </xsl:element>
            </xsl:for-each>
          </xsl:element>
          <xsl:element name="Contacts">
            <xsl:for-each select="$ApplicationUser/Contacts/ContactDTO">
              <xsl:variable name="Contact" select="."/>
              <xsl:element name="Contact">
                <xsl:attribute name="Id">
                  <xsl:value-of select="@Id"/>
                </xsl:attribute>

                <xsl:element name="ContactValue">
                  <xsl:value-of select="ContactValue" />
                </xsl:element>

                <xsl:element name="UserName">
                  <xsl:value-of select="UserName" />
                </xsl:element>

                <xsl:element name="ContactTypeName">
                  <xsl:value-of select="ContactTypeName" />
                </xsl:element>
              </xsl:element>
            </xsl:for-each>
          </xsl:element>
        </xsl:element>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>


Veebiteenuse retsensioon

Meeskonnale: Raavo V2™

Antud töö on ilusti kirjutatud ning ei oma suuremaid vigu ning kõik Must Have eesmärgid on edukalt saavutatud. Nice to Have eesmärgid on kahjuks kõik jäänud tegemata. Kogu projekt on ilusti kommenteeritud ning ei oma vigu, mis jäävad koheselt silma. Projekti struktuur on ilusti püsti pandud ning ükski klass ei ole suvalises kaustas. Projekti sees on tehtud eraldi lisaks WebAppile veel viis eraldi väiksemat projekti, kus hoitakse domeene, liideseid ning Entity Frameworkiga seostuvaid klasse.

Veebiteenuses on täidetud kõik nõuded peale kasutaja statistika. Seda nõuet saab küll täita mitut moodi ning kasutaja statistikat on ka võimalik võtta broneeringutest seega võib seda tehniliselt lugeda täidetuks.

Kõik klassid, millele on mõttekas luua liides, on see ka tehtud. Domeenidel on kõik vajalikud väljad piiratud ning on ära märgitud, mida on vaja ära täita, mis on välisvõti, mis on võti ning väljastatakse ka veateated, kui ületab limiiti.

Projektile on lisatud UnitOfWork meetod ning startupis on ka olemas vajalikud sisendid, et seda kasutada, kuid mitte kordagi ei ole seda projekti vältel kasutatud. UnitOfWork lisab antud projekti palju üleliigset koodi, ilma milleta saaks edukalt hakkama. UnitOfWorki on lisatud ka kõik domeenid seega mingiaeg on mõeldud selle kasutamise peale.

Kontrolleritele ei ole tehtud eraldi teenuseid, seega seda võib-olla hiljem keeruline muuta ja testida. Kõik kontrollerid nõuavad autoriseerimist seega ei tohiks keegi pääseda ligi informatsioonile, millele tal pole õigust. Kahjuks tundub, et autoriseerimine on mingilt maalt jäänud pooleli ning muutmise meetodid pole avatud tavakasutajale. Näiteks kui soovib kasutaja muuta auto informatsiooni, siis ta peab selle hoopis ära kustutama ja uuesti lisama, kuna PUT meetodile on lubatud ligipääs vaid administraatoril. API’de juures oleks võinud kommentaari „summary“ osasse panna täpsema info, et millega antud meetod tegeleb. Hetkel on seal lihtsalt kuidas meetodile ligi pääseda, mis oli automaatselt genereeritud. Igast kontrolleri meetodist ei tule ka tagasi IActionResult, mille tõttu võivad mõned meetodid tagastada vale koodi.

Antud töös ei ole kasutatud Data Transfer Objecteid (DTO’sid), seega kui kasutada API’t, siis saavad kasutajad palju informatsiooni tagasi, kui nemad peaksid saama. Kuna DTO puudub, siis võib ka läbi API saada ligi konfidentsiaalsele informatsioonile, kui ei ole ettevaatlik.

Kuigi kõik kontrollerid on ilusti ära kommenteeritud ning autorisatsioon on kõikidel meetoditel olemas, siis väga tihti on autoriseeritud roll ainult administraatoril, kuigi peaks olema ka teistel. Samuti on näiteks kasutaja lisamine läbi API lubatud ainult administraatoril ja seda tehakse valesti. Kasutaja informatsioon lisatakse otse andmebaasi läbi ApplicationDbContexti, paroole ei hashita ja informatsiooni üle ei kontrollita. Selle jaoks oleks võinud kasutada userManageri, kus on kõik vajalikud meetodid ja kontrollid juba sisse ehitatud.

Klientrakendus ja API ei ole ka väga kooskõlas. Näiteks saab klientrakenduses vahetada kasutajainformatsiooni ka kasutajana, kuid kui teha seda läbi API, siis peab olema administraator, et muuta kasutaja informatsiooni.

BookingArchive ei saa ka töötaja vaadata läbi API, see informatsioon peaks olema neile kindlasti ligipääsetav.

Kasutajatele ei ole kuidagi võimalik läbi API lisada kasutajarolle, rolle on küll ennast võimalik lisada, muuta ja kustutada, kuid nende ühendamist kasutajakontodega ei ole veel lisatud (läbi API).

Projekti käivitades luuakse andmebaasi kohe kolm erinevat rolli, Admin, worker ja User ning kõikidel neil on erinevad õigused teenuse kasutamisel. Ükski roll ei ole ülearu, kuid näiteks worker ei saa lisada teenuse tüüpe ja teenuseid seega mõndade rollide õigused tunduvad algselt poolikud. Kohe alguses luuakse ka administraator, mille parooli vahetamist peaks kasutajalt sisse logides nõudma, et muudaks. Selle jaoks võib ka teha teavituse ülesse serva, kui on algne parool, siis tuletaks meelde, et muutke ära. Igat kasutajat on ka võimalik deaktiveerida, sellehulgas ka administraatori oma. Administraatori kasutaja on ainuke, kelle oma ei tohiks deaktiveerida, kui ta on ainuke administraator. Ehk teha selle jaoks test, kui on ainult 1 isik administraatori rollidega, siis teda deaktiveerida ei saa.

Antud programm on hästi tehtud ning kommenteeritud. Kõik liidesed, mida oleks vaja on olemas, kuid puudavad Data Transfer Objekt klassid, mis ei ole küll nõutud, kuid API vastusteks sobiksid palju paremini. UnitOfWork tundub olevat antud projektis üleliigne ja API peale ei ole täielikult läbi mõeldud. API'le ei pääse ligi kuna ei ole tehtud viisi tokenite küsimiseks ega loomiseks. Kuna veebiteenus ja klientrakendus töötavad ilusti koos, siis see ei ole API absoluutselt vajalik, kuid kui juba tehtud on, siis võiks olla töötav. Kuna API ei ole hetkel kasutatav, siis ei ole antud projekt väärt maksimum punkte.


Klientrakenduse retsensioon

Meeskonnale: Raavo V2™

Klientrakenduses on olemas kõik Must have funktsionaalsused. Analüüsis välja toodud Nice to have funktsionaalsusi sinna lisatud ei ole. Rakenduses saab registreerida kasutajaid, muuta kasutajainfot, vaadata pakutavaid teenuseid, vaadata ning teha broneeringuid. Administraator saab broneeringuid hallata. Ka töötajatel võiks olla broneeringute haldamise võimalus. Vastaval lehel on olemas nupud broneeringute kinnitamiseks ja kustutamiseks, kuid töötaja kontoga sisenedes need nupud ei tööta. Töötaja saab rakenduses ainult broneeringuid vaadata. Võimalused teenuste lisamiseks või muutmiseks puuduvad.

Kõikjal kus toimub info sisestamine võiks pärast edukat lisamist väljad tühjendada, mõnes kohas seda tehakse, mõnes kohas mitte. Niimoodi on palju mugavam järjest asju lisada, siis ei pea enne sisestamist välju ise tühjendama.

Kasutajale tagastatavaid teateid võiks paremaks teha. Näiteks kohas, kus kasutaja saab autot lisada, kuvatakse pärast auto lisamist teade: „added new car type“. See teade võib kasutajas segadust tekitada, sest lisati ju uus auto, mitte auto tüüp.

Broneeringute lisamise kõrval on väga oluline ka võimalus neid muuta ja kustutada. Sellist võimalust kasutajal kahjuks ei ole. Sarnane probleem on ka administraatori kasutajal. Seal ei ole näiteks võimalust teenuseid ja garaaže muuta. Neid saab ainult juurde lisada või kustutada. Garaažide majandamine on üldiselt puudulik funktsioon. Garaaži info on piiratud nime, ühe aadressi ja ühe telefoninumbriga. Usun et reaalne firma tahab rohkem vabadust oma info määramisel. Samuti tundub et töötaja tüüpi kasutajad peaksid olema seotud erinevate garaažide, mida praegu ei ole näha ehk veel üks koht kus tundub töötaja unarusse jäetud.

Teenuste lehel võiks olla teenuse otsimise võimalus. Kui teenuseid on nimekirjas palju, siis on kasutajal raske endale sobivat teenust üles leida. Kahtlane on ka see et admin kasutaja peab erinevatele garaažidele teenuseid lisama, kuna admin kasutajal on väga lai võimekus kõige üle. Seega kui mõni garaaž peaks tahtma oma teenuseid muuta siis peab see tegevus käima läbi mõne lehe admini kuna igale lehel olevale garaažile ei või ilmselt anda kätte administraator kasutajat. Lisaks on teenuste lisamisel hinna piirang 1-100 vahel, kuna seal on ka võimalus määrata hinna ühik siis on erinvaid valuutasid arvestades tegu väga suure piiranguga. Valuuta tüüpide valimisel on probleemne ka vaba teksti kast mis lubab ühikuid ise välja mõelda. Samuti kui mingile teenusele määrata ühik siis broneeringu all näitab hinda eurodes aga üld nimekirjas kasutab teenuse registreerimisel määratud ühikut.

Autode lisamisel on väljalaske aeg väga täpselt pandud (päev, kuu ja aasta), kuigi peaks piisama ainult aastast. Hea on see, et tuleviku kuupäevade lisamine on ära keelatud.

Administraator kasutajaga on pisut liiast anda võimalus deaktiveerida see kasutaja millega ollakse sisse logitud. Kasutajate haldamise lehel tundub ka puudu olevat võimalus muuta teiste kasutajate rolle või siis luua uusi administraator või töötaja kasutajaid. Hetkel ei ole seega võimalik läbi kasutaja liidese uusi töötaja või administraator rollis kasutajaid luua.

Javascripti kood on jaotatud funktsioonidesse, mis teeb selle paremini loetavaks. Funktsioonidel on asjakohased nimed ning kommentaarid.

Lehel on ilusti lisatud erinevad vaated iga kasutaja õiguse kohta, nii et iga kasutaja saab oma õiguste tasemel funktsionaalsusele ligi. Kuigi pisut üleliigne on kõigile kuvatud menüüvalikutest hoida kõrvuti nuppe “garagefy” ja “home” mis mõlemad teevad täpselt sama asja.

Klientrakendus oleks võinud olla eraldi projektis, mitte veebiteenusega samas kohas. Muidu on vajalik funktsionaalsus olemas. Omajagu kohtab küll poolikuid lehti või lihtsalt kohatäitvat funktsionaalsust, eriti töötaja tüüpi kasutajate juures.


XML retsensioon

Kõik esitatud XML failid valideeruvad. XML andmefailile esitatud nõuded on täidetud, ehk 4 dimensiooniline, mõne koha peal näeb isegi vähemalt 5 dimensioonini minemist ja neile dimensioonidele on ka jaotatud mõistlike andmeid. Näiteks kasutaja nimi, email, automudel, auto tüübi nimi jne. Andmefailil on loogiline ja selge ülesehitus. Vajalikud teksti väärtused on ümbritsetud CDATA märgistusega, mis keelab selle sisu tõlgendada XML-ina. Samas on ka näha kuupäevade kasutamist ja isegi valuuta väärtuse sidumist euroga.

HTML-i transformatsiooni faili nõuded on ka täidetud. Lisaks for-each-ile on kasutatud choose-i. Pärast transformatsiooni on kõik broneeringud ja nendega seotud andmed esitatud listi kujul. Arusaamatuks jääb miks on kasutatud osades kohtades id järgi sorteerimist <xsl:sort select="@id"/>, sest väärtustel, millele sorteerimist rakendatakse, puuduvad id-d.

XML-i transformatsioon on ka olemas. HTMLi viies on ilusti selgelt näha kolm broneeringut, millest esimene ja viimane on “pending” ja teine on vastu võetud. Siin puhul on ka ilusti värvi kasutatud kus vastuvõetud broneering on tähistatud roheliselt ja ootel olevad punaselt. Ülejäänu on väga standartselt grupeeritud nii et on pealkiri (N: Klient, Auto) ja siis selle all on tabuleeritult toodud täpsem info selle osa kohta. Selgelt on kõik eristatav ja arusaadav, midagi kurta pole. XSLis on sisse tulnud väikene kirjaviga, kus iga Booking on kirjutatud kolme o’ga. Elementide nimedeks ei ole kasutatud “xsl:element-name” vaid on otse pandud nimetuis, mis ei tundu küll otseselt vigane olevat kuid siiski XLS’is võiksid need olemas olla. XLS’is ei ole samuti kasutatud atribuute, näiteks kaovad kõik ID’d ära. Need oleksid võinud tuua välja atribuutidena või elementidena iga elemendi juures. Kuna ID’d kaovad transformeerimisel ära, siis võib sellest tulla probleeme hiljem terviklikkusega.