Reply Pilot Web App
Tato stranka popisuje modul reply-pilot-app/, ktery po rozdeleni architektury
funguje primarne jako frontend/BFF vrstva nad reply-pilot-be.
UX/UI pravidla pro obrazovky, nadpisy, formulare a navigaci jsou v UX/UI Principles.
Co je soucasti
- Flask aplikace v balicku
reply_pilot_app/ - HTTP klient pro
reply-pilot-be - dashboard s kalendarem, filtry a draft formularem
- search stranka nad party/activity fulltextem
- signpost prehledy pro firmy, osoby, emaily a tasky
- backend-backed formulare pro firmy, osoby, kontakty, identifikace, requirement review a task workflow mutace
- sprava typed AI promptu pro email reply, import wizard a supplier onboarding workflow
GET /healthzpro monitoring- Docker image a Compose runtime s non-root uzivatelem
Runtime
- aplikace bezi v kontejneru jako non-root uzivatel
- runtime UID:GID se do Compose predava pres
HOST_UIDaHOST_GID - lokalni mounty jsou
data -> /app/data,reply-pilot-app/conf -> /app/conf - aplikace se na backend napojuje pres sdilenou Docker sit
reply-pilot-internal - hlavni runtime zavislost je
BACKEND_API_BASE_URL, defaultnehttp://reply-pilot-be:5000 - footer pouzije
DOCUMENTATION_URLjako explicitni override; bez nej nalocalhosta127.0.0.1odkazuje na lokalni docs:9095, jinak nahttps://reply-pilot-docs.mathbox.90.cz - fulltext vola pres
BACKEND_API_BASE_URL; backend dale volareply-pilot-search - mount
conf/zustava read-only - logy jdou vyhradne na
stdout/stderr; lokalne pouzijdocker compose logs - image modulu se jmenuje
reply-pilot-app:latest - operacni skripty jsou
app-start.sh,app-stop.sh,app-deploy.sh
Konfigurace
Hlavni konfigurace je pres promenne prostredi:
APP_PORTBACKEND_API_BASE_URLBACKEND_TIMEOUT_SECONDSDOCUMENTATION_URLAPP_INTERNAL_EMAIL_DOMAINSAPP_DATA_DIRHOST_HTTP_PORTAPP_TIMEZONEFLASK_SECRET_KEYLOG_LEVELMAX_EMAILSHOST_UIDHOST_GID
Zdroj dat
Ve standardnim runtime si appka taha inbox, detail threadu, sync i draft akce z
reply-pilot-be.
Manualni vytvoreni tasku z e-mailoveho vlakna zustava z pohledu UI stejne:
formular, vyber firmy, vyber assignee a AI draft pripravuje appka. Pokud je
nastavene BACKEND_API_BASE_URL, samotne zalozeni Email Thread Reply tasku
probiha pres backend endpoint POST /api/email-threads/<email_id>/reply-tasks.
Backend pak vytvori Jira issue i lokalni task_jira_email_thread_reply vazbu a
pri duplicate odpovedi vraci existujici task, na ktery appka presmeruje.
Delegovane Reply Pilot Task tasky appka zobrazuje ve stejnem prehledu a
detailu jako ostatni Jira tasky. Detail ukazuje navazanou spolecnost, Jira
description a read-only Jira komentare. Prirazeny uzivatel muze otevrit
jednopolozkovou stranku Vyresit; appka pak vola backend mutaci, ktera ulozi
text do Jira description a vrati task zadavateli. Po vraceni tasku zadavatel
vidi na detailu POST akci Uzavrit, ktera vola backend close mutaci.
Detail firmy ma sekci Obecné tickety pro Reply Pilot Task a akci Přidat
úkol; zalozeni pres formular vola backend endpoint
POST /api/companies/<party_id>/reply-pilot-tasks.
Rucni zalozeni firmy probiha z odkazu Nova spolecnost na rozcestniku. Appka
zobrazi jednopage formular pro samotnou spolecnost a pri ulozeni vola backend
endpoint POST /api/companies. Povinne jsou Pravni nazev a ICO; obchodni
nazev je volitelny, web a role firmy se v tomto formulari nenastavuji. Appka
do payloadu doplni aktualniho app uzivatele jako vychoziho obchodnika pro
emailovou komunikaci a show_by_default=true; formular nema samostatnou volbu
viditelnosti. Pri lokalni validaci se chyby ukazuji primo u konkretnich poli;
pri duplicitach backend vraci jen kandidaty, ktere aktualni uzivatel smi videt,
a appka zustava na formulari.
Fulltext si appka taha z reply-pilot-be endpointu /api/search. Backend
nasledne vola reply-pilot-search, ktery vraci vysledky s linkem na detail
firmy, osoby, emailu, obecne aktivity nebo Jira tasku. Task search pouziva
stejny company scope jako ostatni read modely a navic umi aktivni delegovany
Reply Pilot Task najit podle aktualniho assignee. Done delegovane tasky
nevyuzivaji tuto aktivni assignee vyjimku, ale zustavaji dohledatelne pres
normalni company scope nebo company.view_all.
Po prihlaseni appka zajisti app_user profil a do internich backend volani
posila trusted header X-Reply-Pilot-App-User-Id. UI si z backendu nacita
aktualni opravneni a podle nich skryva write/merge/admin akce. Backend zustava
vynucovaci hranice; frontendove skryti akci je jen UX vrstva.
Stejnou backendem overenou identitu pouzivaji vsechny interaktivni Jira
operace. App token nikdy necte ani neposila. Pokud backend vrati HTTP 428 s
kodem jira_oauth_required, Jira formulare zachovaji zadane hodnoty a nabidnou
existujici flow pro pripojeni Jira uctu v nove zalozce. Po novem consentu
uzivatel puvodni operaci odesle znovu. Detailni hranice jsou v
Jira OAuth 2.0 (3LO).
Pokud je zapnute SIMPLE_AUTH_ENABLED, app overuje callback a pouzite
rp_nonce uklada pres backend nonce API. Replay protection tedy zustava
durable, ale app uz kvuli nonce nepristupuje primo do DB.
Typed AI prompty uz appka spravuje pres reply-pilot-be endpointy
/api/ai-prompt-types a /api/ai-prompts. Backend je uklada do tabulek
public.ai_prompt_type a public.ai_prompt. Reply workflow filtruje typ
EMAIL_REPLAY, lead import wizard filtruje typ IMPORT_WIZARD a Supplier
Onboarding workflow filtruje typ SUPPLIER_ONBOARDING.
Lokalni cache fixture zustava jen kvuli testum. Mimo testy je
BACKEND_API_BASE_URL povinne a prazdna hodnota zpusobi chybu startu appky.
BACKEND_API_BASE_URLnastavene -> app vola backend a sama nepracuje primo s Gmail/OpenAI- app modul nema runtime konfiguraci
REPLY_PILOT_DB_*, nema zavislost napsycopga nema produkcni DB-backed directory/record/task store fallback APP_INTERNAL_EMAIL_DOMAINSnahrazuje drivejsi app-side Gmail mailbox config pro UI heuristiky, ktere potrebuji znat interni emailove domeny
Endpointy
/dashboard/searchfulltext nad emaily, party a activity modely/companies/newrucni zalozeni firmy pres backend API/companies/<party_id>detail firmy z party modelu/companies/<party_id>/reply-pilot-tasks/createzalozeni obecnehoReply Pilot Taskpro firmu/companies/<party_id>/notes/newpridani poznamky k firme/companies/<party_id>/contacts/newpridani kontaktu firmy pres backend API/companies/<party_id>/contacts/<contact_mech_id>/edituprava vazby kontaktu firmy/companies/<party_id>/contacts/<contact_mech_id>/removepotvrzeni odebrani kontaktu firmy/companies/<party_id>/identifiers/newpridani identifikace firmy/companies/<party_id>/identifiers/<identifier_id>/removepotvrzeni odebrani identifikace firmy/companies/<company_id>/people/<person_id>/removepotvrzeni odebrani vazby osoby na firmu/people/newrucni zalozeni osoby, volitelne scompany_id/people/<party_id>detail osoby z party modelu/people/<party_id>/notes/newpridani poznamky k osobe/people/<party_id>/editeditace identity osoby/people/<party_id>/contacts/newpridani kontaktu osoby/people/<party_id>/contacts/<contact_mech_id>/edituprava vazby kontaktu osoby/people/<party_id>/contacts/<contact_mech_id>/removepotvrzeni odebrani kontaktu osoby/emails/<activity_id>detail emailu z activity modelu/activities/<activity_id>detail ne-emailove a ne-poznamkove aktivity/tasksprehled JIRA tasku/tasks/<task_id>detail tasku s navazanymi emailovymi vlakny/tasks/<task_id>/reply-pilot-task/resolvevyreseni delegovanehoReply Pilot Tasks jednim textovym polem/tasks/<task_id>/reply-pilot-task/closePOST akce pro uzavreni delegovanehoReply Pilot Task/reassignmentprehled firem pro prerazovani ticketu; filtrdefault_email_sales_useromezi seznam firem podle vychoziho obchodnika pro emailovou komunikaci nebo hodnotyunset/settings/rolesjednoducha sprava prirazeni jedne system role uzivateli; route vyzadujesecurity.manage_roles/ai-promptyCRUD sprava typed promptu s filtrem podle workflow typu/api/emailsJSON vystup pro dalsi integrace/healthzhealth endpoint/draftsplaceholder POST endpoint pro dalsi navazujici logiku
Party CRUD UI
Detail firmy je pracovni prehled se sekcemi Identita, Identifikace,
Kontakty firmy, Osoby, Poznamky a E-mailova vlakna. Editovatelne sekce
maji radkove akce, ale samotne formulare jsou samostatne stranky ve stylu CTA
form. Odkaz Pridat poznamku vede na samostatny formular s jednim povinnym
textarea polem a po ulozeni presmeruje zpet na detail firmy.
Detail osoby pouziva stejne objektove schema jako firma: H1 je jmeno osoby a
H2 je Osoba - Prehled, Osoba - Aktivity nebo Osoba - Editovat.
Prehled osoby obsahuje Identita, Kontakty osoby, Spolecnosti a
Poznamky. Odkaz Pridat poznamku pouziva stejny formular jako firma a po
ulozeni presmeruje zpet na detail osoby. Prehledove sekce Poznamky ukazuji
jen poznamky pripojene primo k zobrazene party.
Aktivity osoby i firmy pouzivaji timeline layout. Timeline firmy bez
kontaktniho filtru zobrazuje i poznamky aktivne navazanych osob jako zdedene
radky s metadatem Z osoby a odkazem na danou osobu. Poznamkove radky v
timeline zobrazuji i Poridil <uzivatel>, pokud backend vratil autora.
Timeline filtrovana na konkretni e-mailovou adresu tyto zdedene osobni
poznamky nezobrazuje.
Appka nove mutace osob, kontaktu, identifikaci a vazeb neposila primo do DB, ale vola backend REST API. Po uspesne mutaci presmeruje zpet na relevantni detail. Odebrani kontaktu, identifikace nebo vazby osoby na firmu vzdy vede pres potvrzovaci stranku; GET nic nemeni.