Jurnal de schimbări
Ce e nou.
Fiecare îmbunătățire a platformei, pe măsură ce se livrează.
· kamo-shared-library
API SIGNATURE api-cheie + EsignGenericEnvelope.origin
Aditiv, nici o versiune cucui: - ApiKeyScope.API SIGATURE - EsignGenericEnvelope.origin (EsignUsageOrigin, nullable) plicul a fost creat prin intermediul API vs MANUAL, deci a completat corect contorul semnăturilor (API contează faţă de media de 0.20 dolari; MANUAL nu contează niciodată). Coloana adăugată la prod prin idepotent ALTER în prealabil.
· kamo-internal
Acțiunea de trimitere pentru semnătură + starea pachetului în editorul de documente
Adaugă un buton "Trimite pentru semnătură" pe antetul editorului șablon care deschide un dialog pentru trimiterea documentului către destinatari și statutul de semnare a liniilor, apelare noul motor ESigService /api/esig/envelopes. - Rutele proxy (OTK prin generareOTK, oglindeste proxy-ul machetelor): POST/GET /api/esig/envelopes, GET [uid], POST [uid]/evident; POST *************** - SendForSignatureDialog: Trimite fila (randuri primitive, mesaj, expirare) + Fila de stare (lista de plicuri per-temper, cipuri de stare, nulă/retrimitere) - Buton dezactivat în timp ce șablonul are modificări nesalvate - I18n via next-intl *************
· ESigService
Creare/trimitere generică a anvelopei motor (sender side)
Adăugați unități OTK-authed /api/esig/envelopes API kamo-internă pentru a trimite documente de semnare, reutilizarea acelorași entități de legătură comună publicul semnarea API citește cuplat KamoLOS/EsignClient crea calea. - Post create-and-send from a template: builds EsignGenericEnvelope (AD HOC), un EsignEnvelopeRecipient per signer cu un token de acces proaspăt hashed și e-mailuri fiecare /s / {env} / {recipient}?t= {token} signing link (best- efort) - Listă GET (panou de bord) + GET {uid} detalii cu statute de destinatar - Post {uid}/evidenţi şi {uid}/recipienti/ {rid}/retrimite (rotează jetonul) - Invitaţie + delegaţi email-uri partajaţi EsignEmailClient.sendInvite; signer-route link- uri corectate la /s/ {env}/ {recipient}
· ESigService
Semnare publică API motor pentru semn.sign.pink
Punerea în aplicare /api/esig/public/* semnarea API apelurile aplicație kamo-signer, Transformarea semnatorului live de la previzualizare-tub într-un suport de lucru. - valida (recipient token - > sesiune signor), sesiune, consimtamant, stepup/start+verify (email OTP), trimite, decodor, delegat, document - Redis-backed signer sesiuni (X-Signer-Sesssion), distinct de personalul OTK - Octet document prin conducta reala Img/MinIO (templat imgId -> Convertit-PDF ImgDat -> MinIO), newired/api/imaging/lobs stub - PDFBox aplatizat: valori de câmp suprapuse + imagini de semnătură la proiectare coordonatele, completarea paginilor de certificat de audit E-SIGN/UETA; semnătura PDF stocată în MinIO sub plicul semnatBlobId cu SHA-256 înregistrat - Adaugă numai rânduri de audit EsignSignature + EsignField Persistența valorii - Emits *************** Contorizarea de origine API urmează în #3/#4 - Branding rezolvat de la Organizatie + OrgDomain pentru prima pictura - OTKAuthFilter bypasss /api/esig/public (token-authed, nu personal OTK) Numai aditivi; existenți/api/esig/templați/* neatinsi.
· kamo-internal
Comutator produs platformă în fila organizații
Suprafață denumirea platformei-produs în cazul în care acesta face parte din platforma Organizaţii. Adaugă un comutator cu poartă per org (dezactivat pentru org de nivel superior); un dialog de confirmare care să explice efectul dreptului de autor, un "produs cu formă" cip, un avertisment fără catalog, actualizare optimistă, și bara de eroare. Toate sforile prin următorul-intl.
· BillingService
Gestionați Organizația.isPlatformProduct de pe Platformă → Orgs
PlatformaContExpuneri Sumare estePlatformProdus + areAbonare Piața; nouă Pune-o aici. (platform-admin gated) stabilește steagul și invalidează drepturile membrilor orgului (produsele lor rădăcină, și astfel caracteristici, schimbare). org de nivel superior este rădăcina implicită și nu poate să fie comutate.
· kamo-shared-library
Organizația Explicit.isPlatformProdus ca semnal right-root
Înlocuirea "proprietății unei piețe de SUBSCRIPTION" euristică derivată cu un explicit; pavilion de proprietate admin-set. Un produs de platformă (de exemplu, sign.pink) este o etichetă albă produs platforma funcționează și este propria sa rădăcină de drept; un client org chiar și unul care rulează propria sa piață SUBSCRIPTION pentru a revinde la clienții săi este nu, și rămâne dreptul la platforma. DreptateRootRezolvator acum citește pavilion (plus rădăcina implicită de nivel superior) și nu mai depinde de piață proprietatea. Adds is platform product column (BOOL DEFAULT FALSE) KamoInitializer pentru a-l crea înainte de serviciile care selectează Organizația.
· SecurityService
Drepturile membrilor domeniului de aplicare la rădăcina produsului, nu KamoCRM
Serviciul de Drept rezolvă acum rădăcina fiecărui membru prin intermediul DreptRezolvator de drepturi (cel mai apropiat strămoș-sau-se) în loc de mersul pe jos la org de nivel superior. Podeaua mai liberă și steagul cu acces la produs derivă din această rădăcină, și esteKamoCrmAbonare devine abonamentGrantsRootAccess (plan-org vs rădăcină, niciodată contul de facturare). Câştiguri din Entitlements produsRootOrgId astfel încât consumatorii poarta de acces împotriva produsului potrivit. BillingSetupServicii surse piata + Plan gratuit de la produsul noii org rădăcină în timp ce păstrarea Contul de facturare pe org de nivel superior KamoCRM parintele detine facturarea, copilul poate detine produsul / piata. Comportamentul este neschimbat până când o org deține de fapt propria piață (KamoCRM este doar proprietarul de piață astăzi, astfel încât fiecare membru încă se rezolvă la ea).
· kamo-shared-library
Rezolvarea drepturilor în funcție de orgul de rădăcină de produs, nu de platforma de nivel superior
IntroduceredreptateRezolvator: cel mai apropiat stramos de piata a unei org (rădăcina sa de produs), care revine la nivelul superior al platformei. Asta decuplează * ce produs aveți dreptul la * (proprietar de piață / plan) de la * care plătește * (cont de facturare) și din org unic de nivel superior, astfel încât un produs de culoare albă org ca semn.pink care deține propria sa piață devine propria rădăcină de drept. ***************** acum sursa de baza gratuita de la org root produs (nu găsițiPrimaByIsTopLevelTrue) și rezolvă planurile de org produs/piață mai degrabă decât org facturare-cont. Backward compatibil: KamoCRM este în prezent singurul proprietar de piață, astfel încât fiecare org existente se rezolvă la ea exact ca înainte de comportamentul doar o singură dată a Sub-arborele deţine propria piaţă. Aditiv; nici un cucui versiune.
· kamo-shared-library
Adăugați destinatarul pachetului, valoarea câmpului, entitățile cu statut de destinatar
Verificați în modelul in-progress esign: EsignEnvelopeRecipient (+repo), EsignFieldValue (+repo), EsignRecipientStatus și o actualizare ESignSignerType. Aditiv; nici un cucui versiune.
· kamo-shared-library
Adaugă EsignUsageRecord pentru contorizarea utilizării pe semnătură
O nouă entitate de utilizare numai pe bază de apendice (oglindă AiUsageRecord) emisă la semnătură Completare. Numai semnăturile de origine API se bazează pe un plan lunar inclus cota + overage (semn.pink Business: 40/mo inclus, apoi 0,20 dolari fiecare); MANUAL Semnăturile unui singur utilizator sunt înregistrate, dar niciodată facturate. perioada de facturare (AAAA-LL) suportă agregarea lunară; raportat to stripe face depunerea de utilizare Stripe idepotent. Numai aditivi; nici un obstacol versiune.
· ConversionService
Raportul de conservare a aspectului, nu se întinde niciodată logo-uri non-pătrate
Ramele Favicon PNG/ICO au fost produse cu mentinereAspectRatio (fals), intindere orice logo non-pătrat într-un pătrat distorsionat. Center-fit the logo on a panza pătrat transparent în schimb, păstrarea raportului de aspect, astfel încât favicons uite corect pentru orice formă de logo încărcat fără a necesita o imagine de sursă pătrată.
· KlusterServices
Semn pre-seed.pink + www.sign.pink in STATIC DOMAINS
sign.pink este un nou domeniu apex (semnătura electronică a consumatorului / eticheta albă Kamo chiriaș org). Pre-seed apex + www so a Let's cripte cert există înainte de Primul trafic HTTPS; *.sign.pink subdomenii primi per-FQDN certificate dinamic la prima lovitură, același mecanism ca *.pretturbo.com.
· kamo-signer-monorepo
Aplicație nouă de semnare monorepo + prima semnătură electronică mobilă
Turborepo + spaţii de lucru pnpm monorepo case de e-sign reutilizabile extras din kamo-internal plus un nou, ultra-poluat kamo-signer aplicație experienţa de SEMNARE a celei de-a doua părţi (partea de designer/autorizare rămâne în kamo-internal). Ambalaje: - @kamo/esign-core types + Design Data wire contract, zod schema, runtime validare câmp, semnStore (zusand) - @kamo/esign-ui intrări interactive de câmp + câmp/annotare numai citire randatoare (furate de la kamo-internal FieldControl) - @kamo/doc-render pachețed pdf.js page reminder (lucrător auto-hosted, no CDN), suprapuse receptive, corecte prin rotație - @kamo/theme per-tenant branding bootstrap (get ThemePath, ThemeLogo, DinamicMetaLoader) - @kamo/api-client browser put + server Redis/forwarding helpers - @kamo/config shared tsconfig / tailwind preset / eslint App (apps/kamo-signer): - token-scoped signer auth (SIGNESH httpOnly session, BFF route manipulators) - bun venit -> consimtamant (ESIGN/UETA) -> EIDAS AES step-up OTP - > ghided signing -> finisaj - > completare, toate fazele animate (în funcţie de cadru, mişcare redusă conştient), mobil-primul egal cu desktop, WCAG-minded - apartament de captare a semnăturii: trage / tip (script fonturi) / upload / adopt-all - multi-document, decodor, delegat/reasign, full i18n (următorul-intl, 22 localuri) - modul de previzualizare executabil (nu este necesar suport) + /.forgejo + /k8s (HostRegext semn.*, fişier Docker turbo-prune)
· kamo-internal
Description
LoanProductForm a fost o singură coloană îngustă (maxWidth: 880) cu hardcoded Engleză peste tot. Acum folosește același model de întreprindere ca pagina de ofertă: Aranjament: - Cap de gradient cu gradient cu pesmet, sageata spate, insigna fel - Grilă cu două coloane (6fr/6fr) pe lg+, o singură coloană de mai jos - Formular pe stânga, live "Product Preview" pe dreapta Forma: - Selector fel ca ToggleButtonGroup cu descrieri (instalare vs LOC), nu este îngropat într-o scădere în jos restul formei, aşa că merită să fie proeminentă. - Blocuri de sectiune cu icoane (Basica · Pret · Limite & Termeni · Conformitate) - Ratele introduse ca %, convertite în Bps pe sârmă (nu mai mult "3600 = 36%") - Toate etichetele de pe teren prin next-intl t() - Informaţii privind numărul de zile care explică ACT 365 vs ACT 360 Partea de previzualizare: - Erou carte: fel cip, produs cod cip, nume, titlu, descriere - grilă de 4 cifre: rata, originea, taxa de întârziere, taxa NSF - Limits & category grid (kind-aware: range + frecvence for ratement, ********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* - Card de ofertă (instalare): plată lunară, dobândă totală; costul total, originea eșantionului la mijlocul intervalului principal - Cipuri de conformitate: state permise (cap 24 + jeton supraîncărcat), autopay Necesar + reducere, obligatoriu șablon cu notă obligatorie - nota Footer explicând modul în care acest produs curge la pagina de oferta LoanProductForm împachetează acum atât paginile noi cât și paginile de editare. Ambalaje pentru pagini trece de pe piaţă, astfel încât pesmet rezolva curat.
· kamo-internal
Layout cu două coloane cu vedere de previzualizare live
Pagina de nou-ofertă a fost o coloană înaltă îngustă pe ecrane largi. Portul vizual. Acum folosește CSS Grid cu formularul din stânga (5fr) și a vedere live "Offer Preview" pe dreapta (7fr) care actualizează ca operator tipuri. O singură coloană pe ecrane mici (< lg). Forma: - Blocuri de sectiune cu icoane (Produs · imprumutator · Suma · Termeni personalizati) - Câmpuri de împrumut stack vertical (membru id + stare) într-un compact prezentare acum că spațiul orizontal este rezervat pentru previzualizare Partea de previzualizare (numai atunci când este ales un produs): - Erou carte cu gradient fundal, fel cip, numele produsului, și un titlu citit de om ("$5,000 · 12 luni rate · 14,99% APR" / "25.000 dolari linie de credit · 9,99% rata") - Grila de 4 statistici: principal, rată, plată lunară, termen (instalare) sau principal, rată, perioadă de tragere, perioadă de rambursare (LOC) - Defalcarea taxelor (origine/late/NSF/anual) cu cipul "custom" atunci când se aplică o suprascriere - Panou rezumat costuri: net platit, dobanda totala, costul total - Program de amortizare peek: primele 3 + ultimele 3 rânduri cu un " {N} mai mult plăți..." rând decalaj pentru termeni > 6 luni - TILA memento nota explicand backend calculeaza adevaratul APR + construieste programul real + face dezvăluiri la trimitere Toate matematica este client-lateral linie dreaptă amortizare (P × r × (1+r)^n / ((1+r)^n - 1)) Platformă Încă deţine adevărul.
· kamo-internal
Pagină poloneză nouă-ofertă
Trei goluri UX pagina de oferte a avut după readucătorul anterior: 1. Starea goală. Atunci când o piață nu are încă produse de împrumut, scăderea utilizată Pentru a face în tăcere gol și operatorul a avut nici o idee ce să facă. Acum înlocuit cu o stare erou gol (icon, titlu, primer pe Instalare vs LOC și un CTA "Creare împrumut" direcționat către produse/nou flux). 2. LOC vs Instalare nu este vizibil în avans Dropdown produs. Adăugat un cip colorat (LOC = albastru + pictogramă repetată, Instalare = pictogramă verde + portofel) redată atât în valoarea selectată și în interiorul fiecărei opțiuni de scădere, plus descrierea produsului în opțiune. 3. Blocul "Locked Termeni" a fost numit în mod confuz fără nici o modalitate de a suprascrie. Adăugat un panou "Custom termeni" colapsabil care expune suprascrie per-ofertă pentru rata dobânzii, APR dezvăluite și taxa de origine (preţuri de relaţionare, exerciţii de dificultate, promoţionale preţuri). Atunci când este setat, cardul cu termene blocate trece vizual prin valoarea produsului și arată suprascrierea (de exemplu 14,99% → 11,99%), astfel încât Operatorul vede exact ce va fi eliberat. Suport suport backend împins în KamoLOS 0e80393; tipuri extinse în losApi.ts astfel Câmpurile de suprascriere curg prin CreateOfferDraft.
· kamolos
Per-ofertă suprascrie pentru rata, APR, și taxa de origine
LoanOfferCreateCâștigări de cerere trei câmpuri opționale AprBps Override, origine FeeAmountOverride. CreateDraft le aplică atunci când set și altfel cade înapoi la instantaneu produs. Utilizare cazuri: relație stabilirea prețurilor (reducere a ratei pentru debitori repetați), exerciții de dificultate (în creștere de origine), oferte promoţionale unice. Pentru produsele de instalare, numai interesRateBpsOverride se află în calea normală APR se calculează din rata + comisioane + program. aprBpsOverride este expus pentru cazul rar în care o APR explicită trebuie să fie diferită de calcul. Audit: scrie OFFER DRAENID pentru fiecare proiect (uniformă cu OFFER SENT/ACCEPTAT). Loguri valori de suprascriere explicite vs produsele implicite astfel încât traseul să poată reconstrui ceea ce a fost moștenit vs. set per-ofertă.
· kamo-internal
Expune personal LOANS în culegători de comerț-tip și angajament
Adaugă personal LOANS la listele COMMERCE TYPES și AngajamentType, astfel încât noua piata de credite personale KamoLOS poate fi creata de pe piete/noi si piete/pagini editate, suprafete in QuickActionsBar (cu /commerce/personal-împrumuturi/noi Traseu), și include în conducta-tip de angajament filtru și configurare.
· kamo-internal
T6+T7 frontend lash + rapoarte org + UI cu plată automată
Poli (T6): - Nou lib/format.ts: local-aware Intl helpers formatCurrency / formatDate / formatDateTime / formatPercentBps. Înlocuiește hardcoded laLocaleString () + felie (0,10) modele împrăștiate pe baza de coduri. - BorrowerAutoPayCard: înscriere completă / pauză / reluare / anulare / editare UI pentru automatul de stat. Suprafețe în modul de scădere (INSTALLMENT SCHEDLED / MIN PAYMENT / FULL STAŢION BALANCE / FIX AMOUNT) + ziua de lună + selectorul metodei de plată. Platforma a fost deja cu fir; aceasta este ultima piesă pentru autoservire împrumutat. - Coadă de încărcare: codul motivului IRS 1099-C scadere (8 oficial literele A Implicit *************** Notiţele rămân. Moneda emisă prin formatCurrency. Rapoartele Org (T7): - Nou *************** Tablou de bord cu 5 bucle (Current / 1-29 / 30-59 / 60-89 / 90+) cu %-din total + cod de culoare Graniţe de top. Verific legătura către coada de încărcare. suplimente losApi: - imbatranireRaport (orgId) + AgingReport type - auditSearch (filtre) pentru criteriul regulator multifiltru - LoanChargeOffReasonCode Union type - confirmă semnătura lui ChargeOff acceptă codul motivului
· kamolos
Tier 6+7+9+10 — frontend polish, org reports, OpenAPI, JaCoCo
T6 (frontend polish): - New /lib/format.ts: locale-aware formatCurrency / formatDate / formatDateTime / formatPercentBps via Intl APIs (replaces hardcoded toLocaleString + slice(0,10) patterns). - BorrowerAutoPayCard: enroll / pause / resume / cancel / edit auto-pay with amount-mode dropdown (INSTALLMENT_SCHEDULED / MIN_PAYMENT / FULL_STATEMENT_BALANCE / FIXED_AMOUNT) + day-of-month + payment-method selector. - Charge-off queue: IRS 1099-C reason code dropdown (8 official letters A–H per IRC §6050P) replaces the free-text reason field; default G. Currency formatting via formatCurrency. T7 (org reports): - New LoanReportsController.aging: counts loans into Current / 1-29 / 30-59 / 60-89 / 90+ buckets via paged DELINQUENT scan + countByOrganizationAndStatus for ACTIVE. - **************** 5-bucket dashboard with %-of-total + color-coded bands + drill-through to charge-off queue. T9-T10 (DX + docs): - **************** /v3/api-docs + /swagger-ui.html auto-generated. OpenApiConfig sets title + description + version. - DevSeedLoader @Profile("dev"): boots two sample LoanProducts (12-mo installment + perpetual LOC). Idempotent (skips on existing productCode). - JaCoCo Maven plugin: prepare-agent + report on test phase. Coverage HTML at target/site/jacoco/index.html for CI consumption. losApi additions: - agingReport(orgId) + AgingReport type - auditSearch(filters) for the multi-filter regulator endpoint - confirmChargeOff signature accepts reasonCode 36 tests passing.
· kamolos
Lotul de conformitate de gradul 5
- OffacSanctionsService: Jaro-Winkler fuszy match @ ≥0.92 după meciul exact Pas. A lovit scorul similaritatii de suprafata. Configurabil prin los.ofac.fuzzy-treshold. - AdverseActionNoticeService: ECOA §1002.9 conform cu denumirea generatorului PDF PCPB ca regulator federal. Rânduri motive-pentru-decodor + standard Limbajul de nediscriminare ECOA. Stocat la MediaService. - *************** cerere de audit multifiltru pentru regulator Citații + controale de reținere. Paged. - LoanChargeOffService.confirma accepta parametrul rationalCode (IRS 1099- C caseta 6 litera), a persistat la Loan.chargeOffReasonCode și a fost introdus în YearEndTaxJob 1099-C PDF redă. G implicit. - LoanProductValidationService avertizeaza cand dobandaRateBps > MLA 3600bps plafon astfel încât conformitatea poate semnaliza pentru oferta-timp de screening MLA. - YearEndTaxJob: eliminat product1099Int ramura a fost inert (nu există un flux de plăți cu împrumut-credit-dobândă). Cămaşa rămasă cu reactivare Îndrumare odată ce un astfel de flux aterizează. Toate cele 30 de teste au trecut.
· kamo-shared-library
Codul de identificare a împrumutului (IRS 1099-C caseta 6) + căutarea auditului
- New LoanChargeOffReasonCode enum (A BANKRUPTY..H Other) per IRC §6050P - Coloana "Imprumut.chargeOffReasonCode" - ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************ (LoanId / kind / actorType / actorMemberId / from / to)
· kamolos
Tier 3 security + Tier 8 bug cleanup batch
T3 — Security: - New RateLimitFilter (Bucket4j): 1000/min per IP for webhooks, 10/min per session for offer accept/decoder/rescind, 60/min general. Registered ahead of ProxyHmacFilter so abuse hits the bucket before cryptographic verification cost. - SecurityConfig adds HSTS + frameOptions(DENY) + contentTypeOptions via Spring Security HeaderWriter. - StripeConfig fails fast on prod profile with non-live key. T8 — Bug cleanup: - **************** looks up Loan.productIdSnapshot → LoanProduct.feeNsfFlat instead of hard-coded $25. $25 remains the fallback when product or fee is missing. - **************** gains an AdjustmentTarget field (PRINCIPAL / INTEREST / FEES). manualAdjust dispatches per target rather than always touching principal. Audit metadata now records which counter was touched. - **************** finds the most recent ACTIVE *or* PAUSED plan and reactivates it instead of creating a new row that orphans paused ones. - **************** typed FetchResult record with status (OK / NOT_FOUND / UNREACHABLE / UNCONFIGURED). fetchBlob(uid) preserved as legacy bytes-or-null adapter.
· kamo-shared-library
Nu-ţi face griji
Folosit de *************** pentru a reactiva un dispozitiv existent PAVIZAT plan în loc de a crea un rând duplicat care orfani cel oprit.
· kamo-internal
/api/los proxy HMAC-semne antete de identitate
Când LOS PROXY HMAC SECRET env var este setat, proxy acum calculează *************secret) şi trimite X-Proxy-Signature + X-Proxy-Timestamp alături de X-Org-Id / Antete X-Member-Id. Noul ProxyHmacFilter al lui Kamolos validează acest lucru (±60s skew, constant-time compay) astfel încât un client ocolind kamo-intern nu se mai poate spoof antete de identitate. Secret nesetat = trecere locală-dev (filtru dezactivat pe suport de asemenea).
· kamo-internal
Pagină detaliată a creditului de tip Org-side + ajustări/promise API
- LosApi: manualAdjust, renunțaFee, Promisiunea de plată - ************* pagina de operaţiuni complete * Carduri de sold 4 up (curent, principal, dobanda, urmatoarea scadenta) * Formular de ajustare manuală (CREDIT/DEBIT, motiv necesar) /api/los/ajustări/manuale * Promise-to-pay sub formă de apeluri ************* * Declaraţii + tabele de plăţi * Embeds <LoanAuditTimeline> pentru jurnalul complet de evenimente - Acest lucru rezolvă link-ul rupt care MarketActiveLoansTab + PipelineActiveLoansTab indicau.
· kamolos
Final batch — compliance, packets, adjustments, Grafana, tests
Compliance: - MlaCheckService — Military Lending Act covered-borrower lookup against DoD MDC single-record query. Returns NotCovered if unconfigured so dev doesn't hard-fail; production MUST configure los.mla.endpoint + api-key OR run manual MLA at the org's KYC step (PII access required). - OfacSanctionsService — Treasury SDN list cached in-memory, refreshed nightly from sdn.csv. Unicode NFD normalization + diacritic stripping. Wired into LoanOfferService.send: SDN hit blocks the send and writes a STATE_RULE_VIOLATION_DETECTED audit row. - LoanLifecycleService cooling-off now reads LoanStateRule.coolingOffDays for the borrower's state (replaces the LocalDateTime.now() placeholder). - Stripe account.updated webhook now syncs charges/payouts/details flags + default_currency + requirements_disabled_reason onto LoanOrgStripeConnect so cron jobs + the org settings UI see live capability state. Disclosure packet: - New DisclosurePacketBuilder bundles TILA box + GLBA privacy notice + ECOA non-discrimination notice + ACH mandate authorization into one PDF via PDFBox PDFMergerUtility + stores in MediaService. Each component is recorded as a LoanDisclosure row keyed to the offer. LoanOfferService.send builds the packet automatically before the ESign envelope is created. Servicing operations: - **************** — fees/principal credit-or-debit with required reason; emits LoanPayment(INTERNAL_ADJUSTMENT or REVERSAL_ADJUSTMENT) + MANUAL_ADJUSTMENT audit - LoanAdjustmentService.waiveFee — flips LoanFee.waivedAt + credits feesPaidToDate + emits FEE_WAIVED audit - **************** — non-financial commitment row used in D60+ workflow tracking, emits PROMISE_TO_PAY_LOGGED audit - LoanAdjustmentController exposes /api/los/adjustments/{manual, fees/{uid}/waive, promise-to-pay} Observability: - **************** — importable dashboard with status gauges, payment outcome rates, R-code returns by code, webhook p50/p90/p99, disbursements/hour, charge-offs/day, JVM heap, HTTP rate Tests (30 total, all green): - 7 AmortizationEngine - 9 InterestAccrualEngine (including the previously-fixed 100x bug) - 5 PaymentAllocator - 4 NachaReturnCode (retry classes + mandate-revoking codes + describe) - 5 OfacSanctionsService (clean match / hit / diacritics / alias / disabled via reflection-injected cache, no network or test container needed)
· kamolos
P2 lot
Observabilitate: - micrometru-registry-prometheus pe clasapath - /acţionare/prometeus expus prin configuraţia managementului (ambele locale + k8s configmap) - LoanMetrics service: *************** - Nu. los charge off total, los dibursement total, los loan status count (status}, E o histogramă. - Contoare cu fir în LoanPaymentPostingService + LoanChargeOffService Matematica + teste: - 21 de teste unitare care acoperă AmortizareaMotor (plată la nivel, APR Newton- Raphson, progresie lunară la termen, principal + interes invariant, paznici bad-input), InterestAcrualEngine (ACT 365 / ACT 360 DPR; o zi / treizeci de zile, LOC ADB), PaymentAlocator (fees→interest → Ordine principală, parţiale, supraplată, nuluri) - ** Fixes 100x rata dobânzii** in ***************** Divisor a fost 36500/36000 în loc de 3,650.000/3,600.000 (Rate anuale) fracţiunea are nevoie atât de 1/10000 bps→fracţie ŞI /365 zile), astfel acumulat Interesul era prea mare. Testul a adăugat că l-ar fi prins. Identificatori reali cu dungi (nu mai mulți deținători): - StripeConnectController.onboard persistă acum LoanOrgStripeConnect on crearea cu succes a contului de dungi; .status întoarce la bordul statului - Nou StripeIdRezolvator: conectatAccountIdForOrg() + lenes getOrCreateBorrownerClientId() (idempotență-cheie client.creat în contul conectat, persistă la împrumut.stripeClient Id) - AutoDebitRunJob.fireAchDebit +.fireDisbursement rezolva acum real ID-uri prin StripeIdResolver în loc de "acct placeholder *" Cadenţa amintirii: - RememberSchedulingJob: nightly matura emite plata DUE 3 DAYS, PLATA DUE AZI, PLATA LATE ZI 1/5/15, OFFER EXPIRARE (24h înainte de expirareaAt), declaraţie AVAILABIL (la generaţie). Dedusă prin Deci reluările sunt idepotente. Taxa pe sfârșit de an: - YearEndTaxJob (ron 06:00 Ianuarie 5): produce 1099-C pentru incarc-off-uri ≥ 600 $ + 1099-INT pentru dobânda de împrumut-credit > 10 dolari. PDFBox-redare formă, stocat la MediaService, înregistrat ca LoanDispension cu formular/an metadatele astfel reluările sunt idepotente. - Împrumut.tax1099 Auto-setat CELIBILE la încărcare-off confirma atunci când suma ≥ 600 $
· kamo-shared-library
LoanOrgStripeConnect + Loan tax/accrual fields + hot indexs
- New LoanOrgStripeConnect entity (one-per-org, holds stripeConnectedAccountId + Conectare la bordul navei) + depozit - Împrumut: stripeClientId (creat sub contul conectat al orgului), lastAcrualDate, tax1099IntEligible, tax1099CEligible - Indexe compozite fierbinţi: * împrumuturi: (org id,status), (bonderer member id,status), (next payment due at); (status,delincvency tier) * imprumut plati: (loan id,initiated at), (loan id,status), (stripe payment intent id), (declaration id) * împrumut declarații: (împrumut id,ment număr DESC), (due date,status) * împrumut oferte: (org id,status), (împrumutator member id,status), (status,expires at)

Universul tău te așteaptă.
Începeți gratuit în câteva minute.Adăugați produse oricând sunteți pregătit — fără migrare, fără autentificări noi.
Gratuit pentru totdeauna — nu este necesar un card de credit