PC KartKicker
Meeskond
- Martin Kask
- Rain Saarmäe
- Jan Eerik
Idee
Käesolev veebirakendus on asendamatu abimees arvuti kokkupanekul (võrdlemisi tugevalt inspireeritud https://pcpartpicker.com).
Kuna teatavasti vajab arvuti töötamiseks kindlaid juppe mingis aktsepteeritud konfiguratsioonis, võimaldab meie rakendus välistada mitteühilduva raudvara "jõuga" ühildamist ja abistab kasutajal optimaalse konfiguratsiooni valimist.
Põhiline funktsionaalsus
- Kasutaja saab lisada üks kuni mitu arvutiskeemi
- Skeemile saab hakata ükshaaval lisama juppe (emaplaat, protsessor, mälud jne)
- Iga kord kui mingi jupp skeemi lisatakse, kitsendab see ülejäänud juppide valikut - näiteks LGA1151 liidesega emaplaadile ei õnnestu lisada AMD protsessorit jne
- Nii pooleliolevaid kui valminud skeeme saab salvestada
- Igal jupil on oma vaade koos tehnilise infoga
Nice to have
- Parima hinna kuvamine (nt Amazon, Newegg)
- Komponentide võrdlus
Ülesanne 1: XML
Teema
Uute arvutikomponentide olemasolevatesse kategooriatesse lisamiseks kasutab administraator ankeeti, mille salvestamisel ja andmete serverisse edastamiseks tekitatakse järgmine XML, kus on võimalik korraga suur hulk erinevaid arvutikomponente lisada, aga võib ka ainult ühe komponendi korraga saata.
XML
<?xml version="1.0" encoding="utf-8"?> <components> <cases> <case brand="NZXT" name="S340" type="Mid Tower" formFactor="ATX" bay5="0" bay3="3" psu="" maxGpuLength="364" maxCpuHeight="161" primaryColor="black" secondaryColor="red" price="66.99"></case> <case brand="Deepcool" name="TESSERACT SW" type="Mid Tower" formFactor="ATX" bay5="2" bay3="4" psu="" maxGpuLength="350" maxCpuHeight="170" primaryColor="black" secondaryColor="light blue" price="38.99"></case> <case brand="Xion" name ="XON-310_BK" type="Mid Tower" formFactor="MicroATX" bay5="0" bay3="1" psu="" maxGpuLength="350" maxCpuHeight="170" primaryColor="black" secondaryColor="" price="22.98"></case> <case brand="Corsair" name="750D" type="Full tower" formFactor="MicroATX" bay5="3" bay3="6" psu="" maxGpuLength="450" maxCpuHeight="170" primaryColor="black" secondaryColor="" price="149.99"></case> </cases> <cpus> <cpu brand="Intel" name="7700k" cooler="false" series="Core i7" family="Kaby Lake" socket="LGA1151" iGPU="HD 630" cores="4" threads="8" ecc="false" speed="4.2" TDP="91" lithography="14" maxPowerDraw="74" price="327.98"></cpu> <cpu brand="Intel" name="7600k" cooler="false" series="Core i5" family="Kaby Lake" socket="LGA1151" iGPU="HD 630" cores="4" threads="4" ecc="false" speed="3.8" TDP="91" lithography="14" maxPowerDraw="69" price="233.89"></cpu> <cpu brand="Intel" name="6700k" cooler="false" series="Core i7" family="Skylake" socket="LGA1151" iGPU="HD 530" cores="4" threads="8" ecc="false" speed="4.0" TDP="91" lithography="14" maxPowerDraw="71" price="316.98"></cpu> <cpu brand="Intel" name="6600k" cooler="false" series="Core i5" family="Skylake" socket="LGA1151" iGPU="HD 530" cores="4" threads="4" ecc="false" speed="3.5" TDP="91" lithography="14" maxPowerDraw="61" price="219.99"></cpu> <cpu brand="Intel" name="E5-2699 V3" cooler="false" series="Xeon" family="Haswell" socket="LGA2011-3" iGPU="" cores="18" threads="36" ecc="true" speed="2.3" TDP="145" lithography="22" maxPowerDraw="120" price="3410.46"></cpu> <cpu brand="AMD" name="1800X" cooler="false" series="Ryzen 7" family="Ryzen" socket="AM4" iGPU="" cores="8" threads="16" ecc="false" speed="3.6" TDP="95" lithography="14" maxPowerDraw="82" price="469.99"></cpu> </cpus> <cpucoolers> <cpucooler brand="Cooler Master" name="Hyper 212 EVO" liquid="false" fans="1" height="159" price="24.88"> <sockets> <socket>AM2</socket> <socket>AM2+</socket> <socket>AM3</socket> <socket>AM3+</socket> <socket>FM1</socket> <socket>FM2</socket> <socket>FM2+</socket> <socket>LGA1150</socket> <socket>LGA1151</socket> <socket>LGA1155</socket> <socket>LGA1156</socket> <socket>LGA1366</socket> <socket>LGA2011</socket> <socket>LGA2011-3</socket> <socket>LGA775</socket> </sockets> </cpucooler> <cpucooler brand="Corsair" name="H100i v2" liquid="true" rad="240" fans="2" height="" price="99.99"> <sockets> <socket>AM2</socket> <socket>AM2+</socket> <socket>AM3</socket> <socket>AM3+</socket> <socket>FM1</socket> <socket>FM2</socket> <socket>FM2+</socket> <socket>LGA1150</socket> <socket>LGA1151</socket> <socket>LGA1155</socket> <socket>LGA1156</socket> <socket>LGA1366</socket> <socket>LGA2011</socket> <socket>LGA2011-3</socket> </sockets> </cpucooler> <cpucooler brand="Noctua" name="NH-D15" liquid="false" fans="2" height="165" price="85.49"> <sockets> <socket>AM2</socket> <socket>AM2+</socket> <socket>AM3</socket> <socket>AM3+</socket> <socket>FM1</socket> <socket>FM2</socket> <socket>FM2+</socket> <socket>LGA1150</socket> <socket>LGA1151</socket> <socket>LGA1155</socket> <socket>LGA1156</socket> <socket>LGA1366</socket> <socket>LGA2011</socket> <socket>LGA2011-3</socket> </sockets> </cpucooler> </cpucoolers> <gpus> <gpu manufacturer="PowerColor" brandname="Radeon" codename="RX460" series="Red Dragon" vram="2" psuPin="" length="226" maxPowerDraw="130" price="73.98"></gpu> <gpu manufacturer="Sapphire" brandname="Radeon" codename="RX480" series="Nitro+" vram="8" psuPin="8" length="240" maxPowerDraw="150" price="253.99"></gpu> <gpu manufacturer="MSI" brandname="Geforce" codename="GTX1070" series="Quick Silver OC" vram="8" psuPin="6+8" length="279" maxPowerDraw="170" price="409.99"></gpu> </gpus> <memorychips> <memorychip brand="Kingston" name="ValueRAM" type="DIMM" rank="single" cas="15" gen="DDR4" speed="2133" moduleSize="8" modules="1" ECC="yes" price="67.58"></memorychip> <memorychip brand="Corsair" name="Dominator Platinum" type="DIMM" cas="15" gen="DDR4" speed="3000" moduleSize="8" modules="2" ECC="no" price="123.25"></memorychip> <memorychip brand="ADATA" name="" type="DIMM" cas="15" gen="DDR3" speed="1600" moduleSize="8" modules="1" ECC="no" price="88.29"></memorychip> </memorychips> <motherboards> <motherboard brand="Asus" name="Z170-A" formFactor="ATX" chipset="Z170" socket="LGA1151" memoryType="DDR4" memorySlots="4" maxMemory="64" maxMemorySpeed="3400" sata3="4" ethernet="1000" usb3="true" price="152.99"></motherboard> <motherboard brand="ASRock" name="H110M-HDS" formFactor="MicroATX" chipset="H110" socket="LGA1151" memoryType="DDR4" memorySlots="2" maxMemory="32" maxMemorySpeed="2133" sata3="4" ethernet="1000" usb3="true" price="37.98"></motherboard> <motherboard brand="Asus" name="Prime X370-PRO" formFactor="ATX" chipset="X370" socket="AM4" memoryType="DDR4" memorySlots="4" maxMemory="64" maxMemorySpeed="3200" sata3="8" ethernet="1000" usb3="true" price="162.98"></motherboard> </motherboards> <psus> <psu brand="EVGA" name="SuperNOVA 650" formFactor="ATX" wattage="650" eff80plus="gold" modular="full" pcie6="0" pcie6p2="4" price="77.88"></psu> <psu brand="be Quiet!" name="Pure Power L8 600W" formFactor="ATX" wattage="600" eff80plus="bronze" modular="no" pcie6="0" pcie6p2="4" price="77.88"></psu> <psu brand="Corsair" name="CX550M" formFactor="ATX" wattage="550" eff80plus="bronze" modular="semi" pcie6="0" pcie6p2="2" price="43.98"></psu> </psus> <storages> <storage brand="Samsung" name="850 PRO" type="ssd" capacity="2048" cache="" interface="sata3" formFactor="2,5" rpm="" price="823.14"></storage> <storage brand="Intel" name="DC P3608" type="ssd" capacity="4096" cache="" interface="pcie8x" formFactor="pcie" rpm="" price="8867.99"></storage> <storage brand="Samsung" name="960 PRO" type="ssd" capacity="1024" cache="" interface="m.2" formFactor="m.2-2280" rpm="" price="629.95"></storage> <storage brand="Western Digital" name="Black" type="hdd" capacity="6144" cache="128" interface="sata3" formFactor="3,5" rpm="7200" price="279.00"></storage> <storage brand="Seagate" name="BarraCuda Pro" type="hdd" capacity="10240" cache="256" interface="sata3" formFactor="3,5" rpm="7200" price="429.99"></storage> <storage brand="Hitachi" name="Travelstar" type="hdd" capacity="1024" cache="32" interface="sata3" formFactor="2,5" rpm="7200" price="53.99"></storage> </storages> </components>
XML skeem (XSD)
<?xml version="1.0" encoding="utf-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="components"> <xs:complexType> <xs:sequence> <xs:element name="cases" minOccurs="0" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="case"> <xs:complexType> <xs:attribute name="brand" type="xs:string" use="required" /> <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="type" type="xs:string" use="required" /> <xs:attribute name="formFactor" type="xs:string" use="required" /> <xs:attribute name="bay5" type="xs:unsignedInt" use="required" /> <xs:attribute name="bay3" type="xs:unsignedInt" use="required" /> <xs:attribute name="psu" type="xs:string" use="required" /> <xs:attribute name="maxGpuLength" type="xs:unsignedInt" use="required" /> <xs:attribute name="maxCpuHeight" type="xs:unsignedInt" use="required" /> <xs:attribute name="primaryColor" type="xs:string" /> <xs:attribute name="secondaryColor" type="xs:string" /> <xs:attribute name="price" type="xs:decimal" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="cpus" minOccurs="0" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="cpu"> <xs:complexType> <xs:attribute name="brand" type="xs:string" use="required" /> <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="cooler" type="xs:boolean" use="required" /> <xs:attribute name="series" type="xs:string" use="required" /> <xs:attribute name="family" type="xs:string" use="required" /> <xs:attribute name="socket" type="xs:string" use="required" /> <xs:attribute name="iGPU" type="xs:string" use="required" /> <xs:attribute name="cores" type="xs:unsignedInt" use="required" /> <xs:attribute name="threads" type="xs:unsignedInt" use="required" /> <xs:attribute name="ecc" type="xs:boolean" use="required" /> <xs:attribute name="speed" type="xs:decimal" use="required" /> <xs:attribute name="TDP" type="xs:unsignedInt" use="required" /> <xs:attribute name="lithography" type="xs:unsignedInt" use="required" /> <xs:attribute name="maxPowerDraw" type="xs:unsignedInt" use="required" /> <xs:attribute name="price" type="xs:decimal" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="cpucoolers" minOccurs="0" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="cpucooler"> <xs:complexType> <xs:sequence> <xs:element name="sockets"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="socket" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="brand" type="xs:string" use="required" /> <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="liquid" type="xs:boolean" use="required" /> <xs:attribute name="rad" type="xs:unsignedInt" /> <xs:attribute name="fans" type="xs:unsignedInt" use="required" /> <xs:attribute name="height" type="xs:string" use="required" /> <xs:attribute name="price" type="xs:decimal" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="gpus" minOccurs="0" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="gpu"> <xs:complexType> <xs:attribute name="manufacturer" type="xs:string" use="required" /> <xs:attribute name="brandname" type="xs:string" use="required" /> <xs:attribute name="codename" type="xs:string" use="required" /> <xs:attribute name="series" type="xs:string" use="required" /> <xs:attribute name="vram" type="xs:unsignedByte" use="required" /> <xs:attribute name="psuPin" type="xs:string" use="required" /> <xs:attribute name="length" type="xs:unsignedInt" use="required" /> <xs:attribute name="maxPowerDraw" type="xs:unsignedInt" use="required" /> <xs:attribute name="price" type="xs:decimal" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="memorychips" minOccurs="0" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="memorychip"> <xs:complexType> <xs:attribute name="brand" type="xs:string" use="required" /> <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="type" type="xs:string" use="required" /> <xs:attribute name="rank" type="xs:string" /> <xs:attribute name="cas" type="xs:unsignedInt" use="required" /> <xs:attribute name="gen" type="xs:string" use="required" /> <xs:attribute name="speed" type="xs:unsignedShort" use="required" /> <xs:attribute name="moduleSize" type="xs:unsignedInt" use="required" /> <xs:attribute name="modules" type="xs:unsignedInt" use="required" /> <xs:attribute name="ECC" type="xs:string" use="required" /> <xs:attribute name="price" type="xs:decimal" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="motherboards" minOccurs="0" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="motherboard"> <xs:complexType> <xs:attribute name="brand" type="xs:string" use="required" /> <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="formFactor" type="xs:string" use="required" /> <xs:attribute name="chipset" type="xs:string" use="required" /> <xs:attribute name="socket" type="xs:string" use="required" /> <xs:attribute name="memoryType" type="xs:string" use="required" /> <xs:attribute name="memorySlots" type="xs:unsignedInt" use="required" /> <xs:attribute name="maxMemory" type="xs:unsignedInt" use="required" /> <xs:attribute name="maxMemorySpeed" type="xs:unsignedInt" use="required" /> <xs:attribute name="video" type="xs:string" /> <xs:attribute name="sata3" type="xs:unsignedInt" use="required" /> <xs:attribute name="ethernet" type="xs:unsignedInt" use="required" /> <xs:attribute name="usb3" type="xs:boolean" use="required" /> <xs:attribute name="price" type="xs:decimal" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="psus" minOccurs="0" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="psu"> <xs:complexType> <xs:attribute name="brand" type="xs:string" use="required" /> <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="formFactor" type="xs:string" use="required" /> <xs:attribute name="wattage" type="xs:unsignedInt" use="required" /> <xs:attribute name="eff80plus" type="xs:string" use="required" /> <xs:attribute name="modular" type="xs:string" use="required" /> <xs:attribute name="pcie6" type="xs:unsignedInt" use="required" /> <xs:attribute name="pcie6p2" type="xs:unsignedInt" use="required" /> <xs:attribute name="price" type="xs:decimal" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="storages" minOccurs="0" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="storage"> <xs:complexType> <xs:attribute name="brand" type="xs:string" use="required" /> <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="type" type="xs:string" use="required" /> <xs:attribute name="capacity" type="xs:unsignedShort" use="required" /> <xs:attribute name="cache" type="xs:string" use="required" /> <xs:attribute name="interface" type="xs:string" use="required" /> <xs:attribute name="formFactor" type="xs:string" use="required" /> <xs:attribute name="rpm" type="xs:string" use="required" /> <xs:attribute name="price" type="xs:decimal" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
XSLT 1
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/components"> <html> <head> <h1>Added computer parts:</h1> </head> <body> <table border="1" cellpadding ="0" cellspacing="0" width="1024"> <tr bgcolor="#58FAF4"> <th>Brand</th> <th>Name</th> </tr> <xsl:for-each select="child::*/child::*"> <tr> <td><xsl:value-of select="@brand" /></td> <td><xsl:value-of select="@name" /></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>
XSLT 2
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/components"> <html> <head> <h1>Added CPU coolers:</h1> </head> <body> <table border="1" cellpadding ="0" cellspacing="0" width="1024"> <tr bgcolor="#58FAF4"> <th>Brand</th> <th>Name</th> </tr> <xsl:for-each select="cpucoolers/cpucooler"> <tr> <td><xsl:value-of select="@brand" /></td> <td><xsl:value-of select="@name" /></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>
XML retsensioonid
XML failide retsensioon meeskonnale DevHelpVR, 27.03.2017: Talk:DevHelpVR
XML failide retsensioon meeskonnale Ninjas_in_pyjamas, 27.03.2017: Talk:Ninjas_in_pyjamas
Ülesanne 2: Veebirakendus
Analüüs
Mõisted
WIP
Rakenduse kirjeldus
Lühidalt:
Meil on lauaarvutite komplekteerimise infosüsteem. Meie klientideks on inimesed kes kaaluvad lauaarvuti ostmist ja kes soovivad enne lauaarvuti või selle komponentide ostmist enda jaoks kogu protseduuri põhjalikult läbi mõelda. Süsteem võimaldab klientidel luua virtuaalse lauaarvuti ja tuvastab mitteühilduvad komponendid ning aitab seega vältida erinevaid probleeme, millega kaasneks aja- ja rahakulu.
Nüansid:
Kliendid saavad ennast meie süsteemis registreerida kasutajateks. Üks füüsiline isik võib teha endale teha ükskõik kui palju kasutajaid, meil ei pea olema päriselt olemasoleva isiku ja süsteemi kasutaja vahel üks-ühest seost. Rakenduse kasutamiseks ei ole kohustuslik serveris konto loomine, klient saab virtuaalse arvuti luua ilma kasutajakontota, aga see ei säilu pärast sessiooni lõppemist. Iga kasutaja võib luua uue virtuaalse lauaarvuti, sellele nimetuse panna ja see seotakse automaatselt tema kasutajakontoga. Igale virtuaalsele arvutile võib lisada komponente. Lauaarvuti põhilisteks komponentideks on keskseade/protsessor (CPU), protsessori jahuti, emaplaat, muutmälu, graafikaseade (GPU), toiteblokk, arvuti korpus ja püsimälu. Iga protsessori generatsioon on ühilduv ainult kindlate emaplaadi kiipseadmete komplektidega (chipset) ja tüüpiliselt on emaplaadi protsessori pesa (socket) see, millest lähtuda emaplaadi ja protsessori ühilduvuse kindlaks tegemisel. Protsessori pesaga ühilduvus on peamine parameeter ka protsessori jahuti valikul, aga kui emaplaadil on ainult ühte tüüpi pesa ja protsessor sobib ainult ühte kindlasse pessa, siis jahutid on üldjuhul sobivad mitmete erinevate pesadega. Samuti ühilduvad iga protsessor ja emaplaat ainult spetsiifiliste muutmälu generatsioonidega. Emaplaadid toetavad muutmälu kindla taktsageduseni, kiirema taktsagedusega mälukiipe saab siiski kasutada, need töötavad lihtsalt emaplaadi poolt lubatud maksimaalse taktsagedusega, mitte muutmälu kiibi maksimaalse taktsagedusega. On olemas emaplaate, mis toetavat mitut protsessorit. Muutmälu võib olla lauaarvutis üks kiip, aga võib ka rohkem. Mitme kiibi korral peaks need olema identsed või identsete näitajatega. Osade protsessoritega on jahuti karbis kaasas, teistel ei ole. Tänapäeva lauaarvutite protsessorid ilma jahutita ei ole töövõimelised. Mõned protsessorid ja emaplaadid sisaldavad graafikaseadet. Diskreetne graafikaseade on üldjuhul võimekam protsessori või emaplaadiga kaasasolevast, seega on tavaline, et arvutile lisatakse diskreetne graafikaseade isegi kui sisene graafikaseade on juba olemas. Emaplaatidel, toiteblokkidel ja arvuti korpustel on mitmed suuruse standardid. Suured (ATX) emaplaadid ja toiteblokid ei mahu väikesesse (microATX) korpusesse. Mõned korpused toetavad väikest emaplaati, samas suurt toiteblokki ja teoreetiliselt on võimalik ka vastupidine olukord. Arvuti korpus toetab protsessori jahutust ainult kuni teatava jahuti kõrguseni ja diskreetse graafikaseadme puhul ainult teatud seadme pikkuseni. Mõned korpused sisaldavad toiteblokki. Erinevatel diskreetsetel graafikaseadmetel on erinevad nõuded toitele, osad saavad oma toite ainult emaplaadi liidese kaudu, teistel on vaja ühte või rohkemat kaablit toiteblokist. Graafikaseadmeid võib lauaarvutis olla mitmeid, ka mitu ühesugust. Toitebloki puhul peab toitebloki võimsus katma kõigi teiste komponentide vajaduse varuga ja diskreetse graafikaseadme korral peab toiteblokil olema selle toiteks piisavalt õigeid kaableid.
Üldine:
WIP
Klient:
WIP
Server
WIP
Andmebaasi skeem
Infomüra vähendamiseks on andmebaasiskeem realiseeritud selliselt, et tabelites on ainult võtmed. Skeemist välja jäetud atribuudid (graafikakaardi pikkus jne) ei ole olulised analüüsi seisukohast.
Ülesanne 3: Klientrakendus
(b)logi
- 27/03/2017: Tehtud retsensioonid meeskondadele DevHelpVR ja Ninjas_in_pyjamas
- 27/03/2017: XML ja XSD parandatud ja täiendatud vastavalt meeskonna JRT tagasisidele https://wiki.itcollege.ee/index.php/JRT#Retsensioon_JRT
- 20/03/2017: Loodud Wiki leht, jagatud ülesanded
- 20/03/2017: Projekti esimene osa valmis