BestInShow
Meeskond BestInShow
Liina Abner
Marju Pütsepp
Liisi Taimre
Analüüs
Loodav infosüsteem kujutab endast tõukoerte registrit, mis võimaldab hallata ja otsida koerte ning koerakasvatajate andmeid.
Tehnoloogia
Projekti käigus luuakse
- REST veebiteenus
- .NET Core 2.0
- Klientrakendus, mis suhtleb loodud veebiteenusega
- Angular 2
Üldised nõuded
- Andmevahetus toimub JSON formaadis
- Klientrakenduspeab töötama enamlevinud veebibrauserite enamlevinud versioonides, nt. Google Chrome Version 65.0.x
Kasutajad
- Registripidaja - rakenduse administraator
- Koerakasvataja e. Kenneliomanik (registreeritud kasutaja)
- Koeraomanik (registreeritud kasutaja)
- Kõik koerahuvilised (registreerimata kasutaja)
Funktsionaalsed nõuded
- Kasutajaks registreerimine - kasutajaks võivad registreeruda kõik inimesed.
- Rakenduse admin saab uusi kasutajaid lisada ja olemasolevaid kasutajaid hallata, nt muuta staatust.
- Rakenduse administraator saab teha väljavõtteid kasutusstatistikast.
- Registreeritud kasutaja saab esitada taotluse hakata kenneliomanikuks.
- Rakenduse admin saab kenneliomaniku taotlusi aktsepteerida ja tagasi lükata
- Rakenduse admin saab kenneleid lisada/muuta/kustutada
- Rakenduse admin saab lisada näituseid
- Rakenduse admin saab lisada näituse tulemusi, laadides üles kindlas formaadis näituse protokolli
- Kenneliomanik saab lisada pesakondi
- Kenneliomanik lisada/muuta koeri
- Kenneliomanik saab saata teate kindla pesakonna koeraomanikele
- Koeraomanik saab lisada koera terviseandmeid
- Koeraomanik saab üle anda koera omandiõiguse teisele registreeritud kasutajale
- Koeraomanik saab muuta koera andmeid - registreerida surmakuupäeva
- Registreerimata kasutaja saab sirvida tõugusid, kenneleid, pesakondi, koeri
- Registreerimata kasutaja saab nime ja/või muude tunnuste alusel otsida kenneleid, pesakondi, koeri. Koeravaates sisaldub koera sugupuu
Nice to have funktsionaalsus
- registreerumise kinnitamine läbi epostile saadetava lingi
- registreeruda näitusele (koeraomanik)
- Koerapiltide lisamine
- Uudisfeed kutsikahuvilistele - lisandunud pesakonnad/koerad
- Sünnipäevafeed - tänased sünnipäevalapsed
Andmemudel
Iga koera sünd registreeritakse. Iga koer on kindlat tõugu. Tõul on omadused, nõuded välimikule (nt. rõngas saba, püstised kõrvad) ja iseloomule (nt. valveinstinkti puudumine). Tõud on FCI nomenklatuuri järgi gruppideks jaotatud (nt. terjerid, taksid, hurdad), FCI grupi sees võivad olla sektsioonid (nt. pikakarvalised hurdad, lühikarvalised hurdad). Koeral on omanik. Koer võib olla kaasomandis. Omanik võib vahetuda. Koer sünnib pesakonnas, millel on emakoer ja isakoer. Pesakond sünnib kennelis e. kindla koerakasvataja juures. Kennelil on üks või rohkem omanikku (kasvatajat). Koertele teostatakse terviseuuringuid, nt. puusauuringuid ja silmauuringuid. Koerad käivad näitustel ja võidavad seal tiitleid (nt. parim isane oma klassis, parim kogu näitusel - Best In Show)
XML failid
Tegemist on koertenäituse tulemuste protokolliga. Arvestust peetakse tõugude kaupa ja iga tõu sees omakorda on erinevad võistlusklassid, emastest kutsikatest isaste veteranideni. Igas võistlusklassis valitakse 4 parimat, ülejäänuid ei järjestata. Tõu isaste ja emaste avaklassi võitja konkureerivad tiitlile tõu parim - BOB (Best Of Breed). Kõikide tõugude parimate seast valitakse näituse parim - BIS (Best In Show).
Schema
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="show">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="2" name="title">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="lang" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="venue">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="country" type="xs:string" />
<xs:element name="city" type="xs:string" />
<xs:element name="street" type="xs:string" />
<xs:element name="zip" type="xs:unsignedShort" />
<xs:element name="location">
<xs:complexType>
<xs:attribute name="lat" type="xs:decimal" use="required" />
<xs:attribute name="lng" type="xs:decimal" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="startdate" type="xs:date" />
<xs:element name="enddate" type="xs:date" />
<xs:element name="judge">
<xs:complexType>
<xs:sequence>
<xs:element name="lastname" type="xs:string" />
<xs:element name="firstname" type="xs:string" />
</xs:sequence>
<xs:attribute name="country" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="fcigroup" maxOccurs="10"> <!-- number of FCI groups -->
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="2" name="name">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="lang" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="fcisection" maxOccurs="15"> <!-- max number of sections in FCIGroup -->
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="name">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="lang" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element maxOccurs="100" name="breed"> <!--max number of breeds in FCISection-->
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="2" name="name">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="lang" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element maxOccurs="20" name="class"><!--number of different classes-->
<xs:complexType>
<xs:sequence minOccurs="0">
<xs:element maxOccurs="unbounded" name="participant">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="owner">
<xs:complexType>
<xs:sequence>
<xs:element name="lastname" type="xs:string" />
<xs:element name="firstname" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="dob" type="xs:date" />
<xs:element minOccurs="0" name="rank" type="xs:unsignedByte" /><!--only first four are ranked-->
<xs:element minOccurs="0" maxOccurs="10" name="title" type="xs:string" />
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedByte" use="required" />
<xs:attribute name="country" type="xs:string" use="required" />
<xs:attribute name="chip" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="type" type="xs:string" use="required" />
<xs:attribute name="gender" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="fcinr" type="xs:unsignedShort" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="fcisectionId" type="xs:unsignedShort" use="required" />
<xs:attribute name="fcigroupId" type="xs:unsignedShort" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="fcigroupId" type="xs:unsignedShort" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XML
<?xml version="1.0" encoding="utf-8" ?>
<show>
<title lang="ee"> IV Rahvusvaheline põhjamaiste kelgukoerte erinäitus</title>
<title lang="en"> IV International Nordic Sledge Dogs Specialty Show</title>
<venue>
<name>Saku Suurhall</name>
<country>Estonia</country>
<city>Tallinn</city>
<street>Paldiski mnt. 104B</street>
<zip>13522</zip>
<location lat="59.5467" lng="26.1830"/>
</venue>
<startdate>2018-02-18</startdate>
<enddate>2018-02-20</enddate>
<judge country="gbr">
<lastname>Dogman</lastname>
<firstname>David</firstname>
</judge>
<fcigroup fcigroupId="5">
<name lang="ee">spitsilaadsed ja algupärased tõud</name>
<name lang="en">spitz and primitive types</name>
<fcisection fcisectionId="1" fcigroupId="5">
<name lang="ee">põhjamaised kelgukoerad</name>
<name lang="en">nordic sledge dogs</name>
<breed fcinr="212">
<name lang="ee">samojeedi koer</name>
<name lang="en">Samoyed</name>
<class type="baby" gender="dog">
<participant id="1" country="fin" chip="fin1234">
<name>Finnadian Heatseeker</name>
<owner>
<lastname>Koiranen</lastname>
<firstname>Pasi</firstname>
</owner>
<dob>2017-12-03</dob>
<rank>1</rank>
<title>BOS</title>
</participant>
<participant id="2" country="est" chip="est1233">
<name>Silvery White Shadow My Hero</name>
<owner>
<lastname>Siirius</lastname>
<firstname>Siiri</firstname>
</owner>
<dob>2017-12-04</dob>
<rank>2</rank>
</participant>
</class>
<class type="baby" gender="bitch">
<participant id="3" country="est" chip="est1234">
<name>Lumeingel October Sky</name>
<owner>
<lastname>Abner</lastname>
<firstname>Liina</firstname>
</owner>
<dob>2017-12-05</dob>
<rank>3</rank>
</participant>
<participant id="4" country="est" chip="est1235">
<name>Lumeingel October Wind</name>
<owner>
<lastname>Peedikaupmees</lastname>
<firstname>Peeter</firstname>
</owner>
<dob>2017-11-03</dob>
<rank>1</rank>
<title>BB</title>
</participant>
<participant id="5" country="est" chip="est1236">
<name>Lumeingel October Sun</name>
<owner>
<lastname>Peedikaupmees</lastname>
<firstname>Peeter</firstname>
</owner>
<dob>2017-12-08</dob>
<rank>2</rank>
</participant>
</class>
<class type="puppy" gender="dog">
<participant id="6" country="est" chip="est1237">
<name>Smiling Snowball Letter to Pushkin</name>
<owner>
<lastname>Pambu</lastname>
<firstname>Peedu</firstname>
</owner>
<dob>2014-12-03</dob>
<rank>3</rank>
</participant>
<participant id="7" country="est" chip="est1238">
<name>Vanderbilt's Captain Cool</name>
<owner>
<lastname>Peedikaupmees</lastname>
<firstname>Peeter</firstname>
</owner>
<dob>2013-12-03</dob>
<rank>2</rank>
</participant>
<participant id="8" country="est" chip="est1239">
<name>Ikiliikkujan Blu Sky O'Traces</name>
<owner>
<lastname>Lehtonen</lastname>
<firstname>Lehti</firstname>
</owner>
<dob>2014-11-03</dob>
<rank>1</rank>
<title>BP</title>
</participant>
</class>
<class type="puppy" gender="bitch"></class>
<class type="junior" gender="dog"></class>
<class type="junior" gender="bitch"></class>
<class type="intermediate" gender="dog"></class>
<class type="intermediate" gender="bitch"></class>
<class type="open" gender="dog">
<participant id="9" country="est" chip="est1230">
<name>Snowmist Acrobat</name>
<owner>
<lastname>Lehtonen</lastname>
<firstname>Lehti</firstname>
</owner>
<dob>2014-11-03</dob>
<rank>1</rank>
<title>BOB</title>
</participant>
</class>
<class type="open" gender="bitch">
<participant id="10" country="est" chip="est2234">
<name>Winter Day's Grand Sensation</name>
<owner>
<lastname>Hiir</lastname>
<firstname>Heino</firstname>
</owner>
<dob>2014-11-03</dob>
<rank>1</rank>
<title>BOS</title>
</participant>
</class>
<class type="veteran" gender="dog"></class>
<class type="veteran" gender="bitch"></class>
</breed>
<breed fcinr="243">
<name lang="ee">alaska malamuut</name>
<name lang="en">Alaskan Malamute</name>
<class type="baby" gender="dog"></class>
<class type="baby" gender="bitch"></class>
<class type="puppy" gender="dog"></class>
<class type="puppy" gender="bitch"></class>
<class type="junior" gender="dog"></class>
<class type="junior" gender="bitch"></class>
<class type="intermediate" gender="dog"></class>
<class type="intermediate" gender="bitch"></class>
<class type="open" gender="dog">
<participant id="11" country="est" chip="est2235">
<name>D-Taro of Xamba Yoshi and Us</name>
<owner>
<lastname>Hiir</lastname>
<firstname>Heino</firstname>
</owner>
<dob>2014-11-03</dob>
<rank>1</rank>
<title>BOS</title>
</participant>
</class>
<class type="open" gender="bitch">
<participant id="11" country="fin" chip="fin2235">
<name>Talvituuli Pikku Myy</name>
<owner>
<lastname>Pehmonen</lastname>
<firstname>Petteri</firstname>
</owner>
<dob>2014-11-03</dob>
<rank>1</rank>
<title>BOB</title>
<title>BIS</title>
</participant>
</class>
<class type="veteran" gender="dog"></class>
<class type="veteran" gender="bitch"></class>
</breed>
<breed fcinr="270">
<name lang="ee">siberi husky</name>
<name lang="en">Siberian Husky</name>
<class type="baby" gender="dog"></class>
<class type="baby" gender="bitch"></class>
<class type="puppy" gender="dog"></class>
<class type="puppy" gender="bitch"></class>
<class type="junior" gender="dog"></class>
<class type="junior" gender="bitch"></class>
<class type="intermediate" gender="dog"></class>
<class type="intermediate" gender="bitch"></class>
<class type="open" gender="dog">
<participant id="11" country="ltu" chip="ltu1234">
<name>Klajokliu Šuo You Are My Treasure</name>
<owner>
<lastname>Sussanikaite</lastname>
<firstname>Susanna</firstname>
</owner>
<dob>2011-12-03</dob>
<rank>1</rank>
<title>BOS</title>
</participant>
<participant id="12" country="est" chip="est3233">
<name>Kenventaki Hot'n Disco's</name>
<owner>
<lastname>Siirius</lastname>
<firstname>Siiri</firstname>
</owner>
<dob>2012-12-03</dob>
<rank>2</rank>
</participant>
</class>
<class type="open" gender="bitch">
<participant id="13" country="pol" chip="pol3235">
<name>Princessa of Tungus</name>
<owner>
<lastname>Pan</lastname>
<firstname>Kleks</firstname>
</owner>
<dob>2011-12-03</dob>
<rank>1</rank>
<title>BOB</title>
</participant>
<participant id="14" country="est" chip="est3236">
<name>Quest for Glory</name>
<owner>
<lastname>Peedikaupmees</lastname>
<firstname>Peeter</firstname>
</owner>
<dob>2014-12-03</dob>
<rank>2</rank>
</participant>
</class>
<class type="veteran" gender="dog"></class>
<class type="veteran" gender="bitch"></class>
</breed>
</fcisection>
</fcigroup>
</show>
XSLT (HTML)
Teeb tabeli iga võistlusklassi võitjatega, kui võistlusklassi võitja on saanud ka tiitli BIS (Best In Show), BOB (Best Of Breed) või BB (Best Baby), siis näidatakse ka seda. Samuti näitab võistlusklassis osalenute koguarvu.
<?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="/">
<xsl:text disable-output-escaping='yes'><!DOCTYPE html></xsl:text>
<html>
<head>
<style>
table, tr, td {
border-collapse: collapse;
border: 1px solid black;
}
td {
padding: 5px;
}
div {
width: 800px; margin: 20px;
}
.breed {
background-color: #f2f2f2;
}
</style>
<title>BestInShow - Best in Class</title>
</head>
<body>
<div>
<h2>
<xsl:value-of select="show/title[@lang='en']"/>
</h2>
<h3>Best In Class - Võistlusklasside võitjad</h3>
<hr/>
BB - Best Baby<br />
BOB - Best Of Breed<br />
BIS - Best In Show
<table>
<xsl:for-each select="//breed">
<tr class="breed">
<td colspan="4">
<xsl:value-of select="name[@lang='en']"/>
<xsl:text> </xsl:text>
<i>
<xsl:value-of select="name[@lang='ee']"/>
</i>
</td>
</tr>
<tr>
<td>Class</td>
<td>Number of participants</td>
<td>Winner</td>
<td>Titles</td>
</tr>
<xsl:for-each select="class">
<xsl:variable name="classType" select="@type" />
<xsl:variable name="classGender" select="@gender" />
<xsl:variable name="participantCount" select ="count(participant)" />
<xsl:for-each select="participant">
<xsl:variable name="participantId" select="@id" />
<xsl:variable name="participantName" select="name" />
<xsl:if test="rank = 1">
<tr>
<td>
<xsl:value-of select="$classType"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$classGender"/>
</td>
<td>
<xsl:value-of select="$participantCount"/>
</td>
<td>
<xsl:value-of select="$participantName"/>
</td>
<td>
<xsl:for-each select="title">
<xsl:choose>
<xsl:when test=".='BIS' or .='BOB' or .='BB'">
<xsl:text> </xsl:text>
<xsl:value-of select="."/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</td>
</tr>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</table>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
XSLT (XML)
Teeb xml-i, milles on ainult BIS (Best In Show) ja BOB (Best Of Breed) tiitli võitnud koerad.
<?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:variable name="bis" select="//participant[title='BIS']"/>
<xsl:variable name="breed" select="//breed[class/participant[@chip=$bis/@chip]]"/>
<winners>
<bis>
<xsl:copy-of select="$bis/name"/>
<breed>
<name>
<xsl:copy-of select="$breed/name[@lang='ee']"/>
</name>
<fcistandard>
<xsl:value-of select="$breed/@fcinr"/>
</fcistandard>
</breed>
<country>
<xsl:value-of select="$bis/@country"/>
</country>
<dogowner>
<xsl:value-of select="$bis/owner/firstname"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$bis/owner/lastname"/>
</dogowner>
</bis>
<xsl:for-each select="//participant[title='BOB']">
<xsl:variable name="chip" select="@chip" />
<bob>
<xsl:variable name="bobreed" select="//breed[class/participant[@chip=$chip]]" />
<xsl:copy-of select="name"/>
<breed>
<name>
<xsl:copy-of select="$bobreed/name[@lang='ee']"/>
</name>
<fcistandard>
<xsl:value-of select="$bobreed/@fcinr"/>
</fcistandard>
</breed>
<country>
<xsl:value-of select="@country"/>
</country>
<dogowner>
<xsl:value-of select="owner/firstname"/>
<xsl:text> </xsl:text>
<xsl:value-of select="owner/lastname"/>
</dogowner>
</bob>
</xsl:for-each>
</winners>
</xsl:template>
</xsl:stylesheet>
Lõpptoode
Lõpptoode veebiteenus: https://www.dropbox.com/s/j5ixmwmx45kxcyo/BestInShow.zip?dl=0
Lõpptoode klient: https://bitbucket.org/Marjup/bestinshow/
XML failid: Schema, XML ja XSLT HTML ja XML transformatsiooniks
Retsensioon veebiteenusele: TODO
Retsensioon klientrakendusele: TODO
Retsensioon XML-ile: TODO
Kasutusjuhend
Veebiteenusele andmebaasi loomiseks ja algandmete sisselaadimiseks:
add-migration migname
update-database
Laadida ab-sse selles järjekorras sisse näidisandmed:
fci.sql
dogs.sql
Näiteks avada sql fail Visual Studios ja vajutada rohelist noolekest üleval vasakul nurgas (Execute)
Klientrakenduse kasutusjuhend on klientrakenduse juures.
Tegevuste logi
11.03.2018 Meeskonna kohtumine, esialgne ülesandepüstitus
16.03.2018 wikilehe ja analüüsi alged
22.03.2018 ab mudeli põhi Vertabelos
25.03.2018 Meeskonna kohtumine, lepiti kokku projekti mahu osas, otsustati klientrakendus teha Angularis; projekt kooskõlastati õppejõuga: võib tegema hakata
27.03.2018 Meeskonna Skype-i kohtumine. Analüüsi ja andmemudeli täpsustamine.
04.04.2018 Projektipõhi domeenimudeliga.
20.04.2018 Vajalike mustrite ja kihtide lisamine projektile, api/FCIGroups koos Swaggeri kommentaaridega.
25.04.2018 Meeskonna Skype kohtumine. API endpointide spec. Tööde jaotamine: Liisi - kennelid, Liina - näitused, Marju alustab klientrakendusega.
25.04.2018 - 08.06.2018 Arendame
08.06.2018 Lõpptoode tarnitud