code wiki / _hdl_build / nx_ad_intake.nx

nx_ad_intake.nx source

↩ module page · 144 lines · 5929 B

1// nx_ad_intake.nx -- LIB: advertiser SELF-SERVE SIGNUP / campaign creation for the "Brought to you 2// by" ad engine (the "businesses sign up to advertise" face). A business picks a goal, sets a flat 3// fee, and submits creative copy; we VALIDATE at the boundary (rule 12), then persist a campaign 4// record ADDITIVELY to the sovereign store (rule 13, append-only versioned). Idempotent (rule 10): 5// re-creating an unchanged campaign is a no-op. 6// 7// PRIVACY LAW (feedback-no-server-side-visitor-identity): this is an ADVERTISER B2B ACCOUNT -- a 8// business deliberately identifying itself as a paying customer. The campaign record holds ONLY 9// advertiser-supplied business data (name, goal, fee, banner, status). It has NO parameter and NO 10// field for any SITE-VISITOR identity -- signup can never become visitor tracking by construction. 11// 12// Record (store key adcamp:<id>): business<tab>goal<tab>fee<tab>banner<tab>status. Creative text is 13// stored RAW and HTML-ESCAPED at emission by nx_ad_serve (the proven boundary), so a "<script>" name 14// is safe on the page. Goals are DATA-DRIVEN (rule 11): a goal is valid iff adgoal:<goal> exists in 15// the store, so adding a goal needs no code change. license_tier: ORIGINAL 16import "nx_ad_serve.nx" 17import "nx_ad_store.nx" 18import "nx_seg_store.nx" 19import "nx_syscalls.nx" 20 21const IN_OK: i64 = 0 22const IN_BAD_GOAL: i64 = 0 - 1 23const IN_BAD_FEE: i64 = 0 - 2 24const IN_BAD_CREA: i64 = 0 - 3 25const IN_COMMIT_ERR: i64 = 0 - 4 26 27// append a non-negative int as decimal into dst at off; return new offset. 28func in_appn(dst: *u8, off: i64, v: i64) -> i64 { 29 if v == 0 { dst[off] = 48 as u8; return off + 1 } 30 var m: i64 = v 31 var o: i64 = off 32 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m } 33 let t: *u8 = sys_mmap(28) 34 var k: i64 = 0 35 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 36 var i: i64 = k - 1 37 while i >= 0 { dst[o] = t[i]; o = o + 1; i = i - 1 } 38 return o 39} 40 41// store key for a campaign id: "adcamp:" + id (NUL-terminated). out must hold id length + 8. 42func in_campaign_key(id: *u8, out: *u8) -> i64 { 43 var o: i64 = as_append(out, 0, "adcamp:" as *u8) 44 o = as_append(out, o, id) 45 out[o] = 0 as u8 46 return o 47} 48 49// build the campaign record bytes into out; returns byte length. Advertiser data ONLY. 50func in_build_record(business: *u8, goal: *u8, fee: i64, banner: *u8, status: *u8, out: *u8) -> i64 { 51 var o: i64 = as_append(out, 0, business) 52 out[o] = 9 as u8; o = o + 1 53 o = as_append(out, o, goal) 54 out[o] = 9 as u8; o = o + 1 55 o = in_appn(out, o, fee) 56 out[o] = 9 as u8; o = o + 1 57 o = as_append(out, o, banner) 58 out[o] = 9 as u8; o = o + 1 59 o = as_append(out, o, status) 60 out[o] = 0 as u8 61 return o 62} 63 64// data-driven goal validation: 1 iff adgoal:<goalname> exists in the store (rule 11). 65func in_goal_known(goalname: *u8) -> i64 { 66 let key: *u8 = sys_mmap(128) 67 var o: i64 = as_append(key, 0, "adgoal:" as *u8) 68 o = as_append(key, o, goalname) 69 key[o] = 0 as u8 70 let pq: *i64 = sys_mmap(16) as *i64 71 let lq: *i64 = sys_mmap(16) as *i64 72 if ads_get(key, pq, lq) == 1 { return 1 } 73 return 0 74} 75 76// the max flat fee we accept (config-hierarchy, rule 17): store adcfg:fee_max wins; absent -> the 77// bootstrap default (lowest tier). Guards against fat-finger / abuse at the boundary. 78func in_fee_max() -> i64 { 79 let pq: *i64 = sys_mmap(16) as *i64 80 let lq: *i64 = sys_mmap(16) as *i64 81 if ads_get("adcfg:fee_max" as *u8, pq, lq) != 1 { return 100000 } 82 let b: *u8 = pq[0] as *u8 83 let n: i64 = lq[0] 84 var v: i64 = 0 85 var i: i64 = 0 86 var go: i64 = 1 87 while go == 1 { 88 if i >= n { go = 0 } else { 89 let c: i64 = b[i] as i64 90 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); i = i + 1 } else { go = 0 } } else { go = 0 } 91 } 92 } 93 if v <= 0 { return 100000 } 94 return v 95} 96 97// creative bounds (boundary defense): business name + banner present and length-bounded. Bootstrap 98// bounds (move to store config later if needed). Escaping happens at emit (nx_ad_serve), not here. 99func in_creative_ok(business: *u8, banner: *u8) -> i64 { 100 let bl: i64 = as_len(business) 101 let tl: i64 = as_len(banner) 102 if bl < 1 { return 0 } 103 if bl > 80 { return 0 } 104 if tl < 1 { return 0 } 105 if tl > 200 { return 0 } 106 return 1 107} 108 109// 1 if the store's value for key byte-equals val[0..vlen]. Idempotent skip + read-back helper. 110func in_streq_store(key: *u8, val: *u8, vlen: i64) -> i64 { 111 let pq: *i64 = sys_mmap(16) as *i64 112 let lq: *i64 = sys_mmap(16) as *i64 113 if ads_get(key, pq, lq) != 1 { return 0 } 114 let b: *u8 = pq[0] as *u8 115 let n: i64 = lq[0] 116 if n != vlen { return 0 } 117 var i: i64 = 0 118 while i < n { if b[i] != val[i] { return 0 } i = i + 1 } 119 return 1 120} 121 122// CREATE a campaign. Validates goal (data-driven) -> fee (>=0, <=max) -> creative (present, bounded), 123// FAIL-CLOSED with a distinct code before any write. On success persists adcamp:<id> additively and 124// returns IN_OK (idempotent: unchanged -> no-op). No visitor identity touches this path. 125func in_create_campaign(id: *u8, business: *u8, goal: *u8, fee: i64, banner: *u8) -> i64 { 126 if in_goal_known(goal) != 1 { return IN_BAD_GOAL } 127 if fee < 0 { return IN_BAD_FEE } 128 if fee > in_fee_max() { return IN_BAD_FEE } 129 if in_creative_ok(business, banner) != 1 { return IN_BAD_CREA } 130 131 let rec: *u8 = sys_mmap(4096) 132 let rlen: i64 = in_build_record(business, goal, fee, banner, "staging" as *u8, rec) 133 let key: *u8 = sys_mmap(256) 134 in_campaign_key(id, key) 135 136 if in_streq_store(key, rec, rlen) == 1 { return IN_OK } // idempotent: already created unchanged 137 138 let w: *i64 = ss_begin() 139 ss_add(w, 1, key, rec, rlen) 140 let segid: i64 = ads_seg_next() 141 let rc: i64 = ss_commit(ADS_PREFIX, w, segid) 142 if rc != 0 { return IN_COMMIT_ERR } 143 return IN_OK 144}