code wiki / (root) / nx_crm_store.nx

nx_crm_store.nx source

↩ module page · 280 lines · 12420 B

1// nx_crm_store.nx -- PERSISTENCE for deals + giving (the DEPTH rung after full-presence 1000): the pipeline and 2// the church statements survive across runs on the sovereign APPEND-ONLY seg_store (additive, tombstone-not-delete, 3// content-addressed = tamper-evident, on YOUR hardware -- the CRM exceed made concrete for the money records). 4// Records: key "dea:"+cid {kind=dea,name,account,amount,stage} ยท key "giv:"+cid {kind=giv,donor,fund,amount,gtype}. 5// THE DEPTH PROOF: the weighted forecast and the household giving statement are recomputed FROM THE STORE and must 6// equal the in-memory oracles of nx_crm/nx_org ($122,500 forecast; $1,350 received) -- two independent paths, one 7// truth. Saves VALIDATE (unknown stage / bad gift type = LOUD -1, nothing committed). Additivity proven: a second 8// commit adds a deal and the recomputed forecast moves exactly (+Lead 40000 -> +4000 weighted). 9// Composes the nx_crm pure core (stage_prob/stage_open/gift vocab lives beside) + canon_cid + seg_store. 10// Argless = selftest gate. license_tier: ORIGINAL expect_exit: 0 11import "nx_crm.nx" 12import "nx_canon_cid.nx" 13import "nx_seg_store.nx" 14const K_MAGIC_2048: i64 = 2048 15const K_MAGIC_50000: i64 = 50000 16const K_MAGIC_120000: i64 = 120000 17const K_MAGIC_30000: i64 = 30000 18const K_MAGIC_20000: i64 = 20000 19const K_MAGIC_200000: i64 = 200000 20const K_MAGIC_122500: i64 = 122500 21const K_MAGIC_1350: i64 = 1350 22const K_MAGIC_40000: i64 = 40000 23const K_MAGIC_240000: i64 = 240000 24const K_MAGIC_126500: i64 = 126500 25 26func cs_kmemeq(b: *u8, off: i64, n: i64, s: *u8) -> i64 { 27 if slen(s) != n { return 0 } 28 var i: i64 = 0 29 while i < n { if b[off + i] != s[i] { return 0 } i = i + 1 } 30 return 1 31} 32func cs_iskind(b: *u8, koff: i64, kl: i64, pfx: *u8) -> i64 { 33 if kl <= 4 { return 0 } 34 return cs_kmemeq(b, koff, 4, pfx) 35} 36func cs_field(rec: *u8, rl: i64, want: *u8, out: *u8, cap: i64) -> i64 { 37 if rl < 8 { return 0 } 38 let nf: i64 = ss_r32(rec, 4) 39 var off: i64 = 8 40 var fi: i64 = 0 41 while fi < nf { 42 if off + 8 > rl { return 0 } 43 let kl: i64 = ss_r32(rec, off) 44 let koff: i64 = off + 4 45 let vl: i64 = ss_r32(rec, koff + kl) 46 let voff: i64 = koff + kl + 4 47 if cs_kmemeq(rec, koff, kl, want) == 1 { 48 var t: i64 = 0 49 while t < vl { if t < cap - 1 { out[t] = rec[voff + t] } t = t + 1 } 50 if t > cap - 1 { t = cap - 1 } 51 out[t] = 0 as u8 52 return 1 53 } 54 off = voff + vl 55 fi = fi + 1 56 } 57 return 0 58} 59func cs_atoi(s: *u8) -> i64 { 60 var v: i64 = 0 61 var i: i64 = 0 62 while s[i] != (0 as u8) { 63 let d: i64 = (s[i] as i64) - 48 64 if d >= 0 { if d <= 9 { v = v * 10 + d } } 65 i = i + 1 66 } 67 return v 68} 69func cs_gift_ok(t: *u8) -> i64 { 70 if seq(t, "donation" as *u8) == 1 { return 1 } 71 if seq(t, "recurring" as *u8) == 1 { return 1 } 72 if seq(t, "pledge-payment" as *u8) == 1 { return 1 } 73 if seq(t, "in-kind" as *u8) == 1 { return 1 } 74 if seq(t, "soft-credit" as *u8) == 1 { return 1 } 75 return 0 76} 77// save one deal (VALIDATED: unknown stage = -1, nothing added) 78func cs_save_deal(w: *i64, name: *u8, account: *u8, amount: i64, stage: *u8) -> i64 { 79 if stage_valid(stage) == 0 { p("CRM-STORE save_deal unknown stage -- fail loud\n" as *u8); return 0 - 1 } 80 if amount < 0 { return 0 - 1 } 81 let ab: *u8 = sys_mmap(32) 82 var ao: i64 = 0 83 ao = ss_catn(ab, ao, amount) 84 ab[ao] = 0 as u8 85 let keys: *i64 = sys_mmap(8 * 8) as *i64 86 let vals: *i64 = sys_mmap(8 * 8) as *i64 87 keys[0]="kind" as *u8 as i64; keys[1]="name" as *u8 as i64; keys[2]="account" as *u8 as i64; keys[3]="amount" as *u8 as i64; keys[4]="stage" as *u8 as i64 88 vals[0]="dea" as *u8 as i64; vals[1]=name as i64; vals[2]=account as i64; vals[3]=ab as i64; vals[4]=stage as i64 89 let enc: *u8 = sys_mmap(K_MAGIC_2048) 90 let el: i64 = canon_encode(keys, vals, 5, enc) 91 let cid: *u8 = sys_mmap(96) 92 cid_of(enc, el, cid) 93 let key: *u8 = sys_mmap(128) 94 var ko: i64 = 0 95 ko = ss_cat(key, ko, "dea:" as *u8) 96 ko = ss_cat(key, ko, cid) 97 key[ko] = 0 as u8 98 return ss_add(w, 1, key, enc, el) 99} 100// save one gift (VALIDATED type) 101func cs_save_gift(w: *i64, donor: *u8, fund: *u8, amount: i64, gtype: *u8) -> i64 { 102 if cs_gift_ok(gtype) == 0 { p("CRM-STORE save_gift unknown type -- fail loud\n" as *u8); return 0 - 1 } 103 if amount < 0 { return 0 - 1 } 104 let ab: *u8 = sys_mmap(32) 105 var ao: i64 = 0 106 ao = ss_catn(ab, ao, amount) 107 ab[ao] = 0 as u8 108 let keys: *i64 = sys_mmap(8 * 8) as *i64 109 let vals: *i64 = sys_mmap(8 * 8) as *i64 110 keys[0]="kind" as *u8 as i64; keys[1]="donor" as *u8 as i64; keys[2]="fund" as *u8 as i64; keys[3]="amount" as *u8 as i64; keys[4]="gtype" as *u8 as i64 111 vals[0]="giv" as *u8 as i64; vals[1]=donor as i64; vals[2]=fund as i64; vals[3]=ab as i64; vals[4]=gtype as i64 112 let enc: *u8 = sys_mmap(K_MAGIC_2048) 113 let el: i64 = canon_encode(keys, vals, 5, enc) 114 let cid: *u8 = sys_mmap(96) 115 cid_of(enc, el, cid) 116 let key: *u8 = sys_mmap(128) 117 var ko: i64 = 0 118 ko = ss_cat(key, ko, "giv:" as *u8) 119 ko = ss_cat(key, ko, cid) 120 key[ko] = 0 as u8 121 return ss_add(w, 1, key, enc, el) 122} 123// recompute the pipeline FROM THE STORE: out[0]=open total, out[1]=weighted forecast, out[2]=won; returns deal count 124func cs_forecast(prefix: *u8, out: *i64) -> i64 { 125 out[0] = 0 126 out[1] = 0 127 out[2] = 0 128 let segp: *i64 = sys_mmap(16) as *i64 129 let ns: i64 = ss_manifest_dyn(prefix, segp) // uncapped: sees the WHOLE store, not the first legacy-cap segs 130 let segs: *i64 = segp[0] as *i64 131 let fa: *u8 = sys_mmap(64) 132 let fs: *u8 = sys_mmap(128) 133 var cnt: i64 = 0 134 var s: i64 = 0 135 while s < ns { 136 let path: *u8 = sys_mmap(512) 137 var po: i64 = 0 138 po = ss_cat(path, po, prefix) 139 po = ss_cat(path, po, segs[s] as *u8) 140 po = ss_cat(path, po, ".docs" as *u8) 141 path[po] = 0 as u8 142 let szp: *i64 = sys_mmap(16) as *i64 143 let b: *u8 = ss_readall(path, szp) 144 let sz: i64 = szp[0] 145 var j: i64 = 0 146 while j + 9 <= sz { 147 let kl: i64 = ss_r32(b, j + 1) 148 let koff: i64 = j + 5 149 let vl: i64 = ss_r32(b, koff + kl) 150 let voff: i64 = koff + kl + 4 151 if b[j] == 1 { 152 if cs_iskind(b, koff, kl, "dea:" as *u8) == 1 { 153 let rec: *u8 = (b as i64 + voff) as *u8 154 cs_field(rec, vl, "amount" as *u8, fa, 64) 155 cs_field(rec, vl, "stage" as *u8, fs, 128) 156 let amt: i64 = cs_atoi(fa) 157 if stage_open(fs) == 1 { 158 out[0] = out[0] + amt 159 out[1] = out[1] + (amt * stage_prob(fs)) / 100 160 } 161 if seq(fs, "ClosedWon" as *u8) == 1 { out[2] = out[2] + amt } 162 cnt = cnt + 1 163 } 164 } 165 j = voff + vl 166 } 167 s = s + 1 168 } 169 return cnt 170} 171// recompute giving FROM THE STORE: returns total; out[0]=count, out[1]=total for fundfilter (or all if filter[0]==0) 172func cs_giving(prefix: *u8, fundfilter: *u8, out: *i64) -> i64 { 173 out[0] = 0 174 out[1] = 0 175 let segp: *i64 = sys_mmap(16) as *i64 176 let ns: i64 = ss_manifest_dyn(prefix, segp) // uncapped: sees the WHOLE store 177 let segs: *i64 = segp[0] as *i64 178 let fa: *u8 = sys_mmap(64) 179 let ff: *u8 = sys_mmap(128) 180 var total: i64 = 0 181 var s: i64 = 0 182 while s < ns { 183 let path: *u8 = sys_mmap(512) 184 var po: i64 = 0 185 po = ss_cat(path, po, prefix) 186 po = ss_cat(path, po, segs[s] as *u8) 187 po = ss_cat(path, po, ".docs" as *u8) 188 path[po] = 0 as u8 189 let szp: *i64 = sys_mmap(16) as *i64 190 let b: *u8 = ss_readall(path, szp) 191 let sz: i64 = szp[0] 192 var j: i64 = 0 193 while j + 9 <= sz { 194 let kl: i64 = ss_r32(b, j + 1) 195 let koff: i64 = j + 5 196 let vl: i64 = ss_r32(b, koff + kl) 197 let voff: i64 = koff + kl + 4 198 if b[j] == 1 { 199 if cs_iskind(b, koff, kl, "giv:" as *u8) == 1 { 200 let rec: *u8 = (b as i64 + voff) as *u8 201 cs_field(rec, vl, "amount" as *u8, fa, 64) 202 cs_field(rec, vl, "fund" as *u8, ff, 128) 203 let amt: i64 = cs_atoi(fa) 204 total = total + amt 205 out[0] = out[0] + 1 206 if fundfilter[0] != (0 as u8) { if seq(ff, fundfilter) == 1 { out[1] = out[1] + amt } } 207 } 208 } 209 j = voff + vl 210 } 211 s = s + 1 212 } 213 return total 214} 215 216func main() -> i64 { 217 p("=== NX-CRM-STORE SELFTEST (deals + giving persisted; forecast + statement recomputed FROM THE STORE) ===\n" as *u8) 218 var ok: i64 = 1 219 let mt: *u8 = sys_mmap(4) 220 mt[0] = 0 as u8 221 let prefix: *u8 = sys_mmap(128) 222 var po: i64 = 0 223 po = ss_cat(prefix, po, "/tmp/crmstore_" as *u8) 224 po = ss_catn(prefix, po, sys_now_us()) 225 po = ss_cat(prefix, po, "_" as *u8) 226 prefix[po] = 0 as u8 227 228 // commit 1: the exact nx_crm dashboard pipeline + the exact nx_org household gifts 229 let w: *i64 = ss_begin() 230 cs_save_deal(w, "Westfield Renovation" as *u8, "Westfield Group" as *u8, K_MAGIC_50000, "Proposal" as *u8) 231 cs_save_deal(w, "Riverside Contract" as *u8, "Riverside LLC" as *u8, K_MAGIC_120000, "Negotiation" as *u8) 232 cs_save_deal(w, "Downtown Lease" as *u8, "Downtown Co" as *u8, K_MAGIC_30000, "Qualified" as *u8) 233 cs_save_deal(w, "Old Bid" as *u8, "Old Co" as *u8, K_MAGIC_20000, "ClosedLost" as *u8) 234 cs_save_gift(w, "Rose" as *u8, "Tithing" as *u8, 500, "donation" as *u8) 235 cs_save_gift(w, "Rose" as *u8, "Missionary" as *u8, 100, "donation" as *u8) 236 cs_save_gift(w, "Ken" as *u8, "Tithing" as *u8, 300, "donation" as *u8) 237 cs_save_gift(w, "Rose" as *u8, "Humanitarian" as *u8, 50, "recurring" as *u8) 238 cs_save_gift(w, "Ken" as *u8, "Building" as *u8, 400, "pledge-payment" as *u8) 239 if ss_commit(prefix, w, sys_now_us()) != 0 { p("commit1 FAILED -- fail loud\n" as *u8); return 1 } 240 241 // recompute FROM THE STORE -- must equal the in-memory oracles (two independent paths, one truth) 242 let fo: *i64 = sys_mmap(8 * 4) as *i64 243 let d1: i64 = cs_forecast(prefix, fo) 244 p(" from-store: deals=" as *u8); pn(d1); p(" open=" as *u8); pn(fo[0]); p(" weighted=" as *u8); pn(fo[1]); p(" won=" as *u8); pn(fo[2]); p("\n" as *u8) 245 if d1 != 4 { ok = 0 } 246 if fo[0] != K_MAGIC_200000 { ok = 0 } 247 if fo[1] != K_MAGIC_122500 { ok = 0 } 248 if fo[2] != 0 { ok = 0 } 249 let go: *i64 = sys_mmap(8 * 4) as *i64 250 let gt: i64 = cs_giving(prefix, "Tithing" as *u8, go) 251 p(" from-store: gifts=" as *u8); pn(go[0]); p(" received=" as *u8); pn(gt); p(" tithing=" as *u8); pn(go[1]); p("\n" as *u8) 252 if go[0] != 5 { ok = 0 } 253 if gt != K_MAGIC_1350 { ok = 0 } 254 if go[1] != 800 { ok = 0 } 255 256 // additivity: a second commit adds one Lead deal -> the recomputed forecast moves EXACTLY 257 let w2: *i64 = ss_begin() 258 cs_save_deal(w2, "New Lead" as *u8, "Fresh Co" as *u8, K_MAGIC_40000, "Lead" as *u8) 259 if ss_commit(prefix, w2, sys_now_us()) != 0 { p("commit2 FAILED -- fail loud\n" as *u8); return 1 } 260 let d2: i64 = cs_forecast(prefix, fo) 261 p(" additive: deals=" as *u8); pn(d2); p(" open=" as *u8); pn(fo[0]); p(" weighted=" as *u8); pn(fo[1]); p("\n" as *u8) 262 if d2 != 5 { ok = 0 } 263 if fo[0] != K_MAGIC_240000 { ok = 0 } 264 if fo[1] != K_MAGIC_126500 { ok = 0 } 265 266 // validation: bad stage / bad gift type refuse LOUD and change nothing 267 let w3: *i64 = ss_begin() 268 let bd: i64 = cs_save_deal(w3, "Bad" as *u8, "X" as *u8, 1000, "Vibes" as *u8) 269 let bg: i64 = cs_save_gift(w3, "X" as *u8, "F" as *u8, 10, "bitcoin-rug" as *u8) 270 if bd != (0 - 1) { ok = 0 } 271 if bg != (0 - 1) { ok = 0 } 272 let d3: i64 = cs_forecast(prefix, fo) 273 if d3 != 5 { ok = 0 } 274 p(" validation: bad-stage=" as *u8); pn(bd); p(" bad-gift=" as *u8); pn(bg); p(" store-unchanged deals=" as *u8); pn(d3); p("\n" as *u8) 275 276 p("NX-CRM-STORE-SELFTEST prefix=" as *u8); p(prefix); p(" " as *u8) 277 if ok == 1 { p("verdict=GREEN (money records persisted, recomputed from store == in-memory oracles, additive)\n" as *u8); return 0 } 278 p("verdict=RED\n" as *u8) 279 return 1 280}