Projekt

Obecné

Profil

Požadavek #170

otevřený

Android aplikace nkBookImport: focení knihy a import do bazaru + agentní endpointy

Přidáno uživatelem Šimon Formánek před asi 3 hodin(y). Aktualizováno před asi 2 hodin(y).

Stav:
Nový
Priorita:
Normální
Přiřazeno:
-
Začátek:
2026-11-04
Uzavřít do:
% Hotovo:

0%

Odhadovaná doba:
Strávený čas:

Popis

h2. Zadání

Android aplikace, která (1) vyfotí knihu a (2) založí z ní bazarovou nabídku na NovéKnihy. Nejčastější případ je obálka + tiráž — dvě fotky, kde druhá (stránka s údaji o vydání) nese metadata: nakladatele, rok, ISBN, číslo vydání, počet stran, překladatele. Varianta "obálka + galerie dalších fotek" je atypická.

Vývoj proti @http://dev.noveknihy.local@ (= 192.168.2.57, tedy stroj @mi@; DocumentRoot @/home/f/git/noveknihy/catalog/@), ne proti produkci.

Kód aplikace: @/home/f/git/nkBookImport@. Serverové změny: @/home/f/git/noveknihy@, větev @functionalHTML@.

Plán: @/home/f/.claude/plans/chci-android-aplikaci-ktera-fancy-planet.md@

h2. Rozhodnutí

  • Komunikace přes nový endpoint ve stávajícím agentním API (Bearer token), ne emulací prohlížeče ani WebView wrapperem.
  • Čtení tiráže na serveru existující pipeline, s potvrzením na telefonu; plus dávkový režim "vyklízení police" přepínačem.
  • Odladěný prompt na tiráž se vytáhne do třídy, aby existoval v jedné kopii a volal ho endpoint i @bin/bazar/bazar_ocr.php@.
  • Toolchain (Android SDK + Gradle wrapper) se instaluje na stroj @mi@.

h2. Hotovo (5. 11. 2026)

Serverová strana, vyzkoušená curlem proti dev:

  • @POST /agent/sell.php@ — @/home/f/git/noveknihy/catalog/agent/sell.php@. Multipart, scope @sell@. Zápis jde jedinou cestou @Noveknihy\Marketplace::createListing()@, takže inzerát z telefonu je k nerozeznání od inzerátu z prohlížeče. Ověřeno: @201@, @status=active@, @currency=CZK@, varianta @Bazar – drobné vady #6@ se skladem 1, tiráž na @products_attributes@, skóre kvality 45 (nad @CATALOG_QUALITY_MIN=20@), kategorie 16, soubory @p--inzerat-.jpg@ + @small_@ + @.avif@ + originály v @catalog/bazar//@, stránka nabídky 200 a nabídka je v bazaru vidět.
  • Negativní případy: @405@ + @Allow: POST@, @401@ bez tokenu, @403 insufficient_scope@ u tokenu bez @sell@, @422@ s mapou @fields@ u ceny nula / "abc" / chybějícího názvu / chybějící obálky / roku 3025, varování při sedmi fotkách (strop 5).
  • @GET /agent/book_suggest.php@ — token-auth našeptávač. Ověřeno: @?q=Čapek@ vrací tři knihy z ČNB, ISBN funguje s pomlčkami i bez.
  • @AgentAuth::SCOPE_SELL@, zaškrtávátko v @account_agent_tokens.php@, jazykové konstanty česky i anglicky (obě sady ověřeně shodné), zápis do @agent/discovery.php@ i @agent/openapi.json@ (spec opravena na tvar nullable podle OpenAPI 3.0, protože se hlásí jako 3.0.3).
  • Dokumentace: @/home/f/git/noveknihy/doc/cs/agentni-nakupovani.md@

Opraveny dvě věci, které webový formulář na serveru nevaliduje vůbec — nová čistá funkce @Noveknihy\Marketplace::validateListingInput()@ s osmi PHPUnit testy:

  • @marketplace_sell.php:119@ přetypovává cenu @(float)@, takže "zdarma" uložilo nabídku za nulu. Jedinou hradbou byl @priceOk()@ v @includes/static/marketplace_sell_wizard.js@ — ve skriptu, který si sám vypíná validaci přes @novalidate@.
  • @published_year@ měl @max@ jen na klientu, na serveru nic.

Kvalita: všech 800 PHPUnit testů prochází. @phpstan@ má v projektu 156 chyb před i po (ověřeno porovnáním s verzí z gitu), @phpcs@ hlásí v @Marketplace.php@ tři chyby, které jsou v gitu na řádcích 811-812 — moje vložka je jen posunula. Nový kód nepřidal ani jednu.

h2. Zbývá

@Noveknihy\BookCatalog\ImprintReader@ — vytáhnout prompt a @isbn_checksum_ok()@ z @/home/f/git/noveknihy/bin/bazar/bazar_ocr.php@ (prompt na řádcích 119-143, checksum 325-348) do třídy, přepsat @bazar_ocr.php@ aby ji volal. Regrese k uhlídání: @book.json@ musí vyjít shodně jako před přepisem.

@POST /agent/imprint.php@ — asynchronní job. Nejdřív @Noveknihy\Crawl\CnbFacts::forIsbn()@ (lokální ČNB, bez modelu), pak vision model @qwen2.5vl:7b@ na to, co ČNB nemá. U každého pole vracet zdroj (@cnb@ / @model@ / @barcode@).

Instalace Android SDK + skelet projektu, @./gradlew assembleDebug@.

Aplikace: scan EAN (ML Kit, offline) → fotky → upload → kontrola → odeslání; pak offline fronta (Room + WorkManager) a dávkový režim.

h2. Nález, který stojí za pozornost

Našeptávač knih je v obchodě rozbitý a mlčí o tom. @/home/f/git/noveknihy/catalog/book_suggest.php@ nenačítá třídy @CnbSource@ a @CnbMarc@; katalogový autoloader namespacy neumí a composerův v obchodě registrovaný není. Při @BOOK_CATALOG_SOURCE=composite@ (výchozí hodnota) sáhne @Suggester::source()@ po @CnbSource@ vždy → @Error: Class not found@ → a @Suggester::suggest()@ to spolkne paušálním @catch (\Throwable) { return []; }@.

Změřeno 5. 11. 2026: se sadou @require@, jakou má ta stránka, vrací @Suggester::suggest('Čapek', 3)@ nulu položek a @class_exists()@ je @false@. Po doplnění dvou @require@ vrátí tři knihy. V @cnb_books@ je 980 201 záznamů, dnes nedosažitelných, aniž by kdokoli viděl chybu.

Ve svém endpointu @/agent/book_suggest.php@ to opraveno a popsáno v dokumentaci jako past. Stránka @catalog/book_suggest.php@ (a její admin varianta) opravena není — je to mimo zadání, čeká na rozhodnutí. Jsou to dva řádky.

h2. Omezení, které plán vědomě neřeší

Vision model běží jen tam, kde je ollama. Stroj @mi@ ji má (@qwen2.5vl:7b@), produkční webserver ne — a @/home/f/git/noveknihy/doc/cs/bazar-skenovani.md:658-680@ to uvádí jako záměr. Čtení tiráže na produkci je samostatné rozhodnutí.

Souvisí: #169 (oprava dev instance, blokovala všechno ostatní).


Související úkoly 1 (1 otevřený — 0 uzavřených)

související s Chyba #169: dev.noveknihy.local: login padá na chybějícím klíči slepého indexu, dev DB zaostává za kódemNový2026-11-04

Akce

Také k dispozici: Atom PDF