Untitled

 avatar
unknown
plain_text
8 days ago
7.4 kB
6
Indexable
# Pytania APK (Analiza Potrzeb Klienta)

## 1. Model Bazodanowy

### Tabele

#### QuestionGroup
```sql
CREATE TABLE question_group (
    id BIGINT PRIMARY KEY,
    code VARCHAR(50) NOT NULL, -- np. MAIN_RISKS, ADDITIONAL_RISKS
    active BOOLEAN DEFAULT true
);
```

#### Question
```sql
CREATE TABLE question (
    id BIGINT PRIMARY KEY,
    group_id BIGINT REFERENCES question_group(id),
    question_order INT NOT NULL,
    dependent_on_question_id BIGINT REFERENCES question(id),
    dependent_on_answer_id BIGINT REFERENCES answer(id),
    active BOOLEAN DEFAULT true
);
```

#### QuestionContent
```sql
CREATE TABLE question_content (
    id BIGINT PRIMARY KEY,
    question_id BIGINT REFERENCES question(id),
    language_code VARCHAR(5), -- np. pl_PL, en_GB
    content TEXT NOT NULL
);
```

#### Answer
```sql
CREATE TABLE answer (
    id BIGINT PRIMARY KEY,
    question_id BIGINT REFERENCES question(id),
    answer_order INT NOT NULL,
    code VARCHAR(50) NOT NULL,
    active BOOLEAN DEFAULT true
);
```

#### AnswerContent
```sql
CREATE TABLE answer_content (
    id BIGINT PRIMARY KEY,
    answer_id BIGINT REFERENCES answer(id),
    language_code VARCHAR(5),
    content TEXT NOT NULL
);
```

#### CustomerQuestionnaire
```sql
CREATE TABLE customer_questionnaire (
    id BIGINT PRIMARY KEY,
    customer_id BIGINT NOT NULL,
    quote_id BIGINT NOT NULL,
    group_id BIGINT REFERENCES question_group(id),
    status VARCHAR(20) NOT NULL, -- IN_PROGRESS, COMPLETED
    created_at TIMESTAMP NOT NULL,
    completed_at TIMESTAMP
);
```

#### CustomerAnswer
```sql
CREATE TABLE customer_answer (
    id BIGINT PRIMARY KEY,
    questionnaire_id BIGINT REFERENCES customer_questionnaire(id),
    question_id BIGINT REFERENCES question(id),
    answer_id BIGINT REFERENCES answer(id),
    answered_at TIMESTAMP NOT NULL
);
```

## 2. API Endpoints

#### 2.1 Inicjalizacja procesu APK
```
GET /apk/questionnaires
Parameters:
{
    "groupCode": string // MAIN_RISKS lub ADDITIONAL_RISKS
}

Response:
{
    "questionnaireId": string
    "questions": [
      {
        "id": long,
        "content": string
      }
    ],
    "answers": [
      {
        "id": long,
        "content": string,
        "nextQuestionId": long,
        "recommendation": string,
      }
    ],
    "initQuestionId": long
    "questionsAndAnswers": [
      {
        "questionId": long,
        "answers": [
            {
              "id": long
            }
         ]
      }
    ]
}
```

#### 2.2 Zapisanie odpowiedzi i pobranie kolejnego pytania
```
POST /apk/questionnaires/{questionnaireId}
Request:
{
    "answers": [
      {
        "questionId": long,
        "answers": long
      }
    ],
    "recommendation": string
}

Response:
200
```

#### 2.3 Pobranie aktualnego statusu kwestionariusza
```
GET /apk/questionnaires/{questionnaireId}
Response:
{
    "questions": [
      {
        "id": long,
        "content": string
      }
    ],
    "answers": [
      {
        "id": long,
        "content": string,
        "nextQuestionId": long,
        "recommendation": string,
      }
    ],
    "answers": [
      {
        "questionId": long,
        "answers": long
      }
    ],
    "recommendation": string
}
```

### Frontend (Angular)

#### Serwisy

```typescript
// apk.service.ts
@Injectable({
    providedIn: 'root'
})
export class ApkService {
    constructor(private http: HttpClient) {}

    initializeQuestionnaire(
        quoteId: number, 
        groupCode: string
    ): Observable<QuestionnaireInitResponse> {
        return this.http.post<QuestionnaireInitResponse>(
            '/apk/questionnaire',
            { quoteId, groupCode }
        );
    }

    submitAnswer(
        questionnaireId: number,
        questionId: number,
        answerId: number,
        isChange: boolean = false
    ): Observable<AnswerResponse> {
        return this.http.post<AnswerResponse>(
            `/apk/questionnaire/${questionnaireId}/answer`,
            { questionId, answerId, isChange }
        );
    }

    getQuestionnaireStatus(
        questionnaireId: number
    ): Observable<QuestionnaireStatus> {
        return this.http.get<QuestionnaireStatus>(
            `/apk/questionnaire/${questionnaireId}`
        );
    }
}
```

## 3. Flow procesu

### 3.1 Standardowy flow

1. **Inicjalizacja**:
    - Frontend otrzymuje oferty ubezpieczeniowe
    - Jeśli oferta zawiera AC lub OC+AC:
        - Wywołuje endpoint inicjalizacji z `groupCode=MAIN_RISKS`
        - Wyświetla pierwsze pytanie z otrzymanej odpowiedzi

2. **Proces pytań głównych**:
    - Po każdej odpowiedzi użytkownika:
        - Frontend wywołuje endpoint submit answer z `isChange=false`
        - Jeśli otrzyma kolejne pytanie - wyświetla je
        - Jeśli otrzyma rekomendację - zapisuje ją i przechodzi do następnego kroku

3. **Inicjalizacja pytań dodatkowych**:
    - Frontend wywołuje endpoint inicjalizacji z `groupCode=ADDITIONAL_RISKS`
    - Proces analogiczny jak dla pytań głównych

### 3.2 Flow zmiany odpowiedzi

1. **Zmiana odpowiedzi**:
    - Użytkownik zmienia odpowiedź na wcześniejsze pytanie
    - Frontend wywołuje endpoint submit answer z `isChange=true`
    - Backend:
        - Aktualizuje odpowiedź w bazie danych
        - Usuwa wszystkie odpowiedzi na pytania o wyższym order
        - Sprawdza logikę biznesową dla nowej ścieżki

2. **Obsługa odpowiedzi przez Frontend**:
    - Po otrzymaniu odpowiedzi z `removedQuestionIds`:
        - Usuwa z lokalnego stanu odpowiedzi na wskazane pytania
        - Jeśli otrzymał `resetToQuestionOrder`:
            - Wraca do pytania o wskazanym order
            - Czyści wszystkie późniejsze odpowiedzi
        - Aktualizuje interfejs użytkownika
        - Czyści rekomendację jeśli proces wraca do wcześniejszego etapu

### 3.3 Flow przywracania sesji

1. **Powrót do procesu**:
    - Frontend wywołuje GET /apk/questionnaire/{questionnaireId}
    - Na podstawie odpowiedzi:
        - Jeśli status "COMPLETED" - wyświetla podsumowanie i rekomendację
        - Jeśli status "IN_PROGRESS" - wyświetla currentQuestion
        - Wypełnia historię odpowiedzi na podstawie answeredQuestions

## 4. Rozszerzalność

System zaprojektowano z myślą o:
- Dodawaniu nowych pytań i odpowiedzi (przez strukturę tabel)
- Wsparciu wielu języków (przez tabele *Content)
- Możliwości uzależniania pytań od poprzednich odpowiedzi
- Łatwym dodawaniu nowych grup pytań
- Śledzeniu historii odpowiedzi klienta
- Obsłudze złożonych scenariuszy zmiany odpowiedzi

## 5. Podział odpowiedzialności

### Backend
- Przechowywanie definicji pytań i odpowiedzi
- Logika wyboru kolejnych pytań
- Wyliczanie rekomendacji
- Walidacja odpowiedzi
- Persystencja danych
- Zarządzanie procesem sekwencyjnym odpowiedzi
- Obsługa usuwania odpowiedzi na późniejsze pytania

### Frontend
- Prezentacja pytań i odpowiedzi
- Obsługa interakcji z użytkownikiem
- Zarządzanie stanem procesu
- Prezentacja rekomendacji
- Obsługa wielojęzyczności UI
- Zarządzanie nawigacją między pytaniami
- Obsługa resetu procesu po zmianie odpowiedzi
Leave a Comment