Züchter-Bereich (Hub) + Settings-Partner-Karte raus + Admin: alle Code-Einlösungen mit Kanal
- Neue Seite #breeder-dashboard (Welten-Chip 'Züchter' role:breeder in HUND, ersetzt die Einzel-Chips Zuchtkartei + Wurfverw.; beide FABs wandern an den neuen Chip; Läufigkeit bleibt eigener Chip in HUND, Rene-Vorgabe): Zwinger-Karte (Name, verifiziert-Badge, Profil-Editor), Wurfverwaltung mit Wurf-Anzahl, Zuchtkartei mit Hunde-Anzahl. Einzelseiten bleiben erreichbar. - Settings: Partner-Karte entfernt — der 🤝-Welten-Chip ist der Einstieg. - Admin 'Aktive Codes': 👥 zeigt jetzt ALLE Einlösungen eines Codes mit Kanal-Badge (QR #seq aus Kontingent vs. Link/manuell), Datum und Bestätigt-Status — Endpoint /admin/partner/codes/{id}/registrations. Suite: 55 passed.
This commit is contained in:
parent
6a6a09d879
commit
ed7c469c6a
11 changed files with 241 additions and 44 deletions
|
|
@ -125,6 +125,30 @@ def test_registration_with_qr_only(client, admin):
|
|||
assert row["referred_qr"] == token
|
||||
|
||||
|
||||
def test_code_registrations_with_channel(client, admin):
|
||||
"""Admin-Liste aller Code-Einloesungen unterscheidet QR-Sticker und Link/manuell."""
|
||||
code = _create_code(client, admin)
|
||||
batch = _create_batch(client, admin, code["id"], quantity=1)
|
||||
token = _batch_tokens(batch["id"])[0]
|
||||
|
||||
# 1x via QR, 1x via Code direkt
|
||||
client.post("/api/auth/register", json={
|
||||
"email": f"ch1-{secrets.token_hex(4)}@example.com", "password": "QrTest1234!",
|
||||
"name": f"ch1{secrets.token_hex(3)}", "ref_code": code["code"], "qr_token": token,
|
||||
})
|
||||
client.post("/api/auth/register", json={
|
||||
"email": f"ch2-{secrets.token_hex(4)}@example.com", "password": "QrTest1234!",
|
||||
"name": f"ch2{secrets.token_hex(3)}", "ref_code": code["code"],
|
||||
})
|
||||
|
||||
r = client.get(f"/api/admin/partner/codes/{code['id']}/registrations", headers=admin["headers"])
|
||||
assert r.status_code == 200
|
||||
regs = r.json()
|
||||
assert len(regs) == 2
|
||||
channels = {(x["qr_seq"] or 0) for x in regs}
|
||||
assert channels == {0, 1} # einer ohne QR (None), einer über Sticker #1
|
||||
|
||||
|
||||
def test_paused_code_not_redeemable(client, admin):
|
||||
"""Pausierter Code (Notbremse) -> keine Einloesung, Info-Endpoint 404; reaktivierbar."""
|
||||
code = _create_code(client, admin)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue