Reply Pilot Backend
Tato stranka popisuje modul reply-pilot-be/.
Role modulu
- vlastni JSON API pro inbox a komunikacni workflow
- vlastni app-facing inbox/read orchestration a DB materializaci emailu
- vola
reply-pilot-gmailpro Gmail sync, cache reads, attachment bytes, drafty a send - pri zobrazeni inboxu/detailu threadu udrzuje komunikacni historii v
reply-pilot-db - vlastni OpenAI debug/generation flow pro
reply-pilot-app - vlastni typed AI prompt CRUD API pro
reply-pilot-app - vlastni reply draft, app user profile, app configuration a Jira assignee mapping API
- vlastni simple-auth nonce persistence API pro replay protection app callbacku
- vlastni read-model API pro firmy, osoby, kontakty, aktivity, emaily a tasky
- vlastni company/task mutace vcetne navazanych Jira operaci
- vlastni app-facing search API a vola
reply-pilot-search - vlastni server-side lead import workflow pro JSONL batch soubory
- je verejna backendova orchestrace e-mailove vrstvy; Gmail API a mailbox cache
fyzicky vlastni
reply-pilot-gmail
Java Backend Contract
Stav k 2026-06-13:
reply-pilot-beje Java 21 Spring Boot/Maven REST/JSON aplikace.- Legacy Python/Flask backend package, Python backend tests, Python-only dependencies and obsolete backend Python utilities were removed.
- Backend contract is now maintained in Java controllers, Java services and
Maven/JUnit 5 tests under
reply-pilot-be/src/test/java.
Endpointove rodiny pokryte backend kontrolery:
| Oblast | Endpointy | Java stav |
|---|---|---|
| Health/meta/Jira meta | 3 | ported |
| Search proxy | 1 | ported |
| AI prompt CRUD | 6 | ported |
| Reply draft storage | 5 | ported |
| User profile/app config/Jira assignee storage | 9 | ported |
| Simple-auth nonce API | 2 | ported |
| Jira proxy + task sync | 14 | ported |
| Company/person/activity/contact/task read models | 19 | ported |
| Company/person/contact/identifier/task mutations | 25 | ported |
| AI draft/debug generation | 3 | ported |
| Lead import | 6 | ported |
| Inbox/email/attachment read | 5 | ported |
| Mailbox watch/import | 9 | ported |
| Worker job endpoints | 5 | ported |
| Email draft/send | 4 | ported |
Route-shape notes:
- Java
ReadModelControllerpouziva jednu catch-all routeGET /api/email-threads/{*threadPath}a uvnitr ji dispatchuje na/companies,/requirementsa/task, aby zustaly podporovane slash-capable thread IDs. - Requirement review route pouziva jeden path segment. Aktualni requirement kody jsou
jednosegmentove hodnoty (
ENLISTMENT_TABLE,FEED,SUPPLIER_IDENTIFIER), takze aktualni kontrakt je pokryty; slash-containing requirement kody nejsou podporovany ani dokumentovane.
Authorization notes:
- Business read/write endpointy pouzivaji trusted internal header
X-Reply-Pilot-App-User-Id, ktery posilareply-pilot-apppo vyreseni nebo zalozeniapp_user. - Backend autorizuje jen podle
app_user.ida efektivnich opravneni zapp_user_role -> app_role_permission; emaily a display names nejsou autorizacni identita. - Company read scope je enforced v backend read modelu i search proxy.
company.view_allvidi vsechny firmy,company.view_assignedvidi jen firmy, kdeparty_organization.default_email_sales_user_id = app_user.id. Mimo delegovanou task vyjimku backend bez techto opravneni nevraci zadne firmy. - Backend read-model company/task endpointy navic udeluji uzkou read-only
vyjimku pro delegovane
Reply Pilot Task: aktualni Jira assignee aktivniho tasku muze nacist jen firmu navazanou na tento aktivni task a samotny aktivni task. Vyjimka neplati pro neprirazene delegovane tasky,Donetasky, nesouvisejici firmy ani zapisove mutace. - Search proxy nepouziva samostatne
task.*opravneni. Reuseuje zakladni company scope a posila search modulu efektivniapp_user_id:company.view_allvidi vsechny indexovane tasky,company.view_assignedvidi tasky podle vlastnika firmy a aktivni delegovaneReply Pilot Taskprirazene aktualnimu uzivateli. Uzivatel bez company view opravneni nedostane zadne search vysledky.Donedelegovane tasky se ve fulltextu nehledi jako aktivni delegated-assignee vyjimka, ale zustavaji dohledatelne pres normalni company scope nebocompany.view_all; defaultni task prehled je skryva oddelene. - Company/task mutace navazane na existujici firmu vyzaduji
company.writenebocompany.write_assigneda zaroven stejny company visibility scope. Beznesalesrole proto muze zapisovat jen prirazene firmy a jejich tasky, ne vsechny firmy. Zalozeni nove firmy zustava globalni operace vyzadujicicompany.write. - Delegovane
Reply Pilot Taskmutace nepouzivaji obecne company write opravneni.POST /api/tasks/{taskId}/reply-pilot-task/resolvesmi zavolat jen aktualni cached Jira assignee aktivniho delegated tasku; backend prida zadany text do Jira description, priradi Jira task na lokalne ulozeneho zadavatele a ponecha stavIn Progress.POST /api/tasks/{taskId}/reply-pilot-task/closesmi zavolat jen lokalne ulozeny zadavatel; backend presune Jira task doDonea assignee nemeni.
Endpoint parity caveats:
- Worker job endpointy jsou v Jave portovane jako REST orchestrace a typovane porty. Java ma konkretni JDBC worker bean pro CME company sync, AI requirement klasifikaci, requirement agregaci, requirement monitoring/report a historicky requirement backfill.
- Java mailbox/send/lead-import aktivita ma produkcni JDBC
ActivityEmailImportRepositorypro zakladniactivity,activity_email,activity_participant,activity_email_attachmentaactivity_email_linkpersistenci. Ten samy importer zapisuje i deterministickeparty_feed_fact,party_supplier_identifier_fact,party_requirement_evidenceaparty_requirement_eval_queueradky pro incoming emaily a preklapi uz navazaneemail_thread_replyJira tasky doDrafting Replypri nove prichozi externi odpovedi. Pro nenavazane incoming odpovedi s jednoznacne vyresenou dodavatelskou firmou Java po uspesnem commit importu zaklada automatickyEmail Thread Replytask pres stejnou prioritu vychoziho assignee jako zbytek backend kontraktu. - Java lead-import outbound email aktivita se zapisuje pres caller-owned JDBC connection uvnitr stejne DB transakce jako update lead-import itemu. Externi Gmail send a Jira issue operace zustavaji mimo DB rollback hranici, protoze jde o externi systemove side efekty.
Runtime
- bezi jako samostatny Java 21 Spring Boot kontejner
- zapisuje do
reply-pilot-be/dataareply-pilot-be/logs conf/zustava read-only mount- na interni siti se hlasi jako
reply-pilot-be reply-pilot-appareply-pilot-workerho volaji preshttp://reply-pilot-be:5000- Gmail sluzbu vola pres
GMAIL_API_BASE_URL, defaultnehttp://reply-pilot-gmail:5000; to je interni URL modulureply-pilot-gmail, ne Google Gmail API endpoint - v
EMAIL_SYNC_BACKEND=gmail_servicemodu necte ani nezapisujereply-pilot-be/data/emails; inbox cache, cursory a attachment bytes cte pres HTTP z Gmail modulu - nedrzi Gmail OAuth token, Gmail mailbox cache, mailbox/query konfiguraci ani Pub/Sub credentials
- Search sluzbu vola pres
SEARCH_API_BASE_URL, defaultnehttp://reply-pilot-search:5000 - PostgreSQL vola pres
reply-pilot-dbna interni siti
Email Artifact Flow
Import emailu probiha ve trech vrstvach:
reply-pilot-bespusti sync/detail/attachment operaci presreply-pilot-gmailHTTP API. Gmail modul vola Google Gmail API a zapisuje fyzickou cache doreply-pilot-gmail/data/accounts/<GMAIL_CACHE_ACCOUNT_ID>/emails/.- BE cte snapshoty, detail, attachment metadata a attachment bytes pres
interni HTTP cache endpointy Gmail modulu.
relative_pathzustava logicka hodnota ve tvaruemails/attachments/<thread>/<file>, ne host filesystem cesta. - Activity import zapise do PostgreSQL:
activity+activity_emailactivity_email_attachmentjako DB metadata nad Gmail-owned cacheactivity_email_linkjako explicitni URL nalezene vbody_text- Pozdejsi attachment phase muze pres Gmail modul dotahnout chybejici binarky;
backend pak znovu synchronizuje
activity_email_attachment, aby DB metadata odpovidala aktualni Gmail-owned cache.
Dulezite pravidlo:
- PostgreSQL je source of truth pro attachment metadata a pro nalezene URL
- binarni obsah priloh zustava v Gmail module cache a BE ho pro klienty proxyuje pres HTTP
- vazba z DB na cache vede pres
activity_email_attachment.relative_path; hodnota je kompatibilni logicky path, ne dukaz vlastnictvi filesystemu v BE - odeslane e-maily se po uspesnem Gmail
sendmaterializuji stejnouActivityImportStorecestou jako importovane zpravy; lead import wizard pri akci odeslat+a importovat posila e-mail v backendu, aby se pred zapisemactivity_emailnejdriv zalozila firma a kontaktni vazby
Lead Import Runtime
Lead import flow cte serverove JSONL soubory z backend storage, typicky pod
reply-pilot-be/data/lead-imports/:
inbox/ceka na operatoraprocessing/drzi soubor navazany na aktivni review batchdone/drzi dokoncene batch souboryfailed/drzi soubory, ktere nesly nacist nebo zalozit do DB
Backend:
- vypise dostupne soubory pro web app
- ze zvoleneho souboru zalozi
lead_import_batchalead_import_item - pri otevreni detailu polozky umi vygenerovat AI draft prvniho osloveni
- pri operatorove akci umi zalozit nebo doplnit firmu, odeslat prvni osloveni,
ulozit odeslany e-mail do kontaktni historie, ulozit
activity_note, propsatparty_outreach_policya vytvorit Jira task
Simple Auth Nonce API
Backend exposeuje male JSON API pro durable replay protection app login callbacku:
POST /api/simple-auth/nonces/checkPOST /api/simple-auth/nonces/mark-used
Backend uklada nonce do existujici tabulky public.simple_auth_nonce.
reply-pilot-app tedy pri simple-auth callbacku necte ani nezapisuje nonce
primo do DB.
Manual Company Create
Backend exposeuje POST /api/companies pro rucni zalozeni firmy z web appky.
Endpoint v jedne transakci zalozi pouze organizaci nad existujicim party modelem.
Kontakty, osoby, poznamky, outreach policy ani Jira tasky nejsou soucasti tohoto
V1 formulare.
V1 request obsahuje:
company:display_name,legal_name,company_registration_number,tax_identifier,show_by_default,default_email_sales_user_id
legal_name a company_registration_number jsou povinne. display_name je
volitelny obchodni nazev; kdyz chybi, backend pouzije pravni nazev jako display
nazev. Web appka neposila website ani roles; backend stare payload fieldy
porad toleruje kvuli kompatibilite.
Web appka rucniho zalozeni posila show_by_default=true, protoze formular uz
neobsahuje samostatnou volbu viditelnosti.
Backend ignoruje klientem poslanou hodnotu default_email_sales_user_id jako
zdroj pravdy a uklada efektivniho uzivatele z X-Reply-Pilot-App-User-Id.
Zalozena firma je tedy hned viditelna pro uzivatele se scoped opravnenim
company.write_assigned.
Pred insertem backend kontroluje duplicity podle presneho ICO, DIC,
normalizovaneho pravniho nazvu a DOMAIN/WEBSITE identifikatoru. Pri nalezu
vraci 409 a zadny zaznam neuklada. Kandidaty v odpovedi filtruje podle
company visibility scope aktualniho uzivatele; pokud duplicita existuje, ale
uzivatel ji nesmi videt, odpoved neobsahuje zadne detaily o firme.
Email Thread Reply Tasky
Backend vlastni vytvareni Jira tasku typu Email Thread Reply.
- UI vola
POST /api/email-threads/<email_id>/reply-taskssparty_id,assignee_user_id,summaryadescription. - Backend nacita e-mailove vlakno ze sve e-mail sluzby, kontroluje duplicitu pres
task_jira_email_thread_reply.external_thread_id, vytvari Jira issue typuJIRA_DEFAULT_ISSUE_TYPE_REPLY_EMAILa uklada existujici lokalni tabulkytask,task_jiraatask_jira_email_thread_reply. - Do Jira description doplnuje link na detail firmy a po lokalnim ulozeni i link
na detail tasku podle
APP_PUBLIC_BASE_URL. - Lokalni
task_jira.jira_summaryatask_jira.jira_description_textcache se aktualizuje hned pri vytvoreni/editaci tasku; pravidelny Jira task sync pak cache dorovnava podle Jiry. - Pri duplicitnim threadu endpoint vraci
409a metadata existujiciho tasku, aby app mohla presmerovat na jiz zalozeny task.
Activity import pri nove prichozi zprave od externiho dodavatele nejdriv
preklopi existujici reply task pro stejne vlakno do stavu Drafting Reply.
Kdyz pro thread reply task jeste neni a importer jednoznacne vyresi
dodavatelskou firmu, backend zalozi novy Email Thread Reply a novy Jira ticket
take prevede do Drafting Reply.
Odeslani odpovedi nebo preposlani z existujiciho emailoveho vlakna nevytvari
novy reply task. Backend posila email v kontextu puvodniho vlakna a existujici
navazany Email Thread Reply task presune do Waiting for Reply, pokud uz v
tomto stavu neni.
Vychozi assignee pro automaticky reply task se bere v tomto poradi:
party_organization.default_email_sales_user_idapp_configuration.default_email_sales_user_idDEFAULT_EMAIL_THREAD_REPLY_ASSIGNEE_JIRA_ACCOUNT_IDDEFAULT_EMAIL_THREAD_REPLY_ASSIGNEE_EMAIL- bez assignee, pokud zadny zdroj nedal dohledatelny Jira account
Java migration toto chovani portuje v
JdbcActivityEmailImportRepository/TaskMutationService. Automaticke vytvareni
bezi az po uspesnem commit email importu, aby Java task service videla i novou
firmu zalozenou importem.
AI Evidence Output Contract
Pro budouci AI klasifikaci requirement evidence jsou source of truth tyto JSON schema soubory:
reply-pilot-be/default-conf/ai-schemas/enlistment-table.schema.jsonreply-pilot-be/default-conf/ai-schemas/feed.schema.jsonreply-pilot-be/default-conf/ai-schemas/supplier-identifier.schema.json
Spolecna pravidla:
- vsechny vystupy musi projit validaci proti schema pred zapisem do DB
additionalPropertiesjsou vsude zakazane, aby backend nemusel resit tichy driftevidence_keyafact_keymusi byt unikatni v ramci jedne AI odpovediconfidenceje vzdy0..1model_name,model_versionaprompt_versionse neberou z AI payloadu; doplnuje je backend pri zapisuextract_jsonma ukladat validovany fragment, ktery vedl ke vzniku konkretniho DB radku, ne jen volny textovy summary
AI Classification Runtime
reply-pilot-be exposeuje worker endpoint POST /api/requirements/ai-classify/run.
Tenhle job:
- vybira jen emaily, ktere uz prosly deterministic prefiltrem
- scope
ENLISTMENT_TABLEbere zparty_requirement_evidencescreated_by = deterministic-enlistment-detector - scope
FEEDbere zparty_feed_factscreated_by = deterministic-email-parser - scope
SUPPLIER_IDENTIFIERbere zparty_supplier_identifier_factscreated_by = deterministic-email-parser - AI job znovu nepousti kandidaty, ktere uz maji AI materializovane radky s
created_by = ai-requirement-classifier - pri chybe jedne AI klasifikace backend zaloguje chybu, preskoci konkretni email a pokracuje dalsim kandidatem
Structured output validace:
- backend posila do OpenAI commitnute JSON schema z
default-conf/ai-schemas/ - OpenAI schema drzi jen subset kompatibilni s Responses API; podminena pravidla
typu
EMAIL_ATTACHMENT => attachment_* povinneneboDIRECT_URL => url_* povinnehlida nasledna backend validace - po odpovedi dela vlastni strict validaci fixnich payload shape pravidel, bez runtime dependency na externi
jsonschemaknihovne - az po uspesne validaci zapisuje DB evidence/facts
Requirement Aggregation Runtime
reply-pilot-be exposeuje i worker endpoint POST /api/requirements/evaluate/run.
Tenhle job:
- cte
party_requirement_eval_queue - claimuje pending polozky pres
FOR UPDATE SKIP LOCKED - pro
ENLISTMENT_TABLEagreguje historickeparty_requirement_evidence - pro
FEEDagreguje historickeparty_requirement_evidenceaparty_feed_fact - pro
SUPPLIER_IDENTIFIERagreguje historickeparty_supplier_identifier_fact - vysledek zapisuje do
party_requirement_state - pro
FEEDpropaguje i finalniresolved_delivery_mode_codeafeed_url - pro
SUPPLIER_IDENTIFIERpropagujeresolved_value_type_codea hodnotu - pri manualnim override radek v
party_requirement_stateneprepisuje - pri chybe jedne queue polozky ji jen odlozi na pozdeji a zpracovani dalsich firem pokracuje
- kdyz se zmeni
REQUIREMENT_AGGREGATION_RULESET_VERSION, backend jednorazove znovu zaqueueuje vsechny firmy doparty_requirement_eval_queue
Java Spring Boot backend ma pro tenhle runtime konkretni
JdbcRequirementAggregationWorker bean. Historicky backfill ma vlastni
konkretni JdbcRequirementBackfillWorker bean.
Historical Requirement Backfill
Pro jednorazovy nebo strankovany backfill historickych threadu exposeuje backend
endpoint POST /api/requirements/backfill/run.
Tenhle job:
- umi zpracovat jednu firmu pres
party_idnebo strankovanou davku presafter_party_id+limit - nejdriv znovu synchronizuje deterministic email artifacts a extracted facts nad historickymi thready dane firmy
- preferuje thread snapshot pres
EmailCacheRepository; vgmail_servicemodu jde o Gmail-module HTTP cache, a kdyz snapshot chybi, spadne na DB-only fallback nadactivity_emailaactivity_email_attachment - AI klasifikaci i requirement agregaci pousti jen nad vybranou sadou firem, ne globalne nad celou frontou
- je idempotentni, protoze deterministic vrstvy delaji replace svych radku a agregace bezi pres existujici queue/upsert model
- vraci operativni report poctu firem, threadu, synchronizovanych zprav, AI kandidatu a prepoctenych atributu
AI prompt refresh:
- AI candidate scan bere v uvahu aktualni
REQUIREMENT_AI_PROMPT_VERSION - pokud pro email existuji jen starsi AI radky s jinou prompt verzi, backend je povazuje za stale a zaradi email znovu do AI klasifikace
ENLISTMENT_TABLE
Schema:
- top-level
summary - pole
evidence_items - kazdy
evidence_itemreprezentuje jeden kandidátní dukaz
Mapovani do DB:
- pro kazdy
evidence_itemvytvor jeden radek vparty_requirement_evidence requirement_code = 'ENLISTMENT_TABLE'source_type_code,verdict_code,confidence,reasonse berou primo z itemuactivity_email_idaexternal_thread_iddoplni backend z aktualniho importovaneho emailu- pokud je
source_type_code = 'EMAIL_ATTACHMENT', backend preneseattachment_filename,attachment_relative_patha volitelneattachment_sha256 - pokud je
source_type_code = 'EMAIL_MESSAGE', attachment sloupce zustanou prazdne extract_jsonna evidence radku ma obsahovat presnyevidence_itema volitelne i top-levelsummary- top-level
summaryse nezapisuje primo doparty_requirement_state; slouzi jako vstup pro pozdejsi agregacni worker
FEED
Schema:
- top-level
summary - pole
evidence_items - pole
feed_facts - kazdy
feed_factodkazuje na jedenevidence_itempresevidence_key
Mapovani do DB:
evidence_itemsse materializuji doparty_requirement_evidencerequirement_code = 'FEED'- backend si vytvori mapu
evidence_key -> party_requirement_evidence.id - pro kazdy
feed_factvytvori jeden radek vparty_feed_fact evidence_idse naplni zevidence_key; kdyz reference chybi nebo ukazuje na neexistujici key, cely AI payload se ma povazovat za nevalidnidelivery_mode_code,url_raw,url_normalized,confidence,reasonse berou primo z factu- pri
delivery_mode_codeDIRECT_URLneboLOGIN_REQUIREDmusi byt vyplneneurl_rawiurl_normalized - pri
IDENTIFIER_ONLY,MANUAL_EXPORT,NO_FEEDneboOTHERmohou byt URL prazdne - attachment metadata se do
party_feed_factkopiruji z navazanehoevidence_item; kdyz je zdrojemEMAIL_MESSAGE, zustanou attachment sloupce prazdne extract_jsonna fact radku ma obsahovat konkretnifeed_fact;extract_jsonna evidence radku konkretnievidence_item
SUPPLIER_IDENTIFIER
Schema:
- top-level
summary - pole
evidence_items - pole
identifier_facts - kazdy
identifier_factodkazuje na jedenevidence_itempresevidence_key
Mapovani do DB:
- v aktualnim schema V1 se
SUPPLIER_IDENTIFIERnematerializuje doparty_requirement_evidence, protozerequirement_typezatim nema odpovidajici kod - backend proto validuje
evidence_items, ale do DB zapisuje jenparty_supplier_identifier_fact evidence_keyslouzi jako interní most pro kopirovani source metadata zevidence_itemsdo fact radkuidentifier_type_code,value_raw,value_normalized,confidence,reasonse berou primo zidentifier_factevidence_idzustavaNULLattachment_filename,attachment_relative_pathaattachment_sha256se kopiruji z navazanehoevidence_item, pokud je zdroj attachmentextract_jsonna fact radku ma obsahovat konkretniidentifier_facta volitelne odkaz na pouzityevidence_item- pokud se pozdeji prida
requirement_typepro identifikatory dodavatele, schema neni potreba menit; backend jen zacneevidence_itemsmaterializovat i doparty_requirement_evidence
Endpointy
Zakladni stav:
GET /healthzGET /api/metaGET /api/jira/meta
App state a BFF storage:
GET /api/ai-prompt-typesGET/POST /api/ai-promptsGET/PATCH/DELETE /api/ai-prompts/<prompt_id>GET/POST /api/reply-draftsGET/PATCH/DELETE /api/reply-drafts/<draft_id>GET/POST /api/user-profilesGET/PATCH /api/user-profiles/<login_key>GET/PATCH /api/app-configurationGET /api/jira/assigneesGET /api/jira/assignees/<app_user_id>/account-idPUT /api/jira/assignees/<app_user_id>POST /api/simple-auth/nonces/checkPOST /api/simple-auth/nonces/mark-used
Read modely pro app obrazovky:
GET /api/companiesGET /api/companies/<party_id>GET /api/companies/<party_id>/tasksGET /api/peopleGET /api/people/<party_id>GET /api/activity-emailsGET /api/activity-emails/<activity_id>GET /api/contact-methods/<contact_mech_id>GET /api/parties/<party_id>/notesGET /api/parties/<party_id>/activitiesGET /api/activities/<activity_id>GET /api/email-threads/<external_thread_id>/companiesGET /api/email-threads/<external_thread_id>/requirementsGET /api/email-threads/<external_thread_id>/taskGET /api/email-threads/tasksGET /api/contact-emails/companiesPOST /api/company-mentionsGET /api/tasksGET /api/tasks/<task_id>
GET /api/companies podporuje filtr
default_email_sales_user=<app_user_id|unset>. Hodnota unset vraci firmy bez
nastaveneho vychoziho obchodnika pro emailovou komunikaci; prazdna nebo
neplatna hodnota filtr neaplikuje.
Supplier Onboarding lze filtrovat pres
supplier_onboarding_ticket=<with|without> a
supplier_onboarding_status=<Jira status name>. Stav se vyhodnocuje pouze nad
tasky s jira_work_type_code=supplier_onboarding; firma vyhovuje, pokud ma
alespon jeden takovy task ve zvolenem stavu. Kombinace without a konkretniho
stavu vraci prazdny vysledek.
Company, party a task mutace:
POST /api/companiesPATCH /api/companies/<party_id>POST /api/companies/<target_party_id>/mergePOST /api/companies/<party_id>/visibilityPOST /api/companies/<party_id>/requirements/<requirement_code>/reviewPOST /api/companies/<party_id>/supplier-onboarding-tasksPOST /api/companies/<party_id>/reply-pilot-tasksPOST /api/peoplePATCH /api/people/<party_id>POST /api/parties/<party_id>/contactsPATCH /api/parties/<party_id>/contacts/<contact_mech_id>DELETE /api/parties/<party_id>/contacts/<contact_mech_id>POST /api/parties/<party_id>/notesPOST /api/companies/<party_id>/identifiersDELETE /api/companies/<party_id>/identifiers/<identifier_id>DELETE /api/companies/<company_id>/people/<person_id>PATCH /api/tasks/<task_id>/companyPOST /api/tasks/<task_id>/email-threadsPATCH /api/tasks/<task_id>/supplier-onboardingPATCH /api/tasks/<task_id>/email-thread-replyPOST /api/tasks/<task_id>/refresh-from-jiraPOST /api/tasks/<task_id>/supplier-onboarding/replyPOST /api/tasks/<task_id>/move-reply-to-waitingPOST /api/tasks/<task_id>/reply-pilot-task/resolvePOST /api/tasks/<task_id>/reply-pilot-task/close
Jira proxy a task drafty:
GET /api/jira/myselfGET /api/jira/users/by-emailGET /api/jira/issues/<issue_key>PUT /api/jira/issues/<issue_key>GET /api/jira/issues/<issue_key>/transitionsPOST /api/jira/issues/<issue_key>/transitionGET/POST /api/jira/issues/<issue_key>/commentsPOST /api/jira/issues/<issue_key>/unassignGET /api/jira/issues/searchGET /api/jira/issues/assignedGET /api/jira/issues/stalePOST /api/jira/issuesPOST /api/jira/task-sync/runPOST /api/supplier-onboarding/draftPOST /api/email-thread-task/draft
Vsechny Jira proxy endpointy vyvolane prihlasenym uzivatelem vyzaduji trusted
app-user kontext a pouzivaji jeho Jira OAuth 2.0 (3LO) bearer token pro cteni i
zapis. Stejny actor-aware klient pouzivaji interaktivni task workflow, lead
import a explicitni refresh tasku. Chybejici nebo nepouzitelny credential se
vraci jako HTTP 428 s kodem jira_oauth_required; request se neopakuje s
technickym uctem.
No-actor varianta Jira klienta je povolena jen pro periodicky Jira task sync, automaticke operace vyvolane prichozim e-mailem a samostatny Jira reports modul. Tyto procesy nemaji prihlaseneho lidskeho aktera a pouzivaji technicky ucet. Presny audit, scope pozadavky a consent flow jsou v Jira OAuth 2.0 (3LO).
Jira task sync pro lokalni task cache pouziva JQL omezeny na nakonfigurovany
projekt a issue typy JIRA_DEFAULT_ISSUE_TYPE_SUPPLIER_ONBOARDING,
JIRA_DEFAULT_ISSUE_TYPE_REPLY_EMAIL a
JIRA_DEFAULT_ISSUE_TYPE_REPLY_PILOT_TASK. Do task_jira zapisuje status, work
type, assignee mapping a plain-text jira_summary/jira_description_text.
U delegovanych Reply Pilot Task issue nacita Jira dropdown
JIRA_REPLY_PILOT_TASK_TYPE_CUSTOM_FIELD_ID a jeho hodnotu uklada do
task_jira_reply_pilot_task.task_type_value. Vychozi task list nevraci
Reply Pilot Task ve stavu Done, dokud request explicitne nefiltruje stav
nebo Jira key.
Pri zalozeni POST /api/companies/<party_id>/reply-pilot-tasks backend vytvori
Jira issue type Reply Pilot Task, nastavi Jira dropdown taskType, do
task_jira_reply_pilot_task ulozi requester app user id a lokalni task type
hodnotu.
Email, Gmail mailbox a OpenAI debug:
GET /api/inboxGET /api/emailsGET /api/emails/<email_id>GET /api/emails/<email_id>/attachmentsPOST /api/email-threads/<email_id>/reply-tasksGET /api/emails/<email_id>/attachments/<filename>GET /api/mailbox/watchPOST /api/mailbox/watch/ensurePOST /api/mailbox/watch/stopPOST /api/mailbox/watch/notifyPOST /api/mailbox/watch/pullPOST /api/mailbox/sync/fullPOST /api/mailbox/sync/sentPOST /api/mailbox/importGET /api/mailbox/import/statusPOST /api/mailbox/import/stepPOST /api/emails/drafts/outboundPOST /api/emails/<email_id>/drafts/replyPOST /api/emails/send/outboundPOST /api/emails/<email_id>/send/replyPOST /api/emails/<email_id>/send/forwardPOST /api/emails/<email_id>/debug/generate
Lead import, CME a requirement joby:
POST /api/cme/company-sync/runGET /api/lead-imports/filesPOST /api/lead-imports/batchesGET /api/lead-imports/batches/<batch_id>GET /api/lead-imports/batches/<batch_id>/items/<item_id>POST /api/lead-imports/batches/<batch_id>/items/<item_id>/draftPOST /api/lead-imports/batches/<batch_id>/items/<item_id>/actionsPOST /api/requirements/ai-classify/runPOST /api/requirements/evaluate/runPOST /api/requirements/backfill/runGET /api/requirements/report
Reply draft/send a forward-send endpointy prijimaji puvodni JSON payload bez
priloh. Pokud odpoved nebo forward obsahuje prilohy, klient posila
multipart/form-data se stejnymi textovymi poli recipient, subject,
body_text, reply_to_message_id, volitelnymi poli body_signature_html a
body_signature_plain_text a opakovanym file polem attachments. Limit je 10
souboru, 10 MB na soubor a 20 MB celkem.
Party Mutation API
Backend exposeuje rucni mutace pro osoby, kontakty, identifikace a vazby nad existujicim party/contact modelem. Vsechny mutace bezi v jedne DB transakci a overuji, ze cilova party existuje, neni mergnuta a ma ocekavany typ.
POST /api/peoplezalozi osobu a volitelne ji navaze na firmu presCONTACT_FOR.PATCH /api/people/<party_id>upravi zakladni identitu osoby.POST/PATCH/DELETE /api/parties/<party_id>/contacts...spravuje aktivni vazbu party naEMAILneboPHONEcontact mechanism.DELETEkontaktu nastavujeparty_contact_mech.thru_date;contact_mechani historie aktivit se nemazou.POST /api/companies/<party_id>/identifierspodporujeWEBSITE,DOMAIN,GLN,VENDOR_CODEaEXTERNAL_ID; ICO/DIC zustavaji v editaci firmy.DELETE /api/companies/<party_id>/identifiers/<identifier_id>mazeparty_identifier, protoze tabulka nema lifecycle sloupec.DELETE /api/companies/<company_id>/people/<person_id>ukonci aktivniCONTACT_FORvztah presthru_date; osoba zustava zachovana.POST /api/parties/<party_id>/notesprida add-only poznamku nad existujicimactivity+activity_notemodelem. Request obsahujenote_texta volitelnecreated_by_user_id; response vraci kompatibilni envelope senote.activity_id,note.party_ida prazdnymnote.url_path, protoze poznamky nemaji samostatnou web detail stranku.GET /api/parties/<party_id>/notesvraci pouze poznamky primo pripojene k dane party, ne poznamky zdedene z navazanych osob.GET /api/parties/<party_id>/activitiespro firmu bezcontact_emailfiltru zahrnuje i poznamky osob, ktere maji v okamziku cteni aktivniCONTACT_FORvztah k firme. Tyto radky majiinherited: trueasource_party_id,source_party_type_code,source_party_label,source_url_path. Activity payload vraci i volitelnecreated_by_user_idacreated_by_display_name, aby UI mohlo u poznamek zobrazit, kdo je poridil. Timeline filtrovana prescontact_emailzdedene osobni poznamky nevraci.
Chyby vraci JSON se status: error a reason. Validacni chyby pouzivaji
400, konflikt duplicit 409 s volitelnymi candidates, chybejici zaznam
404 a nenakonfigurovana DB 503.