Ë
    ~jx·  ã                  óÖ  — U d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
m
Z
mZmZ ddlmZ ddlZddlmZmZmZmZmZmZmZ ddlmZmZmZ ddlmZ dd	lmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%  ee&«      jO                  «       jP                  Z)e)d
z  Z*e)dz  Z+ejX                  j[                  dd«      j]                  «       Z/ejX                  j[                  dd«      ja                  d«      Z1ejX                  j[                  dd«      j]                  «       Z2ejX                  j[                  dd«      j]                  «       Z3 e4ejX                  j[                  dd«      xs d«      Z5ejX                  j[                  dd«      j]                  «       Z6ejX                  j[                  dd«      j]                  «       Z7ejX                  j[                  dd«      j]                  «       Z8ejX                  j[                  dd«      j]                  «       Z9ejX                  j[                  dd«      j]                  «       Z:ejX                  j[                  dd«      j]                  «       Z;ejX                  j[                  dd«      ja                  d«      Z<dZ=dZ>dZ?d Z@d!ZAd"ZBd#ZCd$ZDi ZEd%eFd&<    ejŽ                  «       ZHd'ZIdZd(„ZJ	 d[	 	 	 d\d)„ZKd]d*„ZLd^d+„ZM	 d[	 	 	 d_d,„ZN	 	 	 	 	 	 d`d-„ZOdad.„ZPdbd/„ZQ	 d[	 	 	 dcd0„ZR	 	 	 	 	 	 ddd1„ZSdedfd2„ZTdgd3„ZUdhd4„ZVdid5„ZWdjd6„ZXdkd7„ZYdld8„ZZ ed9e[«      Z\e\j»                  d:d;g¬<«      d=„ «       Z^e\j»                  d>d?g¬<«      dmd@„«       Z_e\j»                  dAd;g¬<«      edB„ «       «       Z`e\j»                  dCd;g¬<«      edD„ «       «       Zae\j»                  dEd;g¬<«      dF„ «       Zbe\j»                  dGd?g¬<«      edH„ «       «       ZcdIjÉ                  dJe=«      ZedKjÉ                  dJe>«      jÉ                  dLe?«      Zfe\j»                  dMd?g¬<«      dN„ «       Zge\j»                  dOd?g¬<«      dP„ «       Zhe\j»                  dQdRd;g¬<«      edS„ «       «       ZidTZjdndU„ZkdV„ ZldodW„ZmdpdX„ZndZdY„Zoy)quŠ  
climbleads_signup.py â€” Sprint 1 Fase 2 ClimbLeads
=================================================

MÃ³dulo isolado que agrupa TODAS as rotas / lÃ³gica adicionadas no Sprint 1
Fase 2. Fica separado do app.py monolÃ­tico pra facilitar review, rollback
e manutenÃ§Ã£o. Ã‰ registrado via `register_climbleads_routes(app)` no boot.

Cobre:
  Item 2 â€” Cadastro pÃºblico self-service (POST /signup, GET /verify/<token>)
  Item 3 â€” IntegraÃ§Ã£o Asaas (customer, trial, subscription, webhook, cancel)
  Item 4 â€” Enforcement de cota (trial 100 leads/7d, plano 1000 leads/mÃªs)
  Item 5 â€” LGPD (termos, privacidade, aceite, deleÃ§Ã£o de conta)

Design:
  - PersistÃªncia 100% em users.db (mesmo banco do resto).
  - Tabelas novas criadas idempotentemente em ensure_schema().
  - Email de verificaÃ§Ã£o: se SMTP/Resend/Sendgrid configurado, envia. Caso
    contrÃ¡rio, imprime o link no log e deixa em um arquivo local pra dev.
  - Captcha: hCaptcha OU Turnstile suportados; se nenhum configurado,
    fica desativado (log warn). Ative com HCAPTCHA_SECRET ou TURNSTILE_SECRET.
  - SeguranÃ§a: rate limit por IP no /signup; token 32 bytes secrets.token_urlsafe.
é    )ÚannotationsN)ÚdatetimeÚ	timedeltaÚtimezone)ÚPath)Ú	BlueprintÚcurrent_appÚjsonifyÚredirectÚrender_template_stringÚrequestÚurl_for)Úcurrent_userÚlogin_requiredÚ
login_user)Úgenerate_password_hash)ÚUserÚ	_get_connÚbuscar_por_emailÚcriar_contaÚcriar_usuarioÚ	get_quotaÚincrementar_quotazusers.dbzdev_verify_links.logÚASAAS_API_KEYÚ ÚASAAS_BASE_URLzhttps://api.asaas.com/v3ú/ÚASAAS_WEBHOOK_TOKENÚ	SMTP_HOSTÚ	SMTP_PORTÚ587iK  Ú	SMTP_USERÚ	SMTP_PASSÚ	SMTP_FROMzno-reply@agenciaclimb.com.brÚRESEND_API_KEYÚHCAPTCHA_SECRETÚTURNSTILE_SECRETÚPUBLIC_BASE_URLz
2026-08-13zcontato@agenciaclimb.com.bré   éd   iè  g      h@g     �›@zdict[str, list[float]]Ú_signup_attemptsé   c                 ó¶  — t        j                  t        t        «      «      } | j	                  «       }|j                  d«       |j                  d«       |j                  d«       |j                  d«       |j                  d«       dD ]  }	 |j                  |«       Œ | j                  «        | j                  «        y# t         j                  $ r Y ŒMw xY w)u<   Cria/migra tabelas do Sprint 1 Fase 2 se ainda nÃ£o existem.a›  
        CREATE TABLE IF NOT EXISTS user_signup_meta (
            user_id INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
            telefone TEXT,
            cpf_cnpj TEXT,
            email_verified_at TEXT,
            verify_token TEXT UNIQUE,
            verify_token_expira_em TEXT,
            criado_em TEXT NOT NULL,
            ip_signup TEXT,
            user_agent TEXT
        )
    aP  
        CREATE TABLE IF NOT EXISTS lgpd_aceites (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
            termos_versao TEXT NOT NULL,
            privacidade_versao TEXT NOT NULL,
            ip TEXT,
            aceito_em TEXT NOT NULL
        )
    a‹  
        CREATE TABLE IF NOT EXISTS assinaturas (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            conta_id INTEGER NOT NULL REFERENCES contas(id) ON DELETE CASCADE,
            user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
            asaas_customer_id TEXT,
            asaas_subscription_id TEXT UNIQUE,
            status TEXT NOT NULL DEFAULT 'trial',
            plano TEXT NOT NULL DEFAULT 'trial',
            valor REAL DEFAULT 0,
            trial_expira_em TEXT,
            ultimo_pagamento TEXT,
            proximo_pagamento TEXT,
            criado_em TEXT NOT NULL,
            atualizado_em TEXT
        )
    aY  
        CREATE TABLE IF NOT EXISTS asaas_webhook_events (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            event_id TEXT UNIQUE,
            event_type TEXT,
            payment_id TEXT,
            subscription_id TEXT,
            customer_id TEXT,
            payload TEXT,
            processado_em TEXT NOT NULL
        )
    ad  
        CREATE TABLE IF NOT EXISTS lgpd_delecoes (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
            solicitado_em TEXT NOT NULL,
            executar_em TEXT NOT NULL,
            executado_em TEXT,
            status TEXT NOT NULL DEFAULT 'pendente'
        )
    )z6ALTER TABLE ghl_config ADD COLUMN trial_expira_em TEXTN)	Úsqlite3ÚconnectÚstrÚDB_PATHÚcursorÚexecuteÚOperationalErrorÚcommitÚclose)ÚconnÚcurÚddls      ú8/opt/mia/workspace/prospeccao_ativa/climbleads_signup.pyÚensure_schemar;   a   sÎ   € ä�?‰?œ3œw›<Ó(€DØ
�+‰+‹-€Cð ‡K�Kð ô 	ð ‡K�Kð 	ô 		ð ‡K�Kð ô 	ð& ‡K�Kð ô 	ð ‡K�Kð 	ô 		ðò ˆð	Ø�K‰K˜Õð	ð 	‡K�K„MØ‡J�J…Løô	 ×'Ñ'ò 	Ùð	ús   ÂCÃCÃCc           
     ó¢  — |xs t        j                  dd|«      }t        r`	 t        j                  ddt        › �ddœt
        | g|||dœd¬	«      }|j                  d
k  rydd|j                  › d|j                  dd › �fS t        ràt        rÚt        rÔ	 ddl}ddlm} ddlm}  |d«      }	||	d<   t
        |	d<   | |	d<   |	j#                   ||dd«      «       |	j#                   ||dd«      «       |j%                  t        t&        d¬«      5 }
|
j)                  «        |
j+                  t        t        «       |
j-                  t
        | g|	j/                  «       «       ddd«       y	 t0        j3                  dd¬ «      5 }|j5                  d!t7        j8                  «       j;                  «       › d"| › d#|› d$�«       |j5                  |d$z   d%z   d$z   «       ddd«       t=        d&| › d'|›�«       y(# t        $ r}dd|› �fcY d}~S d}~ww xY w# 1 sw Y   yxY w# t        $ r}dd|› �fcY d}~S d}~ww xY w# 1 sw Y   ŒaxY w# t        $ r Y Œow xY w))z·Envia email. Ordem de prioridade:
       1. Resend (se RESEND_API_KEY)
       2. SMTP (se SMTP_HOST + SMTP_USER + SMTP_PASS)
       3. Mock (grava em log + arquivo, retorna True)
    z<[^>]+>r   zhttps://api.resend.com/emailszBearer úapplication/json)ÚAuthorizationúContent-Type)ÚfromÚtoÚsubjectÚhtmlÚtexté   ©ÚheadersÚjsonÚtimeouté,  )TÚresendFzresend HTTP ú: NéÈ   zresend erro: r   )ÚMIMEMultipart)ÚMIMETextÚalternativeÚSubjectÚFromÚToÚplainzutf-8rC   )rI   )TÚsmtpzsmtp erro: Úa)Úencodingú[z] TO=z | SUBJ=Ú
z<------------------------------------------------------------z[EMAIL-MOCK] to=z subj=)TÚmock)ÚreÚsubr%   ÚrequestsÚpostr$   Ústatus_coderD   Ú	Exceptionr   r"   r#   ÚsmtplibÚemail.mime.multipartrN   Úemail.mime.textrO   ÚattachÚSMTPr    ÚstarttlsÚloginÚsendmailÚ	as_stringÚDEV_VERIFY_LINKS_LOGÚopenÚwriter   ÚnowÚ	isoformatÚprint)ÚdestinatarioÚassuntoÚ	html_bodyÚ	text_bodyÚrÚera   rN   rO   ÚmsgÚsÚfs               r:   Úenviar_emailry   ¿   sP  € ð Ò>œRŸV™V J°°IÓ>€Iåð	.Ü—‘Ø/à'.¬~Ð.>Ð%?Ø$6ñô
 &Ø'˜.Ø&Ø%Ø%ñð ôˆAð �}‰}˜sÒ"Ø%Ø˜L¨¯©¨°r¸!¿&¹&ÀÀ#¸,¸ÐHÐHÐHõ •Y¥9ð	,ÛÝ:Ý0Ù Ó.ˆCØ$ˆC�	‰NÜ#ˆC�‰KØ$ˆC�‰IØ�J‰J‘x 	¨7°GÓ<Ô=Ø�J‰J‘x 	¨6°7Ó;Ô<Ø—‘œi¬¸B�Ó?ð GÀ1Ø—
‘
”Ø—‘œ	¤9Ô-Ø—
‘
œ9 | n°c·m±m³oÔF÷Gð  ð
Ü!×&Ñ& s°WÐ&Ó=ð 	:ÀØ�G‰G�aœŸ™›×0Ñ0Ó2Ð3°5¸¸ÀhÈwÈiÐWYÐZÔ[Ø�G‰G�I Ñ$¨Ñ1°DÑ8Ô9÷	:ô
 
Ð˜\˜N¨&°°Ð
<Ô=Øøô= ò 	.Ø˜M¨!¨Ð-Ð-Õ-ûð	.ú÷Gð  ûÜò 	,Ø˜K¨ sÐ+Ð+Õ+ûð	,ú÷
	:ð 	:ûô ò ÙðúsŒ   £=G0 Á! G0 ÂA9H ÄAHÅH Å)I Æ AH6ÇI Ç0	H
Ç9HÇ?H
ÈH
ÈHÈH ÈH È	H3È"H.È(H3È.H3È6H?È;I É	IÉIc                óV  — | st         st        st        d«       yyt         rd	 t        j                  dt         | |dœd¬«      }|j
                  dk(  r |j                  «       j                  d	«      ry
dd|j                  dd › �fS t        rd	 t        j                  dt        | |dœd¬«      }|j
                  dk(  r |j                  «       j                  d	«      rydd|j                  dd › �fS y# t        $ r}dd|› �fcY d}~S d}~ww xY w# t        $ r}dd|› �fcY d}~S d}~ww xY w)u°   Valida hCaptcha OU Turnstile. Retorna (ok, provedor|erro).
       Se nenhum secret configurado, retorna (True, 'disabled') pra nÃ£o
       travar dev â€” mas loga um WARN.
    zI[captcha] WARN: nenhum provedor configurado; aceitando signup sem captcha)TÚdisabled)Fzcaptcha ausentezhttps://hcaptcha.com/siteverify)ÚsecretÚresponseÚremoteipé   )ÚdatarI   rM   Úsuccess)TÚhcaptchaFz
hcaptcha: Néx   zhcaptcha erro: z9https://challenges.cloudflare.com/turnstile/v0/siteverify)TÚ	turnstilezturnstile: zturnstile erro: )Fz-nenhum provedor configurado mas token enviado)
r&   r'   ro   r]   r^   r_   rH   ÚgetrD   r`   )ÚtokenÚ	remote_iprt   ru   s       r:   Ú_validar_captcharˆ     s6  € ñ
 ÝÕ#3ÜÐ]Ô^Ø#Ø'åð
	0Ü—‘Ø1Ü /¸UÐPYÑZØôˆAð
 �}‰} Ò#¨¯©«¯©°YÔ(?Ø'Ø˜J q§v¡v¨d¨s | nÐ5Ð5Ð5õ ð
	1Ü—‘ØKÜ 0¸eÐQZÑ[ØôˆAð
 �}‰} Ò#¨¯©«¯©°YÔ(?Ø(Ø˜K¨¯©¨t°¨ ~Ð6Ð6Ð6ð Bøô! ò 	0Ø˜O¨A¨3Ð/Ð/Õ/ûð	0ûô ò 	1ØÐ,¨Q¨CÐ0Ð0Õ0ûð	1úsI   £AC1 Á2C1 ÂAD ÃD Ã1	DÃ:DÄ DÄDÄ	D(ÄD#ÄD(Ä#D(c                 ó   — t         dddœS )Nr=   zClimbLeads/1.0)Úaccess_tokenr?   ú
User-Agent)r   © ó    r:   Ú_asaas_headersrŽ   -  s   € ä%Ø*Ø&ñð r�   c                ó¾  — t         sy| |t        j                  dd|xs d«      dœ}|rt        j                  dd|«      |d<   	 t        j                  t
        › d�t        «       |d¬«      }|j                  d	v r!|j                  «       j                  d
«      dfS dd|j                  › d|j                  dd › �fS # t        $ r}dt        |«      fcY d}~S d}~ww xY w)z4Cria customer no Asaas. Retorna (customer_id, erro).)Nõ   ASAAS_API_KEY nÃ£o configuradoú\Dr   )ÚnameÚemailÚcpfCnpjÚmobilePhonez
/customersrE   rF   ©rM   éÉ   ÚidNúHTTP rL   rM   )r   r[   r\   r]   r^   r   rŽ   r_   rH   r…   rD   r`   r0   )Únomer“   Úcpf_cnpjÚtelefoneÚpayloadrt   ru   s          r:   Úasaas_criar_customerrž   5  sØ   € õ Ø5àØÜ—6‘6˜%  X¢^°Ó4ñ€Gñ
 Ü!#§¡¨¨r°8Ó!<ˆ�ÑðÜ�M‰Mœ^Ð,¨JÐ7ÄÓAQØ&°ô4ˆà�=‰=˜JÑ&Ø—6‘6“8—<‘< Ó% rÐ)Ð)Ø�u˜QŸ]™]˜O¨2¨a¯f©f°T°c¨l¨^Ð<Ð<Ð<øÜò Ø”S˜“Vˆ|Õûðús%   ÁAB< Â B< Â<	CÃCÃCÃCc           
     ó  — t         sddi fS |dk(  r	t        }d}nt        }d}t        j                  «       t        t        ¬«      z   j                  d«      }| d|||d	|› �|||d
œ	}	 t        j                  t        › d�t        «       |d¬«      }	|	j                  dv r$|	j                  «       }
|
j                  d«      d|
fS dd|	j                  › d|	j                  dd › �i fS # t         $ r}dt#        |«      i fcY d}~S d}~ww xY w)u’   Cria assinatura recorrente com cartÃ£o tokenizado.
       plano: 'mensal' | 'anual'
       Retorna (subscription_id, erro, payload_completo).
    Nr�   ÚanualÚYEARLYÚMONTHLY©Údaysz%Y-%m-%dÚCREDIT_CARDzClimbLeads plano )	ÚcustomerÚbillingTypeÚvalueÚnextDueDateÚcycleÚdescriptionÚ
creditCardÚcreditCardHolderInfoÚremoteIpz/subscriptionsé   rF   r–   r˜   r   r™   rL   rJ   )r   ÚPLANO_ANUAL_VALORÚPLANO_MENSAL_VALORr   rm   r   ÚPLANO_TRIAL_DIASÚstrftimer]   r^   r   rŽ   r_   rH   r…   rD   r`   r0   )Úcustomer_idÚplanoÚcredit_cardÚcredit_card_holderr‡   ÚvalorÚcicloÚproximo_vencr�   rt   r€   ru   s               r:   Úasaas_criar_subscriptionr»   K  s  € õ ØÐ5°rÐ9Ð9à�ÒÜ!ˆØ‰ä"ˆØˆä—L‘L“N¤YÔ4DÔ%EÑE×OÑOÐPZÓ[€LàØ$ØØ#ØØ*¨5¨'Ð2Ø!Ø 2Øñ
€Gð Ü�M‰Mœ^Ð,¨NÐ;Ä^ÓEUØ&°ô4ˆà�=‰=˜JÑ&Ø—6‘6“8ˆDØ—8‘8˜D“> 2 tÐ+Ð+Ø�u˜QŸ]™]˜O¨2¨a¯f©f°T°c¨l¨^Ð<¸bÐ@Ð@øÜò  Ø”S˜“V˜RÐÕûð ús%   Á&AC" Ã !C" Ã"	DÃ+C>Ã8DÃ>Dc                ó
  — t         sy	 t        j                  t        › d| › �t	        «       d¬«      }|j
                  dv rydd|j
                  › d	|j                  d d
 › �fS # t        $ r}dt        |«      fcY d }~S d }~ww xY w)N)Fr�   z/subscriptions/rE   )rG   rI   )rM   éÌ   ©Tr   Fr™   rL   rM   )	r   r]   Údeleter   rŽ   r_   rD   r`   r0   )Úsubscription_idrt   ru   s      r:   Úasaas_cancelar_subscriptionrÁ   r  s†   € ÝØ6ðÜ�O‰Oœ~Ð.¨o¸oÐ=NÐOÜ$2Ó$4¸bôBˆà�=‰=˜JÑ&ØØ˜˜aŸm™m˜_¨B¨q¯v©v°d°s¨|¨nÐ=Ð=Ð=øÜò Ø”c˜!“fˆ}Õûðús#   ‰7A" Á A" Á"	BÁ+A=Á7BÁ=Bc                ó–   — t        «       }|j                  d| f«      j                  «       }|j                  «        |rt	        |«      S d S )NzESELECT * FROM assinaturas WHERE conta_id = ? ORDER BY id DESC LIMIT 1)r   r3   Úfetchoner6   Údict)Úconta_idr7   Úrows      r:   Úget_assinatura_by_contarÇ   ƒ  sG   € Ü‹;€DØ
�,‰,ØOØ	ˆó÷ �hƒjð ð 	‡J�J„LÙŒ4�‹9Ð% Ð%r�   c           
     óP  — t        j                  «       t        t        ¬«      z   j	                  «       }t        «       }|j                  d| |||t        j                  «       j	                  «       t        j                  «       j	                  «       f«      }|j                  d| t        t        j                  «       j	                  «       |f«       |j                  «        |j                  }|j                  d|f«      j                  «       }|j                  «        t        |«      S )Nr£   zÝ
        INSERT INTO assinaturas
            (conta_id, user_id, asaas_customer_id, status, plano, valor,
             trial_expira_em, criado_em, atualizado_em)
        VALUES (?, ?, ?, 'trial', 'trial', 0, ?, ?, ?)
    aP  
        INSERT INTO ghl_config (conta_id, leads_limite, leads_usados, quota_reset_em, trial_expira_em)
        VALUES (?, ?, 0, ?, ?)
        ON CONFLICT(conta_id) DO UPDATE SET
            leads_limite=excluded.leads_limite,
            trial_expira_em=excluded.trial_expira_em,
            quota_reset_em=excluded.quota_reset_em
    z&SELECT * FROM assinaturas WHERE id = ?)r   rm   r   r²   rn   r   r3   ÚPLANO_TRIAL_LEADSr5   Ú	lastrowidrÃ   r6   rÄ   )rÅ   Úuser_idÚasaas_customer_idÚ	trial_fimr7   r8   Úass_idrÆ   s           r:   Úcriar_assinatura_trialrÏ   �  sæ   € ä—‘“¤)Ô1AÔ"BÑB×MÑMÓO€IÜ‹;€DØ
�,‰,ð ð
 �GÐ.°	Ü
�,‰,‹.×
"Ñ
"Ó
$¤h§l¡l£n×&>Ñ&>Ó&@ð
BóC€Cð 	‡L�Lð ð Ô%¤x§|¡|£~×'?Ñ'?Ó'AÀ9Ð	MôOð 	‡K�K„MØ�]‰]€FØ
�,‰,Ð?À&ÀÓ
K×
TÑ
TÓ
V€CØ‡J�J„LÜ�‹9Ðr�   c           	     ó:  — t        «       }|j                  d|||t        j                  «       j	                  «       | | f«       |j                  dt
        t        j                  «       j	                  «       | f«       |j                  «        |j                  «        y )Na  
        UPDATE assinaturas
           SET asaas_subscription_id = ?, status = 'ativa',
               plano = ?, valor = ?, atualizado_em = ?
         WHERE conta_id = ?
           AND id = (SELECT id FROM assinaturas WHERE conta_id = ? ORDER BY id DESC LIMIT 1)
    z¨
        UPDATE ghl_config
           SET leads_limite = ?, leads_usados = 0, trial_expira_em = NULL,
               quota_reset_em = ?
         WHERE conta_id = ?
    )r   r3   r   rm   rn   ÚPLANO_PAGO_LEADS_MESr5   r6   )rÅ   rÀ   rµ   r¸   r7   s        r:   Úatualizar_assinatura_pagarÒ   ¨  s�   € ä‹;€DØ‡L�Lð ð ˜5 %¬¯©«×)AÑ)AÓ)CØ
�Hð
ôð 	‡L�Lð ô
 ¤§¡£× 8Ñ 8Ó :¸HÐ	EôGð 	‡K�K„MØ‡J�J…Lr�   c                óÊ   — t        «       }|j                  dd|› �t        j                  «       j	                  «       | | f«       |j                  «        |j                  «        y )Nz»
        UPDATE assinaturas SET status = ?, atualizado_em = ?
         WHERE conta_id = ?
           AND id = (SELECT id FROM assinaturas WHERE conta_id = ? ORDER BY id DESC LIMIT 1)
    Ú	suspensa_©r   r3   r   rm   rn   r5   r6   )rÅ   Úmotivor7   s      r:   Úsuspender_assinaturar×   ¾  sS   € Ü‹;€DØ‡L�Lð ð �f�XÐ
¤§¡£× 8Ñ 8Ó :¸HÀhÐ	Oô	Qð
 	‡K�K„MØ‡J�J…Lr�   c                óÂ   — t        «       }|j                  dt        j                  «       j	                  «       | | f«       |j                  «        |j                  «        y )NzÁ
        UPDATE assinaturas SET status = 'ativa', atualizado_em = ?
         WHERE conta_id = ?
           AND id = (SELECT id FROM assinaturas WHERE conta_id = ? ORDER BY id DESC LIMIT 1)
    rÕ   )rÅ   r7   s     r:   Úreativar_assinaturarÙ   É  sI   € Ü‹;€DØ‡L�Lð ô �,‰,‹.×
"Ñ
"Ó
$ h°Ð	9ô	;ð
 	‡K�K„MØ‡J�J…Lr�   c                óD  — t        | «      }|sy|j                  d«      xs d}|dk(  ry|dk(  rA|j                  d«      }|r-	 t        j                  |«      t        j                  «       k\  ryy	y|j                  d«      rd|fS |dk(  ryd|xs dfS # t
        $ r Y y
w xY w)uI   True se conta pode usar a ferramenta (trial vÃ¡lido OU assinatura ativa).)TÚlegadoÚstatusr   Úativa)TrÝ   ÚtrialÚtrial_expira_em)TrÞ   )FÚtrial_expirado)FÚtrial_data_invalidaÚsuspensaFÚ	cancelada)Frã   Ú
indefinido)rÇ   r…   r   Úfromisoformatrm   r`   Ú
startswith)rÅ   ÚassrÜ   rÍ   s       r:   Úassinatura_permite_usorè   Ô  sº   € ä
! (Ó
+€CÙàØ�W‰W�XÓÒ$ "€FØ�ÒØØ�ÒØ—G‘GÐ-Ó.ˆ	Ùð4Ü×)Ñ)¨)Ó4¼¿¹»ÒFØ(Ø.ð Ø×Ñ˜Ô$Ø�fˆ}ÐØ�ÒØ!Ø�&Ò(˜LÐ(Ð(øô ò 4Ù3ð4ús   Á*B Â	BÂBc                óú   — t        j                   «       }t        5  t        j                  | g «      D �cg c]  }||z
  dk  sŒ|‘Œ }}|t        | <   t	        |«      t
        k  cd d d «       S c c}w # 1 sw Y   y xY w)Ni  )ÚtimeÚ_signup_lockr+   r…   ÚlenÚSIGNUP_LIMIT_PER_HOUR)Úiprm   ÚtÚarrs       r:   Ú_signup_poderñ   ò  so   € Ü
�)‰)‹+€CÜ	ñ 0Ü*×.Ñ.¨r°2Ó6ÖI�Q¸#À¹'ÀD».ŠqÐIˆÐIØ"Ô˜ÑÜ�3‹xÔ/Ñ/÷0ñ 0ùÚI÷0ð 0ús"   ›A1´A,ÁA,ÁA1Á,A1Á1A:c                ó¨   — t         5  t        j                  | g «      j                  t	        j                  «       «       d d d «       y # 1 sw Y   y xY w)N)rë   r+   Ú
setdefaultÚappendrê   )rî   s    r:   Ú_signup_registrarrõ   ú  s?   € Ü	ñ @Ü×#Ñ# B¨Ó+×2Ñ2´4·9±9³;Ô?÷@÷ @ñ @ús   ‡8AÁAc                óR   — t        j                  dd| xs d«      }t        |«      dv S )Nr‘   r   )é   é   )r[   r\   rì   )ÚrawÚds     r:   Ú_cpf_cnpj_okrû     s'   € Ü
�‰ˆu�b˜#š) Ó$€AÜˆq‹6�XÐÐr�   c                ó*   — t        | xs d«      dk  ryy)Nr   r   )Fz'senha precisa ter ao menos 8 caracteresr¾   )rì   )Úsenhas    r:   Ú	_senha_okrþ     s   € Ü
ˆ5Š;�BÓ˜!ÒØ?Ør�   Ú
climbleadsz/signupÚPOST)Úmethodsc                 ó.
  — t         j                  j                  d«      xs t         j                  xs dj	                  d«      d   j                  «       } t        | «      st        dddœ«      dfS t        j                  d	¬
«      xs t         j                  j                  «       }|j                  d«      xs dj                  «       j                  «       }|j                  d«      xs dj                  «       }|j                  d«      xs dj                  «       }|j                  d«      xs dj                  «       }|j                  d«      xs dj                  «       }t        |j                  d«      «      }|j                  d«      xs( |j                  d«      xs |j                  d«      xs d}|rt        j                  d|«      st        dddœ«      dfS |rt        |«      dk  rt        dddœ«      dfS t!        |«      \  }	}
|	st        d|
dœ«      dfS |r#t        t        j"                  dd|«      «      dk  rt        dddœ«      dfS t%        |«      st        dddœ«      dfS |st        dddœ«      dfS t'        || «      \  }}|st        dd|› �dœ«      dfS t)        |«      rt        dd dœ«      d!fS t+        |› d"�¬#«      }t-        |||d$|d%   ¬&«      \  }}|st        dd'|› �dœ«      d(fS t/        |d%   t1        |j2                  «      «       t5        «       }|j7                  d)t1        |j2                  «      t8        t:        | t=        j>                  «       jA                  «       f«       |jC                  «        tE        jF                  d*«      }t=        j>                  «       tI        d+¬,«      z   jA                  «       }|j7                  d-t1        |j2                  «      |t        j"                  dd|«      ||t=        j>                  «       jA                  «       | t         j                  j                  d.d«      d d/ f«       |j7                  d0t1        |j2                  «      f«       |jC                  «        |jK                  «        tM        | «       tN        xs t         jP                  jS                  d1«      }|› d2|› �}d3|› d4|› d5|› d6�}tU        |d7|«      \  }}t        d	t1        |j2                  «      |d%   |||d8d9œ«      d:fS );NúX-Forwarded-Forú?Ú,r   Fzmuitas tentativas, aguarde 1h©ÚokÚerroi­  T©Úsilentr“   r   rý   rš   rœ   r›   Úaceite_lgpdÚcaptcha_tokenzh-captcha-responsezcf-turnstile-responsez^[^@\s]+@[^@\s]+\.[^@\s]+$u   email invÃ¡lidoé�  é   u   nome obrigatÃ³rior‘   é
   u   telefone invÃ¡lido (com DDD)u   CPF ou CNPJ invÃ¡lidou,   Ã© obrigatÃ³rio aceitar Termos e Privacidadeu   captcha invÃ¡lido: u   email jÃ¡ cadastradoi™  z (self-signup))rš   rÞ   r˜   )rš   r“   rý   rµ   rÅ   u"   nÃ£o conseguimos criar sua conta: iô  z�
        INSERT INTO lgpd_aceites (user_id, termos_versao, privacidade_versao, ip, aceito_em)
        VALUES (?, ?, ?, ?, ?)
    é    é   )Úhoursao  
        INSERT INTO user_signup_meta
            (user_id, telefone, cpf_cnpj, verify_token, verify_token_expira_em,
             criado_em, ip_signup, user_agent)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?)
        ON CONFLICT(user_id) DO UPDATE SET
            verify_token=excluded.verify_token,
            verify_token_expira_em=excluded.verify_token_expira_em
    r‹   rM   z'UPDATE users SET ativo = 0 WHERE id = ?r   z/verify/u   
        <p>OlÃ¡, u�   !</p>
        <p>Bem-vindo ao ClimbLeads. Pra ativar sua conta, clique no link abaixo (vÃ¡lido por 24h):</p>
        <p><a href="z">u~   </a></p>
        <p>Se vocÃª nÃ£o solicitou este cadastro, ignore este email.</p>
        <p>â€” Equipe Climb Digital</p>
    zAtive sua conta ClimbLeadsz,conta criada, verifique seu email pra ativar)r  rË   rÅ   r“   Úverify_email_enviadoÚemail_provedorÚmensagemr—   )+r   rG   r…   Úremote_addrÚsplitÚstriprñ   r
   Úget_jsonÚformÚto_dictÚlowerÚboolr[   Úmatchrì   rþ   r\   rû   rˆ   r   r   r   rÏ   Úintr˜   r   r3   ÚLGPD_TERMOS_VERSAOÚLGPD_PRIVACIDADE_VERSAOr   rm   rn   r5   ÚsecretsÚtoken_urlsafer   r6   rõ   r(   Úhost_urlÚrstripry   )rî   r€   r“   rý   rš   rœ   r›   r  r  Úok_senhaÚ
erro_senhaÚok_capÚmsg_capÚcontaÚuserÚerrr7   r†   ÚexpiraÚbase_urlÚlinkrC   Úok_mailÚprovedors                           r:   Úsignup_postr2    s¾  € ä
�/‰/×
Ñ
Ð/Ó
0Ò
N´G×4GÑ4GÒ
NÈ3×	UÑ	UÐVYÓ	ZÐ[\Ñ	]×	cÑ	cÓ	e€Bä˜ÔÜ˜eÐ-LÑMÓNÐPSÐSÐSä×Ñ 4Ô(ÒB¬G¯L©L×,@Ñ,@Ó,B€DØ�X‰X�gÓÒ$ "×+Ñ+Ó-×3Ñ3Ó5€EØ�X‰X�gÓÒ$ "×+Ñ+Ó-€EØ�H‰H�VÓÒ" ×)Ñ)Ó+€DØ—‘˜Ó$Ò*¨×1Ñ1Ó3€HØ—‘˜Ó$Ò*¨×1Ñ1Ó3€HÜ�t—x‘x Ó.Ó/€KØ—H‘H˜_Ó-Òz°·±Ð:NÓ1OÒzÐSW×S[ÑS[Ð\sÓStÒzÐxz€Mñ œŸ™Ð!>ÀÔFÜ˜eÐ->Ñ?Ó@À#ÐEÐEÙ”3�t“9˜q’=Ü˜eÐ-@ÑAÓBÀCÐGÐGÜ$ UÓ+Ñ€HˆjÙÜ˜e¨ZÑ8Ó9¸3Ð>Ð>Ù”sœ2Ÿ6™6 %¨¨XÓ6Ó7¸"Ò<Ü˜eÐ-KÑLÓMÈsÐRÐRÜ˜Ô!Ü˜eÐ-DÑEÓFÈÐKÐKÙÜ˜eÐ-[Ñ\Ó]Ð_bÐbÐbô ' }°bÓ9�O€FˆGÙÜ˜eÐ/BÀ7À)Ð-LÑMÓNÐPSÐSÐSä˜ÔÜ˜eÐ-CÑDÓEÀsÐJÐJô  ˜v ^Ð4Ô5€EÜ 4¨u¸EØ$+°e¸D±kôC�I€Dˆ#áÜ˜eÐ/QÐRUÐQVÐ-WÑXÓYÐ[^Ð^Ð^ô ˜5 ™;¬¨D¯G©G«Ô5ô ‹;€DØ‡L�Lð ô ˆd�g‰g‹,Ô*Ô,CÀRÌÏÉË×IaÑIaÓIcÐ	dôfð 	‡K�K„Mô ×!Ñ! "Ó%€EÜ�l‰l‹nœy¨rÔ2Ñ2×=Ñ=Ó?€FØ‡L�Lð ô ˆd�g‰g‹,˜¤"§&¡&¨°°HÓ"=¸uÀfÜ
�,‰,‹.×
"Ñ
"Ó
$ b¬'¯/©/×*=Ñ*=¸lÈBÓ*OÐPTÐQTÐ*Uð
Wô	Xð 	‡L�LÐ:¼SÀÇÁ»\¸OÔLØ‡K�K„MØ‡J�J„Lä�bÔô Ò>¤'×"2Ñ"2×"9Ñ"9¸#Ó">€HØˆZ�x ˜wÐ'€DðØ�ð à�F˜"˜T˜Fð #ð€Dô % UÐ,HÈ$ÓOÑ€GˆXäØÜ�t—w‘w“<Ø˜$‘KØØ 'Ø"ØBñó ð 	ðð r�   z/verify/<token>ÚGETc           	     ó@  — t        «       }|j                  d| f«      j                  «       }|s|j                  «        t	        dd«      dfS 	 t        j                  |d   «      }|t        j                  «       k  r|j                  «        t	        dd	«      d
fS t        |d   «      }|j                  d|f«       |j                  dt        j                  «       j                  «       |f«       |j                  «        |j                  «        t        j                  |«      }|r	 t        |d¬«       t	        dd|d   › dt!        d«      rt#        d«      nd› d�«      S # t        $ r% t        j                  «       t        d¬«      z
  }Y �Œ(w xY w# t        $ r Y Œhw xY w)NzÎ
        SELECT usm.user_id, usm.verify_token_expira_em, u.email, u.nome, u.conta_id
          FROM user_signup_meta usm
          JOIN users u ON u.id = usm.user_id
         WHERE usm.verify_token = ?
    u   Link invÃ¡lidou8   Este link de verificaÃ§Ã£o nÃ£o existe ou jÃ¡ foi usado.é”  Úverify_token_expira_emé   r£   zLink expiradouC   Este link expirou (vÃ¡lido por 24h). Solicite um novo pelo suporte.iš  rË   z'UPDATE users SET ativo = 1 WHERE id = ?zz
        UPDATE user_signup_meta
           SET email_verified_at = ?, verify_token = NULL
         WHERE user_id = ?
    T)ÚrememberzConta ativada com sucessozBem-vindo, rš   u7   . Sua conta ClimbLeads estÃ¡ pronta pra usar. <a href='Úindexr   z'>Ir pra ferramenta</a>)r   r3   rÃ   r6   Ú_pagina_simplesr   rå   r`   rm   r   r  rn   r5   r   r…   r   Ú_tem_endpointr   )r†   r7   rÆ   r-  rË   r+  s         r:   Ú
verify_getr<  {  sœ  € ä‹;€DØ
�,‰,ð ð
 ˆó÷
 ‘8“:ð ñ Ø�
‰
ŒÜÐ/Ð1kÓlÐnqÐqÐqð4Ü×'Ñ'¨Ð,DÑ(EÓFˆð ”—‘“ÒØ�
‰
ŒÜ˜ØQóSØTWðXð 	Xô �#�i‘.Ó!€GØ‡L�LÐ:¸W¸JÔGØ‡L�Lð ô �,‰,‹.×
"Ñ
"Ó
$ gÐ	.ô	0ð
 	‡K�K„MØ‡J�J„Lô �8‰8�GÓ€DÙð	Ü�t dÕ+ô Ø#Ø
�c˜&‘k�]ð #Ü(5°gÔ(>”G˜GÔ$ÀCÐHÐH_ð	aóð øô3 ò 4Ü—‘“¤)°Ô"3Ñ3‹ð4ûô, ò 	Ùð	ús$   ÁE  Ä'F Å *FÆFÆ	FÆFz/api/asaas/checkoutc            	     óN  — t         j                  j                  d«      xs t         j                  xs dj	                  d«      d   } t        j
                  d¬«      xs i }|j                  d«      xs dj                  «       }|d	vrt        d
ddœ«      dfS |j                  d«      xs i }|j                  d«      xs i }|j                  d«      r|j                  d«      st        d
ddœ«      dfS t        t        j                  xs d«      }|st        d
ddœ«      dfS t        |«      xs i }|j                  d«      xs d}|sÃt        «       }|j                  dt        t        j                  «      f«      j                  «       }	|j!                  «        t#        t        j$                  t        j&                  |	r|	d   n|j                  dd«      |	r|	d   n|j                  dd«      ¬«      \  }}
|st        d
d|
› �dœ«      dfS t)        ||||| ¬«      \  }}}|st        d
d|› �dœ«      dfS |d k(  rt*        nt,        }t/        ||||«       t        «       }|j                  d!|||f«       |j1                  «        |j!                  «        t        d||||d"œ«      d#fS )$u-  Cria/reusa customer Asaas e ativa subscription com cartÃ£o tokenizado.
       Espera JSON:
         { plano: 'mensal'|'anual',
           credit_card: { holderName, number, expiryMonth, expiryYear, ccv },
           credit_card_holder: { name, email, cpfCnpj, postalCode, addressNumber, phone } }
    r  r  r  r   Tr	  rµ   Úmensal)r>  r    Fu   plano invÃ¡lidor  r  r¶   r·   ÚnumberÚccvu   cartÃ£o obrigatÃ³riou   usuÃ¡rio sem contarÌ   r   z?SELECT cpf_cnpj, telefone FROM user_signup_meta WHERE user_id=?r›   r”   rœ   Úphone)rš   r“   r›   rœ   zasaas customer: éö  )r´   rµ   r¶   r·   r‡   zasaas subscription: r    z³
        UPDATE assinaturas SET asaas_customer_id = ?
         WHERE conta_id = ?
           AND id = (SELECT id FROM assinaturas WHERE conta_id = ? ORDER BY id DESC LIMIT 1)
    )r  rÀ   r´   rµ   r¸   rM   )r   rG   r…   r  r  r  r  r
   r  r   rÅ   rÇ   r   r3   r˜   rÃ   r6   rž   rš   r“   r»   r°   r±   rÒ   r5   )rî   r€   rµ   r¶   r·   rÅ   rç   r´   r7   Úmetar,  Úsub_idÚerr_subÚrespr¸   s                  r:   Úasaas_checkoutrG  ¬  s­  € ô �/‰/×
Ñ
Ð/Ó
0Ò
N´G×4GÑ4GÒ
NÈ3×	UÑ	UÐVYÓ	ZÐ[\Ñ	]€BÜ×Ñ 4Ô(Ò.¨B€DØ�X‰X�gÓÒ* (×1Ñ1Ó3€EØÐ'Ñ'Ü˜eÐ->Ñ?Ó@À#ÐEÐEØ—(‘(˜=Ó)Ò/¨R€KØŸ™Ð"6Ó7Ò=¸2ÐØ�?‰?˜8Ô$¨K¯O©O¸EÔ,BÜ˜eÐ-CÑDÓEÀsÐJÐJä”<×(Ñ(Ò-¨AÓ.€HÙÜ˜eÐ-AÑBÓCÀSÐHÐHô " (Ó
+Ò
1¨r€CØ—'‘'Ð-Ó.Ò4°"€KÙä‹{ˆØ�|‰|Ð]Ü ¤§¡Ó1Ð3ó5ß5=±X³Zð 	à�
‰
ŒÜ/Ü×"Ñ"Ü×$Ñ$Ù*.�d˜:Ò&Ð4F×4JÑ4JÈ9ÐVXÓ4YÙ*.�d˜:Ò&Ð4F×4JÑ4JÈ7ÐTVÓ4Wô	
Ñˆ�Sñ Ü %Ð3CÀCÀ5Ð1IÑJÓKÈSÐPÐPä4ØØØØ-ØôÑ€FˆG�Tñ Ü˜eÐ/CÀGÀ9Ð-MÑNÓOÐQTÐTÐTà!&¨'Ò!1ÕÔ7I€EÜ˜h¨°°uÔ=ä‹;€DØ‡L�Lð ð �x Ð	*ô	,ð
 	‡K�K„MØ‡J�J„LäØØ!Ø"ØØñó ð 	ðð r�   z/api/asaas/cancelarc                 óº  — t        t        j                  xs d«      } t        | «      }|r|j	                  d«      st        dddœ«      dfS t        |d   «      \  }}|st        d|dœ«      dfS t        «       }|j                  dt        j                  «       j                  «       |d	   f«       |j                  «        |j                  «        t        d
di«      S )zCancelamento self-service.r   Úasaas_subscription_idFzsem assinatura ativar  r5  rB  zb
        UPDATE assinaturas SET status = 'cancelada', atualizado_em = ?
         WHERE id = ?
    r˜   r  T)r  r   rÅ   rÇ   r…   r
   rÁ   r   r3   r   rm   rn   r5   r6   )rÅ   rç   r  r,  r7   s        r:   Úasaas_cancelarrJ  ô  sÌ   € ô ”<×(Ñ(Ò-¨AÓ.€HÜ
! (Ó
+€CÙ�c—g‘gÐ5Ô6Ü˜eÐ-CÑDÓEÀsÐJÐJÜ)¨#Ð.EÑ*FÓG�G€BˆÙÜ˜e¨SÑ1Ó2°CÐ7Ð7Ü‹;€DØ‡L�Lð ô �,‰,‹.×
"Ñ
"Ó
$ c¨$¡iÐ	0ô2ð 	‡K�K„MØ‡J�J„LÜ�D˜$�<Ó Ð r�   z/webhooks/asaasc                 óð  — t         r9t        j                  j                  dd«      } | t         k7  rt	        dddœ«      dfS t        j
                  d¬«      xs i }|j                  d	«      xs d}|j                  d
«      xs d}|j                  d«      xs i }t        |j                  d«      t        «      r4|j                  d«      xs2 |j                  di «      j                  d	«      n|j                  d«      }t        |t        «      r|j                  d	d«      }n|xs d}|j                  d	«      xs d}|j                  d«      xs d}t        «       }		 |	j                  d|xs dt        j                  «       › �||||t        j                  |«      dd t        j                  «       j!                  «       f«       |	j#                  «        d}
|r!|	j                  d|f«      j+                  «       }
|
s#|r!|	j                  d|f«      j+                  «       }
|	j)                  «        |
st	        dddœ«      S t-        |
d   «      }|dv rØt        «       }	|j                  d«      xs d}|	j                  dt        j                  «       j!                  «       |t        j                  «       j!                  «       |
d	   f«       |	j                  dt        j                  «       j!                  «       |f«       |	j#                  «        |	j)                  «        t/        |«       n‹|dk(  rt1        |d¬«       nx|dk(  rt1        |d¬«       ne|d v rat        «       }	|	j                  d!t        j                  «       j!                  «       |
d	   f«       |	j#                  «        |	j)                  «        t	        d||d"œ«      S # t$        j&                  $ r! |	j)                  «        t	        dddœ«      cY S w xY w)#zBRecebe eventos do Asaas. Valida token (se configurado) e processa.zasaas-access-tokenr   Fu   token invÃ¡lidor  i‘  Tr	  r˜   ÚeventÚpaymentÚsubscriptionr¦   zÈ
            INSERT INTO asaas_webhook_events
                (event_id, event_type, payment_id, subscription_id, customer_id, payload, processado_em)
            VALUES (?, ?, ?, ?, ?, ?, ?)
        znoid-Niˆ  )r  Údedupz9SELECT * FROM assinaturas WHERE asaas_subscription_id = ?zNSELECT * FROM assinaturas WHERE asaas_customer_id = ? ORDER BY id DESC LIMIT 1)r  Úsem_assinatura_vinculadarÅ   )ÚPAYMENT_CONFIRMEDÚPAYMENT_RECEIVEDÚdueDatez�
            UPDATE assinaturas SET status='ativa', ultimo_pagamento=?, proximo_pagamento=?, atualizado_em=?
             WHERE id=?
        zp
            UPDATE ghl_config SET leads_usados = 0, quota_reset_em = ?
             WHERE conta_id = ?
        ÚPAYMENT_OVERDUEÚatrasada)rÖ   ÚPAYMENT_REFUNDEDÚreembolsada)ÚSUBSCRIPTION_DELETEDÚSUBSCRIPTION_INACTIVATEDz[
            UPDATE assinaturas SET status='cancelada', atualizado_em=? WHERE id=?
        )r  ÚeventorÅ   )r   r   rG   r…   r
   r  Ú
isinstancerÄ   r   r3   rê   Útime_nsrH   Údumpsr   rm   rn   r5   r.   ÚIntegrityErrorr6   rÃ   r  rÙ   r×   )Úrecvr�   Úevent_idÚ
event_typerM  rN  rÀ   Ú
payment_idr´   r7   rÆ   rÅ   Úproximos                r:   Úwebhook_asaasrd  	  s£  € õ Ü�‰×"Ñ"Ð#7¸Ó<ˆØÔ&Ò&Ü %Ð1BÑCÓDÀcÐIÐIä×Ñ dÔ+Ò1¨r€GØ�{‰{˜4Ó Ò& B€HØ—‘˜WÓ%Ò+¨€JØ�k‰k˜)Ó$Ò*¨€GÜ_iÐjq×juÑjuð  wEó  kFô  HLô  `M�7—;‘;˜~Ó.Ò[°'·+±+¸nÈbÓ2Q×2UÑ2UÐVZÔ2[ð  SZ÷  S^ñ  S^ð  _mó  Sn€LÜ�,¤Ô%Ø&×*Ñ*¨4°Ó4‰à&Ò,¨"ˆØ—‘˜TÓ"Ò( b€JØ—+‘+˜jÓ)Ò/¨R€Kä‹;€Dð4Ø�‰ð ð Ò2˜E¤$§,¡,£.Ð!1Ð2°JÀ
Ø˜{¬D¯J©J°wÓ,?ÀÀÐ,FÜ�l‰l‹n×&Ñ&Ó(ð*ô		+ð 	�‰Œð €CÙØ�l‰lØGÈ/ÐI[ó
ç
‰(‹*ð 	ñ ‘;Ø�l‰lØ\ØˆNó
÷ ‰(‹*ð 	ð 	‡J�J„Láä˜dÀÑEÓFÐFä�3�z‘?Ó#€HàÐ>Ñ>Ü‹{ˆØ—+‘+˜iÓ(Ò.¨BˆØ�‰ð ô �l‰l‹n×&Ñ&Ó(¨'´8·<±<³>×3KÑ3KÓ3MÈsÐSWÉyÐYô	[ð 	�‰ð ô �l‰l‹n×&Ñ&Ó(¨(Ð3ô	5ð 	�‰ŒØ�
‰
ŒÜ˜HÕ%Ø	Ð(Ò	(Ü˜X¨jÖ9Ø	Ð)Ò	)Ü˜X¨mÖ<Ø	ÐKÑ	KÜ‹{ˆØ�‰ð ä�l‰l‹n×&Ñ&Ó(¨#¨d©)Ð4ô	6ð 	�‰ŒØ�
‰
Œä˜$¨*À(ÑKÓLÐLøôe ×!Ñ!ò 4à�
‰
ŒÜ˜d¨TÑ2Ó3Ò3ð4ús   ÅA8O Ï1O5Ï4O5z/api/minha-contac                 óT  — t        t        j                  xs d«      } t        | «      xs i }t	        | «      }t        | «      \  }}t        dt        j                  t        j                  t        j                  dœ| dD �ci c]  }||j                  |«      “Œ c}|||dœ«      S c c}w )Nr   T)r˜   rš   r“   )rÜ   rµ   r¸   rß   Úultimo_pagamentoÚproximo_pagamentorI  )r  r+  rÅ   Ú
assinaturaÚquotaÚacesso_liberadoÚacesso_motivo)r  r   rÅ   rÇ   r   rè   r
   r˜   rš   r“   r…   )rÅ   rç   ri  ÚpermiterÖ   Úks         r:   Úminha_contarn  `  s¦   € ô ”<×(Ñ(Ò-¨AÓ.€HÜ
! (Ó
+Ò
1¨r€CÜ�hÓ€EÜ,¨XÓ6�O€GˆVÜØÜ#—‘´×0AÑ0AÌL×L^ÑL^Ñ_ØðZö[¨�q˜#Ÿ'™' !›*‘}ò [ð Ø"Øñ
ó 
ð 
ùò[s   Â B%u'  
<!doctype html><meta charset="utf-8"><title>Termos de Uso - ClimbLeads</title>
<style>body{font-family:system-ui;max-width:820px;margin:40px auto;padding:0 24px;line-height:1.55;color:#222}
h1,h2{color:#0a2540}.small{color:#666;font-size:14px}</style>
<h1>Termos de Uso â€” ClimbLeads</h1>
<p class="small">VersÃ£o {ver} â€” Climb Digital LTDA (contato: contato@agenciaclimb.com.br)</p>

<h2>1. Objeto</h2>
<p>O ClimbLeads Ã© uma plataforma SaaS de prospecÃ§Ã£o ativa business-to-business
que coleta dados publicamente disponÃ­veis (Google Maps / Places, sites e redes
sociais abertos) e integra esses dados a um CRM do usuÃ¡rio para fins de contato
comercial legÃ­timo.</p>

<h2>2. Aceite</h2>
<p>Ao criar conta, o usuÃ¡rio declara ter capacidade civil, ser responsÃ¡vel pelas
credenciais e pelo uso conferido aos leads coletados, incluindo o cumprimento da
LGPD (Lei 13.709/2018) e do CÃ³digo de Defesa do Consumidor.</p>

<h2>3. ProspecÃ§Ã£o sobre dados pÃºblicos</h2>
<p>Os leads entregues sÃ£o pessoas jurÃ­dicas ou profissionais cujas informaÃ§Ãµes
comerciais estÃ£o publicamente indexadas. O usuÃ¡rio assume responsabilidade pelo
contato realizado e pelos direitos dos titulares em opt-out imediato.</p>

<h2>4. Planos e cobranÃ§a</h2>
<p>Trial de 7 dias com limite de 100 leads mediante cartÃ£o prÃ©-autorizado. Ao
final do trial, cobranÃ§a automÃ¡tica do plano mensal (R$ 197) ou anual (R$ 1.764)
escolhido no checkout. Cancelamento self-service a qualquer momento.</p>

<h2>5. SuspensÃ£o e rescisÃ£o</h2>
<p>Contas ficam suspensas em caso de inadimplÃªncia (retorna PAYMENT_OVERDUE do
gateway), reembolso ou cancelamento. ReativaÃ§Ã£o automÃ¡tica ao recebimento do
pagamento (PAYMENT_CONFIRMED).</p>

<h2>6. LimitaÃ§Ã£o de responsabilidade</h2>
<p>A Climb Digital nÃ£o se responsabiliza por decisÃµes comerciais tomadas com base
nos leads entregues nem por eventuais indisponibilidades das APIs de terceiros
(Google, GHL/Linkia, Asaas).</p>

<h2>7. Foro</h2>
<p>Fica eleito o foro da comarca de Belo Horizonte (MG) para dirimir quaisquer
questÃµes oriundas destes Termos.</p>
z{ver}uV  
<!doctype html><meta charset="utf-8"><title>PolÃ­tica de Privacidade - ClimbLeads</title>
<style>body{font-family:system-ui;max-width:820px;margin:40px auto;padding:0 24px;line-height:1.55;color:#222}
h1,h2{color:#0a2540}.small{color:#666;font-size:14px}</style>
<h1>PolÃ­tica de Privacidade â€” ClimbLeads</h1>
<p class="small">VersÃ£o {ver} â€” DPO: {dpo}</p>

<h2>1. Dados coletados</h2>
<ul>
  <li><b>Cadastro:</b> nome, email, telefone, CPF/CNPJ, senha (hash).</li>
  <li><b>Pagamento:</b> tokenizaÃ§Ã£o do cartÃ£o feita diretamente no Asaas;
      NÃƒO armazenamos nÃºmero de cartÃ£o em nossos servidores.</li>
  <li><b>Uso:</b> logs de acesso, IP, user-agent, quotas consumidas.</li>
  <li><b>Leads prospectados:</b> dados pÃºblicos de empresas retornados pelo
      Google Places / scraping; retidos por atÃ© 90 dias em nossa base pra evitar
      duplicidade nas rodadas de prospecÃ§Ã£o do prÃ³prio usuÃ¡rio.</li>
</ul>

<h2>2. Base legal (LGPD art. 7Âº)</h2>
<ul>
  <li>ExecuÃ§Ã£o de contrato (I) â€” pra fornecer o serviÃ§o.</li>
  <li>LegÃ­timo interesse (IX) â€” pra prospecÃ§Ã£o B2B sobre dados pÃºblicos.</li>
  <li>Cumprimento de obrigaÃ§Ã£o legal (II) â€” pra emissÃ£o fiscal.</li>
</ul>

<h2>3. Compartilhamento</h2>
<p>Compartilhamos dados exclusivamente com: Asaas (processador de pagamento),
GoHighLevel/Linkia (CRM do prÃ³prio usuÃ¡rio), Google Places (busca de leads),
Resend/SMTP (envio de emails transacionais).</p>

<h2>4. RetenÃ§Ã£o</h2>
<p>Cadastro do usuÃ¡rio: enquanto a conta estiver ativa. ApÃ³s deleÃ§Ã£o, os dados
pessoais do titular sÃ£o anonimizados em atÃ© 30 dias. Registros fiscais sÃ£o
mantidos pelos prazos legais (5 anos).</p>

<h2>5. Direitos do titular</h2>
<p>ConfirmaÃ§Ã£o, acesso, correÃ§Ã£o, portabilidade, anonimizaÃ§Ã£o e eliminaÃ§Ã£o â€”
via endpoint DELETE /api/lgpd/deletar-conta na Ã¡rea do usuÃ¡rio ou solicitaÃ§Ã£o a
{dpo}.</p>

<h2>6. SeguranÃ§a</h2>
<p>ComunicaÃ§Ã£o via HTTPS, senhas com hash bcrypt/werkzeug, backups diÃ¡rios.
Incidentes serÃ£o comunicados Ã  ANPD e aos titulares afetados em atÃ© 72h.</p>

<h2>7. DPO</h2>
<p>Encarregado de ProteÃ§Ã£o de Dados: {dpo}</p>
z{dpo}z/termosc                 ó   — t         dddifS ©NrM   r?   ztext/html; charset=utf-8)Ú_TERMOS_HTMLrŒ   r�   r:   Útermosrr  Ó  s   € ä˜˜~Ð/IÐJÐJÐJr�   z/privacidadec                 ó   — t         dddifS rp  )Ú_PRIVACIDADE_HTMLrŒ   r�   r:   Úprivacidaderu  Ø  s   € ä˜c NÐ4NÐ#OÐOÐOr�   z/api/lgpd/deletar-contaÚDELETEc                 ó  — t        t        j                  xs d«      } t        t        j                  «      }t	        | «      }|r“|j                  d«      r‚|j                  d«      dvrot        |d   «       t        «       }|j                  dt        j                  «       j                  «       |d   f«       |j                  «        |j                  «        t        j                  «       t        d¬«      z   j                  «       }t        «       }|j                  d	|t        j                  «       j                  «       |f«       |j                  d
|f«       |j                  «        |j                  «        t        dd|dœ«      S )uW   Solicita deleÃ§Ã£o da conta. Cancela Asaas imediatamente, agenda anonimizaÃ§Ã£o em 30d.r   rI  rÜ   )rã   zEUPDATE assinaturas SET status='cancelada', atualizado_em=? WHERE id=?r˜   é   r£   zz
        INSERT INTO lgpd_delecoes (user_id, solicitado_em, executar_em, status)
        VALUES (?, ?, ?, 'pendente')
    z#UPDATE users SET ativo=0 WHERE id=?Tu8   conta desativada. AnonimizaÃ§Ã£o automÃ¡tica em 30 dias.)r  r  Úexecutar_em)r  r   rÅ   r˜   rÇ   r…   rÁ   r   r3   r   rm   rn   r5   r6   r   r
   )rÅ   rË   rç   r7   ry  s        r:   Úlgpd_deletarrz  Ý  s2  € ô ”<×(Ñ(Ò-¨AÓ.€HÜ”,—/‘/Ó"€GÜ
! (Ó
+€CÙ
ˆs�w‰wÐ.Ô/°C·G±G¸HÓ4EÈ^Ñ4[Ü# CÐ(?Ñ$@ÔAÜ‹{ˆØ�‰Ð\Ü—l‘l“n×.Ñ.Ó0°#°d±)Ð<ô	>à�‰ŒØ�
‰
Œä—<‘<“>¤I°2Ô$6Ñ6×AÑAÓC€KÜ‹;€DØ‡L�Lð ð ”8—<‘<“>×+Ñ+Ó-¨{Ð	;ô=ð 	‡L�LÐ6¸¸
ÔCØ‡K�K„MØ‡J�J„LäØØNØ"ñó ð r�   )z/prospectarz/enriquecerz/planilha/enriquecerz/analisar-leadz/automacao/rodar-agoraz/api/v1/prospectarz/api/v1/analisarz/api/prospectarz/api/enriquecerz/api/prospeccao/rodarz/api/analisar-leadz/api/enviar-crmc                ó@   — t         D ]  }| j                  |«      sŒ y y)NTF)ÚQUOTA_ROTAS_PREFIXOSræ   )ÚpathÚps     r:   Ú_quota_deve_auditarr    s%   € Ü!ò ˆØ�?‰?˜1ÕÙðð r�   c                ó(   — | j                   d„ «       }y)uM   Registra hook before_request que valida assinatura/quota nas rotas crÃ­ticas.c                 ó^  — t         j                  dk7  ry t         j                  xs d} t        | «      sy t        j
                  sy t        t        t        dd«      xs d«      }|sy t        |«      \  }}|st        dd|ddœ«      d	fS t        |«      }|d
   dk  rt        dd|ddœ«      d	fS y )Nr   r   rÅ   r   Fu)   assinatura suspensa, atualize seu cartÃ£oz/planos)r  r  rÖ   Úupgrade_urli’  Ú
disponivelz!limite de leads do plano atingido)r  r  ri  r‚  )r   Úmethodr}  r  r   Úis_authenticatedr  Úgetattrrè   r
   r   )r}  rÅ   rl  rÖ   ri  s        r:   Ú_guard_assinatura_quotaz;registrar_middleware_quota.<locals>._guard_assinatura_quota!  sÕ   € ô �>‰>˜VÒ#ØÜ�|‰|Ò!˜rˆÜ" 4Ô(ØÜ×,Ò,ØÜ”wœ|¨Z¸Ó;Ò@¸qÓAˆÙØä0°Ó:‰ˆ�ÙÜØØCØ Ø(ñ	ó ð
 ðð ô ˜(Ó#ˆØ�Ñ !Ò#ÜØØ;ØØ(ñ	ó ð
 ðð ð r�   N)Úbefore_request)Úappr‡  s     r:   Úregistrar_middleware_quotarŠ    s   € ð 	×Ññó ñr�   c                óF   — 	 | t         j                  v S # t        $ r Y yw xY w)NF)r	   Úview_functionsr`   )r’   s    r:   r;  r;  G  s*   € ðØ”{×1Ñ1Ð1Ð1øÜò Ùðús   ‚ ”	 Ÿ c                ó   — d| › d| › d|› d�S )Nz,<!doctype html><meta charset="utf-8"><title>z¹</title>
<style>body{font-family:system-ui;max-width:560px;margin:80px auto;padding:0 24px;text-align:center;color:#222}
h1{color:#0a2540}p{line-height:1.6}a{color:#0a2540}</style>
<h1>z</h1><p>z</p>rŒ   )ÚtituloÚmensagem_htmls     r:   r:  r:  N  s(   € Ø;¸F¸8ð Dð €HˆH�]�O 4ð+ð +r�   c                ón   — t        «        | j                  t        «       t        | «       t	        d«       y)u5   Chame do app.py apÃ³s criar Flask app e LoginManager.z¡[climbleads] rotas Sprint 1 Fase 2 registradas: /signup, /verify, /webhooks/asaas, /termos, /privacidade, /api/asaas/*, /api/minha-conta, /api/lgpd/deletar-contaN)r;   Úregister_blueprintÚbprŠ  ro   )r‰  s    r:   Úregister_climbleads_routesr“  Y  s,   € ä„OØ×Ñœ2ÔÜ˜sÔ#Ü	ð  nõ  or�   )ÚreturnÚNone)r   )
rp   r0   rq   r0   rr   r0   rs   r0   r”  útuple[bool, str])r†   r0   r‡   r0   r”  r–  )r”  rÄ   )
rš   r0   r“   r0   r›   r0   rœ   r0   r”  ztuple[str | None, str])r´   r0   rµ   r0   r¶   rÄ   r·   rÄ   r‡   r0   r”  ztuple[str | None, str, dict])rÀ   r0   r”  r–  )rÅ   r  r”  zdict | None)rÅ   r  rË   r  rÌ   r0   r”  rÄ   )
rÅ   r  rÀ   r0   rµ   r0   r¸   Úfloatr”  r•  )Ú	pagamento)rÅ   r  rÖ   r0   r”  r•  )rÅ   r  r”  r•  )rÅ   r  r”  r–  )rî   r0   r”  r  )rî   r0   r”  r•  )rù   r0   r”  r  )rý   r0   r”  r–  )r†   r0   )r}  r0   r”  r  )r’   r0   r”  r  )rŽ  r0   r�  r0   r”  r0   )pÚ__doc__Ú
__future__r   rH   Úosr[   r"  r.   Ú	threadingrê   r   r   r   Úpathlibr   r]   Úflaskr   r	   r
   r   r   r   r   Úflask_loginr   r   r   Úwerkzeug.securityr   Úauthr   r   r   r   r   r   r   Ú__file__ÚresolveÚparentÚBASE_DIRr1   rj   Úenvironr…   r  r   r%  r   r   r   r  r    r"   r#   r$   r%   r&   r'   r(   r   r!  ÚLGPD_DPO_EMAILr²   rÉ   rÑ   r±   r°   r+   Ú__annotations__ÚLockrë   rí   r;   ry   rˆ   rŽ   rž   r»   rÁ   rÇ   rÏ   rÒ   r×   rÙ   rè   rñ   rõ   rû   rþ   Ú__name__r’  Úrouter2  r<  rG  rJ  rd  rn  Úreplacerq  rt  rr  ru  rz  r|  r  rŠ  r;  r:  r“  rŒ   r�   r:   ú<module>r­     s  ðòõ0 #ã Û 	Û 	Û Û Û Û ß 2Ñ 2Ý ã ÷=÷ =ñ =ç @Ñ @Ý 4÷?÷ ?ñ ?ñ �‹>×!Ñ!Ó#×*Ñ*€Ø
�ZÑ
€ØÐ"8Ñ8Ð ð —
‘
—‘˜°Ó3×9Ñ9Ó;€Ø—‘—‘Ð 0Ð2LÓM×TÑTÐUXÓY€Ø—j‘j—n‘nÐ%:¸BÓ?×EÑEÓGÐ ð �J‰J�N‰N˜;¨Ó+×1Ñ1Ó3€	Ù�—
‘
—‘˜{¨EÓ2Ò9°cÓ:€	Ø�J‰J�N‰N˜;¨Ó+×1Ñ1Ó3€	Ø�J‰J�N‰N˜;¨Ó+×1Ñ1Ó3€	Ø�J‰J�N‰N˜;Ð(FÓG×MÑMÓO€	Ø—‘—‘Ð 0°"Ó5×;Ñ;Ó=€ð —*‘*—.‘.Ð!2°BÓ7×=Ñ=Ó?€Ø—:‘:—>‘>Ð"4°bÓ9×?Ñ?ÓAÐ ð —*‘*—.‘.Ð!2°BÓ7×>Ñ>¸sÓC€ð "Ð Ø&Ð Ø.€ð Ð ØÐ ØÐ ØÐ ØÐ ð ,.Ð Ð(Ó -Øˆy�~‰~Ó€ØÐ óWð~ #%ð;Øð;Ø)9ó;óD%BóXð +-ðØ$'ðØ1Góð,$ Ø26ð$ ØCFð$ ØKgó$ óN
ó"&ð 68ðØ/2ðØ<@óð6Ø&)ðØ27ðØ<@óô,óó)ó<0ó@óó
ñ ˆ|˜XÓ&€ð
 ‡�ˆ)˜f˜X€Ó&ñ`ó 'ð`ðF ‡�Ð
 e W€Ó-ò+ó .ð+ð` ‡�Ð
¨&¨€Ó2ØñCó ó 3ðCðL ‡�Ð
¨&¨€Ó2Øñ!ó ó 3ð!ð& ‡�Ð
 f X€Ó.ñQMó /ðQMðl ‡�Ð
 u g€Ó.Øñó ó /ðð()÷R �GˆGÐ'Ó(ðS ðX.÷\ �GˆGÐ,Ó-¯g©g°g¸~Ó.Nð] ðb ‡�ˆ)˜e˜W€Ó%ñKó &ðKð ‡�ˆ. 5 '€Ó*ñPó +ðPð ‡�Ð
#¨h¸Ð-?€Ó@Øñó ó AððJÐ ó&ò"óRó+ôor�   