Webbutvecklingsdagbok (Webbutveckling, 120 hp)

Permalänk

Kort & Snabb uppdatering ^5.6.5!

Jag ville bara snabbt meddela nu att JS-ramverkskrusen ("Fullstack-utveckling med ramverk") är nu officiellt färdig. Nu återstår bara Projektledningskursen där jag gladeligen upptäckte att det är max 15 sidor exklusive försättsblad och källor som gäller. Jag trodde tvärtom: färst 15 sidor plus försättsblad och källor.

Då gör det inget om det hela kanske landar på 10 sidor på sin höjd. Kursen i sig har varit väldigt "meh", även om projektledningsbiten i verkligheten såklart är mycket viktig: att arbeta i samma kodbas, i teams, med "inkompatibla människor", med mera.

I JS-ramverkskursen samarbetade jag med en annan person och det gick oerhört smidigt. Vi var supernoga med vad i vilken kodbas (vi hade två gemensamma repon) vi arbetade i så ingen kunde råka koda i samma fil i samma kodbas som då skulle kunna orsaka en onödigt svårfixad "merge conflict".

Så nu är det Projektledningskursens slutgiltiga individuella och betygsättande uppgift kvar att åtgärda.

Ja, just det:

Jag har nu registrerat mig på de två kommande kurserna där två "intressanta bekanta" gör en comeback!

På återseende - som vanligt, i framtiden!

Mvh,
WKL.

---------
✔️Kurs 1: (B) HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: (A) HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: (A) HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: (B) HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: (A) VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: (C) VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: (A) VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: (A) VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
🚧Kurs 9: (Slutuppgift Pågår) HT2023 IK060G Informatik GR (A), Projektledning
🚧Kurs 10: (Inväntar slutbetyg) HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk
🚧Kurs 11: (Inväntar kursstart) VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp
🚧Kurs 12: (Inväntar kursstart) VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk
Medlem
Skrivet av WebbkodsLärlingen:

I JS-ramverkskursen samarbetade jag med en annan person och det gick oerhört smidigt. Vi var supernoga med vad i vilken kodbas (vi hade två gemensamma repon) vi arbetade i så ingen kunde råka koda i samma fil i samma kodbas som då skulle kunna orsaka en onödigt svårfixad "merge conflict".

Nog för att merge conflicts kan vara jobbigt (eller ja, det mesta med git när du får ett problem är väl rätt jobbigt egentligen.. håll tungan rätt i munnen och testa inte första (vad du tror är bästa) resultatet på google utan att vara säker på vad som sker..) så är det också väldigt bra att vänja sig med det och bli bekväm i hur du löser konflikterna. Att säga "den här filen är låst och bara jag får använda den tills jag är klar" är väldigt förlegat (checka ut/in filer) och hör inte direkt hemma i "vanlig"(*) utveckling längre.

Visual Studio, VS Code, Rider m.fl. har även de riktigt bra stöd för git och konflikthantering så du ska kunna arbeta så smidigt som möjligt.

Varje gång du börjar på en ny "feature", "fix" eller egentligen vad som helst, så bör du alltid skapa en ny branch baserat på main-branchen, t.ex. feature/fix_bug_394388. Då kan du jobba helt fritt i din egna branch medan dina teammedlemmar jobbar i sina respektive feature-branches. Ingen jobbar direkt mot main/master, utan main uppdateras genom Pull Request där du gör en begäran om att få plocka in (merge) din feature-branch mot main-branchen. Det är först här du märker om du behöver hantera någon konflikt, vilket då är på hela din lösning istället för enskilda commits.

(*) inom spelutveckling är det däremot högst aktuellt även idag, då du i regel jobbar med "assets" eller "objekt" som kan bestå av lite allt möjligt.. en konflikt där är inte alls lika rolig att hantera som i en enkel kodfil där du bara jämför rader..

Är du vass på git så har du en enorm fördel när det kommer till jobb sen

Visa signatur

NZXT H510 Flow MSI B450 Tomahawk MAX
AMD Ryzen 5800X3D RX 7900XTX Kingston Fury 64GB

Permalänk

Kort & Snabb uppdatering ^5.7.7!

Kortfattad och gladeligen kan jag meddela att jag är färdig nu med Projektledningskursen i och med inlämningen av den individuella rapporten. Däremot är jag inte särskilt stolt över den. Inte för att jag har "ordbajsat" i den utan snarare för att jag inte riktigt förstår vad jag skrivit och analyserat.

För en projektledare låter mycket uppenbart och självklart men för mig så låter det faktiskt lite för abstrakt för att jag saknar faktisk praktisk erfarenhet med traditionell och agil projektledning. Projektgrupparbetet gav viss verklig erfarenhet men inte riktigt för att förstå alla begrepp och processer inom projektledning på riktigt.

Således känns det både skönt och lite smått pinsamt att äntligen bli färdig med den. Förfallodatum nu på söndag, sedan redan nästa vecka på tisdag börjar de två nya kurserna skarpt (kurs11 & kurs12 nedan). De två före detta "intressanta bekanta" gör comeback och sedan blir det som det blir!

Nu får jag åtminstone koppla av ett par dag tills dess. Jag har haft möjlighet att lira nya Super Mario Wonder, vilket är exakt vad det sista ordet antyder: helt underbart!

På återseende - som vanligt, i framtiden!

Mvh,
WKL.

---------
✔️Kurs 1: (B) HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: (A) HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: (A) HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: (B) HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: (A) VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: (C) VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: (A) VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: (A) VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
🚧Kurs 9: (Inväntar slutbetyg) HT2023 IK060G Informatik GR (A), Projektledning
🚧Kurs 10: (Inväntar slutbetyg) HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk
🚧Kurs 11: (Inväntar kursstart) VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp
🚧Kurs 12: (Inväntar kursstart) VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk

Mustig Uppdatering ^6.9.0 = NICE

"Detta kan inte vara sant?!", var min reaktion när jag såg slutbetyget i projektledningskursen. Det måste ha blivit något fel? Eller så kan det vara som så att vikarierande lärare inte orkar hålla på så mycket. Jag är dessutom stolt för en gångs skull på min förmåga till en snabbfungerande "100 % CRUD" i NodeJS Express vilket är från kursen "Javascriptbaserad webbutveckling". Det är en mustig uppdatering med det NICE-aktiga versionsnumret ^6.9.0, så ingen tid att förlora!

"Jag trodde inte mina ögon först!"
Först och främst så väntade jag mig inget annat än toppbetyg i kursen om Fullstack-utveckling med ramverk även om jag var redo på att det kunde ha sänkts på grund av katastrofalt strukturerad Projektrapport. Samarbetspartnern och jag skrev på helt olika sätt för att presentera och det hela var i stil med först en väggtext följt av ett tio sidor långt bildspel i resultatdelen där allt skulle visas hur det såg ut i praktiken.

När jag såg betyget så trodde jag för att det var betyget från Projektledningskursen och tänkte att någonting inte riktigt stämde. Sedan såg jag att det var JS-ramverkskursen (är vad jag också kallar Fullstacks-utvecklingskursen för) och då såg det hela mer "normalt" ut enligt mig om jag får höja upp näsan mot taket och tittar nedåt mot skärmen medan jag skriver det här.

Vad som chockerade mina ögon var när jag fick Projektledningskursens slutbetyg. Då utbrast jag ett högt "VA!?" för jag kunde inte tro mina ögon. Det var som om det måste ha varit något fel, någon felbedömning från lärarens sida? Det fanns ett bifogat dokument att kika i vilket jag gjorde och där stod det för det mesta bara "Bra" eller "Bra och utförlig" för de olika delarna i rapporten.

Rapporten skrevs på cirka ~10 timmar i samma veva som jag hade vänt på dygnet och jag vara nära då att först vänta en dag innan jag skrev färdigt Reflektion/Analys- och Diskussionsdelarna men jag beslöt mig för att kötta färdigt de två sista delarna hur tråkigt det än var och hur än "sunt förnuft" agil projektledning känns enligt min egen livsåskådning.

Detta tyckte tydligen den vikarierande läraren var bra diskussion så jag klagar inte. Är bara riktigt förvånad och delvis positivt chockerad över slutresultatet. Jag siktade på främst E (godkänt) och kanske C som bästa men jag tyckte att det var svårt att koppla på något "Meningsfullt" sätt mellan empirin/intervjun och teoridelen som fanns för det hela kändes så mycket som upprepningar och rena floskler/självklarheter inom projektledning.

Min åsikt i hela kursen var i princip:"Traditionell projektledning känns förlegat medan agil projektledning känns som sunt förnuft".

Jag är oerhört stolt över denna 100 % CRUD
Vad är inte ljuvligare än 100 % CRUD i både ett REST API och dess konsumerande webbklient? Varför jag är så stolt denna gång är att jag har skämtat om i den virtuella klassen att "U" i CRUD står för "Usch, varför är det så krånligt att uppdatera?"

I majoriteten av tidigare lösningar så har jag gjort så att någonting ändras (nya fält & knappar) eller att en förs till en helt ny sida (som i fallet med PHP-kurserna). Nu implementerade jag för allra första gången

contentEditable=true

i kombination med data-attributet som lagrar de tidigare värdena vilket alltid skrivs ut när kurserna hämtas med GET. För ett år sedan ville jag kunna göra något liknande men saknade kunskaperna och "steglösningstänkandet" i problemlösningsförmågorna. Nu gick det äntligen utan några större problem och det gick som jag föreställde mig!

Det som sker då är att du kan skriva i de olika fälten som har contentEditable satt till true och när du lämnar fokuset så används händelselyssnaren "focusout" för att anmärka på att du lämnat/bytt fokus från ett td-element som också är contentEditable (exempelvis kan du inte ändra rubrikraderna vilket är om jag får låna från projektledningskursen:"sunt förnuft").

När den upptäcker att du lämnat fokus så hämtar den hela raden och radera-knappen längst till höger innehåller rätt id för raden vilket skickas med i PUT som då skickas till REST API:t. Om REST API:t nekar efter sin kontroll så kommer data-attributet som innehåller det gamla/tidigare värdet att ersätta textContent i respektive fält samtidigt som felmeddelande visas ovanför formuläret för att lägga till nytt.

Om REST API:t däremot godkänner så hämtas hela tabellen om eftersom nu har det lagrats på serversidan som då uppdaterat "databasen" vilket i detta moment är bara en JSON-fil vars JSON:ierade data skickas vid giltigt CRUD-anrop.

Det hela fungerar mycket smidigt och som väntat. När en rad raderas via "Hantera"-knapparna vilket är en papperskorg för varje rad så slängs den bort och tabellen hämta som på nytt. All denna 100 % CRUD går också att göra direkt i Thunderclient mot REST API:t och där kontrollerar den också så att du inte kan försöka ändra/radera/läsa in något som inte finns. "Sunt förnuft" återigen!

Lite kortfattat om lösningarna i Laravel & Vue.js
Jag har inte berättat något om lösningarna i Laravel- & Vue.js-kursen där jag samarbetade med en annan i klassen. Det hela handlade om ett intranät med lagerhantering av datorprodukter där datorkomponenter kan laddas upp/läggas till inklusive bildspel för dem. Även nyheter kan läggas till.

Men det läraren blev mest "imponerad" av förutom bilduppladdningslösningen (bilderna läggs upp både som lokala bildobjekt så de syns direkt i webbläsaren och du kan klicka bort dem intuitivt) var kontohanteringslösningen vilket använder sig av faktumet att varje användare har ett fält som heter "accessto" i MySQL-databasens tabell users vilket tillhandahålls av Laravel som standard.

Detta fält är en sträng som delar åtkomsthandlingar (lägga till produkter, visa produkter, radera produkter, uppdatera produkter, samma CRUD för bilder, lägga till nyheter & radera nyheter) med |-tecknet. Denna kan då "explodera" i Laravel för att sedan returnera sant eller falskt till ett API som skickas via endpoint "/api/canaccess/{vad}/".

Om du då skickar "api/canaccess/canaddimages" så skickas ju även användarens uppgifter med så Laravel kan då kolla i "access"-kolumnen för användaren, explodera strängen och sedan om "canaddimages" finns med i den exploderade arrayen eller inte. Returna sant eller falskt. Sedan på Vue.js-frontendsidan så sätts "allowedX", "allowedY" etc. till sant eller falskt vilket i sin tur används av direktiven "v-show" och "v-if" beroende på vad de har rätt att se. Och ja, även i Laravel så kontrolleras "accessto" om du skulle försöka göra CRUD-anrop direkt via REST API och inte via användargränssnittet.

Återigen: SUNT. FÖRNUFT!

Signal, Runes, Meteor Tracker - försöker de återuppfinna Observer-mönstret?
Något annat jag "smuttat" på till och från när jag inte "kodpluggat" är det här med reaktivitet då det är vad jag introducerades för på riktigt i samband med Vue.js och nu snart kommande React i Javaskript-kursen där ett frontend-ramverk ska väljas.

I och med hela konceptet reaktivitet så har det fört mig till saker som Signal (primärt från SolidJS tror jag), Runes (från Svelte) och så läste jag i något YT-kommentar om att redan 2011-2012 så hade Meteor-ramverket kommit med Observer-mönstrade Tracker vilket "moderna" frontend-ramverk idag verkar försöka återuppfinna som om de var först?

Jag minns jag läste någon annan YT-kommentar i annat sammanhang att React som nu försöker komma med SSR-stöd vill framstå som om PHP aldrig hade kommit på den tanken när det först kom 1995! Så försöker nu Runes i Svelte och Signal implementerat i Preact framstå som om detta är revolutionerande?

Om kommentarerna på YT stämmer så ska Vue.js ha haft denna form av reaktivitet sedan länge tillbaka. Och jag vill så klart lära mig detta genom att implementera Observer-mönster som håller koll på vilka värden som ska kollas och koll på vilka funktioner som ska köras när observerade värden ändras och så vidare.

Till sist vill jag göra den förbjudna regeln inom JavaScript: skapa ett eget JS-ramverk! Fast egentligen är det bara för att underlätta min egen utveckling och få bort det här med "prop drilling" vilket React inte verkar komma undan om inte Preact används. Sistnämnda vet jag inte ens om det är tillåtet att få använda till Projektuppgiften i JS-kursen där React kan väljas som frontend-ramverk. Får kolla med den ansvariga läraren.

Ett spännande sidoprojekt och/eller spikat Självständigt arbetesplats???
Idag fick jag även kontakt med någon om kommande C# .NET projekt där jag kanske kan få in foten på något sätt och/eller kanske till och med en spikad självständig arbetsplats? Hm. Det återstå att se och jag lägger inte alla ägg i en och samma korg utan "sprider ut riskerna".

Det finns ett till företag jag skulle kunna kontakta för att få ut fler krokar än att förlita mig på dessa två nuvarande som jag håller kontakt med. Vissa i den virtuella klassen har inte ens börjat kika efter Självständigt arbetsplats!

YouTube slår ned på mina Adblockers på fler datorer
Jag har meddelat i diverse nyhetskommentarsfält att min dator i sovrummet har fått blockerat av YT när adblockers är påslaget och detta har nu även inträffat vid arbetsdatorn. Den enda datorn som inte är drabbad (ännu) är HTPC:n där jag inte får något varningsmeddelande eller påminnelse om att jag använder adblockers när jag klart och tydligt gör det. Enda skillnaden är att ikonerna syns inte för jag har bränt sönder OLED-TV:n för mycket!

Nu blir det bara en tidsfråga och det är lite störande att jag inte kan köpa årsprenumeration för YT Premium utan det måste vara månadsvis. Troligen för att de ska kunna "chockhöja" helt plötsligt? Jag märker att det är riktigt störande att plötsligt få reklam i YT då jag inte har haft det säkert på över ett decennium fram tills nu.

Nåja, det blir vad det blir av det. En fördel i sovrummet är då att jag ägnar mindre tid å YT innan jag ska sova! Så något positivt har det plötsliga och numera oundvikliga reklamtvånget åstadkommit!

På återseende - som vanligt, i framtiden!

Mvh,
WKL.

---------
✔️Kurs 1: (B) HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: (A) HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: (A) HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: (B) HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: (A) VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: (C) VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: (A) VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: (A) VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: (A) HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: (A) HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
🚧Kurs 11: (Pågår) VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
🚧Kurs 12: (Pågår) VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk

Mini-Commit! ^6.9.3

Idag har jag en mindre uppdatering att rapportera.

Hej världen, detta är C# .NET!
(Ja, jag är medveten om att jag lagt till boilerplate-kod som kunde skippas sedan .NET 6 men jag vill veta hur det ser ut så jag inte får en chock första gången jag ser det i någon äldre kodbas! )

Nedan är ett par bilder inuti C# där jag gjort en simpel första app (Moment 2 i kursen) som nyttjar Zellers algoritm för att visa veckodag utifrån givet datum i formatet ÅÅÅÅ-MM-DD (framgår med variabeln correctDatePattern:

Lösningen är relativt simpel förutom att jag inte förstår mig på alls den faktiska matematiska formeln och hur den fungerar. Jag förstår mig inte på den mer än att jag måste ta fram århundrade, årtal, dag och månad där den räknar från 3 upp till 14 bland månaderna. Veckodagarna börjar sedan från 0-6 i en sträng-array med lördag som första dag.

Sedan sker programmets primära logik inuti while-loopen som bara kollar om du skrivit "avsluta" för att då avsluta programmet. Vad som följer sedan är en rad olika if-satser om du har angett korrekt formaterat datum.

Avslutningsvis så kommer alla variabler för sekel, år, månad, dag samt den magiska matematiska formeln:

Som det framgår i kommentarerna så provade jag även en annan variant men den fungerade ej som trott. Programmet kan skriva ut rätt veckodagar för åtminstone när jag är född (1989) och ett par år uppåt och nedåt. Men sedan börjar det bli "slumpartat" huruvida det blir rätt eller fel veckodag vid utskrift. Jag hänvisar även till webbplatsen som jag använt för att "kontrollera" att veckodagarna stämmer för jag har ingen aning själv!

Kommande Moment 3 & Moment 4 i C# .NET-kursen
Och det hela med den matematiska formeln beror på att jag inte riktigt förstår mig på formeln. Uppgiften i sig handlar inte om att nyttja algoritmer i C# utan att bara lära sig grunderna i språket likt du hade gjort med JS, PHP, etc. Det blir möjligen "värre" i Moment 4 när vi då ska hoppa in och lära oss grunderna i Machine Learning med hjälp av C# .NET och då ta fram ett program som kan säga om en recension/ett omdöme är positivt eller negativt.

Låter ju nästan lite överkurs bara för en introduktionskurs i C# .NET, eller? 🤔

Moment 3 blir mer chill för då är det en gästdagbok som nyttjar lokal JSON-fil (likt Moment 2 i NodeJS Express-kursen som går parallellt med denna). Då får jag nyttja liknande while loop-logik fast med ett par klasser nu: en klass som visar gästdagbok, en klass som postar nytt inlägg, och en klass som visar författarna.

Här kommer då också något fenomen som jag har 0 koll på vilket kallas för "marshalling" vilket självklart handlar om: "Marshalling is the process of transforming types when they need to cross between managed and native code." (för mig säger detta ingenting för jag vet inte vad som syftas på med "native code" i sammanhanget!?)

"Hur mår koden? Koden mår inge bra, koden är jätte-broken!"
Detta tar mig tillbaka till min petiga poäng om att nu närmar vi oss "riktig programmering" där vi måste börja förstå oss på nästan minnesallokering, minneshantering, med mera medan mer "högnivåspråk" på ett nästan bortskämt vis sköter sådant åt oss.

Och då fattar jag fortfarande inte hur "JS-motorn" fungerar när den ska tolka/JIT-kompilera min JS-kod i realtid eller hur "Execution plans" ser ut för MySQL eller nu kommande NoSQL-databasvarianten MongoDB! Sen så kanske det inte heller är nödvändigt utan det hela kanske är lite mer "need-to-know-basis"-stuk?

Hursomhelst så är det mycket roligare nu att koda/programmera än det var för drygt ett år sedan när det hela begav sig och jag förstod inte ens varför mitt skapade HTML-element via document.AppendChild('p') inte gick att se i min HTML-fil. Prova att inkludera document.CreateElement('p') i document.AppendChild() denna gång!

Trevlig helg & På återseende - som vanligt, i framtiden!

Mvh,
WKL.

---------
✔️Kurs 1: (B) HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: (A) HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: (A) HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: (B) HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: (A) VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: (C) VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: (A) VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: (A) VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: (A) HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: (A) HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
🚧Kurs 11: (Pågår) VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
🚧Kurs 12: (Pågår) VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk

Mega-Commit 7.6.9 | Mycket på kort tid!

Det har hänt väldigt mycket på kort tid nu i Webbutvecklingsprogrammet sista läsår 2! Först vill jag klargöra att detta skrivs inte som ett sätt att paradera på andras bekostnad då jag är fullt medveten om att andra har det mycket tuffare med studierna just nu än jag. "Stolthetssyftet" är endast utifrån min egen nuvarande livssituation. Och nej, det är inte så att någon privat har "konfronterat" mig i mina studier utan jag klargör bara vilken delvis "tur" jag har haft med mina egna studier.

Jag har studerar som tidigare skrivet för närvarande två parallella kurser: Programmering i C# .NET introduktionskurs och Javascriptbaserad utveckling. Båda kurserna har hittills haft väldigt lättsamma moment utifrån min egen studiesituation. Därför kommer jag att beta av dessa nu i alla moment som jag är färdiga med förutom Moment 4 i JS Utveckling som jag kommer att bli färdig med imorgon någon gång innan lunchtid.

C# .NET - Moment 1
Detta moment var mycket simpelt då det bara handlade om att installera och få igång utvecklingsmiljön i C#. I princip bara installera Visual Studio 2022 och sedan få ut ett enkelt "Hello World!"-program sparad i en "Program.cs"-fil. Jag skrev även så att inmatning från användaren kunde skrivas och sedan skrev den ut det varpå efter programmet avslutades.

Vad som blir riktigt spännande i C# .NET är att få till en CRUD-baserad WPF-applikation. Mer om det längre ned i rubriken om slutprojekten. Lärarna har samtidigt klargjort att de endast kommmer att beröra/lära ut (i den utsträckning det går att använda de orden) C# .NET Konsolapplikationer, dvs., klassiska "DOS"-fönstret. Ja, jag växte upp på den tiden då DOS-spel också fanns!

JS Utveckling - Moment 1
Första momentet i JS Utveckling (i princip NodeJS med MongoDB) var också enkel då det var endast att ändra lite CSS-kod för en färdig statisk webbplats som även läste in JSON från en lokal JSON-fil där jag sedan fick ändra lite för att visa återstående kurser kvar.

Sedan skulle momentet laddas upp någonstans inklusive JSON-filen och så användes inbyggd gammal Angular-kod inuti HTML-filen som då matade ut kurserna och även tillät sortering av kurserna utifrån inmatning från användaren. Allt kring Angular var redan färdigt i de erhållna uppgiftsfilerna - alltså inget vi gjorde.

C# .NET - Moment 2
Nästa moment 2 i C# .NET introduktionskursen var att komma igång med grunderna i programmeringsspråket C#, främst syntaxen och hur klassisk programmering sker inuti C# jämfört med tidigare språk. C# är som insatta känner till starkt typat så om du inte använder "var" för att deklarera variabler så måste du istället ange datatyp. Detta är något jag har haft problem med i TypeScript när jag försökte mig på där då det också är starkt typad version av JavaScript för "bättre kod"(?)

Hursomhelst så var det inga problem med detta moment 2 förutom att vi skulle använda oss av Zeller's algoritm för att ta reda på veckodagsnamn (mån-sön) för valt datum. Tanken var att kunna få mata in ett datum i formatet ÅÅÅÅ-MM-DD eller ÅÅÅÅMMDD (valfritt) så skulle den först kontrollera att du angett giltigt datum (exempelvis 30:e feburari går aldrig medan 29:e februari går i vissa fall - men denna skottårsdel var ej krav att lyckas implementera i felhanteringsdelen i koden) och sedan matade den ut rätt veckodag om allt var OK.

Min lösning var att läsa in strängen i en "var" och sedan kolla om den matchade ett Regex-mönster som kräver "DDDD-DD-DD", dvs:

"@"^\d{4}-\d{2}-\d{2}$";

och sedan splittade jag strängen på "-" och kontrollerade därefter månads- och dagsnummer så att det var giltigt valt antal av vilken månad och dag som valts. Vissa månader har ju 30, 31 dagar och så har vi unika fallet med februari där vi utgick från att det alltid har 28 dagar som högst.

Jag gjorde kanske misstaget att jag hade väldigt många if-satser för att kontrollera rätt antal dagar per månad när jag fick återkoppling - dock godkänt - om att använda en int[]-array med antalet dagar för varje månad som då månadsvärdet kunde använda sig av för att kontrollera om det är rätt array-elementsvärde för den valda månaden, annars neka istället för 12 separata if-satser. Pinsamt att jag inte kom på det då jag har en array för alla veckodagar som nyttjar sådan lösning.

Vad som var smått frustrerande med detta moment var att vi skulle använda oss av en färdig formel, Zeller's algoritm, vilket i sin tur förekommer i två varianter. Jag förstår mig på ingen av dessa varianter och även om jag kan följa matematiska prioriteringsregler så vet jag inte vad den egentligen gör. Som tur var fanns det en webbplats där du kunde välja datum ur en kalender och få veckodag så jag kunde jämföra om min lösning gav samma veckodag vilket den gjorde för de flesta fall men inte vissa vilket möjligen berodde något på skottårs-tjofset.

JS Utveckling - Moment 2
Moment 2 i NodeJS-kursen var faktiskt rolig om än enkel då det hela handlade om en CRUD fast endast krav på R och D men jag gjorde alla fyra vilket jag är glad över att jag gjorde då det påskyndade Moment 3 då det blev krav på det fast då med hjälp av anslutning till en lokal MongoDB-databas.

Återigen skulle vi använda JSON-data som lästes från en NodeJS server (med hjälp av ExpressJS) som sedan READ- & DELETE:ade data utifrån givna endpoints:

- visa alla kurser i årskursen (GET - http://localhost:3000/courses) - visa enskild kurs i årskursen med angivet id (verb GET - http://localhost:3000/courses/2) - radera en enskild kurs från listan med angivet id (verb DELETE - http://localhost:3000/courses/2)

Jag gjorde som sagt även POST- och PUT-bitarna vilket blev enklare än jag trodde senare att anpassa för CRUD-anrop mot lokal MongoDB-databas även att först läsa in JSON-fil och sedan ändra i inläst variabel för att sedan skriva över hela JSON-filen på nytt.

I NodeJS ExpressJS använde jag router-objektet för att förenkla hanteringen av CRUD-anropen mot REST API:t inklusive implementeringen av en "catch-all" när en given endpoint inte fanns. Vedertagen felhantering implementerades också.

C# .NET - Moment 3
Moment 3 i C# .NET introduktionskursen var objektorienteringen i C# där vi skulle ta fram en simpel gästbok i konsolapplikationsanvändargränssnittet där du kunde välja mellan 1 - Skriv inlägg och 2 - Radera inlägg eller "x" för att avsluta programmet. Här skulle då en klass skapas för att hantera möjliga CRUD-anrop mot gästboksklassen.

Här gjorde jag möjligen en tabbe men troligen ändå godkänt vilket var att jag inkluderade all Console.WriteLine() inuti klassen istället för att hålla det utanför och endast hantera simpel logik inuti klassen och dess klassmedlemmar. Min lösning är mer "hårdkodad" än att du bara har en simpel klass som kontrollerar inmatning och sedan lägger in i en JSON-fil om allt är OK annars ska den ge false och så får false-svaret från klassanropet i sig leda till felhantering inuti Main()-funktionen. Som vanligt kom jag på detta i efterhand men inte orkade ändra men tar med mig det tills nästa uppgifter.

Jag gjorde nödvändiga kontroller inklusive en rolig lösning i att när den läste in all gästinlägg lagrade i en JSON-fil så kontrollerade den om det fanns några inlägg och fanns inga gästinlägg först eller för att alla var borttagna så fanns inte heller menyalternativet "2 - Radera inlägg" och siffran två nekades även då som försök att navigera dit vid inmatning.

Övriga vedertagna fehanteringar implementerades som att bara acceptera siffror i huvudmenyn och vid borttagning av inlägg då dessa är indexerade med siffror. Denna är jag 100 % säker på att jag får godkänt men troligen får jag kommentar om att jag hårdkodat för mycket i gästboksklassen och kunde ha nöjt mig med att bara (miss)lyckas att lägga in och/eller radera inlägg och sedan sköta visning av felhanteringstext i Main().

JS Utveckling - Moment 3
Moment 3 i JS utveckling trodde jag först skulle vara jobbigare för att nu skulle vi plötsligt gå ifrån något vi varit mycket bekväma med: JSON, och över till någonting helt annat än JSON och MySQL, nämligen MongoDB. Här dök ett problem upp fort vilket var att det som gör dokumentobjekt unika i MongoDB är ObjectID vilket i sig inte är något du vill skriva in i dina REST API-endpoints.

Du vill fortsätta använda numeriskt {id} så jag la till nytt fält "id" i varje dokumentobjekt även om det kanske är fel när du arbetar med MongoDB - jag har ingen aning. Men den lösningen gjorde att det blev supersimpelt att ändra all CRUD inuti NodeJS ExpressJS. Bara ansluta till MongoDB-klienten och sedan skriva en simpel "query"-liknande operation för MongoDB-databasen ifråga och så var det färdigt!

Här uppgraderade jag även frontend-biten även fast det är noll krav och gjorde det möjligt att kunna ändra genom att bara skriva i fälten för kurskod, kursnamn och period. Detta gjorde jag också i moment 2 men jag tog det extra steget och kontrollerade om värdet som ändrades inte redan fanns sparat i ett data-attribut i tabellcellen. Om värdena var annorlunda så skickades ett PUT-anrop annars ignorerades det. Så då kan du klicka på olika tabellceller men gör du ingen ändring så sker ingen PUT så där snackar vi prestandaoptimering om än i liten skala!

C# .NET - Moment 4
Moment 4 i C# .NET introduktionskursen - och jag upprepar att det är en introduktion till språket och egentligen är det noll .NET i det hela förutom kanske detta omment då - så gällde det att använda ett kodexempel från Machine Learning som finns i .NET 7 där vi skulle ta fram en simpel Konsolapplikation där du matar in ett omdöme om en matrestaurang på engelska.

Sedan skulle den kontrollera mot en färdigtränad ML-modell som i sin tur består av 1000 Yelp-recensioner i första kolumnen medan andra kolumnen har 1 = positiv recension eller 0 = negativ recension. Detta returvärde (1 eller 0) användes sedan i lösningen för att veta om den skulle skriva ut huruvida ett inmatat omdöme på engelska ansångs vara positivt eller negativt.

Jag tränade min modell i 120 sekunder men den insisterade på att vara färdig efter redan 106 sekunder. Resultatet är ändå riktigt dåligt tycker jag, men det fungerar och så länge du använder typiska positiva ord så får du oftast 1 medan negativa ord ger 0 så all träningsdata från kodexemplet från Microsofts officiella webbplats är riktigt axelryckande.

Konceptet i sig är dock coolt: köra ML-träning direkt i ens egen dator med träningsdata och sedan försöka nyttja en färdigkodad (efter den körda 120-sekunders träningen, inget jag själv skrev) ML-modell. Det vore såklart intressant att se vad för annan slags ML-modell som skulle gå att ta fram med egen träningsdata.

Ett videoklipp skulle också spelas in där det redovisades och det berättades om vad de olika delarna i koden gjorde. Jag förstod inte mer av ML-koden mer än att en instans av den verkade skapas där den sedan ville att en skulle välja i vilken kolumn ens inmatning skulle föras in i och sedan försökte den förutse utifrån all tillgänglig träningsdata inklusive det en själv matat med huruvida omdömet var positivt eller negativt.

JS Utveckling - Moment 4
Moment 4 i JS Utveckling är jag snart färdig med. Den handlar enbart om att jämföra tre stora frontend-ramverk: Angular, Vue.js och ReactJS varav sistnämnda också ska inkludera ett simpelt kodexempel som sedan förklaras i detalj. Jag tänker mig klassiska useState för en räknare och sedan hur useEffect också kan användas i samband med detta såväl som hur de skiljer sig åt.

Imorgon ska jag även diskutera ReactJS med en klasskamrat då slutuppgiften i denna JS utveckling-kurs låter oss välja en av de tre stora frontend-ramverken för att utveckla en CRUD-fullstacksapp som nyttjar NodeJS ExpressJS och MongoDB i grunden. Jag ska äntligen bli en av de många CodeTubers som berättar/visar hur en MERN-app webbutvecklas i praktiken!

Lämpliga slutuppgifter för kurserna?
Den stora frågan är dock vad för slags CRUD-appar jag bör utveckla i JS utveckling-kursen såväl som i C# .NET. Som tidigare sagt så är jag sugen på WPF-utveckling i C# .NET då vad jag sett så påminner XAML-delen mig om HTML som haft trekant med CSS och JavaScript. Vi har händelselyssnare som kan hanteras och möjligen går det också att implementera "global states"-liknande funktionalitet med.

En fördel vi har med WPF-appar - tror jag - är att när jag väljer att appen ska dölja något så går det inte att göra något magiskt med Inspect eller CLTR+F5 i WPF-appen. Ska väl vara om de kan dekompilera hela .exe-filen? En utmaning dock är detta: Hur ska jag CRUD:a inuti WPF-appen när jag inte har någon SSL aktiverad? Jag vill ju inte skicka "renskriven data" utan jag vill ju skicka krypterad data via någon SSL/TLS eller kanske krypterat och så finns det en dekrypteringsnyckel på backend-sidan? Men då kommer vi till frågan: blir det för mycket för något som ska vara klart 15:e januari 2023 senast? 🤔

Lärarna sa också som sagt innan att de fokuserar främst på Konsolappar i denna kurs och även om HttpClient-objektet fungerar även där så har jag ändå frågan om vad för CRUD-användbart som kan kodas i en simpel Terminal? Vad finns det för behov där som inte redan har lösts av andra? Alltså, vad för mer unikt och mervärde går att skapa på så kort tid även i en Konsolapp i C# .NET? 🤔

Så många funderar och så fort det har gått med dessa två parallella kurser. De började 1:a november 2023 och nu knappa 2 veckor senare har jag snart bara slutuppgifterna kvar för båda kurserna när de annars brukar vara tänkta att påbörjas två-tre veckor innan kursavslut.

Signaturen är äntligen här - men utan stöd för BB?
Ingen har frågat men nu har jag äntligen en signatur! Dessvärre är den inte som jag önskade då jag ville oavkortat rada upp varje status, slutbetyg och namn för varje kurs hittills. Endast fem rader tillåts dock som mest. Så då fick jag göra vad jag gjorde. Jag hittar dock inte hur jag ska lägga till ett simpelt länkelement? Är det url inuti hakparentes må tro?

Ja just det, "ex-jobbs-mingel" nu nästa vecka!
Nästa vecka är det ex-jobbsmingel vid universitetet där jag bor och då tänkte jag delta. Vad jag har lite svårt med är att myndigheter som vanligtvis söker ex-jobbsfolk tenderar att ha ensidiga arbetsuppgifter tänker jag mig. Sedan har jag full förståelse att få om ens något IT-bolag vill ha någon "n0_ob-c0d3R" vara inne och kladda på deras och/eller deras kunders kodbaser.

Sen har vi det här med karriärsmöjligheter inom myndigheter i och med den myndighetsmässiga anställningsformen. Hursomhelst så blir det nog ett mysigt ex-jobbsmingel och kanske jag kan få in foten hos någon mer lönsamhetsfokuserad verksamhet som också kanske har spännande kunder även om jag kanske inte får vara med så himla nära där.

Jag kan "100 % CRUD™" och nu med olika behörighetsnivåer sedan tack vare Vue.js+Laravel-kursen där jag och en samarbetskodare tog fram ett simpelt men helt fungerande(?) varulagersystem med olika behörighetsnivåer och kontohantering av en primär systemadministratör. Detta kan nu bara bli bättre härifrån! 😎

På återseende - som vanligt, i framtiden!

Mvh,
WKL.
---------
✔️Kurs 1: (B) HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: (A) HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: (A) HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: (B) HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: (A) VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: (C) VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: (A) VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: (A) VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: (A) HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: (A) HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
🚧Kurs 11: (Pågår) VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
🚧Kurs 12: (Pågår) VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk
Medlem
Skrivet av WebbkodsLärlingen:

Som tidigare sagt så är jag sugen på WPF-utveckling i C# .NET då vad jag sett så påminner XAML-delen mig om HTML som haft trekant med CSS och JavaScript. Vi har händelselyssnare som kan hanteras och möjligen går det också att implementera "global states"-liknande funktionalitet med.

En fördel vi har med WPF-appar - tror jag - är att när jag väljer att appen ska dölja något så går det inte att göra något magiskt med Inspect eller CLTR+F5 i WPF-appen. Ska väl vara om de kan dekompilera hela .exe-filen? En utmaning dock är detta: Hur ska jag CRUD:a inuti WPF-appen när jag inte har någon SSL aktiverad? Jag vill ju inte skicka "renskriven data" utan jag vill ju skicka krypterad data via någon SSL/TLS eller kanske krypterat och så finns det en dekrypteringsnyckel på backend-sidan? Men då kommer vi till frågan: blir det för mycket för något som ska vara klart 15:e januari 2023 senast? 🤔

MVVM, model-view-viewmodel. Undvik code behind, dvs att skriva kod i .xaml.cs-filerna. Det går till 97% (i en större applikation) och blir rätt smidigt till slut.

"Vyn" (XAML) kopplas deklarativt till vymodellen (egenspecificierad klass). Det ska i stort sett inte finnas någon kod i samband med inmatningen av ett visst fält, typ bara:

string Foo { get => _model.Foo; set { _model.Foo = value; RaisePropertyChanged() } }

där get/set i vymodellen anropas av ramverket, inte av din kod.

Även validering kopplas deklarativt, men där kan det naturligtvis finnas en valideringsklass (som ärver från lämplig basklass) och implementerar din egen återanvändbara affärslogik. Validering över flera fält samtidigt kan behöva göras i vymodellens setters. Dropdowns (ComboBox) är givetvis deklarativa och får sin data från vymodellen (och i sin tur kanske från modellen/servern).

Det går utmärkt att koppla ihop ett objektträd (träd av "vymodeller") som mappas ihop med ett träd av vyer. Vissa av vymodellernas properties kan vara listor av andra vymodeller.

"Modellen" är hur objektet persisteras, oftast till fil eller databas. I ditt fall kanske det är hur man skickar data över REST-anrop. HttpClient har TLS aktiverat, om du inte stänger av det.

Titta på ICommand/RelayCommand för hur man kopplar händelser i vyn (knapptryck mm) till vymodellen, där man kan ha kod för att till exempel anropa servern.

Om du inte har löst det problemet än: Användare A laddar objekt O från backend. Användare B laddar objekt O från backend. A sätter O.x = X. B sätter O.y = Y. A sparar. B sparar. Vad står det i databasen? Samma frågeställning, men båda användarna ändrar O.x.

Ovanstående problemställning är extremt vanlig och ställer till en jävla oreda om det inte löses "korrekt". För bonuspoäng (som behöver lösas i en professionell applikation): Båda användarna trycker på spara-knappen exakt samtidigt och båda requesten börjar hanteras av (den multitrådade) servern ungefär samtidigt.

Dekompilering kommer hända. Lev med det, användaren har full kontroll på .exe-filen och kan dekompilera, ändra och återkompilera. Säkerheten kan inte hänga på det. Användare A kan naturligtvis inte ändra på användare Bs privata data (men båda kan naturligtvis ändra på det gemensamma objektet O). Om användare A kan ändra på användare B:s .exe blir det dåligt... Datakvaliteten kan inte hänga på att klienten gör rätt.

Permalänk
Skrivet av KAD:

MVVM, model-view-viewmodel. Undvik code behind, dvs att skriva kod i .xaml.cs-filerna. Det går till 97% (i en större applikation) och blir rätt smidigt till slut.

"Vyn" (XAML) kopplas deklarativt till vymodellen (egenspecificierad klass). Det ska i stort sett inte finnas någon kod i samband med inmatningen av ett visst fält, typ bara:

string Foo { get => _model.Foo; set { _model.Foo = value; RaisePropertyChanged() } }

där get/set i vymodellen anropas av ramverket, inte av din kod.

Även validering kopplas deklarativt, men där kan det naturligtvis finnas en valideringsklass (som ärver från lämplig basklass) och implementerar din egen återanvändbara affärslogik. Validering över flera fält samtidigt kan behöva göras i vymodellens setters. Dropdowns (ComboBox) är givetvis deklarativa och får sin data från vymodellen (och i sin tur kanske från modellen/servern).

Det går utmärkt att koppla ihop ett objektträd (träd av "vymodeller") som mappas ihop med ett träd av vyer. Vissa av vymodellernas properties kan vara listor av andra vymodeller.

"Modellen" är hur objektet persisteras, oftast till fil eller databas. I ditt fall kanske det är hur man skickar data över REST-anrop. HttpClient har TLS aktiverat, om du inte stänger av det.

Titta på ICommand/RelayCommand för hur man kopplar händelser i vyn (knapptryck mm) till vymodellen, där man kan ha kod för att till exempel anropa servern.

Om du inte har löst det problemet än: Användare A laddar objekt O från backend. Användare B laddar objekt O från backend. A sätter O.x = X. B sätter O.y = Y. A sparar. B sparar. Vad står det i databasen? Samma frågeställning, men båda användarna ändrar O.x.

Ovanstående problemställning är extremt vanlig och ställer till en jävla oreda om det inte löses "korrekt". För bonuspoäng (som behöver lösas i en professionell applikation): Båda användarna trycker på spara-knappen exakt samtidigt och båda requesten börjar hanteras av (den multitrådade) servern ungefär samtidigt.

Dekompilering kommer hända. Lev med det, användaren har full kontroll på .exe-filen och kan dekompilera, ändra och återkompilera. Säkerheten kan inte hänga på det. Användare A kan naturligtvis inte ändra på användare Bs privata data (men båda kan naturligtvis ändra på det gemensamma objektet O). Om användare A kan ändra på användare B:s .exe blir det dåligt... Datakvaliteten kan inte hänga på att klienten gör rätt.

Tack för det oerhörda JULMUSTIGA svaret!

Jag håller på att kolla på en kort och snabb YT-serie om just WPF. Även den kommer att snart komma in på MVVM. Det jag inte förstår är tanken med att ha Model-View och även View-Model direkt efter? Är View-Model det som ersätter vad som annars skulle vara Controller i klassiska MVC?

Vad gäller backend-biten så får du gärna ge mig en ledtråd i vad för dokumentation jag ska kika på när det gäller att lösa databasbitarna i backend. När jag frågade chatGPT3.5 vad det kan handla som så nämner den något om "Optimistic och Pessimistic Concurrency Control" där ett versionsvärde tycks användas för att kontrollera om det är rätt version av ett givet fält innan någon CRUD tillåts från/på den. Kan det vara något åt det hållet eller är det någon helt annan teknisk lösning som du syftar på?

När jag skrivit lite mer nu med chatGPT3.5 så verkar det handla något om att inkludera version-värde för alla fetchade data. Sedan när jag ändrar data (PUT, DELETE) så skickas även det senaste fetchade version-värdet med för hypotetiskt skulle någon annan ha hunnit ändrat det jag ändrat på och då har de inkrementerat version-värdet före mig och då har vi en konflikt i databasen där då min begäran bör nekas och jag bör få meddelande om det och kanske om att ladda om sidan för att erhålla nytt version-värde?

Verkar jag vara inne på rätt spår nu? Om jag är på rätt spår så innebär detta ju oxå vid GET att det behövs finnas en version-value för varenda annat värde som ska gå att CRUDa. Blir mycket extra data då att få med för att få det "korrekt" i backend, men kanske så det ser ut också i "verkligheten"?

Mvh,
WKL.

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk

Julmustig Uppdatering: 8.4.20

Jag kan ikväll erbjuda på en julmustig uppdatering. Äntligen färdig med alla delmoment i båda kurserna och därmed bara projektuppgifterna kvar. Har deltagit på ett ex-jobbs-evenemang och sökt flera ex-jobbs-platser inom Webbutveckling. Motivationen är låg i nuvarande kurser - anledningar redogörs. Och slutligen projektuppgifterna i båda kurserna har jag tittat lite närmare på vad jag kan tänkas göra för att hålla samma fina kvalitetsnivå!

Moment 4 i JS-kursen
Jag är äntligen färdig med Moment 4 i JS-kursen vilket helt enkelt handlade om att jämföra tre olika frontend-ramverk och även visa kodexempel i frontend-ramverket ReactJS (ja, det kallas egentligen för funktionsbibliotek pga. avsaknad av många vedertagna frontend-bitar för att få kalla sig för ett fullspäckat "ramverk").

Angular är definitivt det mest omfattande/svåraste frontend-ramverket att komma igång med på grund av alla separata filer och all konfiguration som behövs för varje lilla enstaka komponent. Vue.js tycker jag är enklast att komma igång med även om jag kan se likheter i hur ReactJS verkar vara strukturerat.

ReactJS är också det frontend-"ramverket" jag kommer att köra i projektuppgiften i JS-kursen. Då blir det ett stereotypiskt MERN-projekt (MongoDB, ExpressJS, ReactJS, NodeJS). Kanske jag kommer att bli en av de många CodeTubers som lär ut hur du kodar i MERN-stacken som (väldigt få???) företag använder sig?!

Ex-jobbs-evenemanget
För någon vecka sedan var jag på ex-jobbs-evenemang vid det lokala universitet där endast företag som kan erbjuda ex-jobb fick delta. De fick alla 1 minut på sig att först presentera sig med mikrofon i handen där högtalarna var bakom oss så ljudet var inte det bästa. Sedan återgick de till sina montrar och vi fick gå runt och samla på oss kontaktuppgifter för att ansöka om ex-jobb.

En lustig sak vilket säkert inte såg bra ut på plats var att jag har en så dålig mobiltelefon för utomhus att dess kamera-app inte kunde scanna/läsa av QR-koderna. Däremot så var det bara e-postadresser som man samlade på sig i slutändan. När jag kom hem så skickade jag till ett par företag vars kontaktuppgifter jag hade hämtat.

Jag gjorde också som så att jag sökte på webbutvecklarjobb i närheten och sedan mejlade företagen som sökte folk att anställda men jag skrev om att jag sökte ex-jobb i orten där jag bor. Sammanlagt så skickade jag ut 13 ex-jobb-ansökningar. Men egentligen vill jag ex-jobba på distans då jag vill arbeta på distans som jag gör just nu i egenskap av enskild firma.

Så jag ska slänga ut ett par krokar till om "Webbutvecklare söker EX-JOBB på DISTANS" på ett par olika IT-platser.

Projektuppgifterna i JS-kursen och C# .NET-kursen
Vad gäller projektuppgifterna i JS-kursen och C# .NET-kursen så tänker jag som sagt tidigare ta mig an en WPF-app i C# .NET trots att de så kallade "lärarna" (mer om det i sista rubriken nedan) inte kommer att behandla något mer än Console App i denna introduktionskurs till C# .NET.

Vad gäller JS-kursen så funderar jag på en MERN-stack som sagt där det blir en liknande implementering som i tidigare kurs med datorkomponenter, systemadministratör och användare som kan registrera sig för att hantera inventarie av datorkomponenter. Det blir kul att se hur det ska lösas med bilderna denna gång då det nu är filsystemet som ska hanteras via "FS" i NodeJS jämfört med inbyggda filsystemsstödet i Laravel (PHP-ramverk).

En sak jag genast tog reda på är huruvida det finns sexiga "middlewares" i NodeJS/ExpressJS vilket det givetvis finns så då blev jag glad. Då kan jag implementera DRY och mer semantik i parametrarna för rutterna. Exempelvis:

router.get("/components",isAuthenticated,isAuthorized, async (req,res) => {})

Där "isAuthenticated" och "isAuthorized" är enskilda kontroller för att se om användaren först är autentiserad och sedan är auktoriserad för den givna CRUD-begäran. Precis som i Laravel PHP så kan vi avbryta hanteringen genom att någon utav dessa två inte går igenom och därmed skicka tillbaka en "res" innan ens koden inuti async får köras. "Middlewares" är minst lika sexiga som backticks (``) i JavaScript!

Låg pluggmoral i nuvarande kurser
Avslutningsvis för denna gång kan jag direktrapportera från "den virtuella klassfronten" att det finns missnöje just nu med de två pågående kurserna i och med flera saker. Den första är något som skapat en motsägelse: "Lärarna" har sagt att det finns ingen obligatorisk kurslitteratur för dessa två kurser samtidigt som det i varje moments "teoridel" står "Läsanvisningar: Läs kapitel X-Y i kurslitteraturen" och ingenting mer. Ingen egen text, inga YT-klipp eller annat förinspelat inlärningsmaterial att ta del av. I princip skulle vi kunna säga att vi får "universitetsstämplar" i och med dessa kurser men ingenting annat som inte går att ta reda på internet och där på mycket mer pedagogiskt vis.

Det andra är då just att "Lärarna" insisterar på att ingen kurslitteratur är obligatorisk men bidrar inte med någonting mer än kapitelhänvisningar till den icke-obligatoriska kurslitteraturen?! Det förekommer "föreläsningen" men dessa är knappa och "Lärarna" har inte precis ingett förtroende eller någon yrkesprofessionalism i sitt mycket bristande engagemang som så kallade "Lärare". Jo, det fanns faktiskt hur man lade upp på GitHub, sisådär 10+ kurser in i distansutbildningen, för det har vi ju inte hunnit lära oss än?!

Det tredje är att mycket "material" som hänvisas till är då trasiga länkar eller utdaterade rekommendationer såsom att Heroku skulle vara gratis att sjösätta sin webbplats på eller Mlab för MongoDB. Återigen går detta då att koppla till "Lärarnas" avsaknad av engagemang och ens seriositet i kurserna. Ett delmoment i C# .NET-kursen fanns det inte ens något material förrän vi två veckor in i kursen sa åt dem...

Dessa två så kallade "Lärare" har endast oss i dessa två kurser och hade oss även i första kursen Webbutveckling I vilket också visade sig vara långt ifrån "nybörjarvänligt även för icke-tekniskt insatta". Exempelvis introduktionsföreläsningen så sade ena "Läraren" att vi hade lärt oss i C++ och Java (inget vi har läst tidigare), men här tänker jag att "Läraren" kanske syftade på datateknikstudenter och inte oss webbutvecklarstudenter?

Personligen biter jag ihop men jag förstår också 100 % det enormt starka missnöjet hos vissa som har det mycket tuffare livssituationer där detta känns som droppen, speciellt nu när vi bara har 3 kurser kvar efter dessa två "bajsmackiga"-parallellkurser.

På återseende - som vanligt, i framtiden!

Mvh,
WKL.
---------
✔️Kurs 1: (B) HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: (A) HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: (A) HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: (B) HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: (A) VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: (C) VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: (A) VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: (A) VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: (A) HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: (A) HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
🚧Kurs 11: (Pågår) VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
🚧Kurs 12: (Pågår) VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk

Julmirakeluppdatering i förskott? | ^8.420.69 Uppdatering

Allt godkänt nu förutom projekten i nuvarande parallellkurser. Det har kanske inträffat ett julmirakel i förskott tack vare nästa veckas Skype-intervju vilket skulle kunna leda till en spikad ex-jobb-plats redan detta år. Skilda åsikter kring kryptering av JWT-nycklar råder. Till sist har jag en hemlighet att "retas" med!

Allt godkänt - projekten återstår
Med glädjande besked kan jag nu meddela att alla delmoment i parallellkurserna (JS MERN-stack i princip samt C# .NET-introduktionskurs) har rättat och godkänt allt så nu återstår bara projektuppgifterna. Där har jag påbörjat REST API i NodeJS+MongoDB+ExpressJS, klassiska MERN-stacken.

Som det ser ut nu så har jag då en mapp "server" för NodeJS+ExpressJS som pratar med MongoDB lokalt, och så har jag en ytterligare mapp "client" (båda i samma git repo) för ReactJS-delen. Smidigt och praktiskt för just projektuppgiften även om jag förstår att man kanske bör dela in det i flera olika git repon/kodbaser? 🤔

I och med kursernas delvis katastrofala upplägg med bristande studiematerial mer än "googla eller läs i den icke-obligatoriska kurslitteraturens olika kapitel!" så finner jag inget engagemang att försöka publicera MERN-projektet online utan det får bli lokalt och då räcker ett git repo gott och väl enligt mitt resonemang.

Skype-intervju hos eventuellt ex-jobb nästa vecka!
Idag hade jag tänkt att slänga ut fler krokar online för ex-jobb-letandet men till min stora förvåning så hade jag äntligen fått ett svar från en som tidigare hade skrivit "Tack för din ansökan. Vi går nu igenom våra erhållna ansökningar."

Nu bad samma person mig om en Skype-intervju nästa vecka vilket jag givetvis kan. Samtidigt så är det inte spikat förrän det är spikat så jag fortsätter att leta genom att slänga ut krokar överallt online (utan att bli bannlyst)!

Så detta är då julmiraklet i förskott - att jag kanske får en ex-jobb-plats redan innan nästa år!

Kryptera JWT-nycklar eller inte - det är frågan?
På en Discord-grupp som jag är med i så går det skilda åsikter kring huruvida JWT-nycklar bör krypteras eller inte. Det intressanta är att en person berättar om hur deras JWT-nycklar krypteras medan en annan person menar på att det inte finns någon mening med det.

Jag ville prova att kryptera JWT-nycklar med npm crypto vilket gick förutom ett litet problem: vid kryptering skapas ett unikt "iv" (initialization vector) vilket behövs sedan tillsammans med hemlig (de)krypteringsnyckel för att kunna dekryptera den igen.

Problemet är då att veta vilket "iv" som är kopplat till vilken JWT och visst skulle det gå att ha en tabell för JWT kopplad till rätt "iv", men vad blir då syftet med att ens ha "iv" om det är enbart beroende av en och samma unika JWT? Eller håller det ändå god och hög säkerhetsstandard här?

En lösning jag funderat på vilket har sina eventuella nackdelar är att när användaren skickar sin krypterade JWT så finns även `req.ip` att extrahera ur den vilket skulle kunna vara kopplat till ett givet "iv". Men vad händer då om det skulle vara flera med samma ip-adresser? Vi vill ju inte loopa igenom flera iv:s från någon array tills den matchar rätt JWT med dess (de)krypteringsnyckel.

En lösning då på den lösningens problem är att vara superstrikt och endast tillåta en ip-adress få vara ansluten med en given JWT för att få veta viken "iv" som gäller den. T.ex. loggar du in och du får din JWT, nu loggas då att en krypterad JWT för denna användare finns och därmed är dess associerade IP-adress och vilken "iv" som används för att dekryptera den. Om då någon annan försöker logga in från samma IP-adress så kommer de att nekas för att IP-adressen redan har använts och då måste den andra först logga ut vars IP-adress då raderas från databasen och dess associerade krypterade JWT+iv. Detta är superstrikt men gör det också problematiskt för de som vill ansluta från en och samma IP-adress (t.ex. delat nätverk med endast en ip-adress utåt mot internet).

En lösning då på det problemet är att tillåta flera olika användarnamn - som måste vara unika - så vi utökar vad som anses vara "primärnyckeln" (ip-adress i detta fall) genom att vi får en trevlig sammansatt primärnyckel: användarnamnet+deras ip-adress = krypterad JWT vars iv vi vet vilken det är tack vare användarnamnet och den kopplade ip-adressen. Delvis blir ip-adressen meningslös eftersom namnet är ju unikt vilket kan kopplas till rätt "iv" och samtidigt så kan det skydda mot vissa slarviga angrepp genom att kontrollera om ip-adressen är inom svenska omfånget av ip-adresser t.ex.

Du som läser detta får gärna påpeka nya problem här och/eller möjligheterna med detta och/eller om krypterade JWT-nycklar bara är en illusion av ytterligare säkerhetsnivå och därmed en risk för sämre säkerhet på grund av just det!

Teaser - kan utbildningen kanske gå snabbare för min del?
Jag har slängt ut en krok och så kommer jag att behöva kontrollera en sak. Men om det går vägen så kommer jag att kunna påskynda eller åtminstone underlätta de sista par kurserna kvar i denna utbildning.

Jag återkommer vid ett senare tillfälle hur det blev med den saken!

På återseende - som vanligt, i framtiden!

Mvh,
WKL.
---------
✔️Kurs 1: (B) HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: (A) HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: (A) HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: (B) HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: (A) VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: (C) VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: (A) VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: (A) VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: (A) HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: (A) HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
🚧Kurs 11: (Pågår) VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
🚧Kurs 12: (Pågår) VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk
Medlem
Skrivet av WebbkodsLärlingen:

Allt godkänt nu förutom projekten i nuvarande parallellkurser. Det har kanske inträffat ett julmirakel i förskott tack vare nästa veckas Skype-intervju vilket skulle kunna leda till en spikad ex-jobb-plats redan detta år. Skilda åsikter kring kryptering av JWT-nycklar råder. Till sist har jag en hemlighet att "retas" med!

Allt godkänt - projekten återstår
Med glädjande besked kan jag nu meddela att alla delmoment i parallellkurserna (JS MERN-stack i princip samt C# .NET-introduktionskurs) har rättat och godkänt allt så nu återstår bara projektuppgifterna. Där har jag påbörjat REST API i NodeJS+MongoDB+ExpressJS, klassiska MERN-stacken.

Som det ser ut nu så har jag då en mapp "server" för NodeJS+ExpressJS som pratar med MongoDB lokalt, och så har jag en ytterligare mapp "client" (båda i samma git repo) för ReactJS-delen. Smidigt och praktiskt för just projektuppgiften även om jag förstår att man kanske bör dela in det i flera olika git repon/kodbaser? 🤔

I och med kursernas delvis katastrofala upplägg med bristande studiematerial mer än "googla eller läs i den icke-obligatoriska kurslitteraturens olika kapitel!" så finner jag inget engagemang att försöka publicera MERN-projektet online utan det får bli lokalt och då räcker ett git repo gott och väl enligt mitt resonemang.

Skype-intervju hos eventuellt ex-jobb nästa vecka!
Idag hade jag tänkt att slänga ut fler krokar online för ex-jobb-letandet men till min stora förvåning så hade jag äntligen fått ett svar från en som tidigare hade skrivit "Tack för din ansökan. Vi går nu igenom våra erhållna ansökningar."

Nu bad samma person mig om en Skype-intervju nästa vecka vilket jag givetvis kan. Samtidigt så är det inte spikat förrän det är spikat så jag fortsätter att leta genom att slänga ut krokar överallt online (utan att bli bannlyst)!

Så detta är då julmiraklet i förskott - att jag kanske får en ex-jobb-plats redan innan nästa år!

Kryptera JWT-nycklar eller inte - det är frågan?
På en Discord-grupp som jag är med i så går det skilda åsikter kring huruvida JWT-nycklar bör krypteras eller inte. Det intressanta är att en person berättar om hur deras JWT-nycklar krypteras medan en annan person menar på att det inte finns någon mening med det.

Jag ville prova att kryptera JWT-nycklar med npm crypto vilket gick förutom ett litet problem: vid kryptering skapas ett unikt "iv" (initialization vector) vilket behövs sedan tillsammans med hemlig (de)krypteringsnyckel för att kunna dekryptera den igen.

Problemet är då att veta vilket "iv" som är kopplat till vilken JWT och visst skulle det gå att ha en tabell för JWT kopplad till rätt "iv", men vad blir då syftet med att ens ha "iv" om det är enbart beroende av en och samma unika JWT? Eller håller det ändå god och hög säkerhetsstandard här?

En lösning jag funderat på vilket har sina eventuella nackdelar är att när användaren skickar sin krypterade JWT så finns även `req.ip` att extrahera ur den vilket skulle kunna vara kopplat till ett givet "iv". Men vad händer då om det skulle vara flera med samma ip-adresser? Vi vill ju inte loopa igenom flera iv:s från någon array tills den matchar rätt JWT med dess (de)krypteringsnyckel.

En lösning då på den lösningens problem är att vara superstrikt och endast tillåta en ip-adress få vara ansluten med en given JWT för att få veta viken "iv" som gäller den. T.ex. loggar du in och du får din JWT, nu loggas då att en krypterad JWT för denna användare finns och därmed är dess associerade IP-adress och vilken "iv" som används för att dekryptera den. Om då någon annan försöker logga in från samma IP-adress så kommer de att nekas för att IP-adressen redan har använts och då måste den andra först logga ut vars IP-adress då raderas från databasen och dess associerade krypterade JWT+iv. Detta är superstrikt men gör det också problematiskt för de som vill ansluta från en och samma IP-adress (t.ex. delat nätverk med endast en ip-adress utåt mot internet).

En lösning då på det problemet är att tillåta flera olika användarnamn - som måste vara unika - så vi utökar vad som anses vara "primärnyckeln" (ip-adress i detta fall) genom att vi får en trevlig sammansatt primärnyckel: användarnamnet+deras ip-adress = krypterad JWT vars iv vi vet vilken det är tack vare användarnamnet och den kopplade ip-adressen. Delvis blir ip-adressen meningslös eftersom namnet är ju unikt vilket kan kopplas till rätt "iv" och samtidigt så kan det skydda mot vissa slarviga angrepp genom att kontrollera om ip-adressen är inom svenska omfånget av ip-adresser t.ex.

Du som läser detta får gärna påpeka nya problem här och/eller möjligheterna med detta och/eller om krypterade JWT-nycklar bara är en illusion av ytterligare säkerhetsnivå och därmed en risk för sämre säkerhet på grund av just det!

Teaser - kan utbildningen kanske gå snabbare för min del?
Jag har slängt ut en krok och så kommer jag att behöva kontrollera en sak. Men om det går vägen så kommer jag att kunna påskynda eller åtminstone underlätta de sista par kurserna kvar i denna utbildning.

Jag återkommer vid ett senare tillfälle hur det blev med den saken!

På återseende - som vanligt, i framtiden!

Mvh,
WKL.
---------
✔️Kurs 1: (B) HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: (A) HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: (A) HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: (B) HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: (A) VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: (C) VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: (A) VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: (A) VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: (A) HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: (A) HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
🚧Kurs 11: (Pågår) VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
🚧Kurs 12: (Pågår) VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)

Tumregeln är alltid: lek inte med krypto själv, implementera med bibliotek, följ standarder, leta fram en färdig lösning för de egenskaper du letar efter

Det går såklart att göra på andra sätt, problemet är bara att man ofta missar enkla sidokanaler och andra problem som gör säkerheten lätt att omkullkasta

Vad exakt är dessa ’JWK’-nycklar till för i din applikation?

En IV är ungefär samma som en ’salt’ när man hashar något, det är till för att randomisera indatan så att inte samma data krypteras identiskt varje gång. Den ska idealt vara helt slumpmässigt, men andes inte vara hemlig utan kan lagras öppet

———

Angående kodbaserna i samma repo så kan det vara smidigt, men blir snabbt stökigt om man jobbar flera tillsammans

Det vi brukar göra är att ha en för server och en för klient, och en delad subrepo med interface-klasserna som specar rest-api strukturen

Permalänk
Skrivet av medbor:

Tumregeln är alltid: lek inte med krypto själv, implementera med bibliotek, följ standarder, leta fram en färdig lösning för de egenskaper du letar efter

Det går såklart att göra på andra sätt, problemet är bara att man ofta missar enkla sidokanaler och andra problem som gör säkerheten lätt att omkullkasta

Vad exakt är dessa ’JWK’-nycklar till för i din applikation?

En IV är ungefär samma som en ’salt’ när man hashar något, det är till för att randomisera indatan så att inte samma data krypteras identiskt varje gång. Den ska idealt vara helt slumpmässigt, men andes inte vara hemlig utan kan lagras öppet

———

Angående kodbaserna i samma repo så kan det vara smidigt, men blir snabbt stökigt om man jobbar flera tillsammans

Det vi brukar göra är att ha en för server och en för klient, och en delad subrepo med interface-klasserna som specar rest-api strukturen

Tack för ditt snabba svar!

Ja, det är inte så att jag sitter och försöker skriva ihop egen matematisk formel för (de)kryptering! Jag använder bcrypt, crypto och jsonwebtoken npm-paketen. Däremot vet jag inte vad som är standard i vilken krypteringsmetod som är standard, hur lång iv:n bör vara, etc. Se t.ex. koden nedan som är (de)krypteringsfunktion som kan (de)kryptera valfri sträng (den nyttjar aes-256 med läget cbc och jag har ingen aning om det är standard eller katastrofalt farligt):

helpers/de_encrypt.js

// "de_encrypt.js" = Used to decrypt AND encrypt JWTs const crypto = require("crypto"); require("dotenv").config({ path: "../../.env" }); // Load .env variables // Grab stored "ENCRYPTION_KEY" in .env const encryptionKey = process.env.ENCRYPTION_KEY; // ENCRYPT = MAKE IT ENCRYPTED function encrypt(text) { // Generate "iv" (=initalization vector) that will also be returned // since it is needed again to decrypt the encrypted part const iv = crypto.randomBytes(16); try { // Start encrypting const cipher = crypto.createCipheriv( "aes-256-cbc", Buffer.from(encryptionKey), iv ); // Finalize the encrypted text let encrypted = cipher.update(text, "utf-8", "hex"); encrypted += cipher.final("hex"); // Return array which has encrypted data plus its // associated randomly generated IV (initalization vector) return [encrypted, iv]; } catch (err) { // Just return null if it fails for some reason which can then be checked against! return null; } } // DECRYPT = MAKE IT DECRYPTED // It also needs the previous initalization vector which is always new for each encrypted text function decrypt(encrypted, iv) { // Start decrypting try { const decipher = crypto.createDecipheriv( "aes-256-cbc", Buffer.from(encryptionKey), iv ); // Finalize the decrypted text let decrypted = decipher.update(encrypted, "hex", "utf-8"); decrypted += decipher.final("utf-8"); // Return the decrypted now as plain text string! return decrypted; } catch (err) { // Just return null if it fails for some reason which can then be checked against! return null; } } // Export functions as an object with them inside module.exports = { encrypt, decrypt };

Dold text

JWT:ns i MERN-projeketet är till för autentisering (logga in) och auktorisering (åtkomst utifrån tilldelad roll vilket framgår i JWT:n) för ReactJS-frontenden. Dessa skickas - tack vare cookie-parser - via httpOnly-kakor (tidigare i utbildningen har vi använt localStorage vilket är katastrofalt men det var ingen som sade något om httpOnly-kakor innan). Tydligen ska det finnas "accessJWTs" (korta tillfälliga) och sedan "resfreshJWTs" (långvarigare) där sistnämnda är till för att hämta nya accessJWTs för att i sin tur användas för REST API-anrop.

Nu finns det inget absolut som helst krav på den JWT-implementeringen i projektuppgifterna för dessa parallellkurser men jag antar att det är standardimplementering? Två olika slags JWTs där ena (refresh) bara uppdaterar den kortvariga (access) och det är accessToken som gör att du kan logga in vid lyckad inloggning? (annars hade ju en stulen refreshToken räckt vid angrepp!?)

Nej, du behöver inte oroa dig att jag skickar med känsliga uppgifter i JWT:n såsom lösenord (varför skulle man nånsin göra det?) eller liknande. Jag har till och med funderat på att anonymisera rollerna. T.ex. kan en roll vara en `const GET_USERS_ACCESS = "Öl1337_AzlQUisJSIz;i-";` i REST API:t så jag kollar bara efter consten "GET_USERS_ACCESS" som inte kan råka ändras medan utåt står det "Öl1337_AzlQUisJSIz;i-". Vissa verkar köra med någon slags finurlig numrering för tilldelade roller? 🤔

Mvh,
WKL.

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk
Medlem
Skrivet av WebbkodsLärlingen:

Tack för ditt snabba svar!

Ja, det är inte så att jag sitter och försöker skriva ihop egen matematisk formel för (de)kryptering! Jag använder bcrypt, crypto och jsonwebtoken npm-paketen. Däremot vet jag inte vad som är standard i vilken krypteringsmetod som är standard, hur lång iv:n bör vara, etc. Se t.ex. koden nedan som är (de)krypteringsfunktion som kan (de)kryptera valfri sträng (den nyttjar aes-256 med läget cbc och jag har ingen aning om det är standard eller katastrofalt farligt):

helpers/de_encrypt.js

// "de_encrypt.js" = Used to decrypt AND encrypt JWTs const crypto = require("crypto"); require("dotenv").config({ path: "../../.env" }); // Load .env variables // Grab stored "ENCRYPTION_KEY" in .env const encryptionKey = process.env.ENCRYPTION_KEY; // ENCRYPT = MAKE IT ENCRYPTED function encrypt(text) { // Generate "iv" (=initalization vector) that will also be returned // since it is needed again to decrypt the encrypted part const iv = crypto.randomBytes(16); try { // Start encrypting const cipher = crypto.createCipheriv( "aes-256-cbc", Buffer.from(encryptionKey), iv ); // Finalize the encrypted text let encrypted = cipher.update(text, "utf-8", "hex"); encrypted += cipher.final("hex"); // Return array which has encrypted data plus its // associated randomly generated IV (initalization vector) return [encrypted, iv]; } catch (err) { // Just return null if it fails for some reason which can then be checked against! return null; } } // DECRYPT = MAKE IT DECRYPTED // It also needs the previous initalization vector which is always new for each encrypted text function decrypt(encrypted, iv) { // Start decrypting try { const decipher = crypto.createDecipheriv( "aes-256-cbc", Buffer.from(encryptionKey), iv ); // Finalize the decrypted text let decrypted = decipher.update(encrypted, "hex", "utf-8"); decrypted += decipher.final("utf-8"); // Return the decrypted now as plain text string! return decrypted; } catch (err) { // Just return null if it fails for some reason which can then be checked against! return null; } } // Export functions as an object with them inside module.exports = { encrypt, decrypt };

Dold text

JWT:ns i MERN-projeketet är till för autentisering (logga in) och auktorisering (åtkomst utifrån tilldelad roll vilket framgår i JWT:n) för ReactJS-frontenden. Dessa skickas - tack vare cookie-parser - via httpOnly-kakor (tidigare i utbildningen har vi använt localStorage vilket är katastrofalt men det var ingen som sade något om httpOnly-kakor innan). Tydligen ska det finnas "accessJWTs" (korta tillfälliga) och sedan "resfreshJWTs" (långvarigare) där sistnämnda är till för att hämta nya accessJWTs för att i sin tur användas för REST API-anrop.

Nu finns det inget absolut som helst krav på den JWT-implementeringen i projektuppgifterna för dessa parallellkurser men jag antar att det är standardimplementering? Två olika slags JWTs där ena (refresh) bara uppdaterar den kortvariga (access) och det är accessToken som gör att du kan logga in vid lyckad inloggning? (annars hade ju en stulen refreshToken räckt vid angrepp!?)

Nej, du behöver inte oroa dig att jag skickar med känsliga uppgifter i JWT:n såsom lösenord (varför skulle man nånsin göra det?) eller liknande. Jag har till och med funderat på att anonymisera rollerna. T.ex. kan en roll vara en `const GET_USERS_ACCESS = "Öl1337_AzlQUisJSIz;i-";` i REST API:t så jag kollar bara efter consten "GET_USERS_ACCESS" som inte kan råka ändras medan utåt står det "Öl1337_AzlQUisJSIz;i-". Vissa verkar köra med någon slags finurlig numrering för tilldelade roller? 🤔

Mvh,
WKL.

AES-CBC har vissa svagheter, men är väl säker nog med IV och små datamängder

ECB som var dess föregångare var något av ett skämt:
https://www.ubiqsecurity.com/ecb-vs-cbc-block-cipher-mode-dif...

Men GCM är väl den moderna varianten som bör användas om man kan

Men det finns så mycket små detaljer att tänka på. Jag förstår verkligen inte ditt senaste inlägg så ska inte svara för mycket än

Permalänk
Skrivet av medbor:

AES-CBC har vissa svagheter, men är väl säker nog med IV och små datamängder

ECB som var dess föregångare var något av ett skämt:
https://www.ubiqsecurity.com/ecb-vs-cbc-block-cipher-mode-dif...

Men GCM är väl den moderna varianten som bör användas om man kan

Men det finns så mycket små detaljer att tänka på. Jag förstår verkligen inte ditt senaste inlägg så ska inte svara för mycket än

Tack för ditt svar igen!

Jag måste först uttrycka min tillfälliga frustration (och det är inte riktat mot dig eller någon annan): jag läser överallt att man ska följa standarder - samt alla unika detaljer för olika implementeringsfall - och ditten och datten vilket är helt förståeligt men ingen än så länge länkar till något konkret vilket jag som "färsking" kan följa i praktiken vilket gör att det nästan känns som ett slags "hemlighetsmakeri" bland de som arbetar inom industrin för att hålla oss "färskingar" utanför arbetsmarknaden!

I din länk så står det att "iv är ingen hemlighet så det gör inget att det skickas till slutanvändaren" vilket jag tolkar som att skicka en del av en (de)krypteringsnyckel så det låter väl inte så smart eller? Utmaningen jag har är att när något krypterat skickas så vill jag även att något unikt ska skickas med utan att avsändaren själv kan välja detta innan (t.ex. ip-adress fast det går att spoofa för den som vill tillräckligt). Detta kan då kontrolleras att det är rätt avsändare som skickade det krypterade innan det ens börjar dekrypteras.

Jag läser här att "Varför AES GCM suger - använd XChaCha20-Poly1305 eller The Gimli Permutation istället" (källa: https://soatok.blog/2020/05/13/why-aes-gcm-sucks/). chatGPT3.5 rekommenderar då "https://doc.libsodium.org/" för att kunna nyttja XChaCha20-Poly1305 i mitt MERN-projekt. Jag har dock ingen aning om det är "industristandard" eller ej!

Om jag förstått AES rätt så är det tänkt för bestämda stränglängder att krypteras och det finns då risk för "utfyllnad" (eng. padding) om stränglängder varierar vilket då kan bli sårbart då utfyllnadsmönstren kan upptäckas och eventuell dekyrpteras. En detalj vore då att varje JWT som ska krypteras bör få fyllnadsdata så att innan krypteringen så är det samma bestämda stränglängd för att undvika "padding"? T.ex. en JWT som är 100 tecken lång men bör vara 128 tecken lång får då 28 extratecken som saknar mening för backend att bry sig om.

Mvh,
WKL.

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk
Medlem
Skrivet av WebbkodsLärlingen:

Tack för ditt svar igen!

Jag måste först uttrycka min tillfälliga frustration (och det är inte riktat mot dig eller någon annan): jag läser överallt att man ska följa standarder - samt alla unika detaljer för olika implementeringsfall - och ditten och datten vilket är helt förståeligt men ingen än så länge länkar till något konkret vilket jag som "färsking" kan följa i praktiken vilket gör att det nästan känns som ett slags "hemlighetsmakeri" bland de som arbetar inom industrin för att hålla oss "färskingar" utanför arbetsmarknaden!

I din länk så står det att "iv är ingen hemlighet så det gör inget att det skickas till slutanvändaren" vilket jag tolkar som att skicka en del av en (de)krypteringsnyckel så det låter väl inte så smart eller? Utmaningen jag har är att när något krypterat skickas så vill jag även att något unikt ska skickas med utan att avsändaren själv kan välja detta innan (t.ex. ip-adress fast det går att spoofa för den som vill tillräckligt). Detta kan då kontrolleras att det är rätt avsändare som skickade det krypterade innan det ens börjar dekrypteras.

Jag läser här att "Varför AES GCM suger - använd XChaCha20-Poly1305 eller The Gimli Permutation istället" (källa: https://soatok.blog/2020/05/13/why-aes-gcm-sucks/). chatGPT3.5 rekommenderar då "https://doc.libsodium.org/" för att kunna nyttja XChaCha20-Poly1305 i mitt MERN-projekt. Jag har dock ingen aning om det är "industristandard" eller ej!

Om jag förstått AES rätt så är det tänkt för bestämda stränglängder att krypteras och det finns då risk för "utfyllnad" (eng. padding) om stränglängder varierar vilket då kan bli sårbart då utfyllnadsmönstren kan upptäckas och eventuell dekyrpteras. En detalj vore då att varje JWT som ska krypteras bör få fyllnadsdata så att innan krypteringen så är det samma bestämda stränglängd för att undvika "padding"? T.ex. en JWT som är 100 tecken lång men bör vara 128 tecken lång får då 28 extratecken som saknar mening för backend att bry sig om.

Mvh,
WKL.

Det finns kända algoritmer för padding som gör precis rätt, använd en av dessa!

Vanligen brukar man lagra den krypterade datan och iv tillsammans, bara nyckeln man håller på annat håll

Chatgpt skulle jag starkt undvika för dessa frågon, lätt att den ger helt felaktiga rekommendationer

Det är ett djupt och svårt problem du ger dig in på, så det är bökigt att fatta vad som passar

Försök beskriva ditt problem och implementation klart och tydligt, vilka involverade delar, vad som behöver skyddas och från vem så kan vi försöka hjälpa

Permalänk

Snabb uppdatering med ett snabbt erkännande

Advent of Code har gjort mig både mer självödmjuk & ångestfylld
För två dagar sedan så deltog jag för allra första gången i "Advent of Code (AoC)" (2023-upplagan) och där fastnade jag först på del 2 för dag 1 och fick ett tillfälligt nervsammanbrott eftersom det i princip raserade hela min (givetvis onödiga) självbild som någon duktig "programmerare" bara för att jag vid universitetets betygsystem har i princip "toppbetyg" inom just webbutveckling.

Jag lyckades dock tillslut klara av Del 2 i Dag 1 och igår lyckades jag även både Del 1 & Del 2 för Dag 2 utan att råka bli tillfälligt tårögd i ögonen. Nu på Dag 3 så inser jag att jag kommer bara att gå in i väggen både mentalt och känslomässigt om jag inte bara erkänner min onödiga fasad: jag kan koda högnivåspråk till en viss platå/nivå och samtidigt så förstår jag egentligen inte vad det faktiskt är som händer vid JIT-kompilering i JavaScript eller hur diverse renderingsmotorer i olika webbläsarimplementeringar fungerar.

Allt detta säger jag inte i form av sympatifiskande utan snarare för ett verkligt självuppvaknande om att jag kan koda 100 % CRUD™, men inte något som liknar spelprogrammering som kräver koordinatsystemtänk (vilket Dag 3 idag verkar vilja "tvinga" in en på för att kunna lösa delarna), trigonometri, AI-system för fiender, med mera, eller något annat på lågnivåspråk där du måste sköta all minneshantering och även optimera koden utifrån diverse hårdvara.

Ett mer simplare exempel är att jag har ingen aning om hur jag får pixlar att dyka upp på skärmen i något riktigt programmeringsspråk men i skriptspråket JS och/eller märkspråken HTML+CSS så kan jag nyttja antingen HTML-element + CSS och/eller canvas-objektet i JS för att få pixlar att dyka upp i webbläsare. Sistnämnda är ju abstraktioner av vad som egentligen sker med hjälp av lågnivåspråk såsom C(++) exempelvis vilket ligger bakom webbläsarna och sedan erbjuder webbläsarna enkla API:er för skriptspråk att få pixlar att magiskt framstå.

Nu är detta absolut ingen bra marknadsföring av mig själv där jag påstår att jag känner att jag egentligen inte kan någonting för kolla - jag gick redan in i väggen på Dag 3 i AoC 2023. Samtidigt så känner jag att jag deltog där av helt fel anledningar: 1) för att känna var jag står någonstans bland andra och framförallt riktiga programmerare, 2) att se hur långt jag egentligen har kommit med min problemlösningsförmåga, 3) allmän egoboost av att klara av dagens kodutmaning (eller inte).

Helt fel anledningar för det känns inte kul (det kändes delvis som ett obetalt arbetspass), det känns inte motiverande, det känns som en tävling där jag som P15-spelare frivilligt valt att spela mot elitseriespelare (varför gjorde jag det?), det känns snarare ångestfyllt att behöva prestera för det kommer ju nya kodutmaningar varje dag (och man vill ju inte halka efter) och detta ska då kombineras med två pågående projektuppgiftsinlämningar, letande efter ex-jobb inför V12 nästa år.

Och samtidigt känns det som en tillfällig rävsax: nu när jag gett mig in så framstår jag ju inte förtroendeingivande om jag hoppar ur/ger upp redan på dag 3, och samtidigt så känner jag att det äter upp värdefull tid för något som faktiskt är kul (webbutveckling) och något som faktiskt troligen kommer att ge mig betalt i framtiden.

Det var också en sak till som jag fick ångest över vilket var när jag skulle gå in och försöka läsa andras lösningar på samma uppgifter. Förvisso riktiga programmeringsspråk som liknar skriptspråket JS men ändå så hade jag svårt att följa koden pga. korta variabelnamn, inga kommentarer, till viss del annorlunda syntax, mycket abstrakt kedjande av metodanrop, etc. Så detta oroar mig då såklart inför att arbeta i delade kodbaser inom webbutveckling. Förhoppningsvis kan överenskomna kodstandarder underlätta det hela.

De goda nyheterna dock!
Som tur var så är det varken lag eller forumkrav(?) på att delta i AoC utan det är helt valfritt och deltagandet ska ju såklart kännas roligt. En annan tur sak är att med folk jag pratat med inom Webbutvecklingsbranschen så verkar kodutmaningarna i AoC inte riktigt översättas till liknande problem i arbetslivet (iaf inte inom webbutveckling) så det är ingen större förlust på så vis.

Vad gäller problemlösningsförmågan så finns det tre egentliga skillnader skulle jag vilja påstå här: 1) att koda webbutveckling som sedan kan nyttjas i skarpt läge omedelbart är kul och gör att lusten till problemlösning/lösa problem håller i sig längre, 2) när jag väl kodar webbutveckling så kommer jag att vara mer motiverad för jag, 3) kommer att få betalt för det vilket kommer vara den morot och/eller piska som saknades helt i AoC-deltagandet efter att det började öka i subjektiv svårighetsgrad.

En 4:e punkt skulle vara att i arbetslivet så finns det större möjligheter att kunna tänja på "godtagbara lösningsresultat" medan i AoC så är det exakta värden/svar som ska ges även om saker å ting kan lösas på olika sätt och vis i viss utsträckning. Det är lite som i matematikuppgifter i läromedel där svaret måste vara exakt trots att du kanske har följt en "annars godtagbar lösning".

Så nu är det slut på att "skylta med mina toppslutbetyg" i signaturen eftersom det egentligen på ren svenska är patetiskt och sandlådenivå, "Mina betyg är högre än dina betyg!". 🤦‍♂️ Det har däremot varit intressant SEO vad jag har sett i efterhand!

Imorgon blir det intervju om en eventuell ex-jobb-plats inför V12 nästa år.

På återseende - som vanligt, i framtiden!

Mvh,
WKL.

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk
Medlem
Skrivet av WebbkodsLärlingen:

Advent of Code har gjort mig både mer självödmjuk & ångestfylld
För två dagar sedan så deltog jag för allra första gången i "Advent of Code (AoC)" (2023-upplagan) och där fastnade jag först på del 2 för dag 1 och fick ett tillfälligt nervsammanbrott eftersom det i princip raserade hela min (givetvis onödiga) självbild som någon duktig "programmerare" bara för att jag vid universitetets betygsystem har i princip "toppbetyg" inom just webbutveckling.

Jag lyckades dock tillslut klara av Del 2 i Dag 1 och igår lyckades jag även både Del 1 & Del 2 för Dag 2 utan att råka bli tillfälligt tårögd i ögonen. Nu på Dag 3 så inser jag att jag kommer bara att gå in i väggen både mentalt och känslomässigt om jag inte bara erkänner min onödiga fasad: jag kan koda högnivåspråk till en viss platå/nivå och samtidigt så förstår jag egentligen inte vad det faktiskt är som händer vid JIT-kompilering i JavaScript eller hur diverse renderingsmotorer i olika webbläsarimplementeringar fungerar.

Mvh,
WKL.

Webbutveckling och algoritmer är två helt olika saker. Jag har en femårig civilingenjörsexamen i datateknik samt 2års arbetslivserfarenhet i webbutveckling och har själv gett upp med AoC för jag orkar inte, det är för energikrävande.

Att vara duktig programmerare och duktig på AoC är inte samma sak, algoritmer är ren problemlösning. Detta påminner lite om när du för något år sedan ifrågasatte ingenjörer för att de inte kunde just komplexa algoritmer :I)

Visa signatur

CPU: Ryzen 5600xGPU: 1080 TI ROG Strix RAM:2x16GB G.skill Trident @ 3600MHz MoBo: Asus B550FPSU: Corsair SF750
En resa till Nordkorea
2 dagar i Tjernobyl

Permalänk
Medlem
Skrivet av WebbkodsLärlingen:

Advent of Code har gjort mig både mer självödmjuk & ångestfylld
För två dagar sedan så deltog jag för allra första gången i "Advent of Code (AoC)" (2023-upplagan) och där fastnade jag först på del 2 för dag 1 och fick ett tillfälligt nervsammanbrott eftersom det i princip raserade hela min (givetvis onödiga) självbild som någon duktig "programmerare" bara för att jag vid universitetets betygsystem har i princip "toppbetyg" inom just webbutveckling.

Jag lyckades dock tillslut klara av Del 2 i Dag 1 och igår lyckades jag även både Del 1 & Del 2 för Dag 2 utan att råka bli tillfälligt tårögd i ögonen. Nu på Dag 3 så inser jag att jag kommer bara att gå in i väggen både mentalt och känslomässigt om jag inte bara erkänner min onödiga fasad: jag kan koda högnivåspråk till en viss platå/nivå och samtidigt så förstår jag egentligen inte vad det faktiskt är som händer vid JIT-kompilering i JavaScript eller hur diverse renderingsmotorer i olika webbläsarimplementeringar fungerar.

Allt detta säger jag inte i form av sympatifiskande utan snarare för ett verkligt självuppvaknande om att jag kan koda 100 % CRUD™, men inte något som liknar spelprogrammering som kräver koordinatsystemtänk (vilket Dag 3 idag verkar vilja "tvinga" in en på för att kunna lösa delarna), trigonometri, AI-system för fiender, med mera, eller något annat på lågnivåspråk där du måste sköta all minneshantering och även optimera koden utifrån diverse hårdvara.

Ett mer simplare exempel är att jag har ingen aning om hur jag får pixlar att dyka upp på skärmen i något riktigt programmeringsspråk men i skriptspråket JS och/eller märkspråken HTML+CSS så kan jag nyttja antingen HTML-element + CSS och/eller canvas-objektet i JS för att få pixlar att dyka upp i webbläsare. Sistnämnda är ju abstraktioner av vad som egentligen sker med hjälp av lågnivåspråk såsom C(++) exempelvis vilket ligger bakom webbläsarna och sedan erbjuder webbläsarna enkla API:er för skriptspråk att få pixlar att magiskt framstå.

Nu är detta absolut ingen bra marknadsföring av mig själv där jag påstår att jag känner att jag egentligen inte kan någonting för kolla - jag gick redan in i väggen på Dag 3 i AoC 2023. Samtidigt så känner jag att jag deltog där av helt fel anledningar: 1) för att känna var jag står någonstans bland andra och framförallt riktiga programmerare, 2) att se hur långt jag egentligen har kommit med min problemlösningsförmåga, 3) allmän egoboost av att klara av dagens kodutmaning (eller inte).

Helt fel anledningar för det känns inte kul (det kändes delvis som ett obetalt arbetspass), det känns inte motiverande, det känns som en tävling där jag som P15-spelare frivilligt valt att spela mot elitseriespelare (varför gjorde jag det?), det känns snarare ångestfyllt att behöva prestera för det kommer ju nya kodutmaningar varje dag (och man vill ju inte halka efter) och detta ska då kombineras med två pågående projektuppgiftsinlämningar, letande efter ex-jobb inför V12 nästa år.

Och samtidigt känns det som en tillfällig rävsax: nu när jag gett mig in så framstår jag ju inte förtroendeingivande om jag hoppar ur/ger upp redan på dag 3, och samtidigt så känner jag att det äter upp värdefull tid för något som faktiskt är kul (webbutveckling) och något som faktiskt troligen kommer att ge mig betalt i framtiden.

Det var också en sak till som jag fick ångest över vilket var när jag skulle gå in och försöka läsa andras lösningar på samma uppgifter. Förvisso riktiga programmeringsspråk som liknar skriptspråket JS men ändå så hade jag svårt att följa koden pga. korta variabelnamn, inga kommentarer, till viss del annorlunda syntax, mycket abstrakt kedjande av metodanrop, etc. Så detta oroar mig då såklart inför att arbeta i delade kodbaser inom webbutveckling. Förhoppningsvis kan överenskomna kodstandarder underlätta det hela.

De goda nyheterna dock!
Som tur var så är det varken lag eller forumkrav(?) på att delta i AoC utan det är helt valfritt och deltagandet ska ju såklart kännas roligt. En annan tur sak är att med folk jag pratat med inom Webbutvecklingsbranschen så verkar kodutmaningarna i AoC inte riktigt översättas till liknande problem i arbetslivet (iaf inte inom webbutveckling) så det är ingen större förlust på så vis.

Vad gäller problemlösningsförmågan så finns det tre egentliga skillnader skulle jag vilja påstå här: 1) att koda webbutveckling som sedan kan nyttjas i skarpt läge omedelbart är kul och gör att lusten till problemlösning/lösa problem håller i sig längre, 2) när jag väl kodar webbutveckling så kommer jag att vara mer motiverad för jag, 3) kommer att få betalt för det vilket kommer vara den morot och/eller piska som saknades helt i AoC-deltagandet efter att det började öka i subjektiv svårighetsgrad.

En 4:e punkt skulle vara att i arbetslivet så finns det större möjligheter att kunna tänja på "godtagbara lösningsresultat" medan i AoC så är det exakta värden/svar som ska ges även om saker å ting kan lösas på olika sätt och vis i viss utsträckning. Det är lite som i matematikuppgifter i läromedel där svaret måste vara exakt trots att du kanske har följt en "annars godtagbar lösning".

Så nu är det slut på att "skylta med mina toppslutbetyg" i signaturen eftersom det egentligen på ren svenska är patetiskt och sandlådenivå, "Mina betyg är högre än dina betyg!". 🤦‍♂️ Det har däremot varit intressant SEO vad jag har sett i efterhand!

Imorgon blir det intervju om en eventuell ex-jobb-plats inför V12 nästa år.

På återseende - som vanligt, i framtiden!

Mvh,
WKL.

Att läsa andras kod som du inte själv skrivit, i språk du inte vanligen använder är viktigt. Det kommer bredda din kompetens, allting med ’korta variabelnamn’ och ’inga kommentarer’ tillhör vardagen för de flesta i branchen

Problemen som dyker upp i AOC är såklart inte perfekt applicerbara på dina nuvarande problem, men de är speciellt utformade för att tvinga dig att vara noggrann, problemlösande, testande, …

Att parsea och bearbeta information/data är precis sådant man gör dagligen i backend. Aldrig exakt samma som denna, men samma tänk, samma tillvägagångssätt. Parse, bearbera, räkna ut resultat

Sen behöver du såklart inte klara alla dagar och alla problem eller tävla om en plats på leaderboard. Men det är verkligen ingen slöseri med tid om du vill bli bättre på programmering

Permalänk

EN HEL DEL HAR HÄNT - SOM VANLIGT!

Som vanligt har en hel del hänt sedan sist jag skrev: reality-check i Advent of Code, inlämnad slutuppgift i Programmering med C#.NET-kurs, julfirande med ryggskott som oönskad julklapp, letande efter ex-jobb-plats inför V12 2024, jag har missuppfattat det här med sökmotorerna och deras krypande nätspindlar, nyårslöften för 2024, samt en ny användarbild som lanseras/börja användas nästa år.

Reality-check i Advent of Code 2023
När Advent of Code 2023 började den första december 2023 så fick jag med mina slutbetyg i alla kurser fram tills de 3-4 sista kurserna uppleva hur mycket jag egentligen förstår webbkodande och programmering ren i allmänhet. Det blev lite ett uppvaknande där jag insåg att jag må kunna koda CRUD och fullstackar, men jag förstår mig inte på matematik, (kända) algoritmer eller avancerade datastrukturer.

Jag klarade ett par dagar sedan fick jag erkänna för mig själv att jag inte är duktig på Advent of Code helt enkelt. Således slutade jag följa och skriva den tråden på Sweclockers såväl som i vissa Discord-grupper. Som tur var är det inte nödvändigt att alla uppdragsgivare och/eller arbetsgivare bryr sig om hur många dagar i Advent of Code {år} en har klarat för att anlita/anställa en för uppdrag/arbete.

Inlämnad slutuppgift i Programmering med C#.NET
Jag lyckades slutföra och lämna in ena slutuppgiften i ena parallellkursen väl innan Julafton. Vad jag valde att göra i slutuppgiften var en mycket förenklad kommandotolk där en systemadministratör kan CRUDa användare i en databas av typen MongoDB. Nedanför har jag filerna Connection.cs och Login.cs varav första etablerar och returnerar en Http-anslutning för att sedan kunna anropa mot en databas. Den andra är för att kunna logga in mot REST API:t. Det rekommenderas i Microsoft mycket icke-nybörjarvänliga dokumentation att du endast etablerar ett httpClient-objekt för att inte orsaka "socket exhaustion". Och det tyckte jag inte var några konstigheter.

Däremot hela den strikta datatyphanteringen i C#.NET såväl som klurigheterna med att hantera JSON-datatyper var en tillfällig huvudvärk att få koll på. Debugging i C#.NET kräver även att du kör med breakpoints på rätt ställen för att kunna få inspektera lokala variabler och även då är det mycket klurigt för det framgår inte på något "uppenbart" vis hur olika klasser (t.ex. httpClient) är strukturerade med fält, egenskaper, och/eller metoder.

Hursomhelst så gick det vägen och jag fick till en simpel kommandotolk där allt sker inuti ett simpelt Console App-fönster där du skriver först kommando och sedan dess parametrar per rad. Jag fick även till en intressant lösning för att validera inmatningen av kommandon för att säkerställa att kommandot som angavs ens stöds samt att rätt antal parametrar angetts innan det skickades iväg till REST API:t.

Lösningen för att skicka iväg CRUD-anrop till REST API:t återfinns i utdrag enligt nedan från filen MakeRequest.cs vilket jag är mycket stolt över i hur simpel den är. När en anslutning etableras och sedan inloggning lyckas så erhålls en Access Token som lagras i anslutningsobjektet vilket sedan kan användas för att kunna göra auktoriserade CRUD-anrop mot REST API:t.

Anslutningsdelen från MakeRequest.cs:

// bool is whether Response Code is OK or not | resData includes actual JSON response bool resStatus = false; string resData = ""; try { // Create HttpRequestMessage object var reqAll = new HttpRequestMessage { // Choose correct HttpMethod by provided variable Method = methodType == "get" ? HttpMethod.Get : methodType == "post" ? HttpMethod.Post : methodType == "put" ? HttpMethod.Put : HttpMethod.Delete, // Set correct REST API Endpoint by provided string variable RequestUri = new Uri("http://localhost:5000/api" + apiStr), // Finally set any possible JSON Body data Content = new StringContent(jsonString, Encoding.UTF8, "application/json") }; // Make request var resAll = await httpClient.SendAsync(reqAll); // Handle status code and return either OK with JSON if (resAll.IsSuccessStatusCode) { string responseContent = await resAll.Content.ReadAsStringAsync(); resData = responseContent; resStatus = true; return (httpClient, handler, resData, resStatus); } // Or NOT OK with JSON else { string responseContent = await resAll.Content.ReadAsStringAsync(); resData = responseContent; resStatus = false; return (httpClient, handler, resData, resStatus); }} catch (Exception ex)// Catch any possible errors raised and just say it failed talking to the REST API { resStatus =false; // To avoid ambiguity with Newtonsoft.JSON resData = System.Text.Json.JsonSerializer.Serialize(new {error = "Misslyckades kommunicera med REST API:t. Prova igen!"}); return (httpClient, handler, resData, resStatus); }

Dold text

Connection.cs

internal class Connection // Class that just returns the default initialized connection needed { // Return an object tuple with the httpClient and httpClientHandler that extracts cookies! public static (HttpClient httpClient, HttpClientHandler handler) CreateHttpClientAndHandler() { // Handler object is to grab httpOnly secured cookies! HttpClientHandler handler = new HttpClientHandler(); handler.UseDefaultCredentials = true; // Create httpClient object, only one instance will be needed! HttpClient httpClient = new HttpClient(handler); // Starting REST API address to connect to (so we can just change with "api/{endpoint}" later on) httpClient.BaseAddress = new Uri("http://localhost:5000/"); // Add necessary headers before sending POST request httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); // Return the object tuple, so it also has access to the handler object separately! return (httpClient, handler); } }

Dold text

Login.cs

internal class Login // Class that just allows you to login! And it is of type "Task" just so it can use async correctly! { public static async Task<(HttpClient httpClient, HttpClientHandler handler, bool loggedIn, bool serverOnline)> AttemptLogin(HttpClient httpClient, HttpClientHandler handler, bool loggedIn, bool serverOnline) { // Prepare variables and ask for input string loginJSON = ""; string usernameAndpassword = ""; string username = ""; string password = ""; int firstSpacePos = 0; // Loop until break; is used while (true) { // Ask for input Console.Write(">"); usernameAndpassword = Console.ReadLine(); // Check that if (usernameAndpassword.Contains(' ') && usernameAndpassword.Length >= 3) { // Split username and password by finding the first whitespace and then split with substring firstSpacePos = usernameAndpassword.IndexOf(' '); // Check if the firstSpacePos is not first or last in string if (firstSpacePos > 0 && firstSpacePos < usernameAndpassword.Length - 1) { username = usernameAndpassword.Substring(0, firstSpacePos); password = usernameAndpassword.Substring(firstSpacePos + 1); break; // break out of loop when all OK! } } // Only shown when failed above Console.WriteLine("\u001b[31m[FEL]:\u001b[0m Separera användarnamn och lösenord med ett mellanslag!"); } // INPUT VALID -> Split username and password by finding first whitespace and then split with substring firstSpacePos = usernameAndpassword.IndexOf(' '); username = usernameAndpassword.Substring(0, firstSpacePos); password = usernameAndpassword.Substring(firstSpacePos+1); // Create JSON Body with those values loginJSON = @$"{{""username"": ""{username}"",""password"": ""{password}""}}"; // password in REST API is:superAdmin1337 username = ""; // empty the string because of sensitive data password = ""; // empty the string because of sensitive data usernameAndpassword = ""; // empty the string because of sensitive data // Make the POST request to the endpoint http://localhost:5000/api/login try { HttpResponseMessage response = await httpClient.PostAsync("api/login", new StringContent(loginJSON, Encoding.UTF8, "application/json")); loginJSON = ""; // empty the string because of sensitive data // When login was successful (only then do we receive 2XX status code!) if (response.IsSuccessStatusCode) { // Grab cookies var httpOnlyCookie = handler.CookieContainer.GetCookies(httpClient.BaseAddress); // Read and display the content string content = await response.Content.ReadAsStringAsync(); // Serialize & extract accessToken from the `response.Conent` JObject jsonResponse = JObject.Parse(content); string accessToken = jsonResponse["accessToken"].ToString(); // Insert into Header "Authorization" to be used for future HTTP requests httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken); // If we managed to login then set to "true" and return the new connection + loggedIn=true // THE NEW CONNECTION WILL ALSO HAVE THE httpOnly secure cookie neded for future REST API requests! loggedIn = true; serverOnline = true; return (httpClient, handler, loggedIn, serverOnline); // accessToken is used for real requests whereas httpOnly secure cookie just refreshes those! } // Otherwise we return some other status code (NOT 2XX) else { // If we managed failed to login then set to "false" and return the new connection + loggedIn=false meaning the while loop will continue! loggedIn = false; serverOnline = true; return (httpClient, handler, loggedIn, serverOnline); } } // Handle exceptions when REST API not online for whatever reasons catch (HttpRequestException ex) { loggedIn = false; serverOnline = false; return (httpClient, handler, loggedIn, serverOnline); } catch (Exception ex) { loggedIn = false; serverOnline = false; return (httpClient, handler, loggedIn, serverOnline); } } }

Dold text

Jag lämnade in det för länge sedan nu och för den som är intresserad så återfinns GitHub-repot här. Det går att köra lokalt förutsatt att du har MongoDB konfigurerat att kunna köras lokalt (allt står i README i repot). Allt ingår där, inklusive testdata att köra med lokalt.

Julfirande med ryggskott som oönskad julklapp
Jag filade Julafton på annan ort där det blev så mycket snöskottande att jag drabbades av ryggskott eller någon form av överansträngning i nedre ryggraden i högra musklerna där. Fortfarande kvar, men inte lika illa som den 22:a december 2023 när jag först drabbades av det. Julfirandet blev minimalt då jag inte längre tycker det är någon särskild tillställning då varken jag eller mina syskon har barn vilket jag anser Julafton är främst till för. Jag fick en praktisk julklapp trots att jag inte hade önskat mig något.

Ingen ex-jobb-plats ännu spikad inför V12 2024
Jag har fått cirka 5 avslag om jag räknat rätt medan jag har skickat runt cirka 20 ansökningar om ex-jobb inför V12 2024 när Självständigt arbete-kursen börjar vilket är sista kursen i Webbutvecklingsprogrammet. Efter det så startar jag nog en ny Webbutvecklingsdagbok här om vad jag har för mig om dagarna efter den färdiga utbildningen.

Jag inväntar fortfarande svar från ett eventuellt lokalt IT-bolag här i stan som jag bor cirka 3 km från för att en intervju ska äga rum någon gång under V2 där det självständiga arbetet då skulle bli att jämföra AI-plattformar som erbjuder strukturering av icke-strukturerade data och sedan implementera lösningar på dessa och rapportera i Självständiga arbetsrapporten och deras olika för- & nackdelar med de olika AI-plattformarnas lösningar såväl som för- & nackdelar med mina egna implementerade lösningar för att omvandla icke-strukturerade data till strukturerade data med hjälp av de olika AI-plattformarna.

Om Du eller Din arbetsplats där du arbetar behöver cirka 300 timmars gratis arbetskraft inom webbutveckling så får du gärna höra av dig till mig! Cirka 100 timmar kommer att gå åt till rapportskrivandet och det kommer att bli den sista rapporten jag kommer att behöva skriva. Rapportskrivande är något jag har blivit riktigt less på, inte webbkodandet. Det sistnämnda har faktiskt bara blivit roligare om än ansträngande till och från vilket är en del av "kodvardagen" numera!

Jag har fått sökmotorers nätspindlar helt om bakfoten
I en annan tråd här på Sweclockers frågade jag om hur just sökmotorers nätspindlar faktiskt fungerar. Jag hade fått för mig - och därmed helt om bakfoten - att de kan på något magiskt och då illegalt vis läsa av alla nödvändiga webbfiler hos webbplatser för att kunna indexera dessa sedan i sökmotorresultaten. Självfallet går det inte till så.

Utan sökmotorernas nätspindlar är helt enkelt vilka web crawlers som helst och samtidigt de slags web crawlers som majoriteten av webbplatser gärna låter "grävas" av i hopp om att hamna högre upp på sökresultaten. Då jag ska skapa en egen webbplats med tusentals undersidor så funderade jag på modulär struktur genom PHP-filer och då trodde jag först att då PHP-filer renderas på servern och skickar tillbaka HTML så hade jag fått för mig att web crawlers då läser av PHP-filerna och därmed missar massa dynamiskt genererad data (under renderingen på serversidan innan vanlig HTML skickas) och därmed inte kunna indexera det.

Detta hade jag enligt tråden ovan helt fel om och det gör mig glad för då kan jag köra på ett modulärt och strukturerat vis så att jag kan ha olika PHP-filer som går att bygga på utan att varje undersida måste uppdateras. Jag tänker tillbaka på Webbanvändbarhetskursen där endast HTML-filer skulle skapas och det fanns cirka 15 olika undersidor där varje undersida behövde samma navigering och så fort jag ändrade i navigeringen i en HTML-fil så behövde alla övriga också uppdateras - helt manuellt.

Nyårslöften för 2024
Jag har tre Nyårs(bryt)löften för 2024 varav en är webbutvecklingsrelaterad:

1. Börja gymma 4 gånger i veckan igen vilket jag har tidigare gjort men slutade för ett par månader sedan vilket säkerligen har varit en bidragande faktor till mina plötsliga ryggbesvär som en avdankad 34-åring. Min gymkort löper ut någon gång i februari nästa år så då blir det också påfyllning!

2. Börja koda varje vardag istället för dessa "sprintar" jag har och med sprintar menar jag då att jag kan sätta mig ned och koda mellan 6-10 timmar i sträck tack vare mina Aspergertendenser och sedan kodar jag inte på ett par dagar för att jag får så mycket gjort under den där tiden. Samtidigt har jag blivit mycket bättre i början på andra läsåret där jag lärde mig den hårda vägen med att dra ut på saker och ting i skolarbetet (=kodandet så att säga). I och med att nästa år så blir jag färdig med distansutbildningen så blir det samma klassiska kneg igen online och då kommer jag att behöva vara vass, skarp och ständigt utvecklande i mitt webbkodande i samverkan med att jag söker och sköter arbete - förhoppningsvis - för det mesta online/på distans.

3. Byta användarbild här på Sweclockers och på Discord vilket jag berättar mer om i den sista rubriken här nedan.

Till sist: ny användarbild nästa år
Nästa år kommer den "Påtända kodråttan" att digi-utvecklas till "CodeBacca" vilket kommer att framgå klart och tydligt varför den plötsliga namnändringen i samband med användarbildbytet!

På återseende - som vanligt, i framtiden!

Mvh,
WKL.
---------
✔️Kurs 1: HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
🚧Kurs 11: (Slutuppgift pågår) VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
🚧Kurs 12: (Inväntar slutbetyg) VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk
Skrivet av Pelegrino:

Webbutveckling och algoritmer är två helt olika saker. Jag har en femårig civilingenjörsexamen i datateknik samt 2års arbetslivserfarenhet i webbutveckling och har själv gett upp med AoC för jag orkar inte, det är för energikrävande.

Att vara duktig programmerare och duktig på AoC är inte samma sak, algoritmer är ren problemlösning. Detta påminner lite om när du för något år sedan ifrågasatte ingenjörer för att de inte kunde just komplexa algoritmer :I)

Jag får helt enkelt ta tillbaka allt jag sa om dem. Jag ställde krav på andra utan att själv kunna leva upp till dem! 🤦‍♂️

Skrivet av medbor:

Att läsa andras kod som du inte själv skrivit, i språk du inte vanligen använder är viktigt. Det kommer bredda din kompetens, allting med ’korta variabelnamn’ och ’inga kommentarer’ tillhör vardagen för de flesta i branchen

Problemen som dyker upp i AOC är såklart inte perfekt applicerbara på dina nuvarande problem, men de är speciellt utformade för att tvinga dig att vara noggrann, problemlösande, testande, …

Att parsea och bearbeta information/data är precis sådant man gör dagligen i backend. Aldrig exakt samma som denna, men samma tänk, samma tillvägagångssätt. Parse, bearbera, räkna ut resultat

Sen behöver du såklart inte klara alla dagar och alla problem eller tävla om en plats på leaderboard. Men det är verkligen ingen slöseri med tid om du vill bli bättre på programmering

Ja, så här lite i efterhand och när "kodpaniken" har lagt sig och självbilden har återhämtat sig så inser jag nu värdet i dessa kodalgoritm-utmaningar då de tvingar en att tänka mer noga stegvis såväl som att hantera Ordo-grader. Jag har kikat på en YT-video om "algoritmer och datastrukturer" där algoritmer sedan presenteras med olika Ordo-grader.

Algoritmer med rekursion oroar mig dock i och med risken för StackOverflow (fenomenet, inte webbplatsen). Exempelvis vill jag skapa en algoritm som kan kartlägga ett DOM-träd som då börjar från body-elementet men utan att den använder rekursion för att räkna hur djupt det är och sedan kontrollera nodtyp (bl.a. kommentarer ska ignoreras) och endast bry sig om vissa nodtyper som en del av DOM-trädkartläggningen. Ja, denna algoritm finns garanterat redan, men jag vill lyckas skapa en egen för att få någon slags djupare förståelse av hur en måste koda så att datorn gör som en vill att den ska göra!

Det var någon JavaScript-konferens som jag såg på YT där en person visade två funktioner som anropade varandra hela tiden och i första exemplet så kraschade den då via stack overflow. Sedan i andra exemplet så anropade funktionerna istället varandra genom att de var båda function* generators. Då kunde de anropa varandra i evigheter utan att programmet kraschade via stack overflow.

Om jag inte minns fel så ska Promise-objektet i JavaScript vara en slags function* generator? Den mentala utmaningen jag har just nu med function* generators är att förstå hur jag ska använda deras yield för att få dem att fortsätta arbeta då de tycks arbeta i iterationer och inte bara körs rakt av som en vanlig function? 🤔

Mvh,
WKL.

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk

SNABB & KORT UPPDATERING!

Från en Påtänd Kodråtta till en CodeBacca!
Det har nu gått "snart" två år sedan jag påbörjade utbildningen. Jag anlände till distansutbildningen som en "Påtänd Kodråtta" vilket framgår i bilden nedan:

Dold text

Sedan nu i början på 2024 så har jag blivit en "CodeBacca" som jag kallar det för där jag har samlat på mig åtminstone grundläggande webbutvecklingskunskaper och förmågor:

Dold text

Sammanfattningsvis så skedde omvandlingen så här:

Dold text

Den som känner igen "etiketterna" och "medlajerna" den känner igen!

Beträffande nyårslöftena och studierna för övrigt...
Igår var jag och gymmade efter uppehåll sedan den 29:e augusti 2023 vilket är alltså lite mer än 3 månader sedan. Idag tog jag en promenad på 6 km och valde att vila kroppen då det blev en liten "träningschock" och så vill jag inte riskera problem i ryggen igen som följd av snöskottningen från "förra året". Imorgon blir det däremot ett lätt underkroppspass där jag alltså kommer att träna benen, låren, vaderna, samt magen igen.

Jag har nu snart skrivit färdigt Introduktion-, Metod- & Teoridelarna i Projektrapporten för JavaScript-kursen vilket är det tråkigaste jag har varit med om. Att skriva projektrapporter överhuvudtaget utan att de faktiskt uppskattas något särskilt mycket är riktigt tröttsamt nu sisåhär ~1,5 år senare. Det känns som att de tar längre tid att skriva ihop än antalet poäng de utgör i betygsättningen vill säga.

I kodbasen för REST API:t så har jag nu en middleware som hanterar datavalidering innan dessa ens skickas vidare till till rätt rutt för att hantera given CRUD. Exempelvis vid registrering så skickas req-objektet först för att validera att all rätt slags data finns annars så skickas lämplig JSON och statuskod om att inmatningen måste justeras. Inuti rutten för given CRUD så sköts då istället kontroller mot databas (t.ex. om användarnamn och/eller e-post redan används) då den rutten då kan betrakta all data som korrekt angivet men inget mer än så.

Jag håller också på att läsa på om frontend "funktionsbiblioteket" ReactJS och tydligen så är:

<> </> // samma sak som: <React.Fragment> </React.Fragment> // likt hur i Vue.js: @ // är samma som: v-on

I alla fall om chatGPT3.5 talar "sanning". Det förstnämnda i koden är "syntaxsocker" helt enkelt. Utan att jag egentligen förstår varför det är så så verkar det vara som så att ReactJS inte kan tolka (eng. parse) ens DOM korrekt om man inte sveper runt all ens JSX mellan de där fragmenttaggarna eller genom att första elementet är förälder med nästlade element. Då behövs inte fragmenttaggarna. Men varför det är så och måste göras på så vis utifrån någon teknisk begränsning har jag ingen djupare förståelse om varför det är implementerat som så och inte har kunna(?) lösts på något annat vis.🤔

Sedan har vi andra funderingen om användningen av "prop drilling vs useContext". På något vänster så här på förhand så känns ju useContext lämpligt för ett stort föräldraelement som jag vet kommer behöva möjliggöra all sin data för alla sina barnelement under sig? Och då slipper jag ju lägga till för prop drilling så fort jag kommer något nytt jag vill att barnelementen ska komma åt från sin förälder? Eller är det något med prestanda här som gör att prop drilling är mer att föredra än useContext i många/få fall? 🤔

Webbutvecklingsprogrammet fortsätter även 2024 fram till och med V22 när sista veckan i Självständigt arbete-kursen då har nått sitt slut!😎

På återseende - som vanligt, i framtiden!

Mvh,
WKL.
---------
✔️Kurs 1: HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
🚧Kurs 11: (Slutuppgift pågår) VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
🚧Kurs 12: (Inväntar slutbetyg) VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk
Medlem

Använder du TypeScript?

Propdrilling är oftast inget problem.

const Parent = () => { return <Child1 props={props} /> type Child1Props = { .... massa props } const Child1 = (props: Child1Props) => { const onChange = () => {...} return <Child2 onChange={onChange} {...props} /> } type Child2Props = Child1Props & { onChange: () => void } const Child2 = ({onChange, ...rest}: Child2Props) => { return ( <Button onClick={() => onChange} /> <OtherComponent {...rest} /> ) }

Generellt ska du i de flesta fall använda prop drilling.
Context ska du använda främst när du vill dela state i hela applikationen.

T.ex. om du har egen autentisering så wrappar man hela applikationen.
Sedan så har context t.ex. en hook:

const {user} = useAuth() som ger dig tillgång till den inloggade användarens information oavsett vart du är.

const AnyComponent = () => { const {user} = useAuth() .... } const App = () => { return ( <AuthProvider> <MyApp/> </AuthProvider> ) }

En annan sak du bör läsa på om är hur renderingen fungerar i React.
Ändrar du state i en "förälder" så kommer alla "barn" också renderas om.

Därav vill man oftast isolera saker ned i så små bitar som möjligt.

Tänk att du har en stor lista som är tung att rendera. Sedan har du en knapp för att öppna en dialog (för att lägga till nya element i listan). Här ändrar du state via att sätta openDialog till true - varav hela listan och dess underliggande element renderas om.

const MyHugePersonnelList = () => { const [personnel, setPersonnel] = useState([]) const [openDialog, setOpenDialog] = useState(false) return ( <> <Dialog open={openDialog} onAdded={(newPersonnel) => setPersonnel([...personnel, newPersonnel])} /> <Button onClick={() => setOpenDialog(true)}> Add personnel</Button> <HeavyList rows={rows} /> </> ) }

Detta löser man via att göra om knappen till en egen komponent.

type AddPersonnelButtonProps = { onAdded: (personnel: Personnel) => void } const AddPersonnelButton = ({onAdded}: AddPersonnelButtonProps) => { const [showDialog, setShowDialog] = useState(false) return ( <> <Dialog open={openDialog} onAdded={onAdded} /> <Button onClick={() => setOpenDialog(true)}> Add personnel</Button> </> ) } const MyList = () => { const [rows, setRows] = useState([]) return ( <> <AddPersonnelButton onAdded={(personnel) => setRows([...rows, personnel])} /> <HeavyList rows={rows} /> </> ) }

Visa signatur

10700K | NVIDIA RTX 3080

Permalänk

Som vanligt så har en hel del hänt!

Som vanligt som sagt var så har en hel del hänt sedan senast. Bland annat har jag fått en tidigare parallellkurs rättad, godkänd och betygsatt nu (C#.NET-introduktionskursen), möjligen har jag spikat ett ex-jobb på riktigt nu, samt att jag påbörjat Blazor (WebAssembly|Server)-kursen nu eller "Webbutveckling med .NET" som det heter, samt att jag har påbörjat världens tråkigaste kurs (affärsplaner och kommersialisering).

Äntligen är C#.NET-introduktionskursen över!
Jag har nu fått rättat, godkänt och nästan oförskämt högt slutbetyg i C#.NET-introduktionskursen (DT071G). När jag läste kommentarerna så upptäckte jag att jag fick poäng för småsaker såsom skisser och flödesscheman i min projektrapport.

Detta betyder att i andra parallellkursen där jag fortfarande inväntar slutbetyg (DT162G) där jag inte har några flödesscheman på grund av illamående i kroppen av hur dåligt upplagda dessa kurser har varit så kommer jag garanterat få lägre slutbetyg.

Men jag har ändå lärt mig förhållandevis "helt OK" MERN-stack trots att jag fått något buggigt (=okunnigt kodande från mig) med useEffect() och useContext när state för om huruvida en är inloggad eller inte.

Vad som händer är att jag har en boolean "isLoggedIn" som skickas via en AuthContext.Provider ned till alla "undersidor" (via Routes via react-router-dom) och en useEffect() som körs för alla undersidor är att kolla boolean-värdet för "isLoggedIn" som nås via useContext() på varje undersida då.

Är denna false så ska användaren föras till "/login", dvs., inloggningssidan. Men det som verkar hända vissa gånger är att du kommer till startsidan efter lyckad inloggning (vilket är där du hamnar om du faktiskt är inloggad och försöker gå till registrera- eller logga in-sidorna) är att om du klickar på någon länk så tas du direkt tillbaka till startsidan som om den försökte ta dig till inloggningssidan som om "isLoggedIn" är false. Fast när jag har React-Web Developer Tools-extension öppet i FireFox så ser jag inte att värdet har ändrats när jag besöker olika sidor.

Dessutom inträffar det skumma bara vid första klicket efter lyckad inloggning. Så navigera till en undersida, hamna på startsidan igen som om jag ej hade åtkomst, men sen när jag klickar på exakt samma undersida igen så inträffar inte den buggen (=okunnigt kodande från mig med andra ord).

Så global states var en smärta i ReactJS och jag var osäker på hur många "färdiga lösningar" jag kunde använda mig av utan jag ville hålla mig så "vanilj" jag kunde dock så använde jag axios för att kunna nyttja dess sexiga interceptors-objekt för att kunna förnya åtkomstnycklar (access_token) med hjälp av httpOnly-säkrade förnyelsenycklar-(refresh_token)-kakor.

Komponentbaserade states var inga större problem och det var mysigt hur när ett CRUD-anrop gick igenom jag då bara även ändrade rätt objekt i en state-medveten datalista och sedan renderade om. Dock är det klurigt att förstå riktigt alla olika saker som leder till re-renders. Jag tror att useRef() hade varit rätt väg att gå med för att styra det här med "isLoggedIn"-boolean som annars var useState-deklarerad?

Jag inväntar nu som sagt slutbetyg på JS-kursen (där MERN-stacken beskriven ovan tillämpades) vilket jag tror kommer bli lägre än i C#.NET-kursen trots att jag har mycket mer omfattande REST API i JS-kursen. Det blir vad det blir!

Äntligen(?) har jag blivit med ex-jobb-plats?!
För ett par veckor sedan lade en Lärare upp om ett lokalföretag här i stan som sökte efter potentiella ex-jobb-studenter och då dröjde jag ett par dagar innan jag slängde iväg ett mejl. Jag kikade på deras uppdragsbeskrivningar och de verkade intressanta så jag mejlade iväg och bara några dagar senare fick jag svar om inbjudan till inledningsmöte.

Det ägde rum förra veckan och där verkade vi redan ha kommit överens om att de ska skicka mer exakt data om vad som exakt önskas från dem (det är databasbaserat +adminpanel för särskild CRUD - något jag gjort i flera kurser nu). Kruxet med detta företag är dock att det finns inga riktigt IT-insatta då det ej är inom IT-sektorn så jag blir den enda IT-insatta personen där.

Och den lilla biten som "oroar" mig då och som jag funderar på är just hur det ska göras med deployment beroende på vald techstack. Det vanligaste svenska webbhotell erbjuder verkar vara stöd för PHP, JS, CSS och därmed MySQL/MariaDB som databaslösning. Så att försöka köra på MongoDB kommer inte att gå eftersom då blir det problematiskt med GDPR då jag inte vet om Atlas ens lever upp till det?

I och med företagets storlek så betvivlar jag på att de skulle vilja investera i ytterligare månadskostnader med en VPS hos något svenskt webbhotell som jag sedan konfigurerar och langar upp någon MERN-stack eller annan "ovanlig techstackslösning" (kanske Laravel?).

Hursomhelst så var det roligt när de beskrev verksamheten för då blev det faktiskt en slags "flashback" och som i filmer när huvudpersonen hör någon "mentor" tala i deras öra om "lessons of the past". I mitt fall kunde jag höra databasläraren som pratade om normalisering och det här med att bryta ned en beskriven verksamhetsbeskrivning till entiteter med attribut och sambanden/relationerna mellan dessa entiteter!

Företagets önskemål kunde jag då i mitt huvud redan börja spåna på hur de skulle lösas som. Då det hela handlar om en viss slags CRUD inom ett slags administrationsanvändargränssnitt där också vissa andra externa användare ska få begränsad roll så är det ju perfekt: jag har redan gjort några projekt nu med rollbaserad åtkomst och där en administratör ("sysadmin" någon?!) har all makt ("All makt till sysadmin!").

I samma möte erkände jag även att "frontend, dvs., vad som är snyggt utseende är något av min svaghet, men om ni kan berätta vad ni tycker är snyggt så kan jag koda fram det". En av personerna i mötet arbetar just som grafiker så denna person kommer att kunna vägleda mig rent estetiskt hur de vill ha det så kan jag med CSS-kodande (förmodligen TailwindCSS) att kunna ta fram det. Vid leverans vill jag självfallet ha färdigbyggd CSS-fil och inte så att TailwindCSS-skript ska köras varje gång.

Nu nästa vecka ska de återkomma med mer exakt beskrivning såväl som viss förenklad skiss på hur de önskar att det ska se ut. Annars så har de en webbplats vars färgschema det skulle kunna gå att utgå ifrån efter godkännande från dem såklart. Just nu så verkar funktionaliteten vara det viktigaste genom att få till det rätt med entiteterna, deras attribut, och deras samband med varandra. Ja, det lutar mycket mot MySQL/MariaDB eller kanske PostgreSQL? Så länge deras nuvarande webbhotell stödjer det så. Relativt osannolikt att företaget vill investera i en VPS för denna lösning. Kräver ju då också underhåll på lång sikt.

Världens tråkigaste kurs som inte får nämnas!
Jag läser för närvarande en av världens tråkigaste kurser: Affärsplaner och kommersialisering. Det är inte bara att den är tråkig utan den kommer även att utgå nästa år för de som läser läsåret 1 just nu medan jag läser läsåret 2 (andra/sista läsåret).

Därför känns kursen riktigt meningslös så jag kommer knappt att anstränga mig i den kursen för det är saker som går att lära sig i efterhand. Det enda jag tagit med mig hittills från kursen är att, "En välskriven affärsplan talar väl om en som person i affärssammanhang. En slarvig, dåligt genomtänkt affärsplan talar illa om en själv som person i affärssammanhang." Det är det och mer än så kommer jag inte ens att nämna om kursen utan jag återkommer med slutgiltigt betyg om den vid ett senare tillfälle!

Den roligaste kursen hittills - men också den tyngsta av dem alla innan ex-jobb-kursen!
Den andra parallellkursen jag läser för närvarande är Webbutveckling med .NET och den är riktigt tung i och med mina bristande förmågor med C#.NET, främst gällande hantering av klasser+JSON och klasser delvis allmänt i och med att jag bråkat med protected, private, public åtkomstvariationerna till och från.

Nu handlar det dock om ASP.NET Core MVC, Blazor WebAssembly & Blazor Server där Entity Framework (Microsoft SQL antar jag?) används som databaslösning. Till slutuppgiften tänker jag mig en "simpel" webbshop där användare ska kunna surfa och lägga till varor till en varukorg (vilket då behöver global state management-lösning av något slag) och sedan kan gå till kassan och lägga en beställning. Därpå kan en administratör (som vanligt!) gå in i en adminpanel och godkänna och/eller neka en given beställning beroende på rimligheten (69421337 varor av något slag kan bedömas som orimligt beroende på vad för slags vara det är).

Men innan slutuppgiften så var det först grunderna i .NET (en ASP.NET Core Web App med Razor + en Blazor WebAssembly app), ASP.NET Core MVC-arkitekturen, sedan Entity Framework Core, webbtjänster (REST API:er med hjälp av C#.NET), och till sist projektuppgiften vilket jag kallar för slutuppgiften. Det blir både kul, spännande, läskigt och min andra akilleshäl är nog det här med strikt typad objektorienterad programmering såsom C#.NET samt mina estetiska svagheter inom frontend!

På återseende - som vanligt, i framtiden!

Mvh,
WKL.
---------
✔️Kurs 1: HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
🚧Kurs 11: (Inväntar slutbetyg) VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
✔️Kurs 12: VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)
🚧Kurs 13: (Pågår) VT2024 DT191G Datateknik GR (B), Webbutveckling med .NET, 7,5 hp (distans)
🚧Kurs 14: (Pågår) VT2024 IG021G Industriell organisation och ekonomi GR (A), Affärsplaner och kommersialisering, 7,5 hp (distans)
🚧Kurs 15: (Spikat ex-jobb?|V12-V22) VT2024 DT140G Datateknik GR (B), Självständigt arbete, 15 hp

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk
Medlem

Gällande ditt exbjobb kan jag rekommendera deployment via Azure. Det är vanligt i yrkeslivet så fint att ha på ditt CV. Jag använde det själv vid mitt exjobb utan någon tidigare kunskap kring det.

Inte särskilt dyrt, och du kan sätta upp en prototyp för exjobbet helt gratis.

Frontend levereras via Azure static web app / web app.
Backend finns flertalet olika databastyper att välja på (https://azure.microsoft.com/en-us/products/category/databases)

Går även ha ditt repo via Azure och sätta upp pipelines som deployar till din web/backend vid förändringar i repot. Väldigt smidigt.

Visa signatur

10700K | NVIDIA RTX 3080

Permalänk
Skrivet av kwame:

Gällande ditt exbjobb kan jag rekommendera deployment via Azure. Det är vanligt i yrkeslivet så fint att ha på ditt CV. Jag använde det själv vid mitt exjobb utan någon tidigare kunskap kring det.

Inte särskilt dyrt, och du kan sätta upp en prototyp för exjobbet helt gratis.

Frontend levereras via Azure static web app / web app.
Backend finns flertalet olika databastyper att välja på (https://azure.microsoft.com/en-us/products/category/databases)

Går även ha ditt repo via Azure och sätta upp pipelines som deployar till din web/backend vid förändringar i repot. Väldigt smidigt.

Vad som är "dyrt" och "billigt" är givetvis relativt! Tanken är att slutanvändaren och dess eventuella kunder ska kunna nyttja en frontend som då talar med en backend vars databas (troligtvis MySQL av något slag) och frågan är hur många DB-anrop som får göras per månad innan det börjar kosta kanske per 1000-tals anrop eller hur prisuppsättningen fungerar?

Jag har som sagt var mycket begränsad erfarenhet av deployment-biten inom Webbutveckling än så länge. Sedan har vi också biten att förklara detta på ett jordnära vis för slutanvändaren i detta ex-jobb-projekt som INTE är tekniskt insatt överhuvudtaget utan på sin höjd har enbart en webbplats vars techstack ser ut att vara en Wordpress-temamall utvecklat av en anlitad webbyrå för ett tag sedan.

Så det är några bitar att överväga för att hitta en så bra gyllene medelväg så gott som det går!

Det hela är en mycket bra "deployment-kurs" för min del då i samma veva.

Mvh,
WKL.

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk

KOLSYRA-MUSTIG UPPDATERING! 😲

Endast tre kurser kvar, EF Core i C#.NET är på gott och ont, Microsofts subdomän är inte alls nybörjarvänligt, jag har gått och blivit med ex-jobb, webbutvecklingsmarknaden ser inte bra ut för nyexaminerade, och vad händer med denna dagbok efter att webbutvecklingsutbildningen är över efter dessa snart två år?...

Endast tre kurser återstår!
Med glädjande besked kan jag meddela att jag officiellt enbart har kvar tre kurser i den distansbaserade Webbutvecklingsutbildningen. Vecka 12 så börjar den sista kursen vilket är Självständigt arbete vilket i sin tur pågår i 10 veckor. Sedan är det bara att ansöka om examensintyg och börja leta jobb antar jag!

Fortfarande är C#.NET Webbutvecklingskursen roligast medan den andra är så tråkig att jag får gallfeber. Gruppmöten dagarna in och ut och konceptet med affärsplaner går ändå att leta upp i efterhand eller lära sig av redan färdiga officiella affärsplaner. *Gäsp* alltså!

Entity Framework (EF) Core är både angeläget och smått komplicerat
I den roligare kursen Webbutveckling med .NET så är Entity Framework Core (EF Core) - ett ramverk för relationella databastyper(?) - både mysigt och krångligt. En utmaning är att då det abstraherar en hel del åt en och ASP.NET Core är som det är redan så är det ibland (oftast) svårt att förstå vad som ens "händer under motorhuven".

Det är bara att läsa så kallad "officiell dokumentation", mata in kod, anpassa lite och hålla tummarna att det fungerar när det väl körs för fungerar det inte och dess stack trace visas så är åtminstone jag helt chanslös att kunna lösa det. Jag var ej med och skapade C#.NET-arkitekturen så jag kan då inte i efterhand korrigera eventuella fel i hur den vill hantera saker och ting!

Sedan så förvirras jag smått av dbContext hit och dit, men jag antar att det är ett klassobjekt för en databassession (alltså en etablerad anslutning med tillgång till ett antal tabeller via satta dbSet<Table>() inuti dess konstruktör? 🤔 (jag har ingen aning om jag ens bara svamlade fikonspråk helt fel nu)

När det väl fungerar så är det dock smidigt! Samtidigt måste jag slå MVC på fingrarna för ATmodel-direktivet i en given Controller-fil innebär ju att nu helt plötsligt så blir det en delvis "koppling" (coupling) inuti den givna Controller-filen och vald ATmodel-klass medan MVC-arkitekturen är tänkt att skapa "separation of concerns" mellan dessa tre delar?

Möjligen tänker jag på ett REST API här där "kopplingen" är mycket lösare mellan Controller och Model då jag via REST API:t skulle kunna ansluta till flera olika (slags) databaser och sedan endast returnera konsekvent JSON-data istället för att vara fast i ett returnera en given Vy som i MVC-fallet? 🤔

Learn.Microsoft.com behandlar oss "nybörjare" som skämt
På tal om C#.NET och att lära sig helt nya ramverk och programmeringsspråk så måste jag säga att Learn.Microsoft.com behandlar mig som "nybörjare" som rena rama skämten. Det är mer eller mindre omöjligt att hitta något vettigt där och alla diverse Tutorials är begränsade utifrån ändamålen jag har som studerar en kurs i Webbutveckling med .NET.

Tack gode KodGud så finns det en hel del material på svenska i denna kurs till skillnad från tidigare C#.NET-introduktionskurs där det endast var, "Läs dessa kapitel i den icke-obligatoriska kurslitteraturen eller se den officiella dokumentationen".

Den stora utmaningen som jag upplever det just nu med LookUp.Microsoft.Com är att det finns ingen överblick att få över vilka klasser, subklasser, med mera, som är tänkta att användas för diverse vad användningsområden. Bara något så "simpelt" som att vilja hantera HTTP-anrop så hittar du till slut HttpClient men då visar det sig också att du kanske behöver HttpClientHandler om du vill kunna skicka med credentials (t.ex. HttpOnly-säkrade kakor) för det av helt outgrundlig anledning finns inte inbyggt i HttpClient-objektet?! 🥴

Jag börjar förstå den här klassiska meme:n om hur du skapar "Hej Världen!" i JavaScript eller Python kontra C#.NET eller annat valfritt objektorienterat programmeringsspråk (t.ex. Java). När kodbasen växer då börjar meme:n ha något att säga medan det i början kan upplevas som "löjlig jämförelse".

Om NerdNest.Microsoft.com vill kunna bli Learn.Microsoft.com så måste de inkludera - utöver massa tutorials/guider för småsaker - en övergripande blick över vilka klasser, subklasser och klassobjekt som är tänkta att användas för olika användningsområden. För bildhantering, ljudhantering, videohantering, HTTP-hantering, Windowsfönster-hantering, mobila appar, och så vidare.

Det är mina nuvarande "åsikter" och dagliga "rant" om C#.NET!

Exjobb spikat
Det verkar relativt säkert att kunna säga nu att exjobbet är spikat vilket då kommer bli att ta fram ett användarvänligt administratörsanvändargränssnitt för att kunna hantera diverse CRUD vilket företaget ifråga har kartlagt och presenterat i ett par filer jag har erhållit för ett par dagar sedan.

Utöver det så önskas även sökfunktionalitet, sortering utifrån kategorier, såväl som att kunna slumpa fram fem olika sökresultat för externa kunder som skulle vilja nyttja ett annat användargränssnitt av den digitala helhetslösningen. Jag har redan filat på hur detta är tänkt att kunna lösas som.

Den stora rosa elefantfrågan i rummet är deployment, dvs., sjösätta den "färdiga" lösningen. Varför är den så stor och rosa för? Specifikt för detta exjobb så är det endast jag som är den IT-kunniga, den IT-insatta, den som faktiskt agerar den fulla meningen av ordet "konsult". Det är mig som de rådfrågar hur saker och ting bör/kan göras utifrån vad de önskar att få gjort.

Och för närvarande så har detta företag enbart en simpel WordPress-sida med ett kontaktformulär. Jag har ingen aning om vilket webbhotell de använder och/eller vad de har för budget för eventuell skarp sjösättning av denna lösning. Största kruxet i det hela är att jag själv under min utbildning inte har fått prova på faktiska riktiga skarpa sjösättningar mer än Netlify och Studentserver för att på så vis få en känsla för driftkostnader, säkra konfigurationer, med mera.

En skillnad hade varit om ex-jobb var hos ett IT-inriktat företag där det hade funnits handledare/medarbetare som kunde vägleda mig genom dessa steg så jag fick praktisk erfarenhet. Nu måste jag mer eller mindre chansa och prova mig fram vilket känns både läskigt och spännande. Dock dålig sjösättning+drift+underhåll kan innebära en dålig referens efter exjobbet.

Detta exjobb kommer med 99 % sannolikhet INTE att leda till någon form av anställning. På sin höjd kanske ett par uppdrag att ta sig an inom IT-delen. Företaget fokuserar helt enkelt inte så mycket med IT. Spännande och läskigt som sagt!

Framtiden för webbutveckling ser rätt mörk ut just nu
När vi ändå är inne på läskiga saker så ser ju marknaden för webbutvecklingsbranschen inte så god eller ljus ut just nu. Många personer sägs upp vid diverse IT-bolag trots rekordvinster(?) gjorda hos vissa bolag? 🥴 Och en "junior utvecklare" som det så fint heter är ju inte precis eftertraktad dessa dagar.

Jag har valt den "farliga", "tuffa" frilansar-vägen vilket är oerhört svår i början eftersom jag kommer att konkurrera med billigare frilansare från hela världen. Eller så här tänker jag: Jag får nästan hela världen både som min marknad men också att konkurrera med.

Som frilansare utan tidigare gig ("stjärnor", "betyg", etc., som det heter på frilansarsidorna) så måste eventuella uppdragsgivare anta att jag är en "scammer" tills att jag har bevisat motsatsen på grund av hur vanligt förekommande dessa är numera.

Samtidigt så ska det gå (om än kanske rätt omöjligt i början för mig som nyutexaminerad) att kunna hitta distansjobb i Europa där du arbetar hemifrån i Sverige mot företag och/eller dess slutkunder runtom i Europa och resten av världen. Än så länge verkar marknaden dock mycket tuff för alla vill nog spara pengar under rådande mycket oroliga geopolitiska omständigheter vilket skapar "(icke-)ekonomiska ringar" på vattnet så att säga...

Vad händer härnäst efter avslutad Webbutvecklingsutbildning efter snart 2 år?
Till sist så kommer ju en annan fråga som kanske en läsare funderat som följt denna dagbok: Vad blir av den vecka 22 i år när Webbutvecklingsutbildningen når sitt slut?

Där har jag goda nyheter: Jag skapar helt enkelt en ny tråd där det går att följa vad jag gör efter Webbutvecklingsutbildningen. På sin höjd kommer det att då handla om mina egna webbplatser som jag INTE får göra reklam för, såväl som möjliga distansbaserade uppdrag jag tar mig an.

Förhoppningsvis så blir det så det blir efter avslutad distansutbildning och inte att behöva börja knega på lokalt IT-bolag (kanske deltid, hm?) eller i värsta fall knega vid ett icke-IT-relaterat företag vilket hade varit rena mardrömmen. Den som lever får se! 😁

På återseende - som vanligt, i framtiden!

Mvh,
WKL.
---------
✔️Kurs 1: HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
✔️Kurs 11: VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
✔️Kurs 12: VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)
🚧Kurs 13: (Pågår) VT2024 DT191G Datateknik GR (B), Webbutveckling med .NET, 7,5 hp (distans)
🚧Kurs 14: (Pågår) VT2024 IG021G Industriell organisation och ekonomi GR (A), Affärsplaner och kommersialisering, 7,5 hp (distans)
🚧Kurs 15: (Exjobb spikat)|V12-V22) VT2024 DT140G Datateknik GR (B), Självständigt arbete, 15 hp

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk
Medlem

Tja! Lycka till nu med slutklämmen på utbildningen - jag hoppas studera samma utbildning (kandidat-varianten på 3 år) till hösten.

Vad får dig att tro att marknaden är tuff för webbutvexklare? Min uppfattning är tvärtom, att det finns mängder med jobb. Å andra sidan har jag kikat på svenska OCH spanska arbetsmarknaden.

Permalänk
Skrivet av wilsontaylor:

Tja! Lycka till nu med slutklämmen på utbildningen - jag hoppas studera samma utbildning (kandidat-varianten på 3 år) till hösten.

Vad får dig att tro att marknaden är tuff för webbutvexklare? Min uppfattning är tvärtom, att det finns mängder med jobb. Å andra sidan har jag kikat på svenska OCH spanska arbetsmarknaden.

¡Hola! Vad för webbplatser finns det då att besöka för att hitta arbete i Spanien? Finns det en andel där som godtar 100 % distansarbete eller kräver typ alla folk på plats? Jag talar inte spanska så hur är det med engelskans allmänt talat hos den spanska befolkningen?

Mvh,
WKL.

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk

SLUTSPURTEN HAR INLETTS!!! (DE TRE SISTA ETAPPERNA!!!)

3 Inlämningsuppgifter kvar i hela Webbutvecklingsprogrammet på distans! 🤯
Jag har nu anlänt till "sista världen" i Webbutvecklingsprogrammet vilket först gick av stapeln den 28:e augusti 2022 då jag nu endast har kvar tre inlämningsuppgifter kvar i hela distansutbildningen!

1. Inlämningsuppgift (slutuppgift) i Affärsplanering & kommersialisering
2. Inlämningsuppgift (slutuppgift) i Webbutveckling med .NET
3. Inlämningsuppgift (mega-rapport) i Självständigt arbete (exjobb)

Efter detta är jag sedan en så kallad "junior"(?) eller åtminstone en nyutexad webbutvecklare!

Affärsplanering utan kursplanering?!🤔
Denna kurs har varit katastrofal vad gäller kursplaneringen då den till synes "ofrivillige distansläraren" har - ironiskt nog - haft dålig kursplanering. Personen har lagt upp saker i Moodle rätt sent och efter tjat från oss digitala elever.

Det går verkligen emot vad kursen vill kommunicera med tanken bakom affärsplaner: den säger mer om dig och ditt företagande än du tror! Vad säger då denna hemskt dåliga kursplanering då om denna ofrivillige distanslärare?

Jag kallar personen för det då jag - såväl som ett par andra i den virtuella klassen - upplever att läraren egentligen bara vill bedriva forskning och att denna distanskurs är mer något obligatoriskt för denne för att också få fortsätta bedriva forskning. Möjligen är det ett sätt för läraren att dra in forskningsmedel?🤔

Moment 1.1 i Webbutveckling med .NET
Jag minns inte ens om jag hade rapporterat in här om delmomenten i Webbutveckling med .NET ännu? Hursomhelst så var de flesta både enkla och samtidigt svåra. Det svåra var för det mesta att bara hitta rätt klasser, sedan klassmedlemmar som skulle interagera med varann.

Då "LEARN" hos Microsoft för C#.NET inte är riktigt är så mycket "lär dig som nybörjare" som "teknisk dokumentation för dig som redan kan OOP för webbutveckling sedan flera år tillbaka" så har det varit - åtminstone för mig - sjukt svårt att hitta rätt.

Moment 1.1 var att skapa en AspNetCore webbplats med Razor-undersidor (dvs., .cshtml-filer) och det är såklart sjukt förvirrande att det är i Blazor som komponentfilerna heter .razor medan Razor annars enbart avser syntaxen att kunna kombinera C#-kod med HTML-kod i en och samma slags fil.

Moment 1.2 i Webbutveckling med .NET
Moment 1.2 handlade om att skapa en Blazor WebAssembly app och då användes en mapp vid namn "Pages" med undersidor i form av .razor-filer där @page-direktivet då kunde definiera ändpunkt för att komma till den givna undersidan, likt att nå en ändpunkt i ett API.

Det praktiska med .razor-komponenter är att de kan återanvändas och hanteras likt hur jag har använt ReactJS-komponenter i mitt MERN-projekt. Dock vågar jag mig inte an att prova Blazor komponentbaserat projekt i denna kurs för jag upplever att det blir för mycket att få till med något som ändå kommer att gå delvis lika väl med MVC ASP.NET Core.

Moment 2 i Webbutveckling med .NET
På tal om MVC ASP.NET Core så var moment 2 om just det: MVC med Controllers, Models & Views fast istället för med Laravel PHP så var det nu med C#.NET där du deklarerar en modell, dvs., en tabell i en förvald SQL-databas, vilket sedan kan hanteras av kontrollers vilket sedan skickar erhållen data baserat på modellen och CRUD-ändpunkt till en given "View/Vy". Just Vy-delen var något jag aldrig gjorde i Laravel PHP eftersom PHP endast användes som ett REST API.

Jag upplever MVC ASP.NET Core som det "enklaste" valet för det jag vill göra i slutuppgiften: en annonssida där du kan registrera dig och sedan lägga upp annonser inom kategorin datorkomponenter. Det kluriga blir att få till med Authorize-attributet så att exempelvis vissa saker visas för en inloggad admin kontra en vanlig användare. Och när jag skapar en ny användare med hjälp av Microsoft Identity som verkade komma nu i november 2023 i nya .NET8(?), hur ska jag då kunna skapa en specialanvändare beroende på om deras användarnamn är "sysadmin"?

Denna sak ovan har jag lyckats både i Laravel PHP och i MERN-stacken utan några större problem. Men nu när jag "tvingas" att nyttja Microsoft Identity som har katastrofal dokumentation (eller jag har katastrofala C#-förkunskaper) så blir det mycket svårare att skräddarsy klasserna och klassmedlemmarna (åtminstone för mig än så länge) för att uppnå samma slutresultat.

Moment 3 i Webbutveckling med .NET
Visst sa jag SQL-databas? Och i Laravel PHP-kursen så använde vi oss av Eloquent ORM för att underlätta kommunikation med databaser och "byggandet" av erhållen data för att kunna skicka tillbaka det på ett önskat vis med hjälp av praktiskt skapande av associativa arrayer! 🤤

Nu blir det istället Entity Framework Core eller EF förkortat som gäller i denna kurs inom C#.NET-världen. Då blir det helt nytt sätt att kommunicera på med nya kommandon. Det blir en blandning av LINQ om jag förstått rätt? 🤔

Detta Moment 3 innebar fortsättning med föregående moment 2 där MVC ASP.NET Core implementerades först och nu med åtkomst till en lokal EF-baserad SQL-databas. Det finns en sak med modeller i C#.NET som jag inte vet vad som är vanligast:

public class Book { // Book id, needed for DB public int Id { get; set; } // No book is borrowed as default (false) public bool Borrowed { get; set; } = false; // Book name [Required(ErrorMessage = "Ange ett boknamn!")] [StringLength(100, MinimumLength = 3, ErrorMessage = "Färst 3 tecken, max 100 tecken!")] public string? Name {get; set;} // The single author of the book, so author name MUST be created before the book! public int? AuthorId {get; set;} public Author? Author {get; set;} }

I Book-modellen ovan, är det vanligare att INTE använda främmande nyckel mot Author eller är det vanligare att använda främmande nyckel genom ForeignKey-attributet likt hur du skulle skapa en tabell med vanlig SQL-kod rakt av? (jag är medveten om att under migration så skapas SQL-kod som exekveras mot vald SQL-databas)

Om du vet vilket sätt att bygga SQL-modeller inom C#.NET är vanligast (just hur jag ska definiera främmande nycklar på) så meddela gärna här! Den lösning jag gjorde ovan som jag i efterhand kliade mig över huvudet på i moment 4, var just att i moment 4...

Moment 4 i Webbutveckling med .NET
...så skulle vi skapa sånger med kategorier:

// Song Model public class Song { public int Id { get; set; } [Required(ErrorMessage = "Ange ett artistnamn!")] public string? Artist { get; set; } [Required(ErrorMessage = "Ange en sångtitel!")] public string? Title { get; set; } [Required(ErrorMessage = "Ange ett heltal för sångens längd sekunder!")] public int DurationSeconds { get; set; } [Required(ErrorMessage = "Ange en kategori via: 'category': {'name': 'kategorinamn'}")] public Category? Category { get; set; } } // Category Model public class Category { public int Id { get; set; } [Required(ErrorMessage = "Ange en kategori!")] public string? Name { get; set; } }

Varför jag inte blev nöjd med datamodellerna ovan var för att när en Song hämtas så kommer dess Category JSON-fält att heta "Category" och i sin tur innehålla "Id" och "Name" medan det enda intressanta här är fältet "Name" från kategorin.

Men jag följde lite hur det visades i kursmaterialet av vad som fanns att tillgå och därför misstänker jag att jag har gjort fel för jag vill ju inte exponera databasuppbyggnaden i erhållen JSON-data i ett publikt API, eller hur?!

Och då kommer vi till det här med associativa arrayer från Laravel PHP vilket är en dröm eftersom jag då kan ta kategorinamnet och trycka in den på rätt plats för varje given sång om det hade implementerats där.

I C#.NET så "plågas" jag av mina dåliga förkunskaper från C#-introduktionskursen att jag inte vet hur jag ska kunna "bygga ihop" datastrukturen så att för varje sång så får jag med kategorinamnet från tabellen Category. Jag antar att jag kanske hade kunna satt ihop med .Include från LINQ/EF? 🤔

Slutuppgiften - som pågår - i Webbutveckling med .NET
Slutuppgiften i Webbutveckling med .NET är riktigt mustig och samtidigt väldigt öppen i hur den får lösas som. Just valet av ASP.NET Core kontra Blazor är det kluriga:

Jag kommer välja det som känns "enklast" för mig själv att kunna implementera till en acceptabel nivå utifrån mina egna prestationskrav innan slutdatumet nu den 17:e mars 2024 senast kl.23:59. "Enklast" är också ett finare ord än "lat"!

Således lutar jag mot första uppläggsförslaget "ASP.net MVC Core med Entity Framework (EF)" för om jag tolkar det rätt så blir min API-del "inbakad" i Controllers-mappen tack vare MVC-strukturen. Jag hade först tänkt "Blazor Server med EF" men jag oroar mig att jag kommer att fastna med Authorize-attributet i diverse Razor-komponenter och därmed inte få till det lika "snyggt" som jag fått i Laravel PHP- och MERN-projekten. "Prop drilling" är något jag fortfarande får ont i magen av när jag tänker tillbaka på ReactJS från MERN-projektet!

Jag tänker att jag skickar med en rad olika ViewData[]-variabler (t.ex. "ViewData["admin"] och om den INTE är null så kan något visas på en given .cshtml-undersida för den som faktiskt är admin) vilket då kan kontrolleras mot null och då antingen/eller visa något för den som är admin och/eller den som är en vanlig användare.

Men innan det ens kan utföras måste jag kunna ändra vilka data som får lagras när en ny användare via Microsoft Identity skapas. Det här fina nyckelordet "override" är inget som vi precis gick in på djupet med i C#-introduktionskursen! 😱

Det blir och är både spännande och läskigt nu inför slutspurten i Webbutvecklingsprogrammet på distans som först började den 28:e augusti 2022 och som avslutas någon gång i slutet på maj 2024!

På återseende - som vanligt, i framtiden!

Mvh,
WKL.
---------
✔️Kurs 1: HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
✔️Kurs 11: VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
✔️Kurs 12: VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)
🚧Kurs 13: (Slutuppgift Pågår) VT2024 DT191G Datateknik GR (B), Webbutveckling med .NET, 7,5 hp (distans)
🚧Kurs 14: (Slutuppgift Pågår) VT2024 IG021G Industriell organisation och ekonomi GR (A), Affärsplaner och kommersialisering, 7,5 hp (distans)
🚧Kurs 15: (Inväntar kursstart) VT2024 DT140G Datateknik GR (B), Självständigt arbete, 15 hp

Visa signatur

<WKL:"En kodrad i taget!";/>

Permalänk

SJÄLVSTÄNDIGT ARBETE INLEDS DENNA VECKA = DORIME!

YT-klippet ovan beskriver de blandade känslorna över att äntligen bara ha en enstaka kurs kvar i Webbutvecklingsutbildningen som gick av stapeln den 29:e augusti 2022 och nu den 27:e maj 2024 kommer den att avslutas (någon gång i slutet på maj, jag vet mer imorgon).

Känslorna av att gått från en Påtänd Kodråtta till en "CodeBacca" och snart till en "Nyutexad Webbis" som jag kallar det för!

C#.NET ASP.NET Core MVC med EF Webbplats publicerad
Publicering på Microsoft Azure: https://maka2207-projekt.azurewebsites.net (ligger kvar tills att uppgiften har rättats så den lär försvinna om en till två veckor från och med idag).

Påhittad verksamhetsbeskrivning som underlag för datamodelleringen: Webbplatsen är en annonssajt med annonsörer (AspNetUsers/IdentityUser) där varje annonsör kan ha flera annonser (Ad) där varje annons kan ha flera bilder (AdImages). Varje annonsör kanske också skapa flera trådämnen (AdTopics) vilket sin tur kan innehålla flera meddelanden (AdMessages) för att skickas till användare emellan.

Som annonsör/användare går att göra intresseanmälningar på varje enstaka unika annons som ägs av samma annonsör. Med andra ord kan du göra en intresseanmälan per unik annons upplagd av en och samma annonsör.

Jag bad folk i en Discord-grupp testa att "pen-testa" den och vad som lyckades var något jag funderat på innan: Det finns nämligen dolda inmatningsfält (input type="hidden") vilket innebär att nödvändiga data skickas med till backend där jag inte haft tillräckliga kontroller om vem som gjort (och ska få göra) vad vilket lett till att du exempelvis kan ändra någon annans annons eller exempelvis skapa en annons i en kategori som egentligen inte tillhandahålls. Du kan även ändra din annons så den godkänns när det annars bara är användarnamnet "admin" som ska kunna godkänna den.

Sådana här numera "uppenbara sårbarheter" är bra att jag fick bekräftelse på efter att jag misstänkte en problematik med "Meddelande"-funktionaliteten när jag skapade nytt meddelande: Jag kunde nämligen direkt i Inspect i webbläsaren ändra avsändarens namn till något annat namn så det verkade som om jag skickade meddelande i någon annans namn.

Det formuläret har dock åtgärdats som "proof of concept" och jag bär med mig konceptet SecDevOps-konceptet "Principle of Least Privilege", dvs., så lite åtkomst som möjligt och aldrig mer än allra nödvändigast.

C#.NET (jag är medveten om att C# är själva programmeringsspråket och .NET är främst ett C#-bibliotek såväl som ett stort ramverk med många vägar att gå via) är både skönt och ett h*lvete att ha med att göra enligt mina egna erfarenheter som hittills innan C#.NET-kursen endast arbetat med lösa datatyper där jag själv måste ansvara över rätt struktur och dess innehåll. Även om C#.NET nu tvingar mig till att alltid fördefiniera datastrukturerna så har jag samtidigt funnit detta frustrerande även om jag har kunna implementerat liknande strikt datatypskontroll i exempelvis JavaScript med hjälp av exempelvis TypeScript.

Den primära fördelen med strikta datatyper i C#.NET är just att minimera risken för buggar orsakade av fel datatyper som släpps förbi i för många led i koden så att en funderar varför det plötsligt visas ett heltal där det aldrig annars hade kunna visats ett heltal. Annars så har jag enorma personliga invändningar mot C#.NET på grund av min nuvarande "oduglighet" med det!

Sammanfattningsvis för det jag har tagit del av C#.NET i de två kurserna som varit: Introduktionskursen och Webbutveckling med .NET (där jag valde ASP.NET Core MVC med EF-upplägget) är att C# som programmeringsspråk är skönt när det fungerar och jag inte fastnar i dess strikta OOP-paradigm och .NET är skönt så länge jag förstår mig på hur alla dess klasser fungerar. Learn.Microsoft.com känns fortfarande skriven för erfarna OOP-ingenjörer och inte OOP-nybörjare såsom mig?! 🤔

Datamodellerna:

Användare - ärvd av IdentityUser-jklassen

public class ApplicationUser : IdentityUser { // Fullname of the user (first and last name combined) [Required] public string? FullName { get; set; } // Username shown to other users [Required] public string? UsernameShown { get; set; } // Lowercased Username to make sure it's unique [Required] public string? UserNameLowercased { get; set; } // Everyone is NOT admin by default public bool IsAdmin { get; set; } = false; }

Ad:

public class Ad { public int Id { get; set; } // Ad title [Required(ErrorMessage = "Ange en annonstitel!")] [StringLength(50, ErrorMessage = "Annonstitel får vara max 50 tecken!"), MinLength(5, ErrorMessage = "Färst 5 tecken i annonstitel!")] public string? Title { get; set; } // Ad description [Required(ErrorMessage = "Ange en annonsbeskrivning!")] [StringLength(1000, ErrorMessage = "Annonsbeskrivning får vara max 1000 tecken!"), MinLength(10, ErrorMessage = "Färst 10 tecken i annonsbeskrivning!")] public string? Description { get; set; } // Ad category (it's a string because it's received from the option value from a dropdown menu in the form) [Required(ErrorMessage = "Välj en kategori!")] public string? Category { get; set; } // Ad price [Required(ErrorMessage = "Ange ett pris!")] [Range(1, 1000000, ErrorMessage = "Priset ska vara mellan 1 och 1000000 kr!")] public int? Price { get; set; } = 0; // Ad publish date [Display(Name = "Upplagd")] public DateTime PublishDate { get; set; } // Must be approved by admin before it's visible to other users public bool IsApproved { get; set; } = false; public bool UnderReview { get; set; } = false; // SoldOrElseNew (true = sold, false = new) public bool SoldOrElseNew { get; set; } = false; // Foreign key (UserId) for ApplicationUser (User) public string? UserId { get; set; } [ForeignKey("UserId")] public ApplicationUser? User { get; set; } // This is the registered Username of the user who created the ad public string? AdByUsername { get; set; } // Images associated with the model so it can be ".included" in queries public ICollection<AdImages>? AdImages { get; set; } }

AdImages:

public class AdImages { public int Id { get; set; } // Alt text for image (only shown when image can't be loaded) [Required(ErrorMessage = "Ange en bildtext!")] [StringLength(100, ErrorMessage = "Bildtext får vara max 100 tecken!"), MinLength(5, ErrorMessage = "Färst 5 tecken i bildtext!")] public string? ImageAltText { get; set; } // Path to image file: wwwroot/images/{AdId}/{ImagePath} public string? ImagePath { get; set; } // Foreign key (AdId) for Ad public int? AdId { get; set; } [ForeignKey("AdId")] public Ad? Ad { get; set; } }

AdTopics:

public class AdTopics { // Each topic has a unique ID public int Id { get; set; } // Has the topic been read by the sender? public bool IsReadBySender { get; set; } = false; // Has the topic been read by the receiver? public bool IsReadByReceiver { get; set; } = false; // Topic from username (who sent it) // It's just a string because if an account is deleted // we can just delete messages associated to correct username! public string? TopicFromUsername { get; set; } public string? TopicToUsername { get; set; } // Some topics by admin cannot be replied to, so then this turns false! // For example, when admin denies an ad that was up for review. public bool CanBeRepliedTo { get; set; } = true; // Topic subject [Required(ErrorMessage = "Ange ett ämne!")] [StringLength(200, ErrorMessage = "Ämnet får inte vara längre än 100 tecken.")] public string? TopicTitle { get; set; } // Date when topic was created public DateTime TopicCreated{ get; set; } public ICollection<AdMessages>? Messages { get; set; } = new List<AdMessages>(); }

AdMessages:

public class AdMessages { // Each message has a unique ID but several messages can have the same TopicId public int Id { get; set; } // TopicId is the ID of the topic the message belongs to public int TopicId { get; set; } // We set when it is first message in a given topic public bool FirstMessage { get; set; } = false; // Message content [Required(ErrorMessage = "Ange ett meddelande!")] [MinLength(2, ErrorMessage = "Meddelandet måste vara minst 2 tecken.")] [StringLength(2000, ErrorMessage = "Meddelandet får inte vara längre än 2000 tecken.")] public string? MessageContent { get; set; } // Message sent date public DateTime MessageSentDate { get; set; } // Message sender (who sent it) & receiver (who received it) // Both are just purely strings because // if an account is deleted we can just // delete messages associated to correct username! public string? SenderUsername { get; set; } public string? ReceiverUsername { get; set; } // Each message belongs to a topic, thus a message cannot be created without a topic [ForeignKey("TopicId")] public AdTopics? Topic { get; set; } }

InterestList:

public class InterestList { public int Id { get; set; } public int? AdId { get; set; } [ForeignKey("AdId")] public Ad? Ad { get; set; } public string? UserId { get; set; } [ForeignKey("UserId")] public ApplicationUser? User { get; set; } }

Dold text

Exjobb - börjar imorgon
En introduktion till Självständigt arbete börjar imorgon och från och med då ska vi lämna in våra Projekt då ska vi lämna in våra Projektplaner inom två veckor genom att publicera i en och samma diskussionstråd inuti Moodle-undersidan för kursen.

Nu på onsdag kommer jag att ha ett avstämningsmöte med det lokala bolaget jag kommer att genomföra mitt exjobb hos - fast på distans. Eventuellt mötes vi upp för en kopp kaffe ute på stan här. Annars så tänker vi oss att vi kör 100 % agil metod.

Det vill säga: jag gör en massa utifrån avstämningsmöte och vid nästa avstämningsmöte så provkör de den nuvarande "MVP" och så kommer de med återkoppling såväl som prioriteringsordning på vad som ska göras/måste fixas härnäst.

Det är i alla fall tanken men precis som allt annat med agil arbetsmetod så kan vi vara flexibla här.

Exjobbet där jag är helt ensam inom IT
Den största utmaningen jag kommer att ha inom detta exjobb att jag kommer att vara den enda IT-insatta här. Tanken är att jag ska komma mned en modell för kravfångst för att vi ska kunna ta fram ett tillräckligt gott underlag för exjobb-uppdraget.

Under det kommande avstämningsmötet kommer jag att därmed driva den frågan: kravfångsten, såväl som två andra viktiga saker. Det första blir att fråga om hur de tänker sig med "sjösättningen" då jag vet att de har en webbplats som verkar ha tagits fram av en webbyrå. Hur tänker de sig då att denna webbplats ska sjösättas som? För det i sin tur kan påverka val av techstack utifrån mitt perspektiv.

På tal om techstack...

Exjobbet där jag måste balansera val av techstack, kundens önskemål & utbildningens önskemål?
Det blir en situation i att jag måste balansera val av techstack, kundens önskemål såväl som utbildningens önskemål. Sistnämnda tror jag främst handlar om att exjobbet ska kunna omfatta cirka 10 veckors heltidsstudier INKLUSIVE rapportskrivningen.

Jag är riktigt less på rapportskrivningen och självfallet avslutas distansutbildningen med världens längsta rapport som det allra sista! Så länge rapporten och exjobbets omfattning kan omfatta cirka 10 veckors heltidsstudier så tror jag att jag har uppnått utbildningens önskemål.

Då kommer vi till kundens / exjobb-givarens önskemål. Utifrån deras perspektiv som ej icke-IT-insatta så tänker jag mig att de troligen bryr sig om att det fungerar som tänkt, att det ser tillräckligt modernt och proffsigt ut (då de tänker sig att deras externa kunder ska också kunna ta del av delar av webbplatsen).

Sistnämnda för oss då till det kanske allra viktigaste i exjobbet: en mycket hög nivå av SecDev:ing. Jag för blicken tillbaka till det senaste C#.NET-projektet där det finns/fanns allvarliga säkerhetsbrister i hur data kunde manipuleras i frontend för att påverka på backend.

Sådan allvarlig säkerhetsbrist får aldrig förekomma i detta exjobb - och jag är helt ensam i att se till det. Finns ingen externt IT-proffs jag kan fråga och jag bör fråga utbildningen om hur de själva ser på hela SecDev-biten i och med ingen IT-insatt i bolaget jag ska "exjobba" åt.

En techstack jag funderat på är då något i PHP kombinerat med JS och då vill jag ju föra tankarna mot Laravel men då har vi hela sjösättningsbiten här då det inte "bara" är och slänga in Laravel i vilket webbhotell som helst utan särskilda befogenheter som webbhotellanvändare där.

Exjobbet - några tips från Dig?
Till sist vi har min öppna fråga till Dig kära läsare: Vad kan Du ge Mig för tips angående den sista långa resan i denna Webbutvecklingsdistansutbildning när jag nu hoppar på "Slutbossen" som är ett exjobb inom webbutveckling där jag dock är den enda tillräckligt IT-insatta?

På återseende - som vanligt, i framtiden!

Mvh,
WKL.
---------
✔️Kurs 1: HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️Kurs 2: HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️Kurs 3: HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️Kurs 4: HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
✔️Kurs 5: VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
✔️Kurs 6: VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)
✔️Kurs 7: VT2023 DT197G Datateknik GR (B), Webbdesign för CMS, 7,5 hp (distans)
✔️Kurs 8: VT2023 DT173G Datateknik GR (B), Webbutveckling III, 7,5 hp (distans)
✔️Kurs 9: HT2023 IK060G Informatik GR (A), Projektledning, 7,5 hp (distans)
✔️Kurs 10: HT2023 DT193G Datateknik GR (B), Fullstack-utveckling med ramverk, 7,5 hp (distans)
✔️Kurs 11: VT2023 DT162G Datateknik GR (B), Javascriptbaserad webbutveckling, 7,5 hp (distans)
✔️Kurs 12: VT2023 DT071G Datateknik GR (A), Programmering i C#.NET, 7,5 hp (distans)
🚧Kurs 13: (Inväntar slutbetyg) VT2024 DT191G Datateknik GR (B), Webbutveckling med .NET, 7,5 hp (distans)
🚧Kurs 14: (Inväntar slutbetyg) VT2024 IG021G Industriell organisation och ekonomi GR (A), Affärsplaner och kommersialisering, 7,5 hp (distans)
🚧Kurs 15: (Kursstart imorgon) VT2024 DT140G Datateknik GR (B), Självständigt arbete, 15 hp

Visa signatur

<WKL:"En kodrad i taget!";/>