- Turinys
- Sprendžiamo uždavinio aprašymas
- Taikomosios srities objektai
- Sistemos architektūra
- Naudotojo sąsajos projektas
- API specifikacija
- Projekto išvados
Projekto tikslas – sukurti užduočių valdymo įrankį, kuris leistų prisijungusiems sistemos naudotojams efektyviai planuoti, vykdyti ir stebėti savo užduotis. Sistema leis valdyti projektus, sekcijas, užduotis ir naudotojų paskyras.
Aukščiausiame hierarchijos lygyje yra projektai, kurie suskirstomi į sekcijas, o sekcijose kuriamos užduotys. Projektai grupuoja platesnius tikslus, sekcijos leidžia smulkiau suskirstyti veiklas pagal temas ar etapus, o užduotys yra konkretūs darbai, kuriuos reikia atlikti.
Sistemai naudotojai bus trijų rolių: svečias, registruotas naudotojas ir administratorius.
- Peržiūrėti prisijungimo puslapį
- Peržiūrėti registracijos puslapį
- Prisijungti prie sistemos
- Užsiregistruoti į sistemą
- Prisijungti prie sistemos
- Atsijungti nuo sistemos
- Sukurti, ištrinti, redaguoti, peržiūrėti projektus
- Sukurti, ištrinti, redaguoti, peržiūrėti sekcijas
- Sukurti, ištrinti, redaguoti, peržiūrėti užduotis
- Prisijungti prie sistemos
- Atsijungti nuo sistemos
- Valdyti visus projektus, sekcijas, užduotis
Taikomosios srities objektus sieja hierarchinis ryšys: Projektas
⇒ Sekcija
⇒ Užduotis
- Projektas (project)
- tai aukščiausio lygio objektas, kuris grupuoja sekcijas ir užduotis. Projektas turi pavadinimą, aprašymą, sukūrimo datą ir sukūrėją.
- Sekcija (section)
- tai objektas, kuris priklauso tam tikram projektui. Sekcija turi pavadinimą, sukūrimo datą ir sukūrėją.
- Užduotis (task)
- tai objektas, kuris priklauso tam tikrai sekcijai. Užduotis turi pavadinimą, aprašymą, prioritetą, atlikimo būseną, atlikimo terminą, sukūrimo datą ir sukūrėją.
- Naudotojas (user)
- tai objektas, kuris turi prisijungimo duomenis, tokius kaip el. paštas, slapyvardis ir slaptažodis.
- Kliento pusė (angl. Front-end) – bus realizuojama naudojant
SvelteKit
karkasą. SvelteKit - tai Svelte paremtas karkasas, kuris remiasi Svelte pagrindais ir suteikia galingų funkcijų, tokių kodo skaidymas, failų maršrutizavimas, kurios palengvina sudėtingų programų kūrimą. - Serverio pusė (angl. Back-end) – bus realizuojama naudojant
Ktor
karkasą. Ktor yra asinchroninis karkasas, skirtas mikroservisams, žiniatinklio programoms ir kt. kurti, naudojant Kotlin programavimo kalbą. - Duomenys bus saugomi
PostgreSQL
duomenų bazėje, kuri bus pasiekiama perExposed ORM
. Duomenų bazė yra reliacinė, kuri leidžia saugoti duomenis lentelėse bei sudaryti ryšius tarp jų.
Klientinė dalis bus talpinama Vercel
platformoje, o serverinė dalis, API ir duomenų bazė, bus talpinama DigitalOcean App Platform
platformoje.
Toliau pateikiami realizuotų langų ekrano iškarpos ir juos atitinkantys wireframe`ai. Prototipai sukurti naudojant OpenSource shadcn/ui - kit šabloną, naudojantis Figma įrankiu. Prototipai buvo sukurti tik pagrindiniams langams.
Pradinis puslapis yra pirmas puslapis, kurį matys naudotojas atėjęs į svetainę. Jame bus pateikta trumpa informacija apie sistemą, prisijungimo ir registracijos mygtukai. Šis puslapis matomas tik svečiams.
Registracijos puslapyje naudotojas gali užsiregistruoti į sistemą. Registracijos formoje svečias turi suvesti savo slapyvardį, el. paštą ir slaptažodį.
Realizuotas langas | Prototipas lango |
---|---|
![]() |
![]() |
Prisijungimo puslapyje naudotojas gali prisijungti prie sistemos. Prisijungimo formoje naudotojas turi suvesti savo el. paštą ir slaptažodį.
Realizuotas langas | Prototipas lango |
---|---|
![]() |
![]() |
Projektų informacijos lange bus pateikta informacija apie projektą, jo pavadinimą, aprašymą, sukūrimo datą ir sukūrėją. Taip pat yra galimybė redaguoti projektą arba jį ištrinti.
Realizuotas langas | Prototipas lango |
---|---|
![]() |
![]() |
Projekto sukūrimo modale naudotojas gali sukurti naują projektą. Sukūrus projektą, jis bus matomas projekto informacijos lange. Projekto sukūrimo modale naudotojas turi suvesti projekto pavadinimą ir aprašymą. Identiškai atrodys ir projekto redagavimo modalinis langas.
Užduočių puslapyje pateikta informacija apie visas užduotis, kurios yra priskirtos tam tikrai sekcijai. Užduočių puslapyje galima peržiūrėti užduotis, sukurti naują užduotį, redaguoti esamą užduotį arba ją ištrinti.
Realizuotas langas | Prototipas lango |
---|---|
![]() |
![]() |
Paspaudus ant užduoties, atidaromas užduoties informacijos langas, kuriame pateikta informacija apie užduotį, jos pavadinimą, aprašymą, prioritetą, atlikimo būseną, atlikimo terminą.
Sekcijos sukūrimo modale naudotojas gali sukurti naują sekciją. Sukūrus sekciją, ji atsidaras užduočių puslapyje. Sekcijos sukūrimo modale naudotojas turi suvesti sekcijos pavadinimą. Identiškai atrodys ir sekcijos redagavimo modalinis langas.
API specifikacija bus aprašyta naudojant OpenAPI
standartą. Pilnas API aprašas gali būti rastas čia. Specifikacija pateikiama anglų kalba.
POST /api/v1/auth/register
Parameter | In | Type | Required | Description |
---|---|---|---|---|
body | string | true | User email | |
username | body | string | true | User username |
password | body | string | true | User password |
Request Body Example:
{
"username": "Sigmund",
"email": "[email protected]",
"password": "VerySafePassword132"
}
Response Example:
{
"success": true,
"status": "201",
"message": "User created successfully",
"data": {
"id": "9351f427-fba2-4378-99e9-2b82dc2a9466",
"userName": "Sigmund",
"email": "[email protected]"
}
}
Responses:
Status Code | Description |
---|---|
201 | User created |
422 | Unprocessable entity |
POST /api/v1/auth/login
Parameter | In | Type | Required | Description |
---|---|---|---|---|
body | string | true | User email | |
password | body | string | true | User password |
Request Body Example:
{
"username": "Sigmund",
"password": "VerySafePassword132"
}
Response Example:
{
"success": true,
"status": "200",
"message": "Login successful",
"data": {
"accessToken": "dgfgfgdfgdfhbgsdgsdg.dfgfgdfgdfghrtyrtrfiaXNzIjoiTWFudGFzIiwianRpIjoiNmYwMzgzYmMtNjY3MC00ZTMxLTg0N2QtMGVlZGYxNWJkZDJkIiwic3ViIjoiYzFjY2FmYTYtM2Efdgg8F81MXGox9wUMVYWwwwo"
}
}
Responses:
Status Code | Description |
---|---|
200 | Login successful |
422 | Unprocessable entity |
POST /api/v1/auth/accessToken
Parameter | In | Type | Required | Description |
---|---|---|---|---|
RefreshToken | cookie | string | true | Refresh token |
Response Example:
{
"success": true,
"status": "200",
"message": "Access token refreshed successfully",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJUcnVzdGVkQ2xpZW50IiwiaXNzIjoiTWFudGFzIiwianRpIjoiNmYwMzgzYmMtNjY3MC00ZTMxLTg0N2QtMGVlZGYxNWJkZDJkIiwic3ViIjoiYzFjY2FmYTYtM2EwNi00NzA3LThkNDQtNzc3ZWFkZWYzNjM1IiwidXNlcm5hbWUiOiJhZG1pbiIsInJvbGVzIjpbIkFkbWluIl0sImV4cCI6MTcyODkxODU0Mn0.qPQOaKwhjjfMLNriH8D35xP8F81MXGox9wUMVYWwwwo"
}
}
Responses:
Status Code | Description |
---|---|
200 | Access token refreshed |
422 | Unprocessable entity |
POST /api/v1/auth/logout
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
Response Example:
{
"success": true,
"status": "200",
"message": "Logout successful"
}
Responses:
Status Code | Description |
---|---|
200 | Logout successful |
422 | Unprocessable entity |
GET /api/v1/projects
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
Responses:
Status Code | Description |
---|---|
200 | All projects |
401 | Unauthorized |
403 | Forbidden |
Response Example:
{
"success": true,
"status": "200",
"message": "All projects",
"data": [
{
"id": 1,
"name": "Personal Task Manager",
"description": "Plan your day with ease",
"createdAt": "2024-10-01T12:00:00",
"createdBy": "Antonia"
},
{
"id": 2,
"name": "Home Budget",
"description": "Manage your finances",
"createdAt": "2024-08-09T12:00:00",
"createdBy": "Anton"
}
]
}
POST /api/v1/projects
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
name | body | string | true | Project name |
description | body | string | true | Project description |
Request Body Example:
{
"name": "New Project",
"description": "Project description"
}
Response Example:
{
"success": true,
"status": "201",
"message": "Project created",
"data": {
"id": 1,
"name": "Personal Task Manager",
"description": "Plan your day with ease",
"createdAt": "2024-10-01T12:00:00",
"createdBy": "Antonia"
}
}
Responses:
Status Code | Description |
---|---|
201 | Created |
400 | Bad request |
422 | Unprocessable entity |
401 | Unauthorized |
403 | Forbidden |
GET /api/v1/projects/{projectId}
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
Response Example:
{
"success": true,
"status": "200",
"message": "Project by id",
"data": {
"id": 1,
"name": "Personal Task Manager",
"description": "Plan your day with ease",
"createdAt": "2024-10-01T12:00:00",
"createdBy": "Antonia"
}
}
Responses:
Status Code | Description |
---|---|
200 | Project by id |
400 | Bad request |
404 | Not found |
401 | Unauthorized |
403 | Forbidden |
DELETE /api/v1/projects/{projectId}
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
Response Example:
{
"success": true,
"status": "204",
"message": "Project deleted"
}
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
Responses:
Status Code | Description |
---|---|
204 | No content |
400 | Bad request |
404 | Not found |
401 | Unauthorized |
403 | Forbidden |
PATCH /api/v1/projects/{projectId}
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
name | body | string | false | Project name |
description | body | string | false | Project description |
Request Body Example:
{
"name": "Updated Project",
"description": "Updated description"
}
Response Example:
{
"success": true,
"status": "200",
"message": "Project updated",
"data": {
"id": 1,
"name": "Personal Task Manager",
"description": "Plan your day with ease",
"createdAt": "2024-10-01T12:00:00",
"createdBy": "Antonia"
}
}
Responses:
Status Code | Description |
---|---|
200 | OK |
400 | Bad request |
422 | Unprocessable entity |
404 | Not found |
401 | Unauthorized |
403 | Forbidden |
GET /api/v1/projects/{projectId}/sections
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
withTasks | query | boolean | false | Include tasks in sections |
Response Example:
{
"success": true,
"status": "200",
"message": "All sections",
"data": [
{
"id": 1,
"projectId": 1,
"name": "Backlog",
"createdBy": "Virginia",
"createdAt": "2024-09-01T12:00:00"
},
{
"id": 2,
"projectId": 1,
"name": "In Progress",
"createdBy": "Natalie",
"createdAt": "2024-09-02T12:00:00"
}
]
}
Responses:
Status Code | Description |
---|---|
200 | All sections |
POST /api/v1/projects/{projectId}/sections
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
name | body | string | true | Section name |
Request Body Example:
{
"name": "New Section"
}
Response Example:
{
"success": true,
"status": "201",
"message": "Section created",
"data": {
"id": 1,
"projectId": 1,
"name": "Backlog",
"createdBy": "Virginia",
"createdAt": "2024-09-01T12:00:00"
}
}
Responses:
Status Code | Description |
---|---|
201 | Section created |
400 | Bad request |
404 | Not found |
422 | Unprocessable entity |
401 | Unauthorized |
403 | Forbidden |
GET /api/v1/projects/{projectId}/sections/{sectionId}
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
sectionId | path | integer | true | Section id |
Response Example:
{
"success": true,
"status": "200",
"message": "Section by id",
"data": {
"id": 1,
"projectId": 1,
"name": "Backlog",
"createdBy": "Virginia",
"createdAt": "2024-09-01T12:00:00"
}
}
Responses:
Status Code | Description |
---|---|
200 | Section by id |
400 | Bad request |
404 | Not found |
401 | Unauthorized |
403 | Forbidden |
DELETE /api/v1/projects/{projectId}/sections/{sectionId}
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
sectionId | path | integer | true | Section id |
Response Example:
{
"success": true,
"status": "204",
"message": "Section deleted"
}
Responses:
Status Code | Description |
---|---|
204 | No content |
400 | Bad request |
404 | Not found |
401 | Unauthorized |
403 | Forbidden |
PATCH /api/v1/projects/{projectId}/sections/{sectionId}
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
sectionId | path | integer | true | Section id |
name | body | string | true | Section name |
Request Body Example:
{
"name": "Updated Section"
}
Response Example:
{
"success": true,
"status": "200",
"message": "Section updated",
"data": {
"id": 1,
"projectId": 1,
"name": "Backlog",
"createdBy": "Virginia",
"createdAt": "2024-09-01T12:00:00"
}
}
Responses:
Status Code | Description |
---|---|
200 | Section updated |
400 | Bad request |
422 | Unprocessable entity |
404 | Not found |
401 | Unauthorized |
403 | Forbidden |
GET /api/v1/projects/{projectId}/sections/{sectionId}/tasks
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
sectionId | path | integer | true | Section id |
Response Example:
{
"success": true,
"status": "200",
"message": "All tasks",
"data": [
{
"id": 1,
"sectionId": 1,
"name": "Finish REST API",
"description": "Create documentation and tests",
"priority": "Low",
"completed": false,
"dueDate": "2023-10-09T12:00:00",
"createdBy": "Sigmund",
"createdAt": "2024-10-01T12:12:32"
},
{
"id": 2,
"sectionId": 1,
"name": "Upload to GitHub",
"description": "Push code to GitHub",
"priority": "Vital",
"completed": true,
"dueDate": "2023-10-09T12:00:00",
"createdBy": "Viktor",
"createdAt": "2024-10-01T12:12:32"
}
]
}
Responses:
Status Code | Description |
---|---|
200 | All tasks |
400 | Bad request |
401 | Unauthorized |
403 | Forbidden |
POST /api/v1/projects/{projectId}/sections/{sectionId}/tasks
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
sectionId | path | integer | true | Section id |
name | body | string | true | Task name |
description | body | string | true | Task description |
priority | body | string | true | Task priority |
completed | body | boolean | true | Task completed |
dueDate | body | string | false | Task due date |
Request Body Example:
{
"name": "New Task",
"description": "Task description",
"completed": false,
"priority": "Medium"
}
Response Example:
{
"success": true,
"status": "201",
"message": "Task created",
"data": {
"id": 1,
"sectionId": 1,
"name": "Finish REST API",
"description": "Create documentation and tests",
"priority": "Low",
"completed": false,
"dueDate": "2023-10-09T12:00:00",
"createdBy": "Sigmund",
"createdAt": "2024-10-01T12:12:32"
}
}
Responses:
Status Code | Description |
---|---|
201 | Task created |
400 | Bad request |
422 | Unprocessable entity |
401 | Unauthorized |
403 | Forbidden |
GET /api/v1/projects/{projectId}/sections/{sectionId}/tasks/{taskId}
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
sectionId | path | integer | true | Section id |
taskId | path | integer | true | Task id |
Response Example:
{
"success": true,
"status": "200",
"message": "Task by id",
"data": {
"id": 1,
"sectionId": 1,
"name": "Finish REST API",
"description": "Create documentation and tests",
"priority": "Low",
"completed": false,
"dueDate": "2023-10-09T12:00:00",
"createdBy": "Sigmund",
"createdAt": "2024-10-01T12:12:32"
}
}
Responses:
Status Code | Description |
---|---|
200 | Task by id |
400 | Bad request |
404 | Not found |
401 | Unauthorized |
403 | Forbidden |
DELETE /api/v1/projects/{projectId}/sections/{sectionId}/tasks/{taskId}
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
sectionId | path | integer | true | Section id |
taskId | path | integer | true | Task id |
Response Example:
{
"success": true,
"status": "204",
"message": "Task deleted"
}
Responses:
Status Code | Description |
---|---|
204 | No content |
400 | Bad request |
404 | Not found |
401 | Unauthorized |
403 | Forbidden |
PATCH /api/v1/projects/{projectId}/sections/{sectionId}/tasks/{taskId}
Parameter | In | Type | Required | Description |
---|---|---|---|---|
Bearer | header | string | true | Access token |
projectId | path | integer | true | Project id |
sectionId | path | integer | true | Section id |
taskId | path | integer | true | Task id |
name | body | string | false | Task name |
description | body | string | false | Task description |
priority | body | string | false | Task priority |
completed | body | boolean | false | Task completed |
dueDate | body | string | false | Task due date |
Request Body Example:
{
"name": "Updated Task",
"description": "Updated description",
"completed": true,
"priority": "High"
}
Response Example:
{
"success": true,
"status": "200",
"message": "Task updated",
"data": {
"id": 1,
"sectionId": 1,
"name": "Finish REST API",
"description": "Create documentation and tests",
"priority": "Medium",
"completed": true,
"dueDate": "2023-10-09T12:00:00",
"createdBy": "Sigmund",
"createdAt": "2024-10-01T12:12:32"
}
}
Responses:
Status Code | Description |
---|---|
200 | Task updated |
400 | Bad request |
422 | Unprocessable entity |
404 | Not found |
401 | Unauthorized |
403 | Forbidden |
- Projekto kūrimas suteikė galimybę pritaikyti semestro metu įgytas teorines žinias realioje sistemoje, padedant geriau suprasti, kaip įvairios technologijos ir įrankiai veikia kartu.
- Naudotos technologijos, tokios kaip
SvelteKit
(kliento pusė),Ktor
(serverio pusė) irPostgreSQL
(duomenų bazė), buvo tinkamai pasirinktos ir užtikrino sistemai reikalingą funkcionalumą, greitį ir lankstumą. - Naudojant
Figma
įrankį, buvo sukurti prototipai, kurie padėjo ne tik paspartinti UI realizavimo procesą, bet ir užtikrinti, kad galutinė sistema būtų patogi naudoti. - Naudojant
OpenAPI
specifikaciją, buvo sukurtas aiškus ir standartizuotas API, kas leido lengviau valdyti komunikaciją tarp kliento ir serverio bei supaprastino integracijos procesą.