feat: Vorbereitung-Module auf 100% — Compliance-Scope Backend, DELETE-Endpoints, Proxy-Fixes, blocked-content Tab
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 35s
CI / test-python-backend-compliance (push) Successful in 31s
CI / test-python-document-crawler (push) Successful in 23s
CI / test-python-dsms-gateway (push) Successful in 19s
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 35s
CI / test-python-backend-compliance (push) Successful in 31s
CI / test-python-document-crawler (push) Successful in 23s
CI / test-python-dsms-gateway (push) Successful in 19s
Paket A — Kritische Blocker: - compliance_scope_routes.py: GET + POST UPSERT für sdk_states JSONB-Feld - compliance/api/__init__.py: compliance_scope_router registriert - import/route.ts: POST-Proxy für multipart/form-data Upload - screening/route.ts: POST-Proxy für Dependency-File Upload Paket B — Backend + UI: - company_profile_routes.py: DELETE-Endpoint (DSGVO Art. 17) - company-profile/route.ts: DELETE-Proxy - company-profile/page.tsx: Profil-löschen-Button mit Bestätigungs-Dialog - source-policy/pii-rules/[id]/route.ts: GET ergänzt - source-policy/operations/[id]/route.ts: GET + DELETE ergänzt Paket C — Tests + UI: - test_compliance_scope_routes.py: 27 Tests (neu) - test_import_routes.py: +36 Tests → 60 gesamt - test_screening_routes.py: +28 Tests → 80+ gesamt - source-policy/page.tsx: "Blockierte Inhalte" Tab mit Tabelle + Remove Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1097,6 +1097,8 @@ function CoverageAssessmentPanel({ profile }: { profile: Partial<CompanyProfile>
|
||||
export default function CompanyProfilePage() {
|
||||
const { state, dispatch, setCompanyProfile, goToNextStep } = useSDK()
|
||||
const [currentStep, setCurrentStep] = useState(1)
|
||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)
|
||||
const [isDeleting, setIsDeleting] = useState(false)
|
||||
const [formData, setFormData] = useState<Partial<CompanyProfile>>({
|
||||
companyName: '',
|
||||
legalForm: undefined,
|
||||
@@ -1290,6 +1292,52 @@ export default function CompanyProfilePage() {
|
||||
}
|
||||
}
|
||||
|
||||
const handleDeleteProfile = async () => {
|
||||
setIsDeleting(true)
|
||||
try {
|
||||
const response = await fetch('/api/sdk/v1/company-profile?tenant_id=default', {
|
||||
method: 'DELETE',
|
||||
})
|
||||
if (response.ok) {
|
||||
// Reset form and SDK state
|
||||
setFormData({
|
||||
companyName: '',
|
||||
legalForm: undefined,
|
||||
industry: '',
|
||||
foundedYear: null,
|
||||
businessModel: undefined,
|
||||
offerings: [],
|
||||
companySize: undefined,
|
||||
employeeCount: '',
|
||||
annualRevenue: '',
|
||||
headquartersCountry: 'DE',
|
||||
headquartersCity: '',
|
||||
hasInternationalLocations: false,
|
||||
internationalCountries: [],
|
||||
targetMarkets: [],
|
||||
primaryJurisdiction: 'DE',
|
||||
isDataController: true,
|
||||
isDataProcessor: false,
|
||||
usesAI: false,
|
||||
aiUseCases: [],
|
||||
dpoName: null,
|
||||
dpoEmail: null,
|
||||
legalContactName: null,
|
||||
legalContactEmail: null,
|
||||
isComplete: false,
|
||||
completedAt: null,
|
||||
})
|
||||
setCurrentStep(1)
|
||||
dispatch({ type: 'SET_STATE', payload: { companyProfile: undefined } })
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to delete company profile:', err)
|
||||
} finally {
|
||||
setIsDeleting(false)
|
||||
setShowDeleteConfirm(false)
|
||||
}
|
||||
}
|
||||
|
||||
const canProceed = () => {
|
||||
switch (currentStep) {
|
||||
case 1:
|
||||
@@ -1412,6 +1460,34 @@ export default function CompanyProfilePage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Delete Confirmation Modal */}
|
||||
{showDeleteConfirm && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
|
||||
<div className="bg-white rounded-xl p-6 w-full max-w-md shadow-2xl">
|
||||
<h3 className="text-lg font-semibold text-gray-900 mb-2">Profil löschen?</h3>
|
||||
<p className="text-sm text-gray-600 mb-6">
|
||||
Alle gespeicherten Unternehmensdaten werden unwiderruflich gelöscht (DSGVO Art. 17).
|
||||
Diese Aktion kann nicht rückgängig gemacht werden.
|
||||
</p>
|
||||
<div className="flex justify-end gap-3">
|
||||
<button
|
||||
onClick={() => setShowDeleteConfirm(false)}
|
||||
className="px-4 py-2 text-sm text-gray-600 hover:bg-gray-100 rounded-lg"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button
|
||||
onClick={handleDeleteProfile}
|
||||
disabled={isDeleting}
|
||||
className="px-4 py-2 text-sm bg-red-600 text-white rounded-lg hover:bg-red-700 disabled:opacity-50"
|
||||
>
|
||||
{isDeleting ? 'Lösche...' : 'Endgültig löschen'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Sidebar: Coverage Assessment */}
|
||||
<div className="lg:col-span-1">
|
||||
<CoverageAssessmentPanel profile={formData} />
|
||||
@@ -1441,6 +1517,17 @@ export default function CompanyProfilePage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Delete Profile Button */}
|
||||
{formData.companyName && (
|
||||
<div className="mt-6">
|
||||
<button
|
||||
onClick={() => setShowDeleteConfirm(true)}
|
||||
className="w-full px-4 py-2 text-sm text-red-600 border border-red-200 rounded-lg hover:bg-red-50 transition-colors"
|
||||
>
|
||||
Profil löschen (Art. 17 DSGVO)
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user