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 |
functions
| 25 | 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 } |
| 30 | func sv2_pn(v: i64) -> i64 { nxi_out(v); return 0 } calls 1: nxi_out |
| 31 | func sv2_memhas(buf: *u8, n: i64, needle: *u8) -> i64 |
| 45 | 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 |
| 57 | func sv2_hexval(c: i64) -> i64 called by 1: sv2_form_get |
| 64 | func sv2_form_get(body: *u8, blen: i64, key: *u8, out: *u8, cap: i64) -> i64 |
| 99 | func sv2_write_all(fd: i64, buf: *u8, n: i64) -> i64 called by 1: sv2_write_file |
| 105 | func sv2_read_req(fd: i64, buf: *u8, cap: i64) -> i64 calls 1: sys_read |
| 153 | func sv2_read_file(path: *u8, buf: *u8, cap: i64) -> i64 |
| 161 | func sv2_write_file(path: *u8, buf: *u8, n: i64) -> i64 |
| 169 | func sv2_hdr_get(req: *u8, reqlen: i64, key: *u8, out: *u8, cap: i64) -> i64 |
| 195 | func sv2_err(out: *u8, status: *u8, msg: *u8) -> i64 |
| 204 | func sv2_fixed2(dst: *u8, off: i64, x100: i64) -> i64 |
| 214 | func sv2_css(out: *u8, off: i64) -> i64 |
| 231 | func sv2_page_top(out: *u8, off: i64, title: *u8) -> i64 |
| 242 | func sv2_page_foot(out: *u8, off: i64) -> i64 |
| 248 | func sv2_home(prefix: *u8, base: *u8, out: *u8, cap: i64) -> i64 |
| 292 | func sv2_form(prefix: *u8, base: *u8, id: *u8, tok: *u8, out: *u8, cap: i64) -> i64 |
| 426 | func sv2_results(prefix: *u8, base: *u8, id: *u8, out: *u8, cap: i64) -> i64 |
| 590 | func sv2_done(base: *u8, id: *u8, out: *u8) -> i64 |
| 603 | func sv2_admin_ok(keypath: *u8, presented: *u8) -> i64 |
| 622 | func sv2_report(prefix: *u8, id: *u8, out: *u8, cap: i64) -> i64 |
| 722 | 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 |
| 784 | 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 |
| 831 | 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 |
| 885 | func j_q(out: *u8, o: i64) -> i64 { out[o] = 34 as u8; return o + 1 } |
| 886 | 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 } |
| 887 | func j_str(out: *u8, o: i64, s: *u8) -> i64 |
| 899 | func sv2_results_json(prefix: *u8, id: *u8, out: *u8, cap: i64) -> i64 |
| 1028 | func sv2_ins_drivers(out: *u8, o0: i64, bv: *i64, bl: *i64, nb: i64, qkind: *i64, qidp: *i64, qprompt: *i64, nqg: i64) -> i64 |
| 1081 | func sv2_ins_themes(out: *u8, o0: i64, bv: *i64, bl: *i64, nb: i64, qkind: *i64, qidp: *i64, qprompt: *i64, nqg: i64) -> i64 |
| 1124 | func sv2_ins_sentiment(out: *u8, o0: i64, bv: *i64, bl: *i64, nb: i64, qkind: *i64, qidp: *i64, qprompt: *i64, nqg: i64) -> i64 |
| 1173 | 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 |
| 1223 | func sv2_insights(prefix: *u8, base: *u8, id: *u8, out: *u8, cap: i64) -> i64 |
| 1291 | func sv2_embed_top(out: *u8, o0: i64, title: *u8) -> i64 |
| 1305 | func sv2_embed_results(prefix: *u8, base: *u8, id: *u8, out: *u8, cap: i64) -> i64 |
| 1393 | func sv2_embed(prefix: *u8, base: *u8, id: *u8, tok: *u8, out: *u8, cap: i64) -> i64 |
| 1464 | func sv2_finalize(resp: *u8, n: i64, out: *u8, cap: i64) -> i64 |
| 1492 | func sv2_serve_js(out: *u8, cap: i64) -> i64 |
| 1505 | func sv2_handle(prefix: *u8, base: *u8, keypath: *u8, req: *u8, reqlen: i64, out: *u8, cap: i64) -> i64 |
| 1777 | func sv2_ck(name: *u8, cond: i64, pass: *i64, fail: *i64) -> i64 |
| 1783 | func sv2_post(prefix: *u8, base: *u8, keypath: *u8, path: *u8, body: *u8, origin: *u8, out: *u8, cap: i64) -> i64 |
| 1798 | func sv2_get(prefix: *u8, base: *u8, keypath: *u8, path: *u8, out: *u8, cap: i64) -> i64 |
| 1805 | func sv2_selftest() -> i64 |