This is an old revision of the document!


Tema 2 - Bug Tracker Pro

  • Data publicarii:
  • Deadline HARD:
  • Ultima modificare a enuntului:
  • Ultima modificare a testelor:
  • Schelet: GitHub
  • History:

Obiective

  • Implementarea a cel puțin 4 design pattern-uri.
  • Crearea unui cod care respectă principiile de bază POO: Abstracție, Încapsulare, Moștenire, Polimorfism.
  • Respectarea principiilor SOLID.
  • Familiarizarea studenților cu JUnit și rularea testelor unitare.

Descriere

După ce ați încercat, fără succes, să obțineți un job la startup-ul lui Gigelino, ați decis să vă lansați propria aplicație. Întâmplarea a făcut să atrageți atenția unor investitori dispuși să vă finanțeze, însă cu o condiție clară: produsul final trebuie să fie stabil, lipsit de bug-uri majore și să primească feedback pozitiv de la utilizatorii beta.

Pentru a răspunde acestei provocări, veți implementa un sistem de ticket tracking care să vă ajute să:

  • înregistrați tickete noi,
  • raportați problemele apărute,
  • urmăriți progresul și să le rezolvați.

Dezvoltarea va fi împărțită în două etape principale:

  1. testare și raportare tickete
  2. rezolvare acestora de către echipa de ingineri

Obiectivul vostru este să asigurați o gestionare eficientă a bug-urilor, prioritizarea corectă a sarcinilor și o monitorizare constantă a progresului, astfel încât să prezentați investitorilor un produs final solid și de încredere.

Atenție! Timpul este limitat, iar investitorii nu sunt dispuși să aștepte la nesfârșit.

Deadline-ul pentru livrarea produsului este specificat în scheletul oferit.

Workflow

Dezvoltarea aplicației urmează un ciclu iterativ, alcătuit din următoarele etape:

  1. Perioada de testare: reporterii deschid tickete pentru problemele identificate.
  2. Perioada de dezvoltare: managerii creează milestone-uri, iar developerii își asignează tickete și le rezolvă.
  3. Verificarea stabilității aplicației: se generează un raport de stabilitate și se evaluează progresul.
    1. Dacă produsul este stabil, proiectul se încheie cu succes.
    2. Dacă nu, ciclul este reluat.

Acest workflow se repetă până când produsul atinge un nivel acceptabil de stabilitate sau investitorii decid să își retragă finanțarea.

Astfel, procesul de dezvoltare poate fi modelat sub forma unui automat finit:

Etapele Workflow-ului

1. Perioada de Testare

  • La inițierea aplicației, perioada de testare începe automat.
  • Utilizatorii pot raporta tickete noi, pe baza testării produsului și a feedback-ului primit de la clienți.
  • Developerii nu pot rezolva tickete în această etapă.
  • Perioada de testare are o durată fixă de 15 zile.

2. Perioada de Dezvoltare

  • După încheierea perioadei de testare, începe perioada de dezvoltare.
  • Managerii creează milestone-uri și își coordonează echipa.
  • Developerii își pot asocia tickete din milestone-uri și pot începe lucrul la acestea.

3. Verificarea Stabilității

  • Managerii pot genera rapoarte pentru monitorizarea progresului.
  • Dacă raportul de stabilitate este satisfăcător, produsul este considerat stabil și pregătit pentru prezentarea către investitori.
  • Dacă raportul indică probleme, ciclul continuă cu o nouă perioadă de testare și dezvoltare.
  • Această etapă poate fi skipped, trecându-se direct la perioada de testare, dacă un manager execută comanda: startTestingPhase

Tickete

Aplicația gestionează mai multe tipuri de tickete. Toate tipurile împărtășesc un set comun de câmpuri opționale, care pot fi utilizate dacă sunt relevante pentru context.

Câmpuri comune

Câmp Descriere Tip
id Identificator unic al ticket-ului int
type Tipul ticket-ului string
title Titlu scurt string
businessPriority Nivel de prioritate în cadrul aplicației enum(LOW, MEDIUM, HIGH, CRITICAL)
status Statusul curent al ticketului enum(OPEN, IN_PROGRESS, RESOLVED, CLOSED)
expertiseArea Domeniul de expertiză necesar enum(FRONTEND, BACKEND, DEVOPS, DESIGN, DB)
description Descriere detaliată a problemei sau cererii string

Câmpul description este opțional.

1. BUG

Un BUG reprezintă o problemă tehnică apărută în aplicație.

Câmpuri obligatorii

Câmp Descriere Tip
expectedBehavior Comportamentul așteptat string
actualBehavior Comportamentul observat string
frequency Frecvența apariției enum(RARE, OCCASIONAL, FREQUENT, ALWAYS)
severity Severitatea bug-ului (cât de mult afectează aplicația) enum(MINOR, MODERATE, SEVERE)

Câmpuri opționale

Câmp Descriere Tip
environment Mediu de operare String
errorCode Cod de eroare returnat de aplicație int

Atenție! Doar un ticket de tip BUG poate fi raportat ANONIM.

2. FEATURE_REQUEST

Un ticket de tip FEATURE_REQUEST propune o nouă funcționalitate sau extinderea uneia existente.

Câmpuri obligatorii specifice

Câmp Descriere Valori posibile
businessValue Impact estimat asupra afacerii enum(S, M, L, XL)
customerDemand Cererea clienților pentru această funcționalitate enum(LOW, MEDIUM, HIGH, VERY_HIGH)

3. UI_FEEDBACK

Un ticket de tip UI_FEEDBACK colectează sugestii privind experiența de utilizare.

Câmpuri obligatorii specifice

Câmp Descriere Tip
uiElementId Identificatorul elementului de UI string
businessValue Impact estimat asupra utilizatorilor sau business-ului enum (S, M, L, XL)
usabilityScore Scor de utilizabilitate (scala de la 1 la 10) int

Câmpuri opționale specifice

Câmp Descriere Tip
screenshotUrl Link către o captură de ecran string
suggestedFix Sugestie de îmbunătățire pentru UI string


Sugestie: Fiecare tip de ticket definit în aplicație conține atât câmpuri obligatorii, cât și câmpuri opționale. De aceea, instanțierea și construirea obiectelor trebuie gândită și proiectată cu atenție.

Utilizatori

Aplicația definește trei tipuri de utilizatori, fiecare având roluri și atribute specifice:

Reporter

Reporterul are rolul de a raporta tickete în perioadele de testare, pe baza feedback-ului primit de la clienți și a testării interne. De asemenea, poate primi notificări legate de statusul ticketelor raportate.

Input reporter

Input reporter

[
  {
    "username": "reporter_one",
    "role": "REPORTER",
    "email": "reporter_one@gmail.com"
  },
  {
    "username": "reporter_two",
    "role": "REPORTER",
    "email": "reporter_two@gmail.com"
  }
]

Developer

Developerul se ocupă de rezolvarea ticketelor raportate și poate primi notificări legate de activitatea acestora.

Not all devs are made equal.. De aceea, în funcție de experiența profesională, există 3 niveluri de senioritate care determină accesul acestora la tickete:

Acces la tickete în funcție de senioritate:

  • JUNIOR: poate prelua tickete cu prioritate LOW, MEDIUM; tipuri: BUG, UI_FEEDBACK
  • MID: acces JUNIOR + tickete cu prioritate HIGH, inclusiv FEATURE_REQUEST
  • SENIOR: acces MID + tickete CRITICAL

Mai mult! Fiecare developer are o specializare:

Acces în funcție de specializare:

  • FRONTEND Developer: tickete din FRONTEND, DESIGN
  • BACKEND Developer: tickete din BACKEND, DB
  • FULLSTACK Developer: tickete din toate zonele: FRONTEND, BACKEND, DEVOPS, DESIGN, DB
  • DEVOPS Engineer: tickete din DEVOPS
  • UI/UX Designer: tickete din DESIGN
  • Database Admin: tickete din DB

Input developer

Input developer

[
  {
    "username": "dev_three",
    "role": "DEVELOPER",
    "email": "dev_three@bugtracker.com", 
    "hireDate": "2022-07-22", 
    "seniority": "JUNIOR",
    "expertiseArea": "FRONTEND"
  },
  {
    "username": "dev_four",
    "role": "DEVELOPER",
    "email": "dev_four@bugtracker.com",
    "hireDate": "2019-11-05",
    "seniority": "MID",
    "expertiseArea": "FULLSTACK"
  }

Sugestie: Toți developerii execută aceleași comenzi, dar senioritatea și expertiza determină dacă o acțiune este permisă. Think of Separation of Concerns.

Manager

Managerul coordonează propria echipa de developeri, creează și gestionează milestone-uri și menține o listă de subordonați reprezentată prin username-urile developerilor pe care îi are în echipă.

Input manager

Input manager

[
  {
    "username": "gabriel_manager",
    "role": "MANAGER",
    "email": "gabriel@bugtracker.com", 
    "hireDate": "2002-02-28", 
    "subordinates": ["dev_one", "dev_two", "dev_three"]
  },
  {
    "username": "cleopatra_manager",
    "role": "MANAGER",
    "email": "cleopatra@bugtracker.com",
    "hireDate": "2003-03-15",
    "subordinates": ["dev_four", "dev_five"]
  }
]

Milestones

Un milestone reprezintă o etapă majoră în dezvoltarea proiectului. Acesta este stabilit de un manager la finalul unei perioade de testare și conține un set de tickete care trebuie rezolvate într-un interval de timp predefinit.

Doar developerii care fac parte din echipa managerului respectiv pot fi atribuiți acelui milestone.

Atributele unui milestone

  • name – numele milestone-ului (unic).
  • blockingFor – listă de nume ale milestone-urilor care sunt blocate de acest milestone.
  • dueDate – data limită pentru atingerea milestone-ului.
  • tickets – listă de ID-uri ale ticketelor asociate milestone-ului.
  • assignedDevs – listă cu username-urile developerilor repartizați.

Mentiuni speciale

1. La fiecare 3 zile după crearea milestone-ului, prioritatea ticketelor din acel milestone crește automat cu o treaptă (ex: LOWMEDIUM, MEDIUMHIGH etc.).

2. Cu o zi calendaristică înainte de dueDate, toate ticketele rămase active în milestone:

  1. devin automat de prioritate CRITICAL
  2. toți developerii atribuiți primesc o notificare.

3. Un milestone poate bloca alte milestone-uri. Dacă un milestone se află în stare de blocare:

  1. bug-urile din milestone-ul blocat nu pot fi rezolvate sau atribuite
  2. regulile de la punctele 1 și 2 nu se aplică (prioritatea ticketelor nu crește, iar acestea nu devin CRITICAL).

4. Dacă un milestone este deblocat cu o zi calendaristică înainte de dueDate, regula de la punctul 2 se aplică.

5. Dacă un milestone este deblocat după dueDate:

  1. toate ticketele rămase devin automat CRITICAL
  2. se trimite o notificare specială developerilor asignați.

Vom defini următoarele convenții:

daysBetween = date2 − date1 + 1, pentru a include ambele zile. O zi calendaristică înainte de YYYY-MM-DD înseamnă întotdeauna ziua anterioară calendaristică.

Exemple: Pentru intervalul 2023-05-01 → 2023-05-10, daysBetween = 10 Dacă dueDate = 2023-05-10, ziua calendaristică anterioară este 2023-05-09

Notificări

Întreaga aplicație este bazată pe un sistem de notificări. Orice acțiune semnificativă (ex: adăugare comentariu, schimbare status ticket, atribuire ticket, creare milestone) va genera o notificare către utilizatorii vizați.

Formatele notificărilor

Formatele notificărilor

Acțiune Cine primește Format notificare
Adăugare comentariu de către Reporter Developerul căruia îi este atribuit ticketul New comment on ticket <id> by reporter <reporter_name>: <comment_content>
Adăugare comentariu de către Developer Reporterul ticketului (dacă nu este anonim) New comment on your ticket <id> by developer <developer_name>: <comment_content>
Ticket trecut la CLOSED, ultimul dintr-un milestone blocant Toți developerii atribuiți milestone-urilor blocate Milestone <milestone_name> is now unblocked as ticket <id> has been CLOSED.
Generare raport de performanță Developerul vizat Your performance score for the month <month_as_lowercase_english_name> is <score>.
Crearea unui Milestone Toți developerii atribuiți milestone-ului New milestone <milestone_name> has been created with due date <due_date>.
Milestone ajuns la o zi de dueDate Toți developerii atribuiți milestone-ului Milestone <milestone_name> is due tomorrow. All unresolved tickete are now CRITICAL.
Milestone deblocat după dueDate Toți developerii atribuiți milestone-ului Milestone <milestone_name> was unblocked after due date. All active tickete are now CRITICAL.

Sugestie: Pentru a gestiona notificările într-un mod scalabil, gândiți-vă la o soluție în care utilizatorii să fie automat informați.

Metrici de Stabilitate a Aplicației

Pe lângă rapoartele de performanță, aplicația generează și rapoarte pe baza unor metrici specifice, calculate în funcție de tipul fiecărui ticket. Fiecare metrică are o formulă dedicată în funcție de tipul de ticket.

Cele 3 metrici cu care vom lucra sunt: Customer Impact, Resolution Efficiency, Ticket Risk.

Convenții de scor (click pentru a deschide)

Convenții de scor (click pentru a deschide)

frequency:
  RARE        = 1
  OCCASIONAL  = 2
  FREQUENT    = 3
  ALWAYS      = 4

businessPriority:
  LOW         = 1
  MEDIUM      = 2
  HIGH        = 3
  CRITICAL    = 4

severityFactor:
  MINOR       = 1
  MODERATE    = 2
  SEVERE      = 3

businessValue:
  S           = 1
  M           = 3
  L           = 6
  XL          = 10

customerDemand:
  LOW         = 1
  MEDIUM      = 3
  HIGH        = 6
  VERY_HIGH   = 10

Pași generali de calcul

1. Pentru fiecare ticket eligibil se calculează scorul brut (baseScore), în funcție de formula asociată.

2. Se face media scorurilor pentru o categorie.

3. Se normalizează rezultatul pe intervalul 0–100.

Cod: Medie pe categorie

Cod: Medie pe categorie

public double calculateAverageImpact(List<Double> scores) {
    return scores.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
}

Cod: Normalizare rezultat

Cod: Normalizare rezultat

public double calculateImpactFinal(double baseScore, double maxValue) {
    return Math.min(100.0, (baseScore * 100.0) / maxValue);
}

Sugestie: Structura codului ar trebui să permită adăugarea unor metrici noi, fără a altera clasele deja existente.

Code should be open for extension, but closed for modification.

Mai multe detalii, veți găsi la comenzile specifice fiecărei metrici.

Comenzi

Pe parcursul execuției, va trebui să gestionați diverse erori.

Ordinea în care apar în enunț este și ordinea în care trebuie verificate. Astfel, excepția menționată prima va avea întotdeauna prioritate de tratare față de cele care apar mai jos.

1. Utilizator inexistent

Dacă un utilizator trimite o comandă, dar nu există în sistem, comanda este invalidă și trebuie afișată o eroare corespunzătoare.

Output eroare

Output eroare

{
  "command": "command_name",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "The user <user_name> does not exist."
}

2. Comandă nepermisă pentru rol

Dacă utilizatorul nu are rolul necesar pentru a rula o comandă, aceasta este refuzată cu mesaj de eroare clar.

Output eroare

Output eroare

{
  "command": "command_name",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "The user does not have permission to execute this command: required role <role_name> <-> user role <user_role>."
}

3. Ordinea tratării

Aceste excepții sunt verificate înainte de orice validări specifice fiecărei comenzi.

Acum putem trece la comenzile aplicatiei.

lostInvestors

Disponibilă pentru: Manager

Descriere: Investitorii și-au pierdut răbdarea și au renunțat la finanțare. Aplicația se închide și nu mai sunt procesate comenzi după acest moment.

Input

Input

{
  "command": "lostInvestors",
  "username": "gabriel_manager",
  "timestamp": "2025-10-20"
}

Nu există output.

reportTicket

Disponibilă pentru: Reporter

Descriere: Reportarea este permisă doar în perioada de testare. Pentru mai multe detalii, consultă secțiunea Perioada de Testare.

Restricții:

1. ID-urile sunt alocate incremental de sistem, începând de la 0.

2. Se garantează că formatul de input este corect (fără câmpuri invalide sau lipsă).

3. Statusul inițial al unui ticket este întotdeauna OPEN.

Raportare într-o perioadă incorectă

Raportare într-o perioadă incorectă

{
"command": "reportTicket",
"username": "user_name",
"timestamp": "YYYY-MM-DD",
"error": "Tickets can only be reported during testing phases."
} 

4 Raportarea anonimă:

  • Ticketele anonime au automat LOW businessPriority.
  • Doar ticketele de tip BUG pot fi anonime (reportedBy = ”“).

Raport anonim invalid

Raport anonim invalid

{
"command": "reportTicket",
"username": "user_name",
"timestamp": "YYYY-MM-DD",
"error": "Anonymous reports are only allowed for tickets of type BUG."
} 


Format Input:

Exemplu input complet

Exemplu input complet

{
"command": "reportTicket",
"timestamp": "2025-09-10",
"type": "BUG",
"username": "reporter_one",
"reportedBy": "cleopatra",
"params": {
"title": "Crash on settings page",
"description": "App crashes when accessing settings.",
"businessPriority": "HIGH",
"frequency": "FREQUENT",
"expertiseArea": "BACKEND",
"reportedBy": "cleopatra",
"expectedBehavior": "Settings page should load without crashing.",
"actualBehavior": "App crashes immediately.",
"environment": "Windows"
}
} 


Nu există output.

addComment

Disponibilă pentru: Reporter, Developer

Descriere: Adaugă un comentariu la un ticket.

Restricții

1. Dacă ticket-ul nu există (ID inexistent), comanda este ignorată.

2. Un ticket anonim nu poate primi comentarii. Dacă se încearcă adăugarea unui comentariu la un ticket anonim, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "addComment",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Comments are not allowed on anonymous tickets."
}

3. Un Reporter nu poate comenta dacă ticket-ul are status CLOSED. În cazul în care se încearcă comentarea unui ticket cu status CLOSED, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "addComment",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Reporters cannot comment on CLOSED tickets."
}

4. Conținutul comentariului trebuie să aibă minim 10 caractere. Dacă este mai mic, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "addComment",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Comment must be at least 10 characters long."
}

5. Un Developer poate comenta doar pe ticketele care îi sunt atribuite. Dacă un developer încearcă să comenteze un ticket care nu îi este atribuit, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "addComment",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Ticket <id> is not assigned to the developer <developer_name>."
}

6. Un Reporter poate comenta doar pe ticketele pe care le-a raportat. Dacă un reporter încearcă să comenteze un ticket pe care nu l-a raportat, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "addComment",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Reporter <reporter_name> cannot comment on ticket <id>."
}

Format comentariu

{
  "author": "username_of_commenter",
  "content": "string",
  "createdAt": "date_given_by_command_timestamp"
}


Exemplu Input:

Exemplu input complet

Exemplu input complet

{
"command": "addComment",
"username": "dev_one",
"ticketID": 0,
"comment": "I am looking into this issue.",
"timestamp": "2025-09-10"
} 


Nu există output.

undoAddComment

Disponibilă pentru: Reporter, Developer

Descriere: Șterge ultimul comentariu adăugat de utilizator la un ticket.

Restricții

1. Dacă ticket-ul nu există (ID inexistent), comanda este ignorată.

2. Dacă se încearcă ștergerea unui comentariu de la un ticket anonim, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "undoAddComment",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Comments are not allowed on anonymous tickets."
}

3. Dacă utilizatorul nu are comentarii la ticket-ul respectiv, comanda este ignorată.

4. Notificarea trimisă la crearea comentariului nu este ștearsă.


Exemplu Input:

Exemplu input complet

Exemplu input complet

{
"command": "undoAddComment",
"username": "dev_one",
"ticketID": 0,
"timestamp": "2025-09-10"
} 


Nu există output.

createMilestone

Disponibilă pentru: Manager

Descriere: Setează un nou milestone.

Restricții

1. Un ticket poate aparține unui singur milestone la un moment dat. În cazul în care un ticket este deja atribuit unui alt milestone, comanda createMilestone este respinsă:

Output eroare

Output eroare

{
  "command": "createMilestone",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Tickets id already assigned to milestone <milestone_name>."
}

Dacă se încearcă crearea unui milestone cu mai multe tickete din alt milestone, comanda va eșua la primul ticket invalid.

  • Se garantează că formatul de input al milestone-ului este corect. (Fără câmpuri invalide sau lipsă câmpuri obligatorii). Nu vor exista milestone-uri cu același nume.
  • Se garantează că orice milestone va avea o perioadă de soluționare de cel puțin 5 zile.
  • Se garantează că nu se va încerca crearea unui milestone în perioada de testare.


Exemplu Input:

Exemplu input complet

Exemplu input complet

{
"command": "createMilestone",
"username": "gabriel_manager",
"timestamp": "2025-09-15",
"name": "v1.0",
"dueDate": "2025-10-01",
"blockingFor": ["v2.0"],
"tickets": [0, 1, 2],
"assignedDevs": ["dev_one", "dev_two"]
} 


Nu există output.

startTestingPhase

Disponibilă pentru: Manager

Descriere: Începe o nouă perioadă de testare, permițând reporterilor să creeze tickete noi și să redeschidă tickete închise.

Restricții

1. O nouă perioadă de testare poate începe doar dacă nu mai există milestone-uri active (cu tickete nerezolvate). În cazul în care se încearcă începerea unei noi perioade de testare cu milestone-uri active, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "startTestingPhase",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Cannot start a new testing phase."
}

* Se garantează că nu se va încerca începerea unei perioade de testare dacă una este deja activă.


Exemplu Input:

Exemplu input complet

Exemplu input complet

{
"command": "startTestingPhase",
"username": "gabriel_manager",
"timestamp": "2025-10-05"
} 


Nu există output.

assignTicket

Disponibilă pentru: Developer

Descriere: Un developer își poate atribui un ticket conform regulilor de expertiză, senioritate și milestone.

Restricții

1. Un Developer își poate atribui tickete doar din aria lui de expertiză. În cazul în care un developer încearcă să își atribuie un ticket din altă arie de expertiză, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "assignTicket",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Developer <developer_name> cannot assign ticket <id> due to expertise area. Required: <required_area1>, <required_area2>; Current: <current_area>."
}

2. Un Developer își poate atribui singur doar tickete accesibile nivelului său de senioritate. În cazul în care un developer încearcă să își atribuie un ticket care nu îi este permis, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "assignTicket",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Developer <developer_name> cannot assign ticket <id> due to seniority level. Required: <required_level>, <required_level>; Current: <current_level>."
}

3. Un ticket poate fi atribuit doar dacă este în status OPEN. Dacă un developer încearcă să își atribuie un ticket cu alt status, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "assignTicket",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Only OPEN tickets can be assigned."
}

4. Dacă un developer încearcă să își atribuie un ticket dintr-un milestone la care nu este repartizat, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "assignTicket",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Developer <developer_name> is not assigned to milestone <milestone_name>."
}

5. Un developer nu își poate atribui tickete dintr-un milestone blocat (vezi detalii la secțiunea Milestone). Dacă încearcă să își atribuie un ticket dintr-un milestone blocat, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "assignTicket",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Cannot assign ticket <id> from blocked milestone <milestone_name>."
}

  • Odată atribuit, statusul unui ticket devine IN_PROGRESS.
  • Se garantează că ID-ul ticket-ului există.


Exemplu Input:

Exemplu input complet

Exemplu input complet

{
"command": "assignTicket",
"username": "dev_one",
"ticketID": 0,
"timestamp": "2025-09-21"
} 


Nu există output.

undoAssignTicket

Disponibilă pentru: Developer

Descriere: Developer-ul realizează că nu poate rezolva un ticket și decide să renunțe, pentru a fi reatribuit de altcineva.

Restricții

1. Un ticket poate fi „de-asignat” doar dacă are statusul IN_PROGRESS. În cazul în care un developer încearcă să renunțe la un ticket cu alt status, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "undoAssign",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Only IN_PROGRESS tickets can be unassigned."
}

  • Se garantează că ID-ul ticket-ului pentru care se încearcă „de-asignarea” există.
  • Se garantează că ticket-ul este atribuit developerului care inițiază comanda.
  • În urma „de-asignării”, statusul ticket-ului revine la OPEN.
  • Operația rămâne în istoric. Pentru detalii suplimentare, vezi sectiunea viewTicketHistory.


Exemplu Input:

Exemplu input complet

Exemplu input complet

{
"command": "undoAssign",
"username": "dev_one",
"ticketID": 0,
"timestamp": "2025-09-22"
} 


Nu există output.

changeStatus

Disponibilă pentru: Developer

Descriere: Permite unui developer să modifice statusul unui ticket atribuit lui.

Restricții

1. Ticketul trebuie să fie atribuit developerului care face schimbarea. În cazul în care un developer încearcă să schimbe statusul unui ticket care nu îi este atribuit, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "changeStatus",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Ticket <id> is not assigned to developer <developer_name>."
}

  • Sunt permise doar următoarele tranziții de status: IN_PROGRESS → RESOLVED → CLOSED. Nu vor exista excepții în teste.


Exemplu Input:

Exemplu input complet

Exemplu input complet

{
"command": "changeStatus",
"username": "dev_one",
"ticketID": 0,
"timestamp": "2025-09-23"
} 


Nu există output.

undoChangeStatus

Disponibilă pentru: Developer

Descriere: Developer-ul realizează că a făcut o greșeală și decide să reîntoarcă un ticket la statusul anterior.

Restricții

1. Ticketul trebuie să fie atribuit developerului care face schimbarea. În cazul în care un developer încearcă să reîntoarcă statusul unui ticket care nu îi este atribuit, comanda este respinsă:

Output eroare

Output eroare

{
  "command": "undoChangeStatus",
  "username": "user_name",
  "timestamp": "YYYY-MM-DD",
  "error": "Ticket <id> is not assigned to developer <developer_name>."
}

  • Sunt permise doar următoarele tranziții de status: RESOLVED → IN_PROGRESS, CLOSED → RESOLVED. Nu vor exista excepții în teste.
  • Operația rămâne în istoric. Mai multe detalii în secțiunea [View Ticket History](#viewtickethistory).
</note>  


Exemplu Input:

Exemplu input complet

Exemplu input complet

{
"command": "undoChangeStatus",
"username": "dev_one",
"ticketID": 0,
"timestamp": "2025-09-24"
} 


Nu există output.

poo-ca-cd/teme/2025/b73f56dc-17a1-42ac-bd7e-d57f3caaf9fd/tema-2.1759386483.txt.gz · Last modified: 2025/10/02 09:28 by valentin.carauleanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0