fix(sdk): Align scope types with engine output + project isolation + optional block progress
Some checks failed
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 46s
CI/CD / test-python-backend-compliance (push) Successful in 42s
CI/CD / test-python-document-crawler (push) Successful in 29s
CI/CD / test-python-dsms-gateway (push) Successful in 25s
CI/CD / deploy-hetzner (push) Failing after 2s
Some checks failed
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 46s
CI/CD / test-python-backend-compliance (push) Successful in 42s
CI/CD / test-python-document-crawler (push) Successful in 29s
CI/CD / test-python-dsms-gateway (push) Successful in 25s
CI/CD / deploy-hetzner (push) Failing after 2s
Type alignment (root cause of client-side crash):
- RiskFlag: id/title/description → severity/category/message/recommendation
- ScopeGap: id/title/recommendation/relatedDocuments → gapType/currentState/targetState/effort
- NextAction: id/priority:number/effortDays → actionType/priority:string/estimatedEffort
- ScopeReasoning: details → factors + impact
- TriggeredHardTrigger: {rule: HardTriggerRule} → flat fields (ruleId, description, etc.)
- All UI components updated to match engine output shape
Project isolation:
- Scope localStorage key now includes projectId (prevents data leak between projects)
Optional block progress:
- Blocks with only optional questions now show green checkmark when any question answered
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -31,12 +31,12 @@ export function ScopeExportTab({ decision: decisionProp, answers: answersProp, s
|
||||
const handleDownloadCSV = useCallback(() => {
|
||||
if (!decision || !decision.requiredDocuments) return
|
||||
|
||||
const headers = ['Typ', 'Tiefe', 'Aufwand (Tage)', 'Pflicht', 'Hard-Trigger']
|
||||
const headers = ['Typ', 'Priorität', 'Aufwand (Stunden)', 'Pflicht', 'Hard-Trigger']
|
||||
const rows = decision.requiredDocuments.map((doc) => [
|
||||
DOCUMENT_TYPE_LABELS[doc.documentType] || doc.documentType,
|
||||
doc.depth,
|
||||
doc.estimatedEffort || '0',
|
||||
doc.required ? 'Ja' : 'Nein',
|
||||
doc.priority,
|
||||
String(doc.estimatedEffort || 0),
|
||||
doc.requirement === 'mandatory' ? 'Ja' : 'Nein',
|
||||
doc.triggeredBy.length > 0 ? 'Ja' : 'Nein',
|
||||
])
|
||||
|
||||
@@ -58,8 +58,8 @@ export function ScopeExportTab({ decision: decisionProp, answers: answersProp, s
|
||||
markdown += `**Datum:** ${new Date().toLocaleDateString('de-DE')}\n\n`
|
||||
markdown += `## Einstufung\n\n`
|
||||
markdown += `**Level:** ${decision.determinedLevel} - ${DEPTH_LEVEL_LABELS[decision.determinedLevel]}\n\n`
|
||||
if (decision.reasoning) {
|
||||
markdown += `**Begründung:** ${decision.reasoning}\n\n`
|
||||
if (decision.reasoning && decision.reasoning.length > 0) {
|
||||
markdown += `**Begründung:** ${decision.reasoning.map(r => r.description).filter(Boolean).join('. ')}\n\n`
|
||||
}
|
||||
|
||||
if (decision.scores) {
|
||||
@@ -73,10 +73,10 @@ export function ScopeExportTab({ decision: decisionProp, answers: answersProp, s
|
||||
if (decision.triggeredHardTriggers && decision.triggeredHardTriggers.length > 0) {
|
||||
markdown += `## Aktive Hard-Trigger\n\n`
|
||||
decision.triggeredHardTriggers.forEach((trigger) => {
|
||||
markdown += `- **${trigger.rule.label}**\n`
|
||||
markdown += ` - ${trigger.rule.description}\n`
|
||||
if (trigger.rule.legalReference) {
|
||||
markdown += ` - Rechtsgrundlage: ${trigger.rule.legalReference}\n`
|
||||
markdown += `- **${trigger.description}**\n`
|
||||
markdown += ` - ${trigger.description}\n`
|
||||
if (trigger.legalReference) {
|
||||
markdown += ` - Rechtsgrundlage: ${trigger.legalReference}\n`
|
||||
}
|
||||
})
|
||||
markdown += `\n`
|
||||
@@ -84,12 +84,12 @@ export function ScopeExportTab({ decision: decisionProp, answers: answersProp, s
|
||||
|
||||
if (decision.requiredDocuments && decision.requiredDocuments.length > 0) {
|
||||
markdown += `## Erforderliche Dokumente\n\n`
|
||||
markdown += `| Typ | Tiefe | Aufwand | Pflicht | Hard-Trigger |\n`
|
||||
markdown += `|-----|-------|---------|---------|-------------|\n`
|
||||
markdown += `| Typ | Priorität | Aufwand (h) | Pflicht | Hard-Trigger |\n`
|
||||
markdown += `|-----|-----------|-------------|---------|-------------|\n`
|
||||
decision.requiredDocuments.forEach((doc) => {
|
||||
markdown += `| ${DOCUMENT_TYPE_LABELS[doc.documentType] || doc.documentType} | ${doc.depth} | ${
|
||||
doc.estimatedEffort || '0'
|
||||
} | ${doc.required ? 'Ja' : 'Nein'} | ${doc.triggeredBy.length > 0 ? 'Ja' : 'Nein'} |\n`
|
||||
markdown += `| ${DOCUMENT_TYPE_LABELS[doc.documentType] || doc.documentType} | ${doc.priority} | ${
|
||||
doc.estimatedEffort || 0
|
||||
} | ${doc.requirement === 'mandatory' ? 'Ja' : 'Nein'} | ${doc.triggeredBy.length > 0 ? 'Ja' : 'Nein'} |\n`
|
||||
})
|
||||
markdown += `\n`
|
||||
}
|
||||
@@ -97,19 +97,29 @@ export function ScopeExportTab({ decision: decisionProp, answers: answersProp, s
|
||||
if (decision.riskFlags && decision.riskFlags.length > 0) {
|
||||
markdown += `## Risiko-Flags\n\n`
|
||||
decision.riskFlags.forEach((flag) => {
|
||||
markdown += `### ${flag.title} (${flag.severity})\n\n`
|
||||
markdown += `${flag.description}\n\n`
|
||||
markdown += `### ${flag.message} (${flag.severity})\n\n`
|
||||
if (flag.legalReference) markdown += `Rechtsgrundlage: ${flag.legalReference}\n\n`
|
||||
markdown += `**Empfehlung:** ${flag.recommendation}\n\n`
|
||||
})
|
||||
}
|
||||
|
||||
if (decision.gaps && decision.gaps.length > 0) {
|
||||
markdown += `## Gap-Analyse\n\n`
|
||||
decision.gaps.forEach((gap) => {
|
||||
markdown += `### ${gap.description} (${gap.severity})\n\n`
|
||||
markdown += `- **Ist:** ${gap.currentState}\n`
|
||||
markdown += `- **Soll:** ${gap.targetState}\n`
|
||||
markdown += `- **Aufwand:** ~${gap.effort}h\n\n`
|
||||
})
|
||||
}
|
||||
|
||||
if (decision.nextActions && decision.nextActions.length > 0) {
|
||||
markdown += `## Nächste Schritte\n\n`
|
||||
decision.nextActions.forEach((action) => {
|
||||
markdown += `${action.priority}. **${action.title}**\n`
|
||||
decision.nextActions.forEach((action, idx) => {
|
||||
markdown += `${idx + 1}. **${action.title}**\n`
|
||||
markdown += ` ${action.description}\n`
|
||||
if (action.estimatedEffort) {
|
||||
markdown += ` Aufwand: ${action.estimatedEffort}\n`
|
||||
markdown += ` Aufwand: ~${action.estimatedEffort}h\n`
|
||||
}
|
||||
markdown += `\n`
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user