mirror of
https://github.com/skoelle/icloud-contacts-sync.git
synced 2026-09-18 07:50:25 +00:00
fix: build full_name from parts in chat messages endpoint
- SELECT prefix, given_name, middle_name, family_name, suffix alongside full_name - Apply db._build_full_name() fallback when full_name is NULL - Document the pattern in AGENTS.md to prevent future regressions
This commit is contained in:
@@ -145,6 +145,19 @@ See `.env.example` for full list. Key variables:
|
|||||||
4. Update endpoint table in `SPEC.md` and `README.md`
|
4. Update endpoint table in `SPEC.md` and `README.md`
|
||||||
5. Test with: `curl -H "Remote-User: <user>" http://127.0.0.1:8000/<path>`
|
5. Test with: `curl -H "Remote-User: <user>" http://127.0.0.1:8000/<path>`
|
||||||
|
|
||||||
|
### Querying contact names from the DB
|
||||||
|
**IMPORTANT:** The `full_name` column in `contacts` can be NULL — it is
|
||||||
|
NOT guaranteed to be set. Always SELECT `prefix, given_name, middle_name,
|
||||||
|
family_name, suffix` alongside `full_name` and apply the fallback:
|
||||||
|
```python
|
||||||
|
if not row.get("full_name"):
|
||||||
|
row["full_name"] = db._build_full_name(row)
|
||||||
|
```
|
||||||
|
This is what `_row_to_contact_out()` does for API responses. Any code
|
||||||
|
that needs a contact's display name (e.g. proxying to external APIs)
|
||||||
|
must follow the same pattern. See `get_contact_messages()` in
|
||||||
|
`src/api/main.py` for a reference implementation.
|
||||||
|
|
||||||
### Adding a new contact field
|
### Adding a new contact field
|
||||||
1. Add column to `contacts` table in `sql/schema.sql`
|
1. Add column to `contacts` table in `sql/schema.sql`
|
||||||
2. Update `src/vcard_parser.py` to extract the field
|
2. Update `src/vcard_parser.py` to extract the field
|
||||||
|
|||||||
+9
-2
@@ -229,14 +229,21 @@ def get_contact_messages(
|
|||||||
id_clause = "AND id = %s" if where_clause else "WHERE id = %s"
|
id_clause = "AND id = %s" if where_clause else "WHERE id = %s"
|
||||||
with conn.cursor() as cur:
|
with conn.cursor() as cur:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
f"SELECT full_name FROM contacts {where_clause} {id_clause}",
|
f"""SELECT full_name, prefix, given_name, middle_name, family_name, suffix
|
||||||
|
FROM contacts {where_clause} {id_clause}""",
|
||||||
params + [contact_id],
|
params + [contact_id],
|
||||||
)
|
)
|
||||||
row = cur.fetchone()
|
row = cur.fetchone()
|
||||||
|
|
||||||
if not row or not row.get("full_name"):
|
if not row:
|
||||||
return JSONResponse(status_code=404, content={"detail": "Kontakt nicht gefunden"})
|
return JSONResponse(status_code=404, content={"detail": "Kontakt nicht gefunden"})
|
||||||
|
|
||||||
|
if not row.get("full_name"):
|
||||||
|
row["full_name"] = db._build_full_name(row)
|
||||||
|
|
||||||
|
if not row.get("full_name"):
|
||||||
|
return JSONResponse(status_code=404, content={"detail": "Kontakt hat keinen Namen"})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
resp = requests.get(
|
resp = requests.get(
|
||||||
f"{Config.CHATAPI_URL.rstrip('/')}/conversation",
|
f"{Config.CHATAPI_URL.rstrip('/')}/conversation",
|
||||||
|
|||||||
Reference in New Issue
Block a user