-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommit.patch
More file actions
279 lines (257 loc) · 24 KB
/
Copy pathcommit.patch
File metadata and controls
279 lines (257 loc) · 24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
commit 02b9917c179e0a947603c194eac856c4bd427b43
Author: emergent-agent-e1 <github@emergent.sh>
Date: Mon May 4 23:53:15 2026 +0000
auto-commit for b4645a2c-3aa8-43b4-a9ce-67ff3139b8ed
diff --git a/backend/server.py b/backend/server.py
index 23e3d45..48e1e30 100644
--- a/backend/server.py
+++ b/backend/server.py
@@ -18,14 +18,10 @@ import re
ROOT_DIR = Path(__file__).parent
load_dotenv(ROOT_DIR / '.env')
-# ============== KONFIGURATION ==============
-# WICHTIG: Passe diese URL an, falls dein Python-Backend auf einem anderen Port läuft!
-API_BASE_URL = os.environ.get("API_BASE_URL", "http://localhost:8000")
-
# MongoDB connection
-mongo_url = os.environ.get('MONGO_URL', 'mongodb://localhost:27017')
+mongo_url = os.environ['MONGO_URL']
client = AsyncIOMotorClient(mongo_url)
-db = client[os.environ.get('DB_NAME', 'zvg_database')]
+db = client[os.environ['DB_NAME']]
# Resend configuration
resend.api_key = os.environ.get('RESEND_API_KEY', '')
@@ -61,8 +57,9 @@ class Foreclosure(BaseModel):
verkehrswert: Optional[str] = None
beschreibung: Optional[str] = None
klassifizierung: str = "Sonstiges"
- link: Optional[str] = None
- pdf_link: Optional[str] = None
+ zvg_id: Optional[str] = None
+ land_abk: Optional[str] = None
+ pdf_doc_type: Optional[str] = None
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
class ForeclosureResponse(BaseModel):
@@ -81,8 +78,9 @@ class ForeclosureResponse(BaseModel):
verkehrswert: Optional[str] = None
beschreibung: Optional[str] = None
klassifizierung: str
- link: Optional[str] = None
- pdf_link: Optional[str] = None
+ zvg_id: Optional[str] = None
+ land_abk: Optional[str] = None
+ pdf_doc_type: Optional[str] = None
created_at: str
class ClassificationRule(BaseModel):
@@ -421,8 +419,8 @@ async def fetch_foreclosures_from_portal(bundesland_code: str) -> List[dict]:
elif "fotos" in raw_pdf_href.lower() or "showzvgfotos" in raw_pdf_href.lower(): doc_type = "fotos"
elif "dokumente" in raw_pdf_href.lower(): doc_type = "dokumente"
- # ABSOLUTE URL FÜR PDF
- pdf_link = f"{API_BASE_URL}/api/zvg-document?zvg_id={zvg_id}&land_abk={bundesland_code}&doc_type={doc_type}"
+ # Store doc_type for frontend to generate URL
+ pdf_link = doc_type
termin_datum = ""
termin_zeit = ""
@@ -448,9 +446,7 @@ async def fetch_foreclosures_from_portal(bundesland_code: str) -> List[dict]:
if plz_match:
plz, ort = plz_match.group(1), plz_match.group(2).strip()
- # ABSOLUTE URL FÜR DETAIL-SEITE
- full_link = f"{API_BASE_URL}/api/zvg-redirect?zvg_id={zvg_id}&land_abk={bundesland_code}"
-
+ # Store zvg_id and land_abk - frontend generates full URLs
results.append({
"aktenzeichen": aktenzeichen,
"gericht": gericht,
@@ -466,8 +462,8 @@ async def fetch_foreclosures_from_portal(bundesland_code: str) -> List[dict]:
"ort": ort,
"verkehrswert": verkehrswert,
"zvg_id": zvg_id,
- "link": full_link,
- "pdf_link": pdf_link
+ "land_abk": bundesland_code,
+ "pdf_doc_type": pdf_link
})
except Exception as e:
logger.error(f"Error parsing foreclosure: {e}")
@@ -482,14 +478,11 @@ def generate_demo_foreclosures(bundesland_code: str) -> List[dict]:
import random
from datetime import datetime, timedelta
- # ... (Demo Data generation logic) ...
results = []
num_entries = random.randint(3, 8)
for i in range(num_entries):
zvg_id = random.randint(100000, 999999)
- # ABSOLUTE URL FÜR DEMO
- portal_link = f"{API_BASE_URL}/api/zvg-redirect?zvg_id={zvg_id}&land_abk={bundesland_code}"
results.append({
"aktenzeichen": f"00{random.randint(1,9)} K {random.randint(1,999):04d}/2024",
@@ -505,8 +498,8 @@ def generate_demo_foreclosures(bundesland_code: str) -> List[dict]:
"ort": "Musterstadt",
"verkehrswert": "250.000 Ôé¼",
"zvg_id": str(zvg_id),
- "link": portal_link,
- "pdf_link": f"{API_BASE_URL}/api/zvg-document?zvg_id={zvg_id}&land_abk={bundesland_code}&doc_type=gutachten"
+ "land_abk": bundesland_code,
+ "pdf_doc_type": "gutachten"
})
return results
diff --git a/frontend/src/App.js b/frontend/src/App.js
index 0ed7112..aae3d81 100644
--- a/frontend/src/App.js
+++ b/frontend/src/App.js
@@ -91,28 +91,16 @@ const API = `${BACKEND_URL}/api`;
// Helper function to generate ZVG redirect URL
const getZvgRedirectUrl = (zvgId, landAbk) => {
+ if (!zvgId || !landAbk) return null;
return `${API}/zvg-redirect?zvg_id=${zvgId}&land_abk=${landAbk}`;
};
// Helper function to generate ZVG document URL
const getZvgDocumentUrl = (zvgId, landAbk, docType) => {
+ if (!zvgId || !landAbk) return null;
return `${API}/zvg-document?zvg_id=${zvgId}&land_abk=${landAbk}&doc_type=${docType}`;
};
-// Extract zvg_id from link
-const extractZvgId = (link) => {
- if (!link) return null;
- const match = link.match(/zvg_id=(\d+)/);
- return match ? match[1] : null;
-};
-
-// Extract land_abk from link
-const extractLandAbk = (link) => {
- if (!link) return null;
- const match = link.match(/land_abk=(\w+)/);
- return match ? match[1] : null;
-};
-
// Ukrainian translations
const UI_TEXT = {
// Header
@@ -770,9 +758,9 @@ function DashboardView({ statistics, foreclosures, loading, onOpenDetail }) {
</TableCell>
<TableCell className="text-right font-mono text-[#111827] font-semibold">{f.verkehrswert || "-"}</TableCell>
<TableCell className="text-center">
- {f.link && (
+ {f.zvg_id && (
<a
- href={getZvgRedirectUrl(extractZvgId(f.link), extractLandAbk(f.link) || f.bundesland_code)}
+ href={getZvgRedirectUrl(f.zvg_id, f.land_abk || f.bundesland_code)}
target="_blank"
rel="noopener noreferrer"
onClick={(e) => e.stopPropagation()}
@@ -969,9 +957,9 @@ function TermineView({
</TableCell>
<TableCell className="text-right font-mono text-sm font-semibold text-[#111827]">{f.verkehrswert || "-"}</TableCell>
<TableCell className="text-center">
- {f.link && (
+ {f.zvg_id && (
<a
- href={getZvgRedirectUrl(extractZvgId(f.link), extractLandAbk(f.link) || f.bundesland_code)}
+ href={getZvgRedirectUrl(f.zvg_id, f.land_abk || f.bundesland_code)}
target="_blank"
rel="noopener noreferrer"
onClick={(e) => e.stopPropagation()}
@@ -1353,12 +1341,13 @@ function SettingsDialog({ open, onOpenChange, settings, onSave }) {
// Enhanced Foreclosure Detail Component with better contrast and PDF links
function ForeclosureDetail({ foreclosure }) {
- // Get zvg_id and land_abk from foreclosure
- const zvgId = extractZvgId(foreclosure.link) || foreclosure.zvg_id;
- const landAbk = extractLandAbk(foreclosure.link) || foreclosure.bundesland_code;
+ // Get zvg_id and land_abk directly from foreclosure data
+ const zvgId = foreclosure.zvg_id;
+ const landAbk = foreclosure.land_abk || foreclosure.bundesland_code;
// Generate direct PDF document links using proxy endpoints
const generateDocumentLinks = () => {
+ if (!zvgId) return null;
return {
gutachten: {
url: getZvgDocumentUrl(zvgId, landAbk, 'gutachten'),
@@ -1382,7 +1371,7 @@ function ForeclosureDetail({ foreclosure }) {
const documentLinks = generateDocumentLinks();
// Main portal link using proxy
- const mainPortalLink = getZvgRedirectUrl(zvgId, landAbk);
+ const mainPortalLink = zvgId ? getZvgRedirectUrl(zvgId, landAbk) : null;
// Generate extended object details
const generateObjectDetails = () => {
@@ -1609,45 +1598,47 @@ function ForeclosureDetail({ foreclosure }) {
</Accordion>
{/* Documents Section - PDF Links */}
- <div className="bg-white p-4 rounded-lg border border-[#E5E7EB]">
- <h4 className="text-xs uppercase tracking-wider font-semibold text-[#374151] mb-3 flex items-center gap-2">
- <FileText size={16} className="text-[#0052FF]" />
- {UI_TEXT.documents}
- </h4>
- <div className="grid grid-cols-1 gap-2">
- <DocumentLink
- icon={<FilePdf size={20} />}
- label={documentLinks.gutachten.label}
- href={documentLinks.gutachten.url}
- isPdf={true}
- testId="doc-gutachten"
- />
- <DocumentLink
- icon={<FilePdf size={20} />}
- label={documentLinks.expose.label}
- href={documentLinks.expose.url}
- isPdf={true}
- testId="doc-expose"
- />
- <DocumentLink
- icon={<Image size={20} />}
- label={documentLinks.fotos.label}
- href={documentLinks.fotos.url}
- isPdf={false}
- testId="doc-fotos"
- />
- <DocumentLink
- icon={<FilePdf size={20} />}
- label={documentLinks.gerichtsdokumente.label}
- href={documentLinks.gerichtsdokumente.url}
- isPdf={true}
- testId="doc-gerichtsdokumente"
- />
+ {documentLinks && (
+ <div className="bg-white p-4 rounded-lg border border-[#E5E7EB]">
+ <h4 className="text-xs uppercase tracking-wider font-semibold text-[#374151] mb-3 flex items-center gap-2">
+ <FileText size={16} className="text-[#0052FF]" />
+ {UI_TEXT.documents}
+ </h4>
+ <div className="grid grid-cols-1 gap-2">
+ <DocumentLink
+ icon={<FilePdf size={20} />}
+ label={documentLinks.gutachten.label}
+ href={documentLinks.gutachten.url}
+ isPdf={true}
+ testId="doc-gutachten"
+ />
+ <DocumentLink
+ icon={<FilePdf size={20} />}
+ label={documentLinks.expose.label}
+ href={documentLinks.expose.url}
+ isPdf={true}
+ testId="doc-expose"
+ />
+ <DocumentLink
+ icon={<Image size={20} />}
+ label={documentLinks.fotos.label}
+ href={documentLinks.fotos.url}
+ isPdf={false}
+ testId="doc-fotos"
+ />
+ <DocumentLink
+ icon={<FilePdf size={20} />}
+ label={documentLinks.gerichtsdokumente.label}
+ href={documentLinks.gerichtsdokumente.url}
+ isPdf={true}
+ testId="doc-gerichtsdokumente"
+ />
+ </div>
</div>
- </div>
+ )}
{/* Main Portal Link */}
- {foreclosure.link && (
+ {mainPortalLink && (
<Button
className="w-full bg-[#111827] hover:bg-[#1F2937] text-white"
onClick={() => window.open(mainPortalLink, '_blank')}