Untitled
# System Design - Analiza Potrzeb Klienta (APK) ## 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 ### Backend (Java Spring Boot) #### 2.1 Inicjalizacja procesu APK ``` POST /api/v1/apk/questionnaire Request: { "customerId": long, "quoteId": long, "groupCode": string // MAIN_RISKS lub ADDITIONAL_RISKS } Response: { "questionnaireId": long, "firstQuestion": { "id": long, "order": int, "content": string, "answers": [ { "id": long, "content": string } ] } } ``` #### 2.2 Zapisanie odpowiedzi i pobranie kolejnego pytania ``` POST /api/v1/apk/questionnaire/{questionnaireId}/answer Request: { "questionId": long, "answerId": long, "isChange": boolean // flaga określająca czy to zmiana odpowiedzi } Response: { "status": "IN_PROGRESS" | "COMPLETED", "nextQuestion": { "id": long, "order": int, "content": string, "answers": [ { "id": long, "content": string } ] } | null, "recommendation": { "packageCode": string, "description": string } | null, "removedQuestionIds": [long], // lista ID pytań, których odpowiedzi zostały usunięte "resetToQuestionOrder": int | null // informacja do którego pytania wrócić po zmianie } ``` #### 2.3 Pobranie aktualnego statusu kwestionariusza ``` GET /api/v1/apk/questionnaire/{questionnaireId} Response: { "status": "IN_PROGRESS" | "COMPLETED", "answeredQuestions": [ { "questionId": long, "questionContent": string, "questionOrder": int, "answerId": long, "answerContent": string, "answeredAt": timestamp } ], "currentQuestion": { "id": long, "order": int, "content": string, "answers": [...] } | null, "recommendation": { "packageCode": string, "description": string } | null } ``` ### Frontend (Angular) #### Serwisy ```typescript // apk.service.ts @Injectable({ providedIn: 'root' }) export class ApkService { constructor(private http: HttpClient) {} initializeQuestionnaire( customerId: number, quoteId: number, groupCode: string ): Observable<QuestionnaireInitResponse> { return this.http.post<QuestionnaireInitResponse>( '/api/v1/apk/questionnaire', { customerId, quoteId, groupCode } ); } submitAnswer( questionnaireId: number, questionId: number, answerId: number, isChange: boolean = false ): Observable<AnswerResponse> { return this.http.post<AnswerResponse>( `/api/v1/apk/questionnaire/${questionnaireId}/answer`, { questionId, answerId, isChange } ); } getQuestionnaireStatus( questionnaireId: number ): Observable<QuestionnaireStatus> { return this.http.get<QuestionnaireStatus>( `/api/v1/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 /api/v1/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