nx_survey_serve.nx
buildroot/runtime/nx_survey_serve.nx
about
nx_survey_serve.nx -- the SURVEY/POLL product surface over nx_survey_engine (pure core, no main;
the nx_office_serve/nx_relate_serve discipline). A one-question welfare pulse and a deep survey are
the SAME app -- surveys are spec DATA loaded through the admin lane, never code.
ROUTES (base = URL mount prefix, e.g. "/survey" behind the sovereign edge):
GET / open+closed survey list
GET /s/<id> the survey form (respondent token from ?t=<tok> or freshly minted; the
served app.js keeps one stable token per browser -> revote-replace works)
POST /s/<id> record a ballot (engine validates; revote REPLACES by construction)
GET /s/<id>/done thanks page
GET /s/<id>/results AGGREGATE-ONLY results: counts/means/bars; k-floor (@kmin) withholds
below quorum; text answers NEVER render here; @results admin -> 403
GET /app.js progressive-enhancement client (token persistence; no-JS still works)
POST /admin/load|close|report -- key-file-gated (CWD survey_admin.key; FAIL-CLOSED when absent)
POST /admin/insights -- key-gated deep analytics report (cross-tab + chi-square significance, segment
means, key drivers, concern flags, open-text themes) over nx_survey_stats
PRIVACY BY CONSTRUCTION: anon surveys never emit tokens anywhere public; results are counts only;
free text is admin-report only; deep breakdowns that could reveal a small cell are admin-lane only.
Same-origin POST guard. license_tier: ORIGINAL
dependencies 2 imports · 2 importers
imports: nx_survey_sentiment.nxnx_itoa_lib.nx
imported by: nx_survey_daemon.nxnx_survey_serve_gate.nx
structs
| none |
consts
| 22 | const SV2_MAXB: i64 = 512 // ballots the serve layer aggregates per survey (walk stays LOUD past it) |
| 23 | const SV2_MAXS: i64 = 64 // surveys listed on home |
| 56 | const SV2_PATHB: i64 = 400 |
functions
| 34 | func sv2_barr() -> i64 |
| 42 | func sv2_sarr() -> i64 called by 1: sv2_home |
| 58 | func sv2_pathb() -> i64 called by 1: sv2_handle |
| 63 | func sv2_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 68 | func sv2_pn(v: i64) -> i64 { nxi_out(v); return 0 } calls 1: nxi_out |
| 69 | func sv2_memhas(buf: *u8, n: i64, needle: *u8) -> i64 |
| 83 | func sv2_esc(dst: *u8, off: i64, s: *u8) -> i64 called by 11: sv2_page_topsv2_homesv2_formsv2_resultssv2_ins_driverssv2_ins_themes+5 calls 1: se_cat |
| 95 | func sv2_hexval(c: i64) -> i64 called by 1: sv2_form_get |
| 102 | func sv2_form_get(body: *u8, blen: i64, key: *u8, out: *u8, cap: i64) -> i64 |
| 137 | func sv2_write_all(fd: i64, buf: *u8, n: i64) -> i64 |
| 143 | func sv2_read_req(fd: i64, buf: *u8, cap: i64) -> i64 called by 1: main |
| 191 | func sv2_read_file(path: *u8, buf: *u8, cap: i64) -> i64 called by 1: sv2_serve_js |
| 199 | func sv2_write_file(path: *u8, buf: *u8, n: i64) -> i64 |
| 207 | func sv2_hdr_get(req: *u8, reqlen: i64, key: *u8, out: *u8, cap: i64) -> i64 |
| 233 | func sv2_err(out: *u8, status: *u8, msg: *u8) -> i64 |
| 242 | func sv2_fixed2(dst: *u8, off: i64, x100: i64) -> i64 |
| 252 | func sv2_css(out: *u8, off: i64) -> i64 |
| 269 | func sv2_page_top(out: *u8, off: i64, title: *u8) -> i64 |
| 280 | func sv2_page_foot(out: *u8, off: i64) -> i64 |
| 286 | func sv2_home(prefix: *u8, base: *u8, out: *u8, cap: i64) -> i64 |
| 331 | func sv2_form(prefix: *u8, base: *u8, id: *u8, tok: *u8, out: *u8, cap: i64) -> i64 |
| 465 | func sv2_results(prefix: *u8, base: *u8, id: *u8, out: *u8, cap: i64) -> i64 |
| 630 | func sv2_done(base: *u8, id: *u8, out: *u8) -> i64 |
| 643 | func sv2_admin_ok(keypath: *u8, presented: *u8) -> i64 |
| 662 | func sv2_report(prefix: *u8, id: *u8, out: *u8, cap: i64) -> i64 |
| 763 | func sv2_ins_scale(out: *u8, o0: i64, bv: *i64, bl: *i64, nb: i64, qkind: *i64, qidp: *i64, qprompt: *i64, qmax: *i64, qmin: *i64, nqg: i64) -> i64 |
| 825 | func sv2_ins_seg(out: *u8, o0: i64, bv: *i64, bl: *i64, nb: i64, qkind: *i64, qidp: *i64, qprompt: *i64, qopts: *i64, qnopt: *i64, nqg: i64) -> i64 |
| 872 | func sv2_ins_xtab(out: *u8, o0: i64, bv: *i64, bl: *i64, nb: i64, qkind: *i64, qidp: *i64, qprompt: *i64, qopts: *i64, qnopt: *i64, nqg: i64) -> i64 |
| 926 | func j_q(out: *u8, o: i64) -> i64 { out[o] = 34 as u8; return o + 1 } |
| 927 | func j_key(out: *u8, o: i64, k: *u8) -> i64 { var oo: i64 = j_q(out, o); oo = se_cat(out, oo, k); oo = j_q(out, oo); out[oo] = 58 as u8; return oo + 1 } |
| 928 | func j_str(out: *u8, o: i64, s: *u8) -> i64 |
| 940 | func sv2_results_json(prefix: *u8, id: *u8, out: *u8, cap: i64) -> i64 |
| 1070 | func sv2_ins_drivers(out: *u8, o0: i64, bv: *i64, bl: *i64, nb: i64, qkind: *i64, qidp: *i64, qprompt: *i64, nqg: i64) -> i64 |
| 1123 | func sv2_ins_themes(out: *u8, o0: i64, bv: *i64, bl: *i64, nb: i64, qkind: *i64, qidp: *i64, qprompt: *i64, nqg: i64) -> i64 |
| 1166 | func sv2_ins_sentiment(out: *u8, o0: i64, bv: *i64, bl: *i64, nb: i64, qkind: *i64, qidp: *i64, qprompt: *i64, nqg: i64) -> i64 |
| 1215 | func sv2_ins_quality(out: *u8, o0: i64, prefix: *u8, id: *u8, bv: *i64, bl: *i64, nb: i64, qkind: *i64, qidp: *i64, nqg: i64) -> i64 |
| 1265 | func sv2_insights(prefix: *u8, base: *u8, id: *u8, out: *u8, cap: i64) -> i64 |
| 1334 | func sv2_embed_top(out: *u8, o0: i64, title: *u8) -> i64 |
| 1348 | func sv2_embed_results(prefix: *u8, base: *u8, id: *u8, out: *u8, cap: i64) -> i64 |
| 1437 | func sv2_embed(prefix: *u8, base: *u8, id: *u8, tok: *u8, out: *u8, cap: i64) -> i64 |
| 1508 | func sv2_finalize(resp: *u8, n: i64, out: *u8, cap: i64) -> i64 |
| 1536 | func sv2_serve_js(out: *u8, cap: i64) -> i64 |
| 1549 | func sv2_handle(prefix: *u8, base: *u8, keypath: *u8, req: *u8, reqlen: i64, out: *u8, cap: i64) -> i64 |
| 1822 | func sv2_ck(name: *u8, cond: i64, pass: *i64, fail: *i64) -> i64 |
| 1828 | func sv2_post(prefix: *u8, base: *u8, keypath: *u8, path: *u8, body: *u8, origin: *u8, out: *u8, cap: i64) -> i64 |
| 1843 | func sv2_get(prefix: *u8, base: *u8, keypath: *u8, path: *u8, out: *u8, cap: i64) -> i64 |
| 1850 | func sv2_selftest() -> i64 |