<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Nana Yaw Kyei Antwi | Portfolio</title><link>https://nykantwi.github.io/Portfolio/</link><description>Recent content on Nana Yaw Kyei Antwi | Portfolio</description><generator>Hugo</generator><language>en</language><atom:link href="https://nykantwi.github.io/Portfolio/index.xml" rel="self" type="application/rss+xml"/><item><title>About me</title><link>https://nykantwi.github.io/Portfolio/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/about/</guid><description>&lt;p&gt;I&amp;rsquo;m Nana Yaw Kyei Antwi, a Computer Science student at Erhvervsakademi København (EK).&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;m exploring software development through practical projects: breaking down problems, trying out solutions and learning along the way. Over time, I&amp;rsquo;d like to broaden my skills into cybersecurity. This portfolio is where I share what I build, my contributions and the lessons I take from each project.&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;m open to student jobs and internships where I can contribute, learn from others and gain practical experience alongside my studies. In the longer term, I aim to build a full-time career in software development.&lt;/p&gt;</description></item><item><title>Carport FOG</title><link>https://nykantwi.github.io/Portfolio/projects/carport-fog/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/projects/carport-fog/</guid><description>&lt;p&gt;Carport FOG is a group project I worked on with my fellow students. The application lets customers configure a carport and submit an order, with separate areas for customers, sales staff and administrators.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://carport.antwi.dk/"&gt;Open the live application&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="features"&gt;Features&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Customer registration and login.&lt;/li&gt;&#10;&lt;li&gt;Carport configuration with dimensions, roofing and an optional shed.&lt;/li&gt;&#10;&lt;li&gt;Price calculations and carport drawings.&lt;/li&gt;&#10;&lt;li&gt;Order management and role-based pages for sales staff and administrators.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="technology"&gt;Technology&lt;/h2&gt;&#10;&lt;p&gt;The application uses Java 21 and Javalin, with Thymeleaf for server-rendered HTML. PostgreSQL stores users, carport configurations and orders. Maven builds the application and runs the JUnit tests.&lt;/p&gt;</description></item><item><title>CIT – API-dokumentation</title><link>https://nykantwi.github.io/Portfolio/documentation/cit-api/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/documentation/cit-api/</guid><description>&lt;p&gt;API’et bruges til at oprette, hente, opdatere og slette hændelser.&lt;/p&gt;&#10;&lt;p&gt;Baseadresse: &lt;code&gt;http://localhost:7070/api/v1&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="endpoints"&gt;Endpoints&lt;/h2&gt;&#10;&lt;p&gt;Alle URL’er nedenfor er relative til baseadressen.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Metode&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;URL&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Request Body (JSON)&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Response (JSON)&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Fejl&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;POST&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;/auth/register&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Bruger (4)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Bekræftelse (4), status 201&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;400, 409&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;POST&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;/auth/login&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Login (5)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Token (5), status 200&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;401&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;GET&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;/incidents&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ingen&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Liste af hændelser (1), status 200&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;401&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;GET&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;/incidents/{id}&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ingen&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hændelse (1), status 200&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;400, 401, 404&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;POST&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;/incidents&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Oprettelsesformat (2)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hændelse (1), status 201&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;400, 401&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;PUT&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;/incidents/{id}&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Opdateringsformat (3)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hændelse (1), status 200&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;400, 401, 404&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;DELETE&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;/incidents/{id}&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ingen&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ingen body, status 204&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;400, 401, 403, 404&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="login-og-adgang"&gt;Login og adgang&lt;/h2&gt;&#10;&lt;p&gt;Register og login er offentlige. Alle incident-endpoints kræver et gyldigt JWT i denne header:&lt;/p&gt;</description></item><item><title>Contact</title><link>https://nykantwi.github.io/Portfolio/contact/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/contact/</guid><description>&lt;p&gt;Have a student job, internship opportunity or a question about one of my projects? I&amp;rsquo;d be happy to hear from you.&lt;/p&gt;&#10;&lt;p&gt;You can reach me by email:&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="mailto:nanayawtnrn@gmail.com"&gt;nanayawtnrn@gmail.com&lt;/a&gt;&lt;/p&gt;</description></item><item><title>FantasyFUT</title><link>https://nykantwi.github.io/Portfolio/projects/fantasyfut/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/projects/fantasyfut/</guid><description>&lt;p&gt;FantasyFUT is a student group project I worked on with Emil, Tobias and Seif. It began as a JavaFX desktop application backed by SQLite. The web edition brings the core game to the browser and is hosted on my own DigitalOcean server.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://fantasyfut.antwi.dk/classic.html"&gt;Play the web version&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="build-a-squad-and-play-a-season"&gt;Build a squad and play a season&lt;/h2&gt;&#10;&lt;p&gt;Choose a starting eleven in a 4–4–2 formation from the project&amp;rsquo;s dataset of &lt;strong&gt;526 players and 20 clubs&lt;/strong&gt;. Search by player or club, filter by position, or use quick pick to get started.&lt;/p&gt;</description></item><item><title>Footer</title><link>https://nykantwi.github.io/Portfolio/footer/footer/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/footer/footer/</guid><description>&lt;section id="contact" class="section section--border-bottom rad-animation-group section--padding"&gt;&#10; &lt;div class="container"&gt;&#10; &lt;div class="row rad-fade-down"&gt;&#10; &lt;div class="col-12"&gt;&#10; &#10; &lt;h2 class="section__title"&gt;Get in touch&lt;/h2&gt;&#10; &#10; &#10; &lt;div class="text-section__content"&gt;&#10; &lt;p&gt;Have a student job, internship opportunity or a question about one of my projects? I&amp;rsquo;d be happy to hear from you.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="mailto:nanayawtnrn@gmail.com"&gt;nanayawtnrn@gmail.com&lt;/a&gt;&lt;/p&gt;&#10;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/section&gt;</description></item><item><title>Home</title><link>https://nykantwi.github.io/Portfolio/home/home/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/home/home/</guid><description>&lt;section class="section section--border-bottom section--padding" id="home"&gt;&#10; &lt;div class="container" style="padding-top: 5rem; padding-bottom: 3rem;"&gt;&#10; &lt;p class="section__subtitle"&gt;COMPUTER SCIENCE STUDENT · EK&lt;/p&gt;&#10; &lt;h1&gt;Nana Yaw&lt;br&gt;Kyei Antwi&lt;/h1&gt;&#10; &lt;p class="lead" style="max-width: 640px; margin-top: 1.5rem;"&gt;Studying Computer Science at Erhvervsakademi København (EK). Explore my projects as I learn to turn ideas into working software.&lt;/p&gt;&#10; &lt;a class="btn btn-primary" href="https://nykantwi.github.io/Portfolio/projects/"&gt;Explore my work&lt;/a&gt;&#10; &lt;a class="btn btn-outline-primary" href="https://nykantwi.github.io/Portfolio/contact/"&gt;Get in touch&lt;/a&gt;&#10; &lt;/div&gt;&#10;&lt;/section&gt;&#10;&#10;&#10;&#10; &#10;&#10;&#10;&#10;&#10;&#10;&#10;&#10;&#10;&#10;&#10;&#10; &#10; &#10;&#10;&#10;&#10;&#10;&lt;section id="about" class="section section--border-bottom rad-animation-group section--padding"&gt;&#10; &lt;div class="container"&gt;&#10; &lt;div class="row rad-fade-down"&gt;&#10; &lt;div class="col-12"&gt;&#10; &#10; &lt;h2 class="section__title"&gt;About me&lt;/h2&gt;&#10; &#10; &#10; &lt;div class="text-section__content"&gt;&#10; &lt;p&gt;I&amp;rsquo;m Nana Yaw Kyei Antwi, a Computer Science student at Erhvervsakademi København (EK).&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;m exploring software development through practical projects: breaking down problems, trying out solutions and learning along the way. Over time, I&amp;rsquo;d like to broaden my skills into cybersecurity. This portfolio is where I share what I build, my contributions and the lessons I take from each project.&lt;/p&gt;</description></item><item><title>SM3-CIT</title><link>https://nykantwi.github.io/Portfolio/projects/sm3-cit/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/projects/sm3-cit/</guid><description>&lt;p&gt;&lt;a href="https://api.antwi.dk/api/v1/incidents"&gt;Live API →&lt;/a&gt; · &lt;a href="https://github.com/nykantwi/SM3-projekt---Cyber-Incident-Tracker"&gt;GitHub →&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;The API requires authentication to access incidents.&lt;/p&gt;&#10;&lt;h2 id="logbog"&gt;Logbog&lt;/h2&gt;&#10;&lt;div class="development-log"&gt;&#10; &#10; &lt;article class="mb-4"&gt;&#10; &lt;h3&gt;&lt;a href="https://nykantwi.github.io/Portfolio/development-log/sm3-cit/08-deployment/"&gt;Uge 8 – Deployment&lt;/a&gt;&lt;/h3&gt;&#10; &lt;p&gt;Deployment af CIT med GitHub Actions, Docker Hub, DigitalOcean og HTTPS gennem Caddy.&lt;/p&gt;&#10; &lt;/article&gt;&#10; &#10; &lt;article class="mb-4"&gt;&#10; &lt;h3&gt;&lt;a href="https://nykantwi.github.io/Portfolio/development-log/sm3-cit/07-security/"&gt;Uge 7 – Security&lt;/a&gt;&lt;/h3&gt;&#10; &lt;p&gt;Login med bcrypt og JWT, rollebaseret adgangskontrol og tests af beskyttede endpoints.&lt;/p&gt;&#10; &lt;/article&gt;&#10; &#10; &lt;article class="mb-4"&gt;&#10; &lt;h3&gt;&lt;a href="https://nykantwi.github.io/Portfolio/development-log/sm3-cit/06-rest-test/"&gt;Uge 6 – REST &amp;amp; Test&lt;/a&gt;&lt;/h3&gt;&#10; &lt;p&gt;Automatiserede API-tests med REST Assured, Hamcrest og en separat PostgreSQL-testdatabase.&lt;/p&gt;&#10; &lt;/article&gt;&#10; &#10; &lt;article class="mb-4"&gt;&#10; &lt;h3&gt;&lt;a href="https://nykantwi.github.io/Portfolio/development-log/sm3-cit/05-rest-api/"&gt;Uge 5 – REST API intro&lt;/a&gt;&lt;/h3&gt;&#10; &lt;p&gt;REST API til CIT med Javalin, CRUD-endpoints, DTO’er, validering og fejlhåndtering.&lt;/p&gt;</description></item><item><title>Uge 1 – JPA Basics</title><link>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/01-jpa-basics/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/01-jpa-basics/</guid><description>&lt;h2 id="opsumering"&gt;Opsumering&lt;/h2&gt;&#10;&lt;p&gt;Denne uge begyndte jeg på Cyber Incident Tracker og opbyggede fundamentet til projektets backend med Java, JPA/Hibernate&#10;og PostgreSQL.&lt;/p&gt;&#10;&lt;p&gt;Fokus var at kunne oprette hændelser som Java-objekter, gemme dem i databasen og hente dem igen.&lt;/p&gt;&#10;&lt;h2 id="hvad-jeg-har-implementeret"&gt;Hvad jeg har implementeret?&lt;/h2&gt;&#10;&lt;p&gt;Jeg oprettede projektets packages og en &lt;code&gt;Incident&lt;/code&gt;-entity med ID, titel og beskrivelse. Med JPA-annotationer koblede jeg&#10;klassen til tabellen &lt;code&gt;incidents&lt;/code&gt; i min database.&lt;/p&gt;&#10;&lt;p&gt;Derefter implementerede jeg CRUD i &lt;code&gt;IncidentDAO&lt;/code&gt; med metoder til at:&lt;/p&gt;</description></item><item><title>Uge 2 – JPA Relations</title><link>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/02-jpa-relations/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/02-jpa-relations/</guid><description>&lt;h2 id="hvad-har-jeg-implementeret"&gt;Hvad har jeg implementeret?&lt;/h2&gt;&#10;&lt;p&gt;Jeg har implementeret relationer mellem brugere, hændelser og kommentarer med JPA. En hændelse har en rapportør,&#10;og en kommentar tilhører både en bruger og en hændelse.&lt;/p&gt;&#10;&lt;h2 id="implementering"&gt;Implementering&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;User, Incident og Comment med ManyToOne-relationer.&lt;/li&gt;&#10;&lt;li&gt;DAO-klasser og interfaces til databaseoperationer.&lt;/li&gt;&#10;&lt;li&gt;JPQL til brugeropslag, rapportør filtrering og kommentarer til en hændelse.&lt;/li&gt;&#10;&lt;li&gt;IncidentService med validering og håndtering af hændelser.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="test-og-læring"&gt;Test og læring&lt;/h2&gt;&#10;&lt;p&gt;Der er implementeret databasetests med JUnit og Testcontainers for CRUD, relationer, brugeropslag og filtrering.&lt;/p&gt;</description></item><item><title>Uge 3 – Dataintegration med et eksternt API</title><link>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/03-data-integration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/03-data-integration/</guid><description>&lt;h2 id="ugeopsummering"&gt;Ugeopsummering&lt;/h2&gt;&#10;&lt;p&gt;Denne uge har jeg arbejdet med dataintegration ved at hente oplysninger om kendte sikkerhedssårbarheder fra NVD’s CVE-API.&lt;/p&gt;&#10;&lt;p&gt;Formålet er at lære at hente eksterne data i Java og omdanne dem til objekter, som projektet kan bruge. På længere sigt&#10;kan oplysningerne supplere en hændelse i CIT, hvis den vedrører en kendt sårbarhed.&lt;/p&gt;&#10;&lt;h2 id="hvad-jeg-har-implementeret"&gt;Hvad jeg har implementeret&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;CveClient&lt;/code&gt;, som sender GET-requests med Java &lt;code&gt;HttpClient&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;JSON-mapping med Jackson og ObjectMapper.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;CveDTO&lt;/code&gt; med CVE-ID og engelsk beskrivelse.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;CveDemo&lt;/code&gt;, som udfører et opslag og viser resultatet i konsollen.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;I &lt;code&gt;CveClient&lt;/code&gt; henter fetchJson() API-svaret som tekst. Metoden fetchById() læser derefter JSON-strukturen og returnerer en CveDTO med de relevante oplysninger.&lt;/p&gt;</description></item><item><title>Uge 4 – Concurrency</title><link>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/04-concurrency/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/04-concurrency/</guid><description>&lt;h2 id="ugeopsummering"&gt;Ugeopsummering&lt;/h2&gt;&#10;&lt;p&gt;Denne uge har jeg arbejdet med concurrency ved at lave en statistikdemo til Cyber Incident Tracker.&lt;/p&gt;&#10;&lt;p&gt;Programmet henter hændelser fra databasen og sender to tælleopgaver til en ExecutorService med to worker-thread:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Tæl alle åbne hændelser.&lt;/li&gt;&#10;&lt;li&gt;Tæl åbne hændelser med MEDIUM severity.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="hvad-jeg-har-implementeret"&gt;Hvad jeg har implementeret&lt;/h2&gt;&#10;&lt;p&gt;Hver opgave er en &lt;code&gt;Callable&amp;lt;Integer&amp;gt;&lt;/code&gt;, som returnerer et antal. Begge opgaver indsendes med submit(), før resultaterne hentes med Future.get().&#10;Det giver opgaverne mulighed for at køre samtidigt.&lt;/p&gt;</description></item><item><title>Uge 5 – REST API intro</title><link>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/05-rest-api/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/05-rest-api/</guid><description>&lt;h2 id="hvad-jeg-har-implementeret"&gt;Hvad jeg har implementeret&lt;/h2&gt;&#10;&lt;p&gt;Denne uge har jeg lavet et REST API til CIT med Javalin. Før testede jeg funktionerne direkte i Java.&#10;Nu kan jeg sende HTTP-requests og oprette, hente, opdatere og slette hændelser.&lt;/p&gt;&#10;&lt;h2 id="opbygning-af-apiet"&gt;Opbygning af API’et&lt;/h2&gt;&#10;&lt;p&gt;Jeg brugte Hotel API fra undervisningen som hjælp til strukturen. Mine routes starter med &lt;code&gt;/api/v1&lt;/code&gt;, og serveren kører på port &lt;code&gt;7070&lt;/code&gt;.&#10;Routes sender requesten videre til controlleren, som bruger service- og DAO-laget.&#10;Jeg har også lavet DTO’er til oprettelse, opdatering og svar. Der er kontrol af blandt andet tom titel, ugyldigt ID og&#10;manglende severity. Fejl sendes tilbage som JSON med en statuskode.&lt;/p&gt;</description></item><item><title>Uge 6 – REST &amp; Test</title><link>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/06-rest-test/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/06-rest-test/</guid><description>&lt;h2 id="hvad-jeg-har-implementeret"&gt;Hvad jeg har implementeret&lt;/h2&gt;&#10;&lt;p&gt;Denne uge har jeg lavet automatiserede tests af mit REST API med REST Assured og Hamcrest. Jeg brugte mine DAO-tests og Hotel API fra undervisningen som hjælp.&lt;/p&gt;&#10;&lt;h2 id="testopsætning"&gt;Testopsætning&lt;/h2&gt;&#10;&lt;p&gt;Testcontainers starter en separat PostgreSQL-database. Før hver test rydder jeg tabellerne og opretter en testbruger og&#10;en hændelse. Serveren og testene bruger den samme testdatabase.&lt;/p&gt;&#10;&lt;h3 id="hvad-testene-kontrollerer"&gt;Hvad testene kontrollerer&lt;/h3&gt;&#10;&lt;p&gt;Jeg har nu 7 API-tests:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;GET af alle hændelser:&lt;/strong&gt; Kontrollerer status &lt;code&gt;200&lt;/code&gt; og JSON som indholdstype.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;GET med kontrol af indhold:&lt;/strong&gt; Kontrollerer, at listen indeholder testhændelsens titel.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;GET via ID:&lt;/strong&gt; Kontrollerer, at den rigtige hændelse returneres med det forventede ID, titel og status.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;POST:&lt;/strong&gt; Opretter en hændelse og kontrollerer status &lt;code&gt;201&lt;/code&gt;, et genereret ID og de forventede felter. Hændelsen hentes bagefter med GET for at kontrollere, at den er gemt.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;POST med tom titel:&lt;/strong&gt; Kontrollerer status &lt;code&gt;400&lt;/code&gt; og fejlbeskeden &lt;code&gt;Titel må ikke være tom&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;PUT:&lt;/strong&gt; Ændrer titel, beskrivelse, severity og status. Et efterfølgende GET kontrollerer, at ændringerne er gemt.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;DELETE:&lt;/strong&gt; Kontrollerer status &lt;code&gt;204&lt;/code&gt; og en tom response body og derefter et GET på samme ID skal give &lt;code&gt;404&lt;/code&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="resultat"&gt;Resultat&lt;/h2&gt;&#10;&lt;p&gt;Alle syv tests i &lt;code&gt;ApiTest&lt;/code&gt; bestod ved kørslen. Det var kun API-testklassen, ikke hele projektets tests.&lt;/p&gt;</description></item><item><title>Uge 7 – Security</title><link>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/07-security/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/07-security/</guid><description>&lt;h2 id="hvad-jeg-har-implementeret"&gt;Hvad jeg har implementeret&lt;/h2&gt;&#10;&lt;p&gt;Denne uge har jeg tilføjet registrering og login til CIT. Passwords gemmes som en bcrypt-hash, og ved login får brugeren&#10;et JWT, der gælder i en time. Jeg bruger&lt;code&gt;TokenSecurity&lt;/code&gt;-bibliotek, og nøglen hentes fra &lt;code&gt;JWT_SECRET&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="brugere-passwords-og-roller"&gt;Brugere, passwords og roller&lt;/h2&gt;&#10;&lt;p&gt;Min &lt;code&gt;User&lt;/code&gt; har fået et &lt;code&gt;passwordHash&lt;/code&gt;. Når en bruger oprettes med navn, e-mail og password, hasher constructoren passwordet&#10;med bcrypt. Ved login bruger &lt;code&gt;verifyPassword()&lt;/code&gt; bcrypt til at kontrollere det indtastede password mod den gemte hash.&lt;/p&gt;</description></item><item><title>Uge 8 – Deployment</title><link>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/08-deployment/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nykantwi.github.io/Portfolio/development-log/sm3-cit/08-deployment/</guid><description>&lt;h2 id="hvad-jeg-har-implementeret"&gt;Hvad jeg har implementeret&lt;/h2&gt;&#10;&lt;p&gt;Denne uge har jeg deployet CIT til DigitalOcean, så API&amp;rsquo;et kan bruges uden at køre på min egen computer.&lt;/p&gt;&#10;&lt;p&gt;API&amp;rsquo;et er tilgængeligt på:&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://api.antwi.dk/api/v1/incidents"&gt;https://api.antwi.dk/api/v1/incidents&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Endpointet kræver et gyldigt JWT. Derfor får man 401, hvis man åbner linket direkte uden et token.&lt;/p&gt;&#10;&lt;h2 id="build-og-github-actions"&gt;Build og GitHub Actions&lt;/h2&gt;&#10;&lt;p&gt;Jeg har tilføjet Maven Shade Plugin, som samler projektet og dets biblioteker i én fil: &lt;code&gt;app.jar&lt;/code&gt;. Min Dockerfile bruger&#10;Java 17 og starter serveren fra denne fil.&lt;/p&gt;</description></item></channel></rss>