Spaces:
Sleeping
Sleeping
Download backend/identity.py from Success-dev/receipter-pro: direct link, hf CLI and curl.
- Browser
- Download file 3.62 kB
-
https://huggingface.co/spaces/Success-dev/receipter-pro/resolve/main/backend/identity.py
- Command line
-
hf download hf://spaces/Success-dev/receipter-pro/backend/identity.py
-
curl -L -o identity.py https://huggingface.co/spaces/Success-dev/receipter-pro/resolve/main/backend/identity.py
3.62 kB
| """Identity check (KYC), level 1: the recommended fields from docs/product/account-types.md section 6. | |
| Stored at identity/{uid}. A submission is "submitted" until a person on our side reviews it; nothing | |
| here verifies anything or gates any action yet. ID numbers and uploads are not collected at this level. | |
| """ | |
| from __future__ import annotations | |
| import re | |
| from datetime import datetime, timezone | |
| from backend import accounts | |
| from backend import firestore_client as db | |
| # (key, label, required) in the order they are shown. | |
| FIELDS = { | |
| accounts.ORGANIZATION: [ | |
| ("legal_name", "Legal name", True), | |
| ("trading_name", "Trading name", False), | |
| ("registration_number", "Registration number (RC)", True), | |
| ("country", "Country of registration", True), | |
| ("address", "Registered address", True), | |
| ("business_type", "Business type", True), | |
| ("contact_name", "Contact person", True), | |
| ("contact_role", "Their role", True), | |
| ("contact_phone", "Their phone", True), | |
| ("website", "Website or social page", True), | |
| ], | |
| accounts.INDIVIDUAL: [ | |
| ("legal_name", "Legal name", True), | |
| ("date_of_birth", "Date of birth", True), | |
| ("phone", "Phone", True), | |
| ("address", "Home or work address", True), | |
| ("occupation", "What you send mail for", False), | |
| ("website", "Website or social page", False), | |
| ], | |
| } | |
| # Filled in by the map picker alongside country and address; kept if present, never required. | |
| PHONE_KEYS = ("phone", "contact_phone") | |
| PLACE_EXTRAS = ("state", "lga", "postal_code") | |
| def _path(uid: str) -> str: | |
| return f"identity/{uid}" | |
| def describe(uid: str) -> dict: | |
| account_type = accounts.account_type_of(uid) | |
| if not account_type: | |
| raise accounts.AccountError("Choose an account type first") | |
| doc = db.get_doc(_path(uid)) or {} | |
| return { | |
| "status": doc.get("status", "not_started"), | |
| "values": doc.get("values", {}), | |
| "submitted_at": doc.get("submitted_at"), | |
| "fields": [{"key": k, "label": l, "required": r} for k, l, r in FIELDS[account_type]], | |
| } | |
| def status_of(uid: str) -> str: | |
| return (db.get_doc(_path(uid)) or {}).get("status", "not_started") | |
| def submit(uid: str, values: dict) -> dict: | |
| account_type = accounts.account_type_of(uid) | |
| if not account_type: | |
| raise accounts.AccountError("Choose an account type first") | |
| clean: dict[str, str] = {} | |
| for key, label, required in FIELDS[account_type]: | |
| value = str(values.get(key) or "").strip()[:300] | |
| if required and not value: | |
| raise accounts.AccountError(f"{label} is needed") | |
| if key in PHONE_KEYS and value and not re.fullmatch(r"\+\d{1,4} \d{6,14}", value): | |
| raise accounts.AccountError(f"{label} should be a calling code and digits only") | |
| if value: | |
| clean[key] = value | |
| if clean.get("country") == "Nigeria": | |
| rc = clean.get("registration_number") | |
| if rc and not re.fullmatch(r"(?i)(RC|BN|IT|LP|LLP)\s?-?\s?\d{4,8}", rc): | |
| raise accounts.AccountError("Registration number should look like RC1234567") | |
| code = str(values.get("postal_code") or "").strip() | |
| if code and not re.fullmatch(r"\d{6}", code): | |
| raise accounts.AccountError("Postal code should be 6 digits") | |
| for key in PLACE_EXTRAS: | |
| value = str(values.get(key) or "").strip()[:300] | |
| if value: | |
| clean[key] = value | |
| db.set_doc(_path(uid), {"status": "submitted", "values": clean, "submitted_at": datetime.now(timezone.utc).isoformat()}) | |
| return describe(uid) | |