diff --git a/frontend/src/api/interview.js b/frontend/src/api/interview.js
new file mode 100644
index 00000000..0f5cdbf5
--- /dev/null
+++ b/frontend/src/api/interview.js
@@ -0,0 +1,29 @@
+import service from './index'
+
+export async function startPre(simId) {
+ const r = await service.post(`/api/interview/${simId}/pre`)
+ return r
+}
+export async function startPost(simId) {
+ const r = await service.post(`/api/interview/${simId}/post`)
+ return r
+}
+export async function rerun(simId, subagent) {
+ const r = await service.post(`/api/interview/${simId}/rerun`, { subagent })
+ return r
+}
+export async function getStatus(simId, taskId) {
+ const r = await service.get(`/api/interview/${simId}/status`, { params: { task_id: taskId } })
+ return r
+}
+export async function getResults(simId, subagent) {
+ const r = await service.get(`/api/interview/${simId}/results/${subagent}`)
+ return r
+}
+export async function getSynthesis(simId) {
+ const r = await service.get(`/api/interview/${simId}/results/synthesis`)
+ return r
+}
+export function exportCsvUrl(simId) {
+ return `/api/interview/${simId}/export.csv`
+}
diff --git a/frontend/src/components/Step4bInterviews.vue b/frontend/src/components/Step4bInterviews.vue
new file mode 100644
index 00000000..d2aed844
--- /dev/null
+++ b/frontend/src/components/Step4bInterviews.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/components/interviews/DelphiPanel.vue b/frontend/src/components/interviews/DelphiPanel.vue
new file mode 100644
index 00000000..f8b27647
--- /dev/null
+++ b/frontend/src/components/interviews/DelphiPanel.vue
@@ -0,0 +1,4 @@
+Delphi: results will appear here.
+
diff --git a/frontend/src/components/interviews/DiversityPanel.vue b/frontend/src/components/interviews/DiversityPanel.vue
new file mode 100644
index 00000000..759114b3
--- /dev/null
+++ b/frontend/src/components/interviews/DiversityPanel.vue
@@ -0,0 +1,4 @@
+Diversity: results will appear here.
+
diff --git a/frontend/src/components/interviews/LongitudinalPanel.vue b/frontend/src/components/interviews/LongitudinalPanel.vue
new file mode 100644
index 00000000..189c2488
--- /dev/null
+++ b/frontend/src/components/interviews/LongitudinalPanel.vue
@@ -0,0 +1,4 @@
+Longitudinal: results will appear here.
+
diff --git a/frontend/src/components/interviews/ScenarioPanel.vue b/frontend/src/components/interviews/ScenarioPanel.vue
new file mode 100644
index 00000000..ea2686e3
--- /dev/null
+++ b/frontend/src/components/interviews/ScenarioPanel.vue
@@ -0,0 +1,4 @@
+Scenarios: results will appear here.
+
diff --git a/frontend/src/components/interviews/SynthesisPanel.vue b/frontend/src/components/interviews/SynthesisPanel.vue
new file mode 100644
index 00000000..7f3f7966
--- /dev/null
+++ b/frontend/src/components/interviews/SynthesisPanel.vue
@@ -0,0 +1,4 @@
+Synthesis: results will appear here.
+
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
index 62d23201..30b072b8 100644
--- a/frontend/src/router/index.js
+++ b/frontend/src/router/index.js
@@ -4,6 +4,7 @@ import Process from '../views/MainView.vue'
import SimulationView from '../views/SimulationView.vue'
import SimulationRunView from '../views/SimulationRunView.vue'
import ReportView from '../views/ReportView.vue'
+import InterviewView from '../views/InterviewView.vue'
import InteractionView from '../views/InteractionView.vue'
const routes = [
@@ -36,6 +37,12 @@ const routes = [
component: ReportView,
props: true
},
+ {
+ path: '/interview/:simulationId',
+ name: 'Interview',
+ component: InterviewView,
+ props: true
+ },
{
path: '/interaction/:reportId',
name: 'Interaction',
diff --git a/frontend/src/views/InterviewView.vue b/frontend/src/views/InterviewView.vue
new file mode 100644
index 00000000..767ac9b7
--- /dev/null
+++ b/frontend/src/views/InterviewView.vue
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
diff --git a/locales/de.json b/locales/de.json
new file mode 100644
index 00000000..4032d4db
--- /dev/null
+++ b/locales/de.json
@@ -0,0 +1,15 @@
+{
+ "interview": {
+ "title": "Stakeholder-Interviews",
+ "subtitle": "Vier unabhängige Befragungen der simulierten Stakeholder-Population.",
+ "runAll": "Alle Post-Simulations-Interviews starten",
+ "downloadCsv": "CSV herunterladen",
+ "tab": {
+ "longitudinal": "Längsschnitt (Δ)",
+ "diversity": "Diversität",
+ "delphi": "Delphi",
+ "scenario": "Szenarien",
+ "synthesis": "Synthese"
+ }
+ }
+}
diff --git a/locales/en.json b/locales/en.json
index 544c68b1..d22cf64f 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -661,5 +661,18 @@
"llmSelectAgentFailed": "LLM agent selection failed, using default selection: {error}",
"generateInterviewQuestionsFailed": "Failed to generate interview questions: {error}",
"generateInterviewSummaryFailed": "Failed to generate interview summary: {error}"
+ },
+ "interview": {
+ "title": "Stakeholder interviews",
+ "subtitle": "Four independent surveys of the simulated stakeholder population.",
+ "runAll": "Run all post-simulation interviews",
+ "downloadCsv": "Download CSV",
+ "tab": {
+ "longitudinal": "Longitudinal (Δ)",
+ "diversity": "Diversity",
+ "delphi": "Delphi",
+ "scenario": "Scenarios",
+ "synthesis": "Synthesis"
+ }
}
}
diff --git a/locales/zh.json b/locales/zh.json
index cd747e2f..71ed6c4b 100644
--- a/locales/zh.json
+++ b/locales/zh.json
@@ -661,5 +661,18 @@
"llmSelectAgentFailed": "LLM选择Agent失败,使用默认选择: {error}",
"generateInterviewQuestionsFailed": "生成采访问题失败: {error}",
"generateInterviewSummaryFailed": "生成采访摘要失败: {error}"
+ },
+ "interview": {
+ "title": "利益相关者访谈",
+ "subtitle": "对模拟利益相关者群体进行的四项独立调查。",
+ "runAll": "运行所有模拟后访谈",
+ "downloadCsv": "下载 CSV",
+ "tab": {
+ "longitudinal": "纵向分析 (Δ)",
+ "diversity": "多样性",
+ "delphi": "德尔菲法",
+ "scenario": "情景分析",
+ "synthesis": "综合分析"
+ }
}
}