+
    ZjZ                        R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t
^ RIHtHtHt ^ RIHt ]! R4      t]R,          t]R,          t]R,          t]R,          t]! R	4      t]! ]4      P.                  R
,          t]R,          tRt^t. ReOt^R^R^R^R^R^R^R^R/tRRRRR/RRRRR/RRRRR//tR R!R"R#R$R%R&R'R(R(R)R*R+R,R-R.R/R0R1R2R3R4/t. RfOt . RgOt!. RhOt". RiOt#. RjOt$. RkOt%R5t&R6 t'R7 t(R8 t)R9 t*R: t+R; t,R< t-RlR= lt.RmR> lt/RmR? lt0R@ t1RA t2RB t3RC t4RD t5RnRE lt6RF t7RG t8RH t9RI t:RJ t;RK t<RL t=RM t>RN t?RO t@RP tARQ tBRR tCRS tDRT tERU tFRV tGRW tHRX tIRY tJRZ tKR[ tLR\ tMR] tNR^ tOR_tPR` tQRa tRRb tSRc tT]URd8X  d
   ]T! 4        R# R# )ou  
i4Fuel deal pipeline v2 — single-file CLI.

Companies and contacts are first-class entities (independent of deals).
Inquiries are the pre-deal layer — every inbound FCO/RFQ lands here first.
Incidents track scams, no-shows, breaches against companies over time.

Auto-checks on company creation:
- Local blacklist folder scan (Dropbox/Petrol trade/Blacklists/)
- OFAC SDN list match (cached weekly)

Storage: SQLite on Dropbox. Dashboard: auto-regenerated HTML.
N)datetime	timedeltatimezone)PathzX/Users/bjornvanwieringen/Library/CloudStorage/Dropbox-i4fuel/i4fuel team folder/Pipelinez	i4fuel.dbzdashboard.htmlACTIVECLOSEDzg/Users/bjornvanwieringen/Library/CloudStorage/Dropbox-i4fuel/i4fuel team folder/Petrol trade/Blacklistscachezofac_sdn.csvz/https://www.treasury.gov/ofac/downloads/sdn.csvInquiryzMandate / LOIzOffer (ICPO/FCO)zContract (SPA)zVerification / POPPaymentzCommission settlementClosedi4fuelnamez	i4Fuel BVkvk97064874	hertsbergzHertsberg Ventures BV82687978glayazGlaya Holding BV82618464EN590zEN590 10ppm DieselJA1zJet Fuel A1D6zD6 Virgin Fuel OilCRUDEz	Crude OilLNGSUGARzBrazil Sugar ICUMSA 45SBOzCrude Soybean OilSFOLzSunflower OilBITUMBitumenCHEM	ChemicalsLUBE
Lubricantsa  
CREATE TABLE IF NOT EXISTS companies (
    id                       INTEGER PRIMARY KEY AUTOINCREMENT,
    name                     TEXT NOT NULL,
    name_normalized          TEXT NOT NULL,
    country                  TEXT,
    registration_no          TEXT,
    address                  TEXT,
    website                  TEXT,
    email                    TEXT,
    phone                    TEXT,
    trust_level              TEXT NOT NULL DEFAULT 'unknown',
    dd_status                TEXT NOT NULL DEFAULT 'not_checked',
    dd_score                 TEXT,
    dd_report_path           TEXT,
    dd_checked_at            TEXT,
    ofac_status              TEXT NOT NULL DEFAULT 'not_checked',
    ofac_checked_at          TEXT,
    ofac_hit_details         TEXT,
    blacklist_folder_match   TEXT,
    notes                    TEXT,
    created_at               TEXT NOT NULL,
    updated_at               TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_companies_normalized ON companies(name_normalized);
CREATE INDEX IF NOT EXISTS idx_companies_trust ON companies(trust_level);
CREATE INDEX IF NOT EXISTS idx_companies_dd ON companies(dd_status);

CREATE TABLE IF NOT EXISTS contacts (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    company_id   INTEGER REFERENCES companies(id) ON DELETE CASCADE,
    name         TEXT NOT NULL,
    email        TEXT,
    phone        TEXT,
    title        TEXT,
    passport_no  TEXT,
    nationality  TEXT,
    notes        TEXT,
    created_at   TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_contacts_company ON contacts(company_id);

CREATE TABLE IF NOT EXISTS inquiries (
    id                 INTEGER PRIMARY KEY AUTOINCREMENT,
    direction          TEXT NOT NULL,
    type               TEXT NOT NULL,
    channel            TEXT NOT NULL,
    company_id         INTEGER REFERENCES companies(id) ON DELETE SET NULL,
    contact_id         INTEGER REFERENCES contacts(id) ON DELETE SET NULL,
    raw_company_name   TEXT,
    raw_contact        TEXT,
    commodity_code     TEXT,
    volume_mt          REAL,
    monthly_mt         REAL,
    price_usd          REAL,
    price_unit         TEXT,
    incoterm           TEXT,
    origin             TEXT,
    port               TEXT,
    payment_terms      TEXT,
    received_at        TEXT,
    status             TEXT NOT NULL DEFAULT 'open',
    rejection_reason   TEXT,
    deal_id            TEXT REFERENCES deals(id) ON DELETE SET NULL,
    next_action        TEXT,
    notes              TEXT,
    created_at         TEXT NOT NULL,
    updated_at         TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_inquiries_status ON inquiries(status);
CREATE INDEX IF NOT EXISTS idx_inquiries_company ON inquiries(company_id);

CREATE TABLE IF NOT EXISTS incidents (
    id                 INTEGER PRIMARY KEY AUTOINCREMENT,
    company_id         INTEGER NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
    date               TEXT NOT NULL,
    type               TEXT NOT NULL,
    description        TEXT,
    related_inquiry_id INTEGER REFERENCES inquiries(id) ON DELETE SET NULL,
    related_deal_id    TEXT REFERENCES deals(id) ON DELETE SET NULL,
    created_at         TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_incidents_company ON incidents(company_id);

CREATE TABLE IF NOT EXISTS deals (
    id                       TEXT PRIMARY KEY,
    commodity_code           TEXT NOT NULL,
    commodity                TEXT NOT NULL,
    counterparty_company_id  INTEGER REFERENCES companies(id) ON DELETE SET NULL,
    counterparty_name        TEXT NOT NULL,
    our_role                 TEXT NOT NULL,
    our_entity               TEXT NOT NULL,
    stage                    INTEGER NOT NULL DEFAULT 1,
    volume_mt                REAL,
    monthly_mt               REAL,
    price_usd                REAL,
    price_unit               TEXT,
    incoterm                 TEXT,
    port                     TEXT,
    origin                   TEXT,
    payment_terms            TEXT,
    folder_path              TEXT,
    inquiry_id               INTEGER REFERENCES inquiries(id) ON DELETE SET NULL,
    notes                    TEXT,
    created_at               TEXT NOT NULL,
    updated_at               TEXT NOT NULL,
    closed_at                TEXT
);
CREATE INDEX IF NOT EXISTS idx_deals_stage ON deals(stage);
CREATE INDEX IF NOT EXISTS idx_deals_company ON deals(counterparty_company_id);

CREATE TABLE IF NOT EXISTS deal_parties (
    id                INTEGER PRIMARY KEY AUTOINCREMENT,
    deal_id           TEXT NOT NULL REFERENCES deals(id) ON DELETE CASCADE,
    company_id        INTEGER NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
    contact_id        INTEGER REFERENCES contacts(id) ON DELETE SET NULL,
    role              TEXT NOT NULL,
    bank_name         TEXT,
    bank_iban         TEXT,
    bank_swift        TEXT,
    bank_account_name TEXT,
    notes             TEXT,
    created_at        TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_dealparties_deal ON deal_parties(deal_id);
CREATE INDEX IF NOT EXISTS idx_dealparties_company ON deal_parties(company_id);

CREATE TABLE IF NOT EXISTS commissions (
    id                INTEGER PRIMARY KEY AUTOINCREMENT,
    deal_id           TEXT NOT NULL REFERENCES deals(id) ON DELETE CASCADE,
    deal_party_id     INTEGER NOT NULL REFERENCES deal_parties(id) ON DELETE CASCADE,
    amount_per_unit   REAL NOT NULL,
    unit              TEXT NOT NULL,
    total_amount      REAL,
    paid              INTEGER NOT NULL DEFAULT 0,
    paid_at           TEXT,
    notes             TEXT,
    created_at        TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_commissions_deal ON commissions(deal_id);

CREATE TABLE IF NOT EXISTS documents (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    deal_id     TEXT REFERENCES deals(id) ON DELETE CASCADE,
    inquiry_id  INTEGER REFERENCES inquiries(id) ON DELETE CASCADE,
    doc_type    TEXT NOT NULL,
    stage       INTEGER,
    filename    TEXT,
    filepath    TEXT,
    signed      INTEGER NOT NULL DEFAULT 0,
    sent_at     TEXT,
    received_at TEXT,
    notes       TEXT,
    created_at  TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_documents_deal ON documents(deal_id);

CREATE TABLE IF NOT EXISTS comms_log (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    deal_id     TEXT REFERENCES deals(id) ON DELETE CASCADE,
    inquiry_id  INTEGER REFERENCES inquiries(id) ON DELETE CASCADE,
    company_id  INTEGER REFERENCES companies(id) ON DELETE SET NULL,
    contact_id  INTEGER REFERENCES contacts(id) ON DELETE SET NULL,
    direction   TEXT NOT NULL,
    channel     TEXT NOT NULL,
    subject     TEXT,
    summary     TEXT,
    timestamp   TEXT NOT NULL,
    created_at  TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_commslog_deal ON comms_log(deal_id);
CREATE INDEX IF NOT EXISTS idx_commslog_inquiry ON comms_log(inquiry_id);

CREATE TABLE IF NOT EXISTS stage_history (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    deal_id     TEXT NOT NULL REFERENCES deals(id) ON DELETE CASCADE,
    from_stage  INTEGER,
    to_stage    INTEGER NOT NULL,
    changed_at  TEXT NOT NULL,
    notes       TEXT
);
c                      \         P                  ! \        4      p \         P                  V n        V P                  R 4       V # )zPRAGMA foreign_keys = ON)sqlite3connectDB_PATHRowrow_factoryexecuteconns    B/Users/bjornvanwieringen/BJVRN/scripts/i4fuel-pipeline/pipeline.pydbr,   
  s.    ??7#D{{DLL+,K    c                  @   \         P                  R R R7       \        P                  R R7       \        P                  R R7       \        P                  R R7       \        4       ;_uu_ 4       p V P                  \        4       RRR4       R#   + '       g   i     R# ; i)Tparentsexist_okr1   N)DROPBOX_ROOTmkdir
ACTIVE_DIR
CLOSED_DIR	CACHE_DIRr,   executescriptSCHEMAr)   s    r+   init_dbr:     sh    td3d#d#OOTO"	6" 
s   ,BB	c                  j    \         P                  ! \        P                  4      P	                  R R7      # )seconds)timespec)r   nowr   utc	isoformat r-   r+   r>   r>     s#    <<%///CCr-   c                 F    V '       g   R # R P                  R V  4       4      # ) c              3   p   "   T F,  qP                  4       '       g   K  VP                  4       x  K.  	  R # 5iN)isalnumlower.0cs   & r+   	<genexpr>normalize.<locals>.<genexpr>"  s      7a99;917799as   66)joinss   &r+   	normalizerP     s    777a777r-   c                 R   Rp \         P                  4       '       dd   \        P                  ! 4       \        P                  ! \         P                  4       P                  4      ,
          pVP                  \        8  d   Rp V '       d    \        RRRR7       \        P                  P                  \        RR/R7      p\        P                  P                  V^R	7      ;_uu_ 4       pVP                  4       pR
R
R
4       \         P!                  X4       \        R\#        V4      R,           R24       \         P                  4       # \         P                  4       #   + '       g   i     Ll; i  \$         d-   p\        RT R24        R
p?\         P                  4       # R
p?ii ; i)zBDownload OFAC SDN list if missing or older than OFAC_REFRESH_DAYS.TFz  fetching OFAC SDN list... )endflushz
User-Agentzi4fuel-pipeline/2)headers)timeoutNzok (i   z kB)zfailed (z!); using stale cache if available)
OFAC_CACHEexistsr   r>   fromtimestampstatst_mtimedaysOFAC_REFRESH_DAYSprinturllibrequestRequestOFAC_URLurlopenreadwrite_byteslen	Exception)needs_refreshagereqrdataes         r+   ensure_ofac_cachern   %  s8   Mllnx55joo6G6P6PQQ88''!M	C/cF..((LJ];^(_C''R'88Avvx 9""4(DTD)./ : 98  	CHQC@ABB	Cs1   	AE/ 'E8<E/ E,	'E/ /F&:F!!F&c                   \        4       '       g   R# \        V 4      p\        V4      ^8  d   R	# . p\        \        RRR7      ;_uu_ 4       p\
        P                  ! V4      pV F  p\        V4      ^8  d   K  V^,          P                  4       P                  R4      p\        V4      '       d6   V\        V4      9   d&   VP                  V4       \        V4      ^8  d    M`K  \        V4      '       g   K  \        V4      ^8  g   K  \        V4      V9   g   K  VP                  V4       \        V4      ^8  g   K   M	  RRR4       V'       d   RRP                  V4      3# R
#   + '       g   i     L-; i)zASubstring match against OFAC SDN list. Returns (status, details).zutf-8replace)encodingerrors"Nhitz | )not_checkedzOFAC list unavailable)ru   zName too short for safe match)clearN)
rn   rP   rf   openrW   csvreaderstripappendrM   )company_nametargethitsfry   rowsdn_names   &      r+   
ofac_checkr   9  s!   77|$F
6{Q??D	j79	=	=AC3x!|1v||~++C0H""v81D'DH%t9> "8$$X):y?RV\?\H%t9>  
> uzz$'((! 
>	=s%   B(E)9E)E)E) E))E9	c                `   \         P                  4       '       g   R# \        V 4      p\        V4      ^8  d   R# \         P	                  4        F\  pVP                  4       '       g   K  VP                  p\        V4      pV'       d   \        V4      ^8  d   KL  W9   g	   WA9   g   KZ  Vu # 	  R# )zUSubstring match against local blacklist folder names. Returns matched folder or None.N)LOCAL_BLACKLIST_DIRrX   rP   rf   iterdiris_dirr   )r|   r}   entryfolderns   &    r+   blacklist_folder_checkr   T  s    %%''|$F
6{Q$,,.||~~fCFQJ;!+M / r-   c                 x    Ve   RV R2MRpV'       d   VRRP                  V4       R2,          p\        V  V R24      P                  4       pV'       g   Ve   V# V'       g   V'       g   R# V'       g   V'       d   \        R	4       K  V'       d&   WS9  d    \        R
RP                  V4       24       K  V# )TNz []rC    (/): z  required.z  must be one of: , )rM   inputrz   r^   )labeldefaultrequiredoptionssuffixvals   &&&&  r+   promptr   h  s    
$+$72gYaR388G,-Q//FugfXR()//1w*N8x- s)&tyy'9&:;<
r-   c                 |     \        WVR7      pVf   R#  \        V4      #   \         d    \        R4        K9  i ; i)Tr   r   Nz  must be a number.)r   float
ValueErrorr^   r   r   r   r   s   &&& r+   prompt_floatr   {  s@    
Uh?;	): 	)'(	)   
! ;;c                 |     \        WVR7      pVf   R#  \        V4      #   \         d    \        R4        K9  i ; i)Tr   Nz  must be an integer.)r   intr   r^   r   s   &&& r+   
prompt_intr     s?    
Uh?;	+s8O 	+)*	+r   c                 ^    R P                  R V  4       4      P                  R4      R,          # )rC   c              3   T   "   T F  qP                  4       '       d   TMR x  K   	  R# 5i)-N)rF   rH   s   & r+   rK   slug.<locals>.<genexpr>  s     ;d		1,ds   &(r   N   N)rM   rz   )texts   &r+   slugr     s'    77;d;;AA#FsKKr-   c           	      
   \         P                  ! 4       P                  p\        4       ;_uu_ 4       pVP	                  R V RV  R234      P                  4       pRRR4       XR,          ^,           #   + '       g   i     L ; i)z/SELECT COUNT(*) AS n FROM deals WHERE id LIKE ?z-%-z-%Nr   )r   r>   yearr,   r(   fetchone)commodity_coder   r*   r   s   &   r+   next_deal_seqr     sj    <<>D	ll=vS(+-
 (* 	 

 s8a< 
s   (A22B	c           	          \         P                  ! 4       P                  p\        V 4      pV R VR R V  R \	        V4      P                  4       R,           2# )r   02dN
   N)r   r>   r   r   r   upper)r   counterpartyr   seqs   &&  r+   make_deal_idr     sQ    <<>D

'CV1SIQ~.a\0B0H0H0J30O/PQQr-   c                     V  R \        V4       R \        V4       2p\        V,          pVP                  RRR7       \         F  pWE,          P                  RR7       K  	  V# )_Tr/   r2   )r   r5   r4   DEAL_SUBFOLDERS)deal_id	commodityr   r   r   subs   &&&   r+   create_deal_foldersr     s_    YaY($|*<)=>D$F
LLL-	d+ Mr-   c                     \        V 4      p\        4       ;_uu_ 4       pVP                  R V34      P                  4       pRRR4       V#   + '       g   i     X# ; i)z1SELECT * FROM companies WHERE name_normalized = ?N)rP   r,   r(   r   )r   r   r*   r   s   &   r+   find_company_by_namer     sI    $A	llNQRPTU^^` 
J 
Js   "A

A	c                <   . p\        4       p	\        V 4      p
\        V 4      w  rVR8w  d   T	MRpRpV
'       g   VR8X  d:   RpV
'       d   VP                  RV
 24       VR8X  d   VP                  RV 24       \	        4       ;_uu_ 4       pVP                  RV \        V 4      WW4WVWWWW34      pVP                  pV
'       d   VP                  R	VV	R
RV
 2V	34       VR8X  d   VP                  R	VV	RW34       RRR4       VV3#   + '       g   i     XT3# ; i)zOCreate company and run blacklist + OFAC checks. Returns (company_id, warnings).ru   Nunknownrt   blacklistedzBLACKLIST FOLDER MATCH: z
OFAC HIT: a1  INSERT INTO companies (name, name_normalized, country, registration_no,
               address, website, email, phone, trust_level, ofac_status, ofac_checked_at,
               ofac_hit_details, blacklist_folder_match, notes, created_at, updated_at)
               VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)ZINSERT INTO incidents (company_id, date, type, description, created_at) VALUES (?,?,?,?,?)blacklist_hitzFolder match: ofac_hit)r>   r   r   r{   r,   r(   rP   	lastrowid)r   countryregistration_noaddresswebsiteemailphonenoteswarningstsbl_matchofac_statusofac_detailsofac_tstrust_levelr*   curcids   &&&&&&&&          r+   create_company_with_checksr     s4    H	B%d+H *4 0K=0bdGK;%'#OO6xjAB%OOj78	ll; 9T?GgPUwhrW
 mmLLlb/^H:+FK %LLlb*l7# 
* =+ 
* =s   A0DD	c                    \        R24       \        R4       \        R24       \        RRRR.R7      p\        RR\        R7      p\        RR. R3OR7      p\        R	RR
7      p\        V4      pRp. pV'       d5   VR,          p\        RVR,           RVR,           RVR,           R24       M\        R4       \        R4      p\        R4      p	\        R4      p
\        R4      p\        R4      p\        R4      p\	        WHWWV4      w  rgV F  p\        RV 24       K  	  V'       d   \        R4       \        R4      p\        R4       \        R\        \        P                  4       4      R7      p\        R 4      p\        R!4      p\        R"4      p\        R#R$R%7      p\        R&4      p\        R'4      p\        R(4      p\        R)R*R%7      p\        R+4      p\        R,4      p\        4       p\        4       ;_uu_ 4       pVP                  R-WW6WOVVVVVVVVVVR.VVVV34      pVP                  pRRR4       \        R/X R024       V'       d   \        R14       \        4        R#   + '       g   i     L>; i)4=zNew inquiry	DirectionTinboundoutboundr   r   TypeChannelzCounterparty company namer   Nidu"     → linked to existing company #	 (trust: r   , DD: 	dd_statusr   u4     company not in DB — creating with auto-checks...z	  Countryz  Registration / KVK noz	  Addressz	  Websitez  Company emailz  Phone     ⚠ uU     → company created as 'blacklisted'. Override with: pipeline.py company trust <id>uG   Contact person (name only — add full contact later via 'contact new')z)
Deal terms (as proposed in the inquiry):z  Commodity code)r   z  Volume MTz  Monthly MTz  Price USDz  Price unitMTr   z
  Incotermz  Originz  Portz  Payment termsMT103/TTzNext actionNotesap  INSERT INTO inquiries (direction, type, channel, company_id, raw_company_name,
               raw_contact, commodity_code, volume_mt, monthly_mt, price_usd, price_unit,
               incoterm, origin, port, payment_terms, received_at, status, next_action,
               notes, created_at, updated_at)
               VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)rw   u   
✓ Inquiry #z logged.uJ     ⚠ Counterparty has blacklist/OFAC flags — review before progressing.<============================================================)r   teamswhatsappr   broker)r^   r   INQUIRY_TYPESr   r   listCOMMODITY_CODESkeysr   r>   r,   r(   r   regenerate_dashboard)args	directioninq_typechannelr|   existing
company_idr   r   regaddrwebr   r   wcontact_rawr   	volume_mt
monthly_mt	price_usd
price_unitincotermoriginportpayment_termsnext_actionr   r   r*   r   iids   &                              r+   cmd_inquiry_newr
    sj   	(O	-	(O{TIz;RSIft]CHYNPG 5EL#L1HJHd^
28D>2B)HUbLcKddjkst  lA  kB  BC  D  	EDE%./k"[!()y!93c% 

 AF1#, ijbcK	
67._=Q=Q=S8TUN]+In-J]+I5Jl#HJF(D,jAM'K7OE	B	llE
 '|Y
Izvt]BB

 mm 
 
OC5
)*Z[# 
s   ?1I&&I6	c                    V P                   '       g   R MRp\        4       ;_uu_ 4       pVP                  RV R24      P                  4       pRRR4       X'       g   \	        R4       R# \	        RRR R	R
R RRR RRR RRR RRR RRR RRR 24       \	        R!4       V F  p\	        VR,          R R	VR,          R RVR,          R RVR,          R RVR,          ;'       g    RR RVR,          ;'       g    RR,          R RVR,          ;'       g    RR RVR ,          ;'       g    RR 24       K  	  R#   + '       g   i     L; i)"zWHERE status = 'open'rC   zSELECT i.*, c.trust_level, c.dd_status FROM inquiries i
               LEFT JOIN companies c ON c.id = i.company_id
               z ORDER BY created_at DESCNzNo inquiries.
ID>4s  Dir8srR   r   6sStatus12s	CommodityCounterparty28sTrustDDr   >4dr   typestatusr      —raw_company_name:N   Nr   r   zn--------------------------------------------------------------------------------------------------------------)allr,   r(   fetchallr^   )r   wherer*   rowsrk   s   &    r+   cmd_inquiry_listr$  #  sl   +/888#E	||w/3
 (*	 	 
 o	BtCj5*AfR[(3qQ~c2!GC=$sM N	)4R+r2!AfIb>1X;sBSST$%..4Aq9K7L7R7RPRTW6XY\5]]^M"++eS1AkN4K4KeS2QS 	T  
s   $D<<E	c                 x   \        4       ;_uu_ 4       pVP                  R V P                  34      P                  4       pRRR4       X'       g0   \	        RV P                   R24       \
        P                  ! ^4       \	        RR; RVR,           RR; 24       \	        RVR,           24       \	        R	VR
,           24       \	        RVR,           24       \	        RVR,           24       \	        RVR,          ;'       g
    VR,           RVR,          ;'       g    R R24       \	        RVR,          ;'       g    R RVR,          ;'       g    R 24       \	        RVR,          ;'       g    R 24       \	        RVR,          ;'       g    R 24       \	        RVR ,          ;'       g    R R!VR",          ;'       g    R R#24       \	        R$VR%,          ;'       g    R R&VR',          ;'       g    R 24       \	        R(VR),          ;'       g    R 24       \	        R*VR+,          ;'       g    R R,VR-,          ;'       g    R 24       \	        R.VR/,          ;'       g    R 24       \	        R0VR1,          '       d   VR1,          R2,          MR 24       \	        R3VR4,          ;'       g    R 24       \	        R5VR6,          ;'       g    R 24       VR7,          '       d   \	        R8VR7,           24       VR9,          '       d   \	        R:VR9,           24       R# R#   + '       g   i     EL; i)<zSELECT i.*, c.trust_level, c.dd_status, c.name AS company_name
               FROM inquiries i LEFT JOIN companies c ON c.id = i.company_id
               WHERE i.id = ?NInquiry  not found.r  z
  Inquiry #r   z  Direction:    r   z  Type:         r  z  Channel:      r   z  Status:       r  z  Company:      r|   r   (#r   ?r   z  Trust / DD:   r   r   / r   z  Contact:      raw_contactz  Commodity:    r   z  Volume:       r    MT (monthly r  z MT)z  Price:        r   USD/r  z  Incoterm:     r  z  Origin/Port:  r      → r  z  Payment:      r  z  Received:     received_atN   Nz  Next action:  r  z  Deal ID:      r   rejection_reasonz  Rejection:    r   z  Notes:        F======================================================================)r,   r(   r   r   r^   sysexit)r   r*   rk   s   &  r+   cmd_inquiry_showr6  7  s   	LL!#'77*
 (*	 	
 
 	-.	BxjagYb

;<	Q{^,
-.	QvYK
()	Qy\N
+,	Qx[M
*+	Q~.GG!4F2GHAlOLbLb_bKccd
ef	Q}-667s1[>;R;RU:S
TU	Q}-667
89	Q/099E:
;<	Q{^44u5]1\?C[C[V[B\\`
ab	Q{^44u5U1\?;S;Se:T
UV	Qz]33e4
56	Qx[11E2%&	8J8JU7K
LM	Q/8859
:;	a6F6FQ}-c2ER
ST	Q}-667
89	Qy\22U3
45	 #5!6 789zz 7-. 9 
s   ,L((L9	c                    \        4       ;_uu_ 4       pVP                  R V P                  34      P                  4       pV'       g0   \	        RV P                   R24       \
        P                  ! ^4       VR,          R8X  d-   \	        RVR,           R24       \
        P                  ! ^4       VR,          '       g"   \	        R	4       \
        P                  ! ^4       VP                  R
VR,          34      P                  4       pRRR4       \	        RXR,           R24       \	        RXR,           RVR,           RVR,           R24       VR,          R89   dU   V P                  '       g-   \	        RVR,           R24       \
        P                  ! ^4       \	        RVR,           R24       VR,          R8w  dJ   V P                  '       g-   \	        RVR,           R24       \
        P                  ! ^4       \	        R4       \        RR. R9OR"7      p\        R#R$\        \        P                  4       4      R%7      pVR&,          ;'       g*    \        R'R\        \        P                  4       4      R"7      p\        V,          p\        R(4      p\        WcR,          4      p	\        WVR,          4      p
\        4       p\        4       ;_uu_ 4       pVP                  R)WWsR,          VR,          WEVR*,          VR+,          VR,,          VR-,          VR.,          VR/,          VR0,          VR1,          \!        V
4      VR,          VW34       VR 8X  d   R!MR pVP                  R2WR,          W34       VP                  R3V	R^VR4VR,           234       VP                  R5WVR,          34       RRR4       \	        R6V	 24       \	        R7V
 24       \#        4        R#   + '       g   i     EL; i  + '       g   i     LL; i):$SELECT * FROM inquiries WHERE id = ?r&  r'  r  	convertedz"Inquiry already converted to deal r   .r   zGInquiry has no linked company. Link one first: pipeline.py inquiry link$SELECT * FROM companies WHERE id = ?NzConverting inquiry #r   z	 to deal.zCounterparty: r   r   r   r   r   r   u   ⚠ Counterparty is z. Use --force to override.u   ⚠ Proceeding despite z flag.passedu   ⚠ DD status is 'z'. Run DD first or use --force.u!   ⚠ Proceeding without passed DD.Our roleTbuyersellerr   
Our entityr   r   r   r   Commodity codez.Notes (optional, in addition to inquiry notes)av  INSERT INTO deals (id, commodity_code, commodity, counterparty_company_id,
               counterparty_name, our_role, our_entity, stage, volume_mt, monthly_mt,
               price_usd, price_unit, incoterm, port, origin, payment_terms,
               folder_path, inquiry_id, notes, created_at, updated_at)
               VALUES (?,?,?,?,?,?,?,1,?,?,?,?,?,?,?,?,?,?,?,?,?)r   r  r  r  r  r  r  r  z`INSERT INTO deal_parties (deal_id, company_id, role, created_at)
               VALUES (?,?,?,?)_INSERT INTO stage_history (deal_id, from_stage, to_stage, changed_at, notes) VALUES (?,?,?,?,?)zConverted from inquiry #zSUPDATE inquiries SET status = 'converted', deal_id = ?, updated_at = ? WHERE id = ?u   
✓ Converted to deal 
  Folder: scammerr   r>  r?  intermediary)r,   r(   r   r   r^   r4  r5  forcer   r   ENTITIESr   r   r   r   r>   strr   )r   r*   inqcompanyour_role
our_entityr   r   r   r   r   r   counterparty_roles   &            r+   cmd_inquiry_convertrQ  X  sl   	llADGG:NWWYHTWWI[12HHQKx=K'6s9~6FaHIHHQK<  [\HHQK,,ELHYG[\eeg 
 
 T9
56	N76?+9W]5K4LFSZ[fSgRhhi
jk}!;;zzz()?(@@Z[\HHQK'(>'?vFG{x'zzz&w{';&<<[\]HHQK13j49\]Hk4CXYJ)* \ \f5EPT>B?CWCWCY>Z/\N/ICDE>6?;G WV_EF	B	E
 i3{#3S5Fs<0#j/3v;]C0#f+s4y%		
 )1G(;H#dm%6;	

 	mdAr%=c$i[#IJ	
 	a#d)$	
1 
: 
$WI
./	Jvh
 M 
N 
s    B+O ?A	O CO4 O1	4P	c                 X   V P                   ;'       g    \        R RR7      p\        RRRR.R7      R8H  pRpV'       d2   \        RR	P                  \        4      4       \        R
R\        R7      p\        4       p\        4       ;_uu_ 4       pVP                  RV P                  34      P                  4       pV'       g0   \        RV P                   R24       \        P                  ! ^4       VP                  RWV P                  34       V'       dX   VR,          '       dI   VP                  RVR,          WCWP                  V34       VR9   d   VP                  RWFR,          34       RRR4       \        RV P                   R24       \        4        R#   + '       g   i     L5; i)zRejection reasonTr   z,Log as incident on company? (scam/fake/etc.)r   yrA  NzIncident types:r   zIncident typer   r8  r&  r'  z[UPDATE inquiries SET status = 'rejected', rejection_reason = ?, updated_at = ? WHERE id = ?r   zINSERT INTO incidents (company_id, date, type, description,
                   related_inquiry_id, created_at) VALUES (?,?,?,?,?,?)zeUPDATE companies SET trust_level = 'suspect', updated_at = ? WHERE id = ? AND trust_level = 'unknown'   ✓ Inquiry #z
 rejected.)scam_attempt
fake_offerpayment_default)reasonr   r^   rM   INCIDENT_TYPESr>   r,   r(   r   r   r4  r5  r   )r   rX  log_incidentincident_typer   r*   rL  s   &      r+   cmd_inquiry_rejectr\    sU   [[EEF#5EFHRU`ceh_ijnqqLM>!:;~V	B	llADGG:NWWYHTWWI[12HHQKi!	
 C--LLK\"BvwwK  QQ{\*+# 
* 
M$''*
-.- 
s   BF$AFF)	c           	     F   \        4       ;_uu_ 4       pVP                  RV P                  34      P                  4       pVP                  RV P                  34      P                  4       pV'       d	   V'       g"   \        R4       \        P                  ! ^4       VP                  RV P                  \        4       V P                  34       RRR4       \        RV P                   RV P                   RXR	,           R
24       \        4        R#   + '       g   i     LL; i)z!Link inquiry to existing company.r8  r;  zInquiry or company not found.z@UPDATE inquiries SET company_id = ?, updated_at = ? WHERE id = ?NrT  z linked to company #r   r   z).)
r,   r(   r   r   r   r^   r4  r5  r>   r   )r   r*   rL  rM  s   &   r+   cmd_inquiry_linkr^    s    	llADGG:NWWY,,EGYZcce'12HHQKN__ceTWW-	
 
 
M$''"6t6Gr'RX/IZZ\
]^ 
s   A&D:ADD 	c           
      H   \        R4       \        R4       \        R4       \        RRR7      p\        V4      pV'       d6   \        RVR,           RVR,           24       \        P                  ! ^4       \        R	4      p\        R
4      p\        R4      p\        R4      p\        R4      p\        R4      p\        R4      p	\        R4       \        WWEWgW4      w  rV F  p\        RV 24       K  	  \        RV
 R24       V'       d   \        R4       \        4        R# )r   zNew companyzCompany nameTr   u   ⚠ Company already exists: #r   rR   r   CountryzRegistration / KVK noAddressWebsiteEmailPhoner   z#
Running blacklist + OFAC checks...r   u   
✓ Company #z	 created.uF     → trust_level set to 'blacklisted'. Review and override if needed.Nr   )r^   r   r   r4  r5  r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   s   &            r+   cmd_company_newre    s    	(O	-	(O.40D#D)H-htn-=Qx?O>PQRYG
(
)C)D

C7OE7OE7OE	
01.tcUZbMCqcl 	OC5	
*+VXr-   c                    V P                   '       d   R pMV P                  '       d   RpMRp\        4       ;_uu_ 4       pVP                  RV R24      P	                  4       pRRR4       X'       g   \        R4       R# \        RRR	 R
RR RRR RRR RRR RRR RRR 24       \        R"4       V F~  pVR,          '       d   RMRp\        VR,          R R
VR,          R,          R RVR,          ;'       g    RR,          R RVR,          R RVR ,          R RVR!,          R RVR 24       K  	  R#   + '       g   i     L; i)#z<WHERE dd_status IN ('not_checked', 'in_progress', 'flagged')z:WHERE trust_level IN ('suspect', 'scammer', 'blacklisted')rC   zSELECT * FROM companies  ORDER BY updated_at DESCNzNo companies.r  r  r  r  Name30srR   r`  r  r  r  OFAC10sBL5sblacklist_folder_match   ✓r   r  r   r   r   r  :N   Nr   r   r   z_-----------------------------------------------------------------------------------------------)needs_ddflaggedr,   r(   r!  r^   )r   r"  r*   r#  rk   bls   &     r+   cmd_company_listrt    sU   }}}N	L	||&ug-FG

(* 	 
 o	BtCj6#,a	#a}Ad3ZqQWX[P\\]^bce]f
gh	(O011Ur4R&	#s31a	l6K6KeS5QRU4VVW=!#&a+s';1Q}=Mc<RRSTVWYSZ\ 	]  
s   $D88E	c                 	   \        4       ;_uu_ 4       pVP                  R V P                  34      P                  4       pV'       g0   \	        RV P                   R24       \
        P                  ! ^4       VP                  RV P                  34      P                  4       pVP                  RV P                  34      P                  4       pVP                  RV P                  V P                  34      P                  4       pVP                  RV P                  34      P                  4       pRRR4       \	        RRM R	XR
,           RVR,           RRM 24       \	        RVR,          ;'       g    R 24       \	        RVR,          ;'       g    R 24       \	        RVR,          ;'       g    R 24       \	        RVR,          ;'       g    R RVR,          ;'       g    R 24       \	        RVR,          ;'       g    R 24       \	        RVR,           24       \	        RVR,           RVR,          ;'       g    R R 24       \	        R!VR",          ;'       g    R 24       \	        R#VR$,          ;'       g    R 24       \	        R%VR&,           R'VR(,          '       d   R)VR(,           R 2MR* 24       \	        R+VR,,          ;'       g    R- 24       VR.,          '       d   \	        R/VR.,           24       \	        R0\        X4       R124       V FM  p\	        R2VR
,          R3 R4VR,          R5 R'VR6,          ;'       g    R*R7 R'VR,          ;'       g    R* 24       KO  	  \	        R8\        X4       R124       V FE  p\	        R9VR:,          R;,           R'VR<,          R= R'VR>,          ;'       g    R*R?,           24       KG  	  \	        R@\        X4       R124       V F-  p	\	        R9V	R
,          RA RBV	RC,           RDV	RE,           24       K/  	  \	        RF\        X4       R124       V FC  p\	        RGVR
,          RH RDVRI,          RJ R'VR<,          RK R'VRL,          ;'       g    R 24       KE  	  R#   + '       g   i     ELU; i)Nr;  Company r'  z+SELECT * FROM contacts WHERE company_id = ?z?SELECT * FROM incidents WHERE company_id = ? ORDER BY date DESCzSELECT id, stage, commodity FROM deals WHERE counterparty_company_id = ? OR id IN (SELECT deal_id FROM deal_parties WHERE company_id = ?)zKSELECT id, status, type, commodity_code FROM inquiries WHERE company_id = ?Nr  z
  Company #r   r   r   z  Country:        r   r  z  Registration:   r   z  Address:        r   z  Website / Mail: r   r*  r   z  Phone:          r   z  Trust level:    r   z  DD status:      r   z	 (score: dd_scorer   z  DD report:      dd_report_pathz  DD checked at:  dd_checked_atz  OFAC status:    r   rR   ofac_hit_details(rC   z  Blacklist:      rn  no matchr   z  Notes:          z
  Contacts ():    [3d] 25stitle20sz
  Incidents (    dater   r  18sdescription:N<   Nz

  Deals (ri  z stage stager  r   z
  Inquiries (z    #z>3dr  r  r  r   r3  )	r,   r(   r   r   r^   r4  r5  r!  rf   )
r   r*   rJ   contacts	incidentsdeals	inquiriesctids
   &         r+   cmd_company_showr    sE   	LL?$''LUUWHTWWI[12HHQK<<9DGG:

(* 	 LLMPTPWPWz

(* 	  XWWdgg
 (* 	 LLY\`\c\c[e

(* 	 
& 
BxjagYb62hZ
HI	q|44u5
67	q!23<<u=
>?	q|44u5
67	q|44u5S79L9Lu8M
NO	qz22U3
45	q/0
12	q~.i*8N8N7Oq
QR	q!12;;e<
=>	q1::U;
<=	q/0RSTfRgRgAa8J6K5LA2Nmo1p
qr	q!9:HHjI
JKzz"1W:,/0	N3x=/
,-bhr]"RZ$4Abk6G6GR5LAbQXkN_N_]_M`ab  
OC	N+2
./QvYs^$Aai_Aq7G7M7M2s6S5TUV  
KE
|2
&'QtWSM7Bq~6FGH  
OC	N+2
./agc]"Qx[$5QqynAaHXFYFbFb]bEcde _ 
s   DQ99R
	c                2   \        4       ;_uu_ 4       pVP                  RV P                  34      P                  4       pV'       g0   \	        RV P                   R24       \
        P                  ! ^4       RRR4       \	        RXR,           24       \        RR\        R	7      pRpVR9   d   \        R
R. ROR	7      p\        R4      p\        RR\        R.,           R7      p\        4       p\        4       ;_uu_ 4       pVP                  RW4WWWpP                  34       VR8w  d   VP                  RW`P                  34       RRR4       \	        RT RT;'       g    R 24       \        4        R#   + '       g   i     EL; i  + '       g   i     LK; i)z/Update DD status after running /supplier-check.r;  rv  r'  NzDD update for: r   z	DD statusTr   zDD scorez DD report file path (in Dropbox)zUpdate trust level?norA  zUPDATE companies SET dd_status = ?, dd_score = ?, dd_report_path = ?,
               dd_checked_at = ?, updated_at = ? WHERE id = ?z1UPDATE companies SET trust_level = ? WHERE id = ?u   ✓ DD updated: z, score=r  )r<  failedrr  )lowmediumhigh)r,   r(   r   r   r^   r4  r5  r   DD_STATUSESTRUST_LEVELSr>   r   )r   r*   rJ   r  scorereporttrustr   s   &       r+   cmd_company_checkr  9  sB   	LL?$''LUUWHTWWI[12HHQK	 

 
OAfI;
'(K$DFE00zD:ST67F($PTv@UVE	B	AFGG4	

 D=LLLuV]V]N^_ 
 
VHHU^^e,<
=>- 
 
s   A#E2?AF2F	F	c                F   V P                   ;'       g    \        RR\        R7      p\        4       ;_uu_ 4       pVP	                  RV\        4       V P                  34       RRR4       \        RV P                   RV 24       \        4        R#   + '       g   i     L7; i)zSet trust level directly.zTrust levelTr   zAUPDATE companies SET trust_level = ?, updated_at = ? WHERE id = ?Nu   ✓ Company #u    trust level → )	levelr   r  r,   r(   r>   r   r^   r   )r   r  r*   s   &  r+   cmd_company_trustr  T  ss    JJTT&|TE	OCE477#	
 

 
M$''"3E7
;< 
s   (BB 	c           
        \        4       ;_uu_ 4       pVP                  RV P                  34      P                  4       pV'       g0   \	        RV P                   R24       \
        P                  ! ^4       RRR4       \	        RXR,           24       \        VR,          4      w  r4\        4       p\        4       ;_uu_ 4       pVP                  RW5WEV P                  34       VR8X  d>   VP                  R	V P                  VR
WE34       VP                  RV P                  34       RRR4       \	        RT RV'       d
   RV,           MR 24       \        4        R#   + '       g   i     L; i  + '       g   i     LQ; i)zRe-run OFAC check.r;  rv  r'  NzRunning OFAC check for: r   z{UPDATE companies SET ofac_status = ?, ofac_checked_at = ?,
               ofac_hit_details = ?, updated_at = ? WHERE id = ?rt   r   r   z=UPDATE companies SET trust_level = 'blacklisted' WHERE id = ?u
   ✓ OFAC: rR   u   — rC   )
r,   r(   r   r   r^   r4  r5  r   r>   r   )r   r*   rJ   r  detailsr   s   &     r+   cmd_company_ofacr  `  s(   	LL?$''LUUWHTWWI[12HHQK	 

 
$QvYK
01 6+OF	B	Ddgg.	

 U?LLl"j'6 LLX[_[b[bZde 
 
JvhaG 0D
EF+ 
 
s   A#EA$E0E-	0F 	c           
         \        R V P                   24       \        RRP                  \        4      4       \	        RR\        R7      p\	        RRR7      p\        4       p\        4       ;_uu_ 4       pVP                  RV P                  W1W#34       R	R	R	4       \        R
4       \        4        R	#   + '       g   i     L'; i)zNew incident for company #zTypes:r   r   Tr   Descriptionr   ziINSERT INTO incidents (company_id, date, type, description, created_at)
               VALUES (?,?,?,?,?)Nu   ✓ Incident logged.)	r^   r   rM   rY  r   r>   r,   r(   r   )r   itypedescr   r*   s   &    r+   cmd_company_incidentr  z  s    	&twwi
01	(DIIn-.6D.AE-$/D	B	%WWb*	
 
 
 " 
s   3 B22C	c                    \        4       ;_uu_ 4       pVP                  R V P                  34      P                  4       pV'       g0   \	        RV P                   R24       \
        P                  ! ^4       RRR4       \	        RXR,           24       \        RRR7      p\        R	4      p\        R
4      p\        R4      p\        R4      p\        R4      p\        R4      p	\        4       ;_uu_ 4       pVP                  RV P                  W4WVWxV	\        4       3	4      p
V
P                  pRRR4       \	        RX R24       \        4        R#   + '       g   i     L; i  + '       g   i     L>; i)r;  rv  r'  NzNew contact at r   rh  Tr   rc  rd  TitlezPassport noNationalityr   zINSERT INTO contacts (company_id, name, email, phone, title, passport_no,
               nationality, notes, created_at)
               VALUES (?,?,?,?,?,?,?,?,?)u   ✓ Contact #z added.)r,   r(   r   r   r^   r4  r5  r   r>   r   r   )r   r*   rJ   r   r   r   r  passportnationalityr   r   r   s   &           r+   cmd_contact_newr    s   	LL?$//AST]]_HT__-[9:HHQK	 

 
OAfI;
'(&4(D7OE7OE7OEm$H'K7OE	ll- __d5PUWZW\]	
 mm 
 
M#g
&'- 
 
s   A#E47E!E	!E1	c                p   \        R24       \        R4       \        R24       \        R4       \        RRR7      p\        4       ;_uu_ 4       pVP                  RV34      P	                  4       pRRR4       X'       g&   \        RV R	24       \
        P                  ! ^4       \        R
VR,           RVR,           RVR,           R24       VR,          R39   g   VR,          R8w  d,   \        RRRR.R7      R8w  d   \
        P                  ! ^ 4       \        RRP                  \        P                  4       4      4       \        RRR7      P                  4       pV\        9  d%   \        RV 24       \
        P                  ! ^4       \        V,          p\        RR. R4OR7      p\        RR\        \        P                  4       4      R7      p\        R 4      p\        R!4      p	\        R"4      p
\        R#R$R%7      p\        R&4      p\        R'4      p\        R(4      p\        R)R*R%7      p\        R+4      p\        WCR,          4      p\!        VWSR,          4      p\#        4       p\        4       ;_uu_ 4       pVP                  R,VWEWR,          WgWWWVV\%        V4      VVV34       VR8X  d   RMRpVP                  R-VVVV34       VP                  R.VR^VR/34       RRR4       \        R0V 24       \        R1V 24       \'        4        R#   + '       g   i     EL; i  + '       g   i     LL; i)5uR   Create deal directly (without going through inquiry — outbound proactive deals).u*   New deal (direct — bypass inquiry layer)z^Note: typically inbound deals start as 'inquiry new'. Use this for outbound origination only.
z-Counterparty company ID (from 'company list')Tr   r;  Nrv  r'  u     → r   r   r   r   r   r   r<  zProceed anyway?r   rS  rA  z
Commodity codes:r   rB  zUnknown code: r=  r>  r?  r   r@  r   zTrial volume MTzMonthly volume MTz	Price USDz
Price unitr   r   IncotermPortOriginzPayment termsr   r   ah  INSERT INTO deals (id, commodity_code, commodity, counterparty_company_id,
               counterparty_name, our_role, our_entity, stage, volume_mt, monthly_mt,
               price_usd, price_unit, incoterm, port, origin, payment_terms,
               folder_path, notes, created_at, updated_at)
               VALUES (?,?,?,?,?,?,?,1,?,?,?,?,?,?,?,?,?,?,?,?)zQINSERT INTO deal_parties (deal_id, company_id, role, created_at) VALUES (?,?,?,?)rC  zDeal created (outbound)u   
✓ Created deal rD  r   rE  rG  )r^   r   r,   r(   r   r4  r5  r   rM   r   r   r   r   rJ  r   r   r   r>   rK  r   )r   r   r*   rJ   r   r   rN  rO  r   r  r  r  r  r  r  r  r   r   r   r   rP  s   &                    r+   cmd_deal_newr    s   	(O	
67	(O	
klKVZ[J	LL?*OXXZ 
K01	F1V9+Yq'7&8q~>Na
PQ55;89S#S3*ELHHQK	
		/*>*>*@ AB,t<BBDN_,~./0/Ij49\]Hk4CXYJ./I12J[)Id3Jj!H&>DHF?J?M7OE>V95G )vY?F	B	C
 nvYI86CKB8		
 )1G(;H_j"3R8	
 	mdAr#<=	
! 
( 
y
)*	Jvh
 m 
@ 
s   "L9A(L%L"	%L5	c                 z   V P                   p\        4       ;_uu_ 4       pTP                  R V'       d   RMR R24      P                  4       pRRR4       X'       g   \	        R4       R# \	        RRR R	R
R R	RR R	RR R	RR R	RR 24       \	        R4       V F  pVR,           R\
        VR,          ,           2p\	        VR,          R R	VR R	VR,          R,          R R	VR,          R,          R R	VR,          ;'       g    ^ R R	VR,          ;'       g    ^ R 24       K  	  R#   + '       g   i     L; i) zSELECT * FROM deals WHERE z	stage = 8z	stage < 8rg  Nz	No deals.r  r  ri  rR   Stage22sr  r  r  24szVol/MTz>10sz$/Uz>8sr  . r   r   :N   Ncounterparty_name:N   Nr   z>10,.0fr  z>8,.2fzx------------------------------------------------------------------------------------------------------------------------)closedr,   r(   r!  r^   STAGES)r   r  r*   r#  rk   stage_labels   &     r+   cmd_deal_listr    s?   [[F	||(K(PPij

(* 	 
 k	BtCj'#aC'8.9MQxX\o]^_deh^i
jk	)7Bvaj'9&:;4Q{3/q;$S)1-@+A#+Fs*K1K.%%Aw/q!K.2E2EAv0NP 	Q  
s   .D**D:	c                 B
   \        4       ;_uu_ 4       pVP                  R V P                  34      P                  4       pV'       g0   \	        RV P                   R24       \
        P                  ! ^4       VP                  RV P                  34      P                  4       pVP                  RV P                  34      P                  4       pVP                  RV P                  34      P                  4       pVP                  RV P                  34      P                  4       pRRR4       \	        RRc R	XR
,           RRc 24       \	        RVR,           R\        VR,          ,           24       \	        RVR,           24       \	        RVR,           RVR,          ;'       g    R R24       \	        RVR,           R\        VR,          ,          R,           R24       \	        RVR,          ;'       g    R RVR,          ;'       g    R R24       \	        R VR!,          ;'       g    R R"VR#,          ;'       g    R 24       \	        R$VR%,          ;'       g    R 24       \	        R&VR',          ;'       g    R 24       \	        R(VR),          ;'       g    R 24       \	        R*VR+,          ;'       g    R 24       \	        R,VR-,           24       VR.,          '       d   \	        R/VR.,           24       VR0,          '       d   \	        R1VR0,           24       \	        R2\        X4       R324       V FD  p\	        R4VR
,          R5 R6VR7,          R8 R9VR:,          R; R<VR=,          R> R?VR@,           2
4       KF  	  X'       d   \	        RA\        V4       R324       V Fe  pVRB,          '       d   RCMRDp	\	        R4VR
,          R5 R6VRE,          R; R9VRF,          RG RHVRI,          RJ RKVRL,          ;'       g    ^ RM RNV	 24       Kg  	  X'       dm   \	        RO\        V4       R324       V FN  p
V
RP,          '       d   RQMR9p\	        R4V
R
,          R5 RRT R6V
RS,          RT R9V
RU,          ;'       g    R 24       KP  	  X'       dy   \	        RV\        V4       R324       V FZ  pVRW,          RX8X  d   RYMRZp\	        R[VR\,          R],           R9T R9VR^,          R_ R9VR`,          ;'       g    RaRb,           24       K\  	  \	        4        R#   + '       g   i     EL; i)d SELECT * FROM deals WHERE id = ?Deal r'  zSELECT dp.*, c.name AS company_name, c.trust_level, c.dd_status
               FROM deal_parties dp JOIN companies c ON c.id = dp.company_id
               WHERE dp.deal_id = ? ORDER BY dp.idzSELECT cm.*, c.name AS party_name FROM commissions cm
               JOIN deal_parties dp ON dp.id = cm.deal_party_id
               JOIN companies c ON c.id = dp.company_id
               WHERE cm.deal_id = ? ORDER BY cm.idzBSELECT * FROM documents WHERE deal_id = ? ORDER BY created_at DESCzJSELECT * FROM comms_log WHERE deal_id = ? ORDER BY timestamp DESC LIMIT 10Nr  z
  r   z  Stage:         r  r  z  Commodity:     r   z  Counterparty:  r  r(  counterparty_company_idr  r   z  Our role:      rN  r   rO  r   z  Volume:        r   z MT trial / r  z MT monthlyz  Price:         r  r-  r  z  Incoterm:      r  z  Port:          r  z  Origin:        r  z  Payment:       r  z  Folder:        folder_path
inquiry_idz  From inquiry:  #r   z  Notes:         z
  Parties (r}  r~  r  r  role13srR   r|   ri  z trust=r   rk  z DD=r   z
  Commissions (paidPAIDPENDING
party_nameamount_per_unitz>8.2fr   unitz<3sz total $total_amountz>10,.2fr  z
  Documents (signedro  z] [doc_typer  filenamez
  Recent comms (r   out   →   ←r  	timestampr0  r   r  subjectrC   :N2   Nr3  )r,   r(   r   r   r^   r4  r5  r!  r  rJ  rf   )r   r*   dealpartiescommissionsdocscommsprJ   r  r  r  arrows   &            r+   cmd_deal_showr    s   	||>PYY[E$,,{34HHQK,,68<
 (*	 	
 ll6 9=	

 (* 	 ||PSWS_S_Ra

(* 	 X\\O
 (* 	' 
0 
BxjT$ZL8*
56	d7m_Bvd7m/D.E
FG	d;/0
12	d#678DAZ<[<d<d_d;eef
gh	d:./r(4;M2Nv2V1WWX
YZ	d;/8859d<FXFaFa\aEbbm
no	d;/8859tL?Q?Z?ZUZ>[
\]	d:.77%8
9:	d6l33e4
56	d8n556
78	d?3<<u=
>?	d=12
34L"4#5"678G}}!$w-12	M#g,r
*+agb\AfIc?!An4Ec3J K',D;0@B 	C  !#k"2!3267A yyViFE!D'"R,'<Aa@Q>RSX=YYZ[\]c[dehZi jn-227;2fXG H 
 D	{"-.AkkUsFE!D'"S1Z=2EQq}G]G]X]F^_`  "3u:,b12A{^u4E%ED;,-QugQq|B6Gq!I,J\J\Z\^aIbHcde  
GA 
s   DTT	c                    \        4       ;_uu_ 4       pVP                  R V P                  34      P                  4       pV'       g0   \	        RV P                   R24       \
        P                  ! ^4       V P                  '       d   V P                  MVR,          ^,           pV^8  g   V^8  d"   \	        R4       \
        P                  ! ^4       \        4       pVP                  RW4V P                  34       VP                  RV P                  VR,          W4V P                  34       V^8X  d   VP                  RW@P                  34       \        VR,          4      pVP                  4       '       d   VP                  \        8X  d~   \        VP                  ,          pVP                  4       '       gQ   \         P"                  ! \%        V4      \%        V4      4       VP                  R	\%        V4      V P                  34       R
R
R
4       \	        RV P                   RXR,           RX R\&        V,           R2	4       \)        4        R
#   + '       g   i     LP; i)r  r  r'  r  zStage must be 1-8.z7UPDATE deals SET stage = ?, updated_at = ? WHERE id = ?rC  z+UPDATE deals SET closed_at = ? WHERE id = ?r  z-UPDATE deals SET folder_path = ? WHERE id = ?Nu   ✓ z: stage r.  r   r   )r,   r(   r   r   r^   r4  r5  r  r>   noter   rX   parentr5   r6   r   shutilmoverK  r  r   )r   r*   r  	new_stager   r   dsts   &      r+   cmd_deal_advancer  =  s   	||>PYY[E$,,{34HHQK"&***DJJ$w-!2C	q=IM&'HHQKUEDLL)	
 	m\\4=)C	
 >LLF\\HZ[$}-.F}}6==J#> 6;;.zz||KKFSX6LLGS4<<03 
: 
DhtG}oU9+RyHYGZZ[
\]= 
s   A4ID1I:AII"	c                 `    ^V n         V P                  ;'       g    RV n        \        V 4       R# )   zDeal closedN)r  r  r  r   s   &r+   cmd_deal_closer  _  s$    DJ		**]DITr-   c                   \        4       ;_uu_ 4       pVP                  RV P                  34      P                  4       '       g0   \	        RV P                   R24       \
        P                  ! ^4       RRR4       \        RRR7      p\        RR\        R	7      p\        R
4      p\        R4      p\        R4      p\        R4      p\        R4      p\        R4      p	\        4       ;_uu_ 4       pVP                  RV P                  W$W5VWxV	\        4       3
4      p
V
P                  pRRR4       \	        RX R24       \        4        R#   + '       g   i     L; i  + '       g   i     L>; i)z.Link an existing company as a party to a deal. SELECT 1 FROM deals WHERE id = ?r  r'  Nz Company ID (from 'company list')Tr   Roler   zContact ID (optional)z	Bank namezIBAN / account noz	SWIFT/BICzBank account namer   zINSERT INTO deal_parties (deal_id, company_id, contact_id, role,
               bank_name, bank_iban, bank_swift, bank_account_name, notes, created_at)
               VALUES (?,?,?,?,?,?,?,?,?,?)u   ✓ Party #z added to deal.)r,   r(   r   r   r^   r4  r5  r   r   PARTY_ROLESr>   r   r   )r   r*   r   r  
contact_id	bank_name	bank_iban
bank_swiftbank_account_namer   r   pids   &           r+   cmd_deal_party_addr  e  s   	||>PYY[[E$,,{34HHQK 
 >NJ&4=D34J{#I*+I$J237OE	ll/ \\:4IE35:	
 mm 
 
KuO
,-- 
 
s   A!E
/8E
E	E-	c                    \        4       ;_uu_ 4       pVP                  R V P                  34      P                  4       pVP                  RV P                  V P                  34      P                  4       pV'       d	   V'       g"   \        R4       \        P                  ! ^4       RRR4       \        RRR7      p\        RXR,          ;'       g    R	R
7      pVR,          '       d   YBR,          ;'       g    ^ ,          MRp\        RV'       d   VR MRR
7      p\        R4      p\        4       ;_uu_ 4       pVP                  RV P                  V P                  WEWx\        4       34       RRR4       \        RXR,           RVR RV 24       \        4        R#   + '       g   i     L; i  + '       g   i     LK; i)r  zSELECT dp.*, c.name AS company_name FROM deal_parties dp
               JOIN companies c ON c.id = dp.company_id
               WHERE dp.id = ? AND dp.deal_id = ?zDeal or party not found.NzAmount per unit (USD)Tr   Unitr  r   r   r   zTotal amount (USD)z.2fr   zINSERT INTO commissions (deal_id, deal_party_id, amount_per_unit,
               unit, total_amount, notes, created_at)
               VALUES (?,?,?,?,?,?,?)u   ✓ Commission added for r|   z: $r   )r,   r(   r   r   party_idr^   r4  r5  r   r   r>   r   )	r   r*   r  partyamountr  total_defaulttotalr   s	   &        r+   cmd_commission_addr    s\   	||>PYY[5 ]]DLL)	

 (* 	 5,-HHQK 
 1DAF&$|"4"<"<=D;?;L;LVK055A6RVM-Q^-9LdhiE7OE	) \\4==&ceL		
 
 
%eN&;%<Cs|1TF
ST1 
  
s   A1F!F94F0F-	0G 	c                     \        4       ;_uu_ 4       pVP                  R \        4       V P                  34       RRR4       \	        RV P                   R24       \        4        R#   + '       g   i     L5; i)z9UPDATE commissions SET paid = 1, paid_at = ? WHERE id = ?Nu   ✓ Commission z marked paid.)r,   r(   r>   commission_idr^   r   )r   r*   s   & r+   cmd_commission_payr    sW    	GUD&&'	
 

 
OD../}
=> 
s   'A''A7	c                    \        V R R4      p\        4       ;_uu_ 4       pV'       d/   VP                  RV P                  34      P	                  4       pRpM>VP                  RV P                  34      P	                  4       pV'       d
   VR,          MRpV'       g"   \        R4       \        P                  ! ^4       RRR4       \        RR. ROR	7      p\        R
4      p\        RRRR.R7      R8H  p\        R4      p\        4       ;_uu_ 4       pV'       d5   TP                  RV P                  YVV'       d   ^M^ V\        4       34       M4TP                  RV P                  TXYg'       d   ^M^ V\        4       34       RRR4       \        RV 24       \        4        R#   + '       g   i     L; i  + '       g   i     L=; i)inquiryFr8  Nr  r  zTarget not found.zDoc typeTr   FilenamezSigned?r   rS  rA  r   zyINSERT INTO documents (inquiry_id, doc_type, filename, signed, notes, created_at)
                   VALUES (?,?,?,?,?,?)zINSERT INTO documents (deal_id, doc_type, stage, filename, signed, notes, created_at)
                   VALUES (?,?,?,?,?,?,?)u   ✓ Document logged: )ICPOFCOSCOLOINCNDAIMFPASPACIPOPMT103
CommissionOthergetattrr,   r(   	target_idr   r^   r4  r5  r   r>   r   )	r   target_inquiryr*   r}   r  r  r  r  r   s	   &        r+   cmd_doc_addr    se   T9e4N	\\"H4>>J[\eegFE\\"Dt~~FWXaacF'-F7O4E%'HHQK 
 j4STH j!HIsS#J?3FF7OE	LL+&QaPSPUV LL-5(AQPUWZW\] 
 
!(
,-= 
  
s%   A)F$
F$!F$A1F7$F4	7G	c                 n   \        V R R4      p\        4       ;_uu_ 4       pV'       dT   VP                  RV P                  34      P	                  4       '       g"   \        R4       \        P                  ! ^4       MRVP                  RV P                  34      P	                  4       '       g"   \        R4       \        P                  ! ^4       RRR4       \        RRR	R
.R7      p\        RR. ROR7      p\        R4      p\        R4      p\        4       p\        4       ;_uu_ 4       pV'       d"   VP                  RV P                  W4WVWw34       M VP                  RV P                  W4WVWw34       RRR4       \        R4       \        4        R#   + '       g   i     L; i  + '       g   i     L:; i)r  Fz$SELECT 1 FROM inquiries WHERE id = ?zInquiry not found.r  zDeal not found.Nr   Tinr  r   r   SubjectSummaryzINSERT INTO comms_log (inquiry_id, direction, channel, subject, summary, timestamp, created_at)
                   VALUES (?,?,?,?,?,?,?)zINSERT INTO comms_log (deal_id, direction, channel, subject, summary, timestamp, created_at)
                   VALUES (?,?,?,?,?,?,?)u   ✓ Comm logged.)r   r   r   r   otherr  )r   r  r*   r   r   r  summaryr   s   &       r+   cmd_comm_logr    sB   T9e4N	<< FHYZccee*+<< BT^^DUV__aa'( 
 {TD%=IIY7ghGYGYG	B	LL-WrN LL-WrN 
 

9 
 
s%   9FAF-!F(A
F$F!	$F4	c                 >    \        4        \        R \         24       R# )u   ✓ Dashboard regenerated: N)r   r^   DASHBOARD_PATHr  s   &r+   cmd_dashboardr    s    	''7
89r-   u%  <!doctype html>
<html lang="en"><head>
<meta charset="utf-8">
<title>i4Fuel Pipeline</title>
<style>
  :root {
    --bg: #0f1419; --panel: #1a1f26; --panel2: #232930; --border: #2c333c;
    --text: #e6e8eb; --muted: #8b95a5; --accent: #5eb3ff;
    --green: #4ade80; --amber: #fbbf24; --red: #f87171; --darkred: #991b1b;
    --gray: #6b7280;
  }
  * { box-sizing: border-box; margin: 0; padding: 0; }
  body { font: 13px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: var(--bg); color: var(--text); }
  header { padding: 16px 24px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; }
  header h1 { font-size: 18px; font-weight: 600; }
  header .meta { color: var(--muted); font-size: 12px; }
  nav { background: var(--panel); padding: 0 24px; display: flex; gap: 4px; border-bottom: 1px solid var(--border); }
  nav button { background: none; border: none; color: var(--muted); padding: 12px 16px; cursor: pointer; font-size: 13px; border-bottom: 2px solid transparent; }
  nav button.active { color: var(--text); border-bottom-color: var(--accent); }
  nav button:hover { color: var(--text); }
  section { display: none; padding: 16px 24px; }
  section.active { display: block; }
  .stats { display: flex; gap: 24px; margin-bottom: 20px; }
  .stat { font-size: 12px; color: var(--muted); }
  .stat strong { display: block; font-size: 22px; font-weight: 600; color: var(--text); margin-top: 2px; }
  .stat strong.amber { color: var(--amber); }
  .stat strong.green { color: var(--green); }
  .stat strong.red { color: var(--red); }
  .board { display: grid; grid-template-columns: repeat(8, minmax(220px, 1fr)); gap: 12px; overflow-x: auto; padding-bottom: 12px; }
  .col { background: var(--panel); border-radius: 8px; padding: 10px; min-height: 200px; }
  .col h3 { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin-bottom: 10px; padding: 4px; display: flex; justify-content: space-between; }
  .col h3 .count { background: var(--border); color: var(--text); padding: 1px 7px; border-radius: 10px; }
  .card { background: var(--panel2); border: 1px solid var(--border); border-radius: 6px; padding: 10px; margin-bottom: 8px; cursor: pointer; transition: border-color 0.15s; position: relative; }
  .card:hover { border-color: var(--accent); }
  .card.flagged { border-left: 3px solid var(--red); }
  .card .id { font-size: 10px; color: var(--muted); font-family: ui-monospace, monospace; }
  .card .commodity { font-weight: 600; margin: 2px 0; }
  .card .cp { font-size: 12px; color: var(--muted); }
  .card .row { display: flex; justify-content: space-between; margin-top: 6px; font-size: 11px; color: var(--muted); }
  .card .row strong { color: var(--text); }
  .empty { color: var(--muted); font-size: 12px; padding: 10px; text-align: center; font-style: italic; }
  table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 12px; background: var(--panel); border-radius: 6px; overflow: hidden; }
  th { text-align: left; padding: 10px; border-bottom: 1px solid var(--border); color: var(--muted); font-weight: 500; font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; }
  td { padding: 10px; border-bottom: 1px solid var(--border); }
  tr:last-child td { border-bottom: none; }
  td a { color: var(--accent); text-decoration: none; cursor: pointer; }
  td a:hover { text-decoration: underline; }
  .badge { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 11px; font-weight: 500; }
  .badge.paid { background: rgba(74,222,128,0.15); color: var(--green); }
  .badge.pending { background: rgba(251,191,36,0.15); color: var(--amber); }
  .badge.role { background: var(--border); color: var(--text); }
  .badge.trust-unknown { background: rgba(107,114,128,0.2); color: var(--gray); }
  .badge.trust-verified { background: rgba(74,222,128,0.15); color: var(--green); }
  .badge.trust-suspect { background: rgba(251,191,36,0.15); color: var(--amber); }
  .badge.trust-scammer { background: rgba(248,113,113,0.2); color: var(--red); }
  .badge.trust-blacklisted { background: var(--darkred); color: white; }
  .badge.dd-not_checked { background: rgba(107,114,128,0.2); color: var(--gray); }
  .badge.dd-in_progress { background: rgba(94,179,255,0.15); color: var(--accent); }
  .badge.dd-passed { background: rgba(74,222,128,0.15); color: var(--green); }
  .badge.dd-failed { background: rgba(248,113,113,0.2); color: var(--red); }
  .badge.dd-flagged { background: rgba(251,191,36,0.15); color: var(--amber); }
  .badge.ofac-clear { background: rgba(74,222,128,0.15); color: var(--green); }
  .badge.ofac-hit { background: var(--darkred); color: white; }
  .badge.ofac-not_checked { background: rgba(107,114,128,0.2); color: var(--gray); }
  .badge.status-open { background: rgba(94,179,255,0.15); color: var(--accent); }
  .badge.status-converted { background: rgba(74,222,128,0.15); color: var(--green); }
  .badge.status-rejected { background: rgba(248,113,113,0.2); color: var(--red); }
  .badge.status-in_review { background: rgba(251,191,36,0.15); color: var(--amber); }
  .badge.status-no_response { background: rgba(107,114,128,0.2); color: var(--gray); }
  .badge.status-stale { background: rgba(107,114,128,0.2); color: var(--gray); }
  .alert { background: rgba(248,113,113,0.1); border-left: 3px solid var(--red); padding: 12px 16px; border-radius: 4px; margin-bottom: 16px; color: var(--text); }
  .alert strong { color: var(--red); }
  .deal-detail { display: none; position: fixed; top: 5vh; left: 5vw; right: 5vw; bottom: 5vh; background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 24px; overflow-y: auto; box-shadow: 0 20px 60px rgba(0,0,0,0.5); z-index: 100; }
  .deal-detail.show { display: block; }
  .deal-detail .close { position: absolute; top: 16px; right: 20px; background: none; border: none; color: var(--muted); font-size: 24px; cursor: pointer; }
  .deal-detail h2 { font-size: 20px; margin-bottom: 4px; }
  .deal-detail h3 { font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin: 20px 0 8px; font-weight: 500; }
  .grid2 { display: grid; grid-template-columns: 200px 1fr; gap: 8px 24px; margin-top: 12px; font-size: 13px; }
  .grid2 .k { color: var(--muted); }
  .backdrop { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.6); z-index: 99; }
  .backdrop.show { display: block; }
</style>
</head><body>
<header>
  <h1>i4Fuel Pipeline</h1>
  <div class="meta">Generated {ts} · {db_path}</div>
</header>

<nav>
  <button class="tab-btn active" onclick="showTab('overview')">Overview</button>
  <button class="tab-btn" onclick="showTab('inbox')">Inbox <span class="count">{n_inbox}</span></button>
  <button class="tab-btn" onclick="showTab('deals')">Deals <span class="count">{n_active}</span></button>
  <button class="tab-btn" onclick="showTab('companies')">Companies <span class="count">{n_companies}</span></button>
  <button class="tab-btn" onclick="showTab('flagged')">Flagged <span class="count">{n_flagged}</span></button>
</nav>

<section id="overview" class="active">
  {alerts}
  <div class="stats">
    <div class="stat">Open inquiries<strong>{n_inbox}</strong></div>
    <div class="stat">Active deals<strong>{n_active}</strong></div>
    <div class="stat">Companies<strong>{n_companies}</strong></div>
    <div class="stat">DD needed<strong class="amber">{n_dd_needed}</strong></div>
    <div class="stat">Flagged companies<strong class="red">{n_flagged}</strong></div>
    <div class="stat">Active contract value<strong>${total_value:,.0f}</strong></div>
    <div class="stat">Commissions pending<strong class="amber">${comm_pending:,.0f}</strong></div>
    <div class="stat">Commissions paid<strong class="green">${comm_paid:,.0f}</strong></div>
  </div>

  <h3 style="margin: 24px 0 12px; font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted)">Deal kanban</h3>
  <div class="board">
    {kanban_columns}
  </div>
</section>

<section id="inbox">
  <h3 style="margin-bottom:12px">Open inquiries</h3>
  {inbox_table}
  <h3 style="margin-top:24px;margin-bottom:12px">Recently rejected / converted</h3>
  {inbox_closed_table}
</section>

<section id="deals">
  <h3 style="margin-bottom:12px">Active deals ({n_active})</h3>
  {deals_active_table}
  <h3 style="margin-top:24px;margin-bottom:12px">Closed deals ({n_closed})</h3>
  {deals_closed_table}
</section>

<section id="companies">
  <h3 style="margin-bottom:12px">All companies</h3>
  {companies_table}
</section>

<section id="flagged">
  <h3 style="margin-bottom:12px">Flagged companies (suspect / scammer / blacklisted)</h3>
  {flagged_table}
  <h3 style="margin-top:24px;margin-bottom:12px">Recent incidents</h3>
  {incidents_table}
</section>

<div class="backdrop" id="backdrop" onclick="closeDetail()"></div>
{detail_modals}

<script>
function showTab(id) {
  document.querySelectorAll('section').forEach(s => s.classList.remove('active'));
  document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
  document.getElementById(id).classList.add('active');
  event.target.classList.add('active');
}
function showDetail(id) {
  document.getElementById('detail-' + id).classList.add('show');
  document.getElementById('backdrop').classList.add('show');
}
function closeDetail() {
  document.querySelectorAll('.deal-detail').forEach(d => d.classList.remove('show'));
  document.getElementById('backdrop').classList.remove('show');
}
document.addEventListener('keydown', e => { if (e.key === 'Escape') closeDetail(); });
</script>
</body></html>
c                     V f   R# \        V 4      P                  RR4      P                  RR4      P                  RR4      P                  RR	4      # )
NrC   &z&amp;<z&lt;>z&gt;rs   z&quot;)rK  rp   rN   s   &r+   her$    sE    yFNN3(00f=WS&!''#x"8:r-   c                 &    R V  R\        V4       R2# )z<span class="badge z">z</span>r$  )clsr   s   &&r+   badger(    s     R4z99r-   c                  #  aaCaDaEaFaG \        4       ;_uu_ 4       p V P                  R 4      P                  4       pV P                  R4      P                  4       pV P                  R4      P                  4       pV P                  R4      P                  4       pV P                  R4      P                  4       pV P                  R4      P                  4       pV P                  R4      P                  4       pV P                  R4      P                  4       pRRR4       / oGX F+  p	SGP                  V	R	,          . 4      P	                  V	4       K-  	  / p
X F+  oV
P                  SR	,          . 4      P	                  S4       K-  	  / pX F<  pVR	,          '       g   K  VP                  VR	,          . 4      P	                  V4       K>  	  / pX F<  pVR	,          '       g   K  VP                  VR	,          . 4      P	                  V4       K>  	  / p\        4       ;_uu_ 4       p V P                  R
4      P                  4        F+  pVP                  VR,          . 4      P	                  V4       K-  	  RRR4       X Uu. uF  qR,          ^8  g   K  VNK  	  ppV Uu. uF  qR,          ^8X  g   K  VNK  	  ppX Uu. uF  pVR,          R8X  g   K  VNK  	  ppV Uu. uF  pVR,          R8w  g   K  VNK  	  ppX Uu. uF  pVR,          R9   g   K  VNK  	  ppV Uu. uF  pVR,          R9   g   K  VNK  	  pp\        R V 4       4      p\        R V 4       4      p\        R V 4       4      p. pV Uu. uF  pVR,          R8X  g   K  VNK  	  ppV'       dh   RP                  R VR,           4       4      p\        V4      ^8  d   R\        V4      ^,
           R2MRpVP	                  R\        V4       V R24       V'       d   VP	                  R\        V4       R24       . p\        ^^	4       EF  p V Uu. uF  qR,          V 8X  g   K  VNK  	  p!p. p"V! EF  pSGP                  VR,          . 4      p#\        ;QJ d    R  V# 4       F  '       g   K   R!M	  R"M! R  V# 4       4      p$V$'       d   R#MR$p%VR%,          '       d   VR%,          R& R'2MR(p&VR),          '       d"   R*VR),          R+ R,VR-,          ;'       g    R. 2MR(p'V"P	                  R/V% R0VR,           R1\        VR,          4       R2\        VR3,          4       R4\        VR5,          4       R6\        VR7,          4       R8V& R9V' R:24       EK!  	  V"'       g   V"P	                  R;4       VP	                  R<V  R=\        V ,           R>\        V!4       R?RP                  V"4       R@2	4       EK  	  VG3RA loDRBp(V'       d"   RCV( RP                  VD3RD lV 4       4       RE2MRFp)V'       d"   RCV( RP                  VD3RG lV 4       4       RE2MRHp*RI oFRJp+V'       d"   RCV+ RP                  VF3RK lV 4       4       RE2MRLp,V'       d)   RCV+ RP                  VF3RM lVRN,           4       4       RE2MROp-RP oCRQp.V'       d"   RCV. RP                  VC3RR lV 4       4       RE2MRSp/V'       d"   RCV. RP                  VC3RT lV 4       4       RE2MRUp0RV oEX'       d    RWRP                  VE3RX lV 4       4       RE2MRYp1. p2V EF+  pSGP                  VR,          . 4      p#V
P                  VR,          . 4      p3VP                  VR,          . 4      p4VP                  VR,          . 4      p5RP                  RZ V# 4       4      ;'       g    R[p6RP                  R\ V3 4       4      ;'       g    R]p7RP                  R^ V4 4       4      ;'       g    R_p8RP                  R` V5Ra,           4       4      ;'       g    Rbp9VRc,          '       d   Rd\        VRc,          4       Re2MR(p:T2P	                  RP                  . RfNVR,           NRgN\        VR,          4       NRhN\        VR3,          4       NR6N\        VR5,          4       NRiNVR,           NR=N\        \        VR,          ,          4       NRjN\        VR7,          4       NRkN\        \        VRl,          ,          Rm,          4       NRnNVR%,          ;'       g    ^ R& NRoNVRp,          ;'       g    ^ R& NRqNVR),          ;'       g    ^ R+ NRrN\        VR-,          ;'       g    R.4       NRsN\        VRt,          ;'       g    R(4       NRuN\        VRv,          ;'       g    R(4       NRwN\        VRx,          ;'       g    R(4       NRyN\        VRz,          ;'       g    R(4       NR{NV: NR|NVR},          '       d   R~VR},           2MR( NRN\        VR,          ;'       g    R(4       NRNV6 NRNV7 NRNV8 NRNV9 NRN4      4       EK.  	  V EF  pT2P	                  RP                  . RNVR,           NRNVR,           NRhN\        VR,          4       NR6N\        VR,          4       NR6N\        VR,          4       NR6N\        RVR,           2VR,          4       NRN\        VR,          ;'       g    R(4       NRNVR,          '       d   RVR,           R2MR NRN\        VR,          ;'       g    R(4       NRN\        VR,          ;'       g    R(4       NRNVR%,          ;'       g    ^ R& NRNVRp,          ;'       g    ^ R& NRNVR),          ;'       g    ^ R+ NR,N\        VR-,          ;'       g    R.4       NRsN\        VRt,          ;'       g    R(4       NRN\        VRx,          ;'       g    R(4       NRN\        VRv,          ;'       g    R(4       NRN\        VRz,          ;'       g    R(4       NRN\        VR,          ;'       g    RR,          4       NRN\        VR,          ;'       g    R(4       NRN\        VR	,          ;'       g    R(4       NRN\        VR,          ;'       g    R(4       NRN\        VR,          ;'       g    R(4       NRN4      4       EK  	  V EF(  oVP                  SR,          . 4      p;RP                  R V; 4       4      ;'       g    Rp<V Uu. uF  qR,          SR,          8X  gq   \        ;QJ d6    V3R lSGP                  VR,          . 4       4       F  '       g   K   R!M+	  R"M'! V3R lSGP                  VR,          . 4       4       4      '       g   K  VNK  	  p=pRP                  R V= 4       4      ;'       g    Rp>T2P	                  RP                  . RNSR,           NRgN\        SRm,          4       NRN\        RSR,           2SR,          4       NRN\        RSR,           2SR,          4       NRN\        RSR,           2SR,          4       NRN\        SR,          ;'       g    R(4       NRN\        SR,          ;'       g    R(4       NRN\        SR,          ;'       g    R(4       NRN\        SR,          ;'       g    R(4       NRN\        SR,          ;'       g    R(4       NRwN\        SR,          ;'       g    R(4       NRN\        SR,          ;'       g    R(4       NR6N\        SR,          ;'       g    R(4       NRN\        SR,          ;'       g    RR,          ;'       g    R(4       NRN\        SR,          ;'       g    R(4       NRN\        SR,          ;'       g    R4       NRN\        SR,          ;'       g    R(4       NRNV< NRNV> NRN4      4       EK+  	  / R\        4       R,          P!                  RR4      bR\#        \$        4      bR\#        \        V4      4      bR\#        \        V4      4      bR\#        \        V4      4      bR\#        \        V4      4      bR\#        \        V4      4      bR\#        \        V4      4      bRVR& bRVR& bRVR& bRRP                  V4      bRRP                  V4      bRV,bRV-bRV)bRV*bRV/RV0RV1RRP                  V24      /Cp?\&        p@V?P)                  4        F  w  pApBX@P!                  VAVB4      p@K  	  \*        P-                  X@4       R#   + '       g   i     ELu; i  + '       g   i     EL0; iu upi u upi u upi u upi u upi u upi u upi u upi u upi )z,SELECT * FROM deals ORDER BY updated_at DESCz%SELECT * FROM companies ORDER BY namez0SELECT * FROM inquiries ORDER BY created_at DESCzSELECT i.*, c.name AS company_name FROM incidents i
               JOIN companies c ON c.id = i.company_id ORDER BY date DESC LIMIT 30zSELECT dp.*, c.name AS company_name, c.trust_level, c.dd_status
               FROM deal_parties dp JOIN companies c ON c.id = dp.company_idzSELECT cm.*, c.name AS party_name FROM commissions cm
               JOIN deal_parties dp ON dp.id = cm.deal_party_id
               JOIN companies c ON c.id = dp.company_idz0SELECT * FROM documents ORDER BY created_at DESCz/SELECT * FROM comms_log ORDER BY timestamp DESCNr   z*SELECT * FROM incidents ORDER BY date DESCr   r  r  rw   r   r   r   c              3   v   "   T F/  qR ,          ;'       g    ^ VR,          ;'       g    ^ ,          x  K1  	  R# 5i)r  r   NrA   rI   r  s   & r+   rK   'regenerate_dashboard.<locals>.<genexpr>  s.     Z\~**q~/B/BCC\s   999c              3   h   "   T F(  qR ,          '       d   K  VR,          ;'       g    ^ x  K*  	  R# 5ir  r  NrA   rH   s   & r+   rK   r,    s)     Ry!&		-q(--A-y   222c              3   h   "   T F(  qR ,          '       g   K  VR,          ;'       g    ^ x  K*  	  R# 5ir.  rA   rH   s   & r+   rK   r,    s)     KIq6*An%***Ir/  r   c              3   2   "   T F  qR ,          x  K  	  R# 5i)r   NrA   rH   s   & r+   rK   r,    s     >-=F))-=s   :N   Nz (+z more)rC   z1<div class="alert"><strong>BLACKLISTED:</strong> z%. Review before any engagement.</div>z<div class="alert"><strong>zb companies need DD.</strong> Run /supplier-check, then: pipeline.py company check &lt;id&gt;</div>r   c              3   b   "   T F%  pVR ,          R9   ;'       g    VR,          R8g  x  K'  	  R# 5ir   r   r<  NsuspectrF  r   rA   rI   r  s   & r+   rK   r,    s>      I@G1 M*.SS 7 7kNh67@G   -/TFzcard flaggedcardr   ,.0fz MTr  r  $,.2fr   r  r   z
              <div class="z" onclick="showDetail('deal-z%')">
                <div class="id">z.</div>
                <div class="commodity">r   z'</div>
                <div class="cp">r  u    · rN  z.</div>
                <div class="row"><span>z</span><strong>z1</strong></div>
              </div>
            u   <div class="empty">—</div>z3
          <div class="col">
            <h3><span>r  z</span><span class="count">z</span></h3>
            z
          </div>
        c                   < SP                  V R ,          . 4      p\        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      pV'       d   RMRpRT RV R ,           R\        V R ,          4       R	V R
,           R\        \        V R
,          ,          4       R\        V R,          4       R\        V R,          4       R\        V R,          4       R\        \        V R,          ,          R,          4       RV R,          ;'       g    ^ R RV R,          ;'       g    ^ R R\        V R,          ;'       g    R4       R\        V R,          ;'       g    R4       R\        V R,          R,          4       R2# )r   c              3   b   "   T F%  pVR ,          R9   ;'       g    VR,          R8g  x  K'  	  R# 5ir4  rA   r7  s   & r+   rK   9regenerate_dashboard.<locals>.deal_row.<locals>.<genexpr>  s>      E<Cq &*OO 3 3+(23<Cr8  TFu*   <span style="color:var(--red)">⚠</span> rC   <tr>
          <td>z<a onclick="showDetail('deal-')"></a></td>
          <td>r  r  </td>
          <td>r   r  rN  rO  r   r   r:  </td>
          <td>$r  r<  r   r  r  r  
updated_atr   </td>
        </tr>)getanyr$  r  rJ  )r  r  rr  flagparties_by_deals   &   r+   deal_row&regenerate_dashboard.<locals>.deal_row   s   !%%agr2# E<CE### E<CE E?F;Bf1!D'$r!D'{m Lzl"Rqz 234 5!K.!" #!'()* +!J- ! "(1\?+F345 6+##!T* +;$$1d+1R,0E0E2-F,G H!J-((5)* +!L/#&'( ) 	r-   z<tr><th></th><th>Stage</th><th>Commodity</th><th>Counterparty</th>
                   <th>Role</th><th>Entity</th><th>Vol/MT</th><th>Price</th>
                   <th>Incoterm</th><th>Updated</th></tr>z<table>c              3   4   <"   T F  pS! V4      x  K  	  R # 5irE   rA   rI   r  rK  s   & r+   rK   r,         &ILqx{{L   z</table>z%<p class="empty">No active deals.</p>c              3   4   <"   T F  pS! V4      x  K  	  R # 5irE   rA   rN  s   & r+   rK   r,    rO  rP  z%<p class="empty">No closed deals.</p>c                 p   R V R,           RV R,           R\        V R,          4       R\        V R,          4       R\        V R,          4       R\        V R,          ;'       g    R	4       R\        V R
,          ;'       g    R	4       RV R,          ;'       g    ^ R RV R,          ;'       g    ^ R R\        V R,          ;'       g    R4       R\        RV R,           2V R,          4       R\        V R,          ;'       g    RR,          4       R\        V R,          ;'       g    RR,          4       R2# )z3<tr>
          <td><a onclick="showDetail('inquiry-r   z')">#rB  r   rC  r  r   r  r  r   r   r:  rD  r  r<  r   r  rC   status-r  r  :N(   Nr/  r   rF  r$  r(  r  s   &r+   inquiry_row)regenerate_dashboard.<locals>.inquiry_row  sP   //0wiuQtWI F!K.!" #!F)}o !I,  !!&'00512 3!$%../0 1+##!T* +;$$1d+1R,0E0E2-F,G Hwq{m,ak:; <1]#))r3/01 21]#))r3/01 2 	r-   z<tr><th>ID</th><th>Dir</th><th>Type</th><th>Channel</th><th>Company</th>
                      <th>Commodity</th><th>Vol/MT</th><th>Price</th><th>Status</th>
                      <th>Next action</th><th>Received</th></tr>c              3   4   <"   T F  pS! V4      x  K  	  R # 5irE   rA   rI   r  rW  s   & r+   rK   r,  2  s     )Q.Q+a...rP  z'<p class="empty">No open inquiries.</p>c              3   4   <"   T F  pS! V4      x  K  	  R # 5irE   rA   rZ  s   & r+   rK   r,  6  s     )XBWQ+a..BWrP  r   z<p class="empty">None.</p>c                    V R ,          '       d   RMRpRV R,           R\        V R,          4       R\        V R,          ;'       g    R	4       R
\        V R,          ;'       g    R	4       R
\        RV R,           2V R,          4       R
\        RV R,           2V R,          4       R\        V R,          ;'       g    R4       R
\        RV R,           2V R,          4       R
V R2# )rn  u)   <span style="color:var(--red)">⚠</span>rC   z3<tr>
          <td><a onclick="showDetail('company-r   rA  r   rB  r   r  rC  r   trust-r   dd-r   rR   rw  ofac-r   rF  rU  )rJ   rs  s   & r+   company_row)regenerate_dashboard.<locals>.company_row;  s   <=>V<W<W8]_//0witBqyM? K!I,''%() *!%&//%01 2va./0!M2BCD Es1[>*+Q{^<=Qr!J-BUBUSU?V>W XuQ}-./=1ABC Dd  	r-   z}<tr><th>Name</th><th>Country</th><th>Reg no</th>
                      <th>Trust</th><th>DD</th><th>OFAC</th><th>BL</th></tr>c              3   4   <"   T F  pS! V4      x  K  	  R # 5irE   rA   rI   rJ   r`  s   & r+   rK   r,  J  s     )L)Q+a..)rP  z&<p class="empty">No companies yet.</p>c              3   4   <"   T F  pS! V4      x  K  	  R # 5irE   rA   rc  s   & r+   rK   r,  N  s     )TBSQ+a..BSrP  z*<p class="empty">No flagged companies.</p>c                     R \        V R,          R,          4       RV R,           R\        V R,          4       R\        V R,          4       R	\        V R
,          ;'       g    RR,          4       R2# )r@  r  r   z4</td>
          <td><a onclick="showDetail('company-r   rA  r|   rB  r  rC  r  rC   :NP   NrF  r&  rV  s   &r+   incident_row*regenerate_dashboard.<locals>.incident_rowS  s~    !F)C.!" #//0.?tBqGXDYCZ [!F)}o 1]#))r3/01 2	 	r-   zN<table><tr><th>Date</th><th>Company</th><th>Type</th><th>Description</th></tr>c              3   4   <"   T F  pS! V4      x  K  	  R # 5irE   rA   )rI   r  rg  s   & r+   rK   r,  ]  s     6Iq<??IrP  z)<p class="empty">No incidents logged.</p>c              3   (  "   T F  pR \        RVR,          4       R\        VR,          4       R\        RVR,           2VR,          4       R\        RVR,           2VR,          4       R\        VR,          ;'       g    R	4       R
2x  K  	  R# 5i)<tr><td>r  	</td><td>r|   r]  r   r^  r   r  rC   
</td></tr>N)r(  r$  r7  s   & r+   rK   r,  k  s      
  uVQvY/0 1a'() *6!M"2!34a6FGH I3q~./;@A Ban**+,J	8
 s   BBz;<tr><td colspan='5' class='empty'>No parties yet.</td></tr>c              3   Z  "   T F  pR \        VR,          4       RVR,          R R\        VR,          4       RVR,          ;'       g    ^ R R\        VR	,          '       d   R	MR
VR	,          '       d   RMR4       R\        VR,          ;'       g    RR,          4       R2x  K  	  R# 5i)rk  r  z
</td><td>$r  r<  r   r  r  rl  r  pendingr  r  paid_atrC   r   rm  NrU  rH   s   & r+   rK   r,  t  s      
  r!L/*+ ,'(.a1V9 ?n%**40 11V99)qyyVV_`a bq|))r3/01	=
 s   AB+	*B+4B+B+zB<tr><td colspan='5' class='empty'>No commissions logged.</td></tr>c              3     "   T Fz  pR \        VR,          4       RVR,          ;'       g    R R\        VR,          ;'       g    R4       RVR,          '       d   RMR R\        VR,          R	,          4       R
2x  K|  	  R# 5i)rk  r  rl  r  rC   r  r  ro  
created_atr   rm  Nr&  )rI   docs   & r+   rK   r,  }  s      

 	 r#j/*+9S\5G5GR4H Ic*o++,- .MM5r2 3c,',-.j: s   (BBB)Bz9<tr><td colspan='5' class='empty'>No documents.</td></tr>c              3     "   T F  pR \        VR,          R,          4       RVR,          R8X  d   RMR R\        VR,          4       R\        VR	,          ;'       g    R
4       R\        VR,          ;'       g    R
4       R2x  K  	  R# 5i)rk  r  r0  rl  r   r  r  r  r   r  rC   r  rm  Nr&  )rI   ls   & r+   rK   r,    s      
  r!K.-./ 0kNE15u= >a	l#$ %a	l((b)* +a	l((b)**	6
 s   ABB:B:N   Nz5<tr><td colspan='5' class='empty'>No comms.</td></tr>r  z<a href="file://z">Open folder</a>z4
          <div class="deal-detail" id="detail-deal-uY   ">
            <button class="close" onclick="closeDetail()">×</button>
            <h2>z3</h2>
            <div style="color: var(--muted)">u
    · Stage zW</div>
            <div class="grid2">
              <div class="k">Our role</div><div>r   rO  r   z?)</div>
              <div class="k">Trial / Monthly</div><div>z MT / r  z8 MT</div>
              <div class="k">Price</div><div>$z per z7</div>
              <div class="k">Incoterm</div><div>r  z<</div>
              <div class="k">Port / Origin</div><div>r  r*  r  z<</div>
              <div class="k">Payment terms</div><div>r  z5</div>
              <div class="k">Folder</div><div>z;</div>
              <div class="k">From inquiry</div><div>r  #z4</div>
              <div class="k">Notes</div><div>r   z</div>
            </div>
            <h3>Parties</h3>
            <table><tr><th>Role</th><th>Company</th><th>Trust</th><th>DD</th><th>Bank</th></tr>z</table>
            <h3>Commissions</h3>
            <table><tr><th>Party</th><th>Per unit</th><th>Total</th><th>Status</th><th>Paid</th></tr>z</table>
            <h3>Documents</h3>
            <table><tr><th>Type</th><th>Stage</th><th>Filename</th><th>Signed</th><th>Logged</th></tr>z</table>
            <h3>Recent comms</h3>
            <table><tr><th>Time</th><th>Dir</th><th>Channel</th><th>Subject</th><th>Summary</th></tr>z"</table>
          </div>
        z7
          <div class="deal-detail" id="detail-inquiry-ub   ">
            <button class="close" onclick="closeDetail()">×</button>
            <h2>Inquiry #r   r  r   rS  zV</div>
            <div class="grid2">
              <div class="k">Company</div><div>r  rR   z(#r   z6</div>
              <div class="k">Contact</div><div>r+  z8</div>
              <div class="k">Commodity</div><div>r   z5</div>
              <div class="k">Volume</div><div>r,  z9 MT)</div>
              <div class="k">Price</div><div>$z<</div>
              <div class="k">Origin / Port</div><div>r.  z6</div>
              <div class="k">Payment</div><div>z7</div>
              <div class="k">Received</div><div>r/  r0  z:</div>
              <div class="k">Next action</div><div>r  z6</div>
              <div class="k">Deal ID</div><div>z?</div>
              <div class="k">Rejection reason</div><div>r2  z3</div>
            </div>
          </div>
        c           
   3      "   T FR  pR \        VR,          R,          4       R\        VR,          4       R\        VR,          ;'       g    R4       R2x  KT  	  R# 5i)	rk  r  r   rl  r  r  rC   rm  Nr&  )rI   incs   & r+   rK   r,    s\      
" r#f+c*+,IbVo5FiPRSVWdSeSkSkikPlOmmwx"s   AAz9<tr><td colspan='3' class='empty'>No incidents.</td></tr>r  c              3   H   <"   T F  qR ,          SR,          8H  x  K  	  R# 5i)r   r   NrA   )rI   r  rJ   s   & r+   rK   r,    s     \;[a!D'1;[s   "c              3      "   T F`  pR VR,           R\        VR,          4       RVR,           R\        \        VR,          ,          4       R\        VR,          4       R2x  Kb  	  R	# 5i)
z3<tr><td><a onclick="closeDetail();showDetail('deal-r   rA  z</a></td><td>r  r  rl  r   rm  N)r$  r  r+  s   & r+   rK   r,    ss      
  C1T7)5QSTUVZT[Q\P] ^W:,bF1W:$6!7 8	"Q{^BTAUU_as   A(A*z5<tr><td colspan='3' class='empty'>No deals.</td></tr>z7
          <div class="deal-detail" id="detail-company-z</h2>
            <div>r]  r^  r_  r   zV</div>
            <div class="grid2">
              <div class="k">Country</div><div>r   z;</div>
              <div class="k">Registration</div><div>r   z6</div>
              <div class="k">Address</div><div>r   z6</div>
              <div class="k">Website</div><div>r   z<</div>
              <div class="k">Email / Phone</div><div>r   r   z@</div>
              <div class="k">DD score / report</div><div>rw  rx  z<</div>
              <div class="k">DD checked at</div><div>ry  r   z;</div>
              <div class="k">OFAC details</div><div>rz  z></div>
              <div class="k">Blacklist match</div><div>rn  r|  z</div>
            </div>
            <h3>Incidents</h3>
            <table><tr><th>Date</th><th>Type</th><th>Description</th></tr>zk</table>
            <h3>Deals</h3>
            <table><tr><th>ID</th><th>Stage</th><th>Commodity</th></tr>z{ts}Tz	{db_path}z	{n_inbox}z
{n_active}z
{n_closed}z{n_companies}z{n_flagged}z{n_dd_needed}z{total_value:,.0f}z{comm_pending:,.0f}z{comm_paid:,.0f}z{alerts}z{kanban_columns}z{inbox_table}z{inbox_closed_table}z{deals_active_table}z{deals_closed_table}z{companies_table}z{flagged_table}z{incidents_table}z{detail_modals}r5  )ru   in_progressrr  )r,   r(   r!  
setdefaultr{   sumrM   rf   r$  rangerG  rH  r  rJ  r(  r>   rp   rK  r%   DASHBOARD_TEMPLATEitemsr  
write_text)Hr*   r  	companiesr  r  all_parties	all_commsall_docsall_logsr  comms_by_dealdocs_by_dealr  logs_by_dealru  incidents_by_companyr  active_dealsclosed_dealsopen_inquiriesclosed_inquiriesrJ   flagged_companies	dd_neededtotal_valuecomm_pending	comm_paidalerts_htmlbl_companiesnamesmorecolumns_html	stage_numstage_deals
cards_htmlr  rr  klass
volume_str	price_strdeal_headerdeals_active_htmldeals_closed_htmlinquiry_headerinbox_tableinbox_closed_tablecompany_headercompanies_tableflagged_tableincidents_tablemodals_htmlr  r  logsparties_rows
comms_rows	docs_rows	logs_rowsfolder_linkc_incidentsinc_rowsc_deals	deal_rowsreplacementshtmlkvr`  rK  rg  rW  rJ  sH                        `                                             @@@@@r+   r   r     s   	KLUUWLL!HIRRT	LL!ST]]_	LLV
 (* 	 llP
 (* 	 LL;
 (*	 	
 << RS\\^<< QR[[]% 
( O""1Y<4;;A> M  9r299!< LY<<##AiL"5<<Q?  LY<<##AiL"5<<Q?  	JKTTVA ++AlOR@GGJ W 
  %7u!'
QAAuL7$8u!'
aAAuL8!*DAakV.CaaND#,F9a(v0E9F$-kIq=1AEj1jIk%eIq;;d)dIIeZ\ZZKRyRRLKIKKI K(Ny!Am,<,MAAyLN		>\"-=>>474E4IS&q()0r?5	{4&Puv	
 )#i.)9  :\  ]	

 L1a[	"'C%QW:+Bqq%C
A%))!D'26Gc I@GIccc I@GI IG&-N6E89+AkN404EJOPQ\~~!AkN40!L/2I2IT1JKchI # '!=agY G!!#AdG .((*1[>(:'; <!!#A&9$:!; <DAjMAR@S T((2|?9+ N   <= ! kF9$5#66QRUVaRbQc dWWZ ! "	 	) !8$=K
  +rww&IL&IIJ(SD   +rww&IL&IIJ(SD DN
  .!"'')Q.)Q"Q!RRZ[H   .!"'')XBRSVBW)X"X!YYab!= 
PN  .!"'')L))L"L!MXVB   .!"'')TBS)T"T!UU]^"N   Y776I66
7x	AE  K !%%agr2!!!D'2.$,$,ww 
 
 
 K K K 	 WW 
 
 
 R R R 	 GG 

 
 
 I I I 	 GG 
 #Y
 
 E E E 	 M** *"Q}-=*>)??PQ05 	 	    4 45dG9= AdG. /1;.@-A	 BF	 GIK^I_F`Ea	 bl	 mnnulvkw	 xz	 {}  ~D  EF  GN  EO  ~P  {Q  zR	R1	 24AjM1B0C DF GIRST`RaIbciIjFkElm8 :;;9L9L1d7S TZ \]]i[j[o[onoquYvw/ 12+0C0C!T.J KP QSSTUaSbSjSjfjPkOlm1 24AjM4J4JU1K0LM6 7969K9Ke6L5M NQ RTTUV^T_ThThchQiPjk6 79?9K9T9Tu6U5VW/ 0;m<5 OPP\ooq<8I5Jch4ij. /171D1Du.E-FG`" am_m#"nf#& gqeq'&rg'* hqfq+*rf+. gpep/.q	/ 	Y P     7 78wi@ D'#. /1;.@-A	 BF	 GI6m_	 UY	 Z\\]^g\hYiXj	 ko	 puw~  @A  BJ  @K  L  vM  OP  QY  OZ  p[  o\	\0	 1315G3H3Q3QE0R/S TU qrr~ppWYZ[\hZiYjjkUl  FH  UII0 131]3C3L3Lu0M/NO2 35Q7G5H5Q5QE2R1ST/ 12+0C0C!T.J KX Z[[gYhYmYmlmosWtu/ 12+0C0C!T.J KL MOqQ]OfOfbfLgKhi1 24AjM4J4JU1K0LM6 7989M9M6N5O PU VXXYZ`XaXjXjejUkTlm0 131_3E3N3N0O/PQ1 24Q}5E5K5KS4Q1R0ST4 57q7G7P7P54Q3RS0  131Y<3H3H50I/J! K9!" :<A>P<Q<Z<ZUZ9[8\#"].#$ /171D1Du.E-F%$G	% 	 2 *..qw;77 
"
 
 I I I 	
 $ ^e)B'Cqw'N3\?;N;NqQUwXZ;[\333\?;N;NqQUwXZ;[\\ 1e ^GG 
 
 
 E E E	 	 	    7 78wi@ AfI  &=!1 23Q}5EFG	 HI	 JOQTUVWbUcTdOeghitguIvHw	 xy	 z  BG  HI  JW  HX  GY  @Z  \]  ^k  \l  zm  yn	n0	 131Y<3H3H50I/JK5 68:K8L8U8UPU5V4WX0 131Y<3H3H50I/JK0 131Y<3H3H50I/JK6 7979L9Lu6M5N OR SUUVW^U_UhUhchRiQjk: ;=Qz]=S=Se:T9U VZ []]^_o]p]y]ytyZzY{|6 79!O:L:R:RPRTW9X9a9a\a6b5cd5 68:L8M8V8VQV5W4XY8 9;1=U;V;d;dZd8e7fg. /171D1Du.E-FGK$ LT*%$UH%( IR{)(S	) 	 Nc
""3,S\ 	S^,- 	c#l+,	
 	c#l+, 	S^, 	s3012 	S^, 	T 2 	,t!4 	y. 	BGGK( 	BGGL1 	 	 2  	 1!" 	 1#$ 	_=_277;/+L. D""$1||Aq! % d#M 
F 
 88DFke O DP^s   C9AE>AAF7AF&AF&AF++AF+7AF0AF0AF5-AF59AF:AF:AF?/AF?3AGAG;AG	AG	#AG%+AG2AG
AGE>AF	FAF#	c                     \         P                  ! R R\         P                  \        P                  ! R4      R7      p V P                  RRR7      pVP                  R4      pVP                  RRR7      pVP                  R	4       VP                  R
4      pVP                  RRR7       VP                  R4      pVP                  R\        R7       VP                  R4      pVP                  R\        R7       VP                  RRR7       VP                  R4      pVP                  R\        R7       VP                  RRR7       VP                  R4      pVP                  R\        R7       VP                  R\        RRR7       VP                  R4      p	V	P                  RRR7      p
V
P                  R	4       V
P                  R
4      pVP                  RRR7       VP                  RRR7       V
P                  R4      pVP                  R\        R7       V
P                  R4      pVP                  R\        R7       V
P                  R4      pVP                  R\        R7       VP                  R \        R!7       V
P                  R"4      pVP                  R\        R7       V
P                  R#4      pVP                  R\        R7       VP                  R$4      pVP                  RRR7      pVP                  R	4      pVP                  R\        R7       VP                  R%4      pVP                  RRR7      pVP                  R	4       VP                  R
4      pVP                  R&RR7       VP                  R4      pVP                  R'4       VP                  R(4      pVP                  R'4       VP                  R)\        R7       VP                  R*RR7       VP                  R+4      pVP                  R'4       VP                  R*RR7       VP                  R,4      pVP                  R-RR7      pVP                  R.4      pVP                  R'4       VP                  R/4      pVP                  RRR7      pVP                  R.4      pVP                  R'4       VP                  R0\        RR1R7       VP                  R24      p V P                  R3\        R7       VP                  R44      p!V!P                  RRR7      p"V"P                  R.4      p#V#P                  R54       V#P                  R6RR7       VP                  R74      p$V$P                  R54       V$P                  R6RR7       VP                  R84       V P                  4       p%\        4        / R9\        bR:\        bR;\        bR<\        bR=\         bR>\"        bR?\$        bR@\&        bRA\(        bRB\*        bRC\,        bRD\.        bRE\0        bRF\2        bRG\4        bRH\6        bRI\8        bRJ\:        RK\<        RL\>        RM\@        RN\B        /Cp&V%PD                  \G        V%RR4      3p'V%PD                  R88X  d   \I        V%4       R# V%PD                  R78X  d   \K        V%4       R# V%PD                  R%8X  d   V%PL                  R,8X  d   \O        V%4       R# V'V&9   d   V&V',          ! V%4       R# V PQ                  4        \R        PT                  ! ^4       R# )OpipelineuA   i4Fuel deal pipeline (v2 — companies, inquiries, incidents, DD)a  
            common flow:
              pipeline.py inquiry new                          new inbound FCO/RFQ
              pipeline.py company check <id>                   record DD result
              pipeline.py inquiry convert <id>                 promote to deal
              pipeline.py deal advance <deal-id>               next stage
              pipeline.py deal close <deal-id>

            other:
              pipeline.py inquiry list [--all]
              pipeline.py inquiry reject <id> --reason "..."
              pipeline.py inquiry link <id> --company <cid>

              pipeline.py company new
              pipeline.py company list [--needs-dd|--flagged]
              pipeline.py company show <id>
              pipeline.py company trust <id> --level scammer
              pipeline.py company ofac <id>
              pipeline.py company incident <id>

              pipeline.py contact new <company-id>

              pipeline.py deal new                             outbound origination
              pipeline.py deal list [--closed]
              pipeline.py deal show <deal-id>
              pipeline.py deal party add <deal-id>
              pipeline.py comm add <deal-id> --party <party-id>
              pipeline.py comm pay <commission-id>
              pipeline.py doc add <deal-id-or-inquiry-id> [--inquiry]
              pipeline.py log <deal-id-or-inquiry-id> [--inquiry]
              pipeline.py dashboard
        )progr  formatter_classepilogcmdT)destr   r  actionnewr   z--all
store_true)r  showr   )r  convertz--forcerejectz--reasonNr   linkz	--companyr   )r  r   r  rM  z
--needs-ddz	--flaggedcheckr  z--level)choicesofacincidentcontactr  z--closedr   advancez--stagez--notecloser  action2addcommz--partyr  payr   rs  r  z	--inquirylog	dashboard)r  r  )r  r   )r  r  )r  r  )r  r  )r  r  )rM  r  )rM  r   )rM  r  )rM  r  )rM  r  )rM  r  )rM  r  )r  r  )r  r  )r  r   )r  r  )r  r  )r  r  )r  r  )r  r  )rs  r  )+argparseArgumentParserRawDescriptionHelpFormattertextwrapdedentadd_subparsers
add_parseradd_argumentr   r  
parse_argsr:   r
  r$  r6  rQ  r\  r^  re  rt  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  
print_helpr4  r5  )(parserr   rL  inq_subinq_listinq_showinq_convinq_rejinq_linkcoco_subco_listco_showco_checkco_trustco_ofacco_incr  ct_subct_newr  deal_subd_listd_showd_advd_closed_partyd_party_subd_party_addr  comm_subc_addc_payrs  doc_subd_addr  r   handlerskeys(                                           r+   mainr    s   $$W <<   	$FJ 

UT

:C ..
#C  h >Gu!!&)H',7!!&)H$S)!!),H$S))L9  *GC(T2!!&)H$S)+C$\R 
		"BHt<F
e'Gl;\:'GC(  )H$S)  )H$S))\:'GC(z*F
3' 
		"BHt<Fu%F
3/ >>&!D""4"@H  (F

<8  (F
	"	*E	y!	ys+	x.!!'*G#40!!'*G((i$(GK((/KY' >>&!D""4"@H&E	y!	ysT
K&E	S1 ..
C  h >Gu%E	{#	{<8 ..
C[![6NN;DIO- 	- 	 3	
 	1 	- 	O 	- 	- 	/ 	/ 	- 	 !5 	O 	  	-!" 	-#$ 	->++-H0 88WT8T2
3Cxx;d	U	T	V	w 64 	dr-   __main__)
01_Inquiry
02_Mandate03_Offer04_Contract05_Verification
06_Payment07_Commission	08_Closed)r>  r?  rH  mandater   	paymaster)r   verifiedr6  rF  r   )ru   r}  r<  r  rr  )rw   	in_reviewr9  rejectedno_responsestale)RFQr  r  r  introductioncold_outreach)
rU  rV  no_showrW  contract_breachsuspicious_docr   r   rejected_inquiryr  )NFN)NF)NNNNNNN)V__doc__r  rx   jsonosr  r#   r4  r  urllib.requestr_   r   r   r   pathlibr   r3   r%   r  r5   r6   r   __file__r  r7   rW   rb   r]   r   r  rJ  r   r  r  r  INQUIRY_STATUSESr   rY  r9   r,   r:   r>   rP   rn   r   r   r   r   r   r   r   r   r   r   r   r
  r$  r6  rQ  r\  r^  re  rt  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r$  r(  r   r  __name__rA   r-   r+   <module>r     s    
  	   
   2 2  ^ 
$ 00H$
H$
m  N!!G+	'
<  y!_a);0!Y8
 v{E:6&15*Ef(%< !5-?S[%1I	)
K	 TKKY Mu
p#D
8(6(&)+LR&TAHT(/BGTD"4],1fh6	4"6>BQ$AHD88 FB:b J::g$VdN zF r-   