code wiki / _hdl_build / nx_legal_portal_daemon.nx
nx_legal_portal_daemon.nx source
↩ module page · 110 lines · 5333 B
1// nx_legal_portal_daemon.nx -- runnable Client Workspace portal: bind
2// 127.0.0.1:8455 and serve the legal portal in an accept loop over the real
3// lp_handle router. Browse http://127.0.0.1:8455/portal/envelopes
4// (LOOPBACK ONLY -- a public bind + mTLS + file-backed tenant stores is the
5// separate, operator-gated production deploy step).
6//
7// The pctx here is a DEMO tenant fixture (two envelopes incl. a Will routed to
8// REQUIRES_WET so the never-void surfacing is visible, plus a vault doc + a
9// pending checklist). Wiring real per-tenant file-backed stores replaces this
10// fixture at deploy time. license_tier: ORIGINAL
11import "nx_legal_portal.nx"
12import "nx_legal_portal_boot.nx"
13import "nx_legal_store.nx"
14import "nx_doc_envelope.nx"
15import "nx_doc_serve.nx"
16import "nx_doc_annotate.nx"
17import "nx_doc_vault.nx"
18import "nx_legal_compliance.nx"
19import "nx_syscalls.nx"
20const LPD_MAGIC_8601: i64 = 8601
21const LPD_MAGIC_9601: i64 = 9601
22const LPD_MAGIC_9602: i64 = 9602
23const LPD_MAGIC_8602: i64 = 8602
24const LPD_MAGIC_2000: i64 = 2000
25const LPD_MAGIC_5001: i64 = 5001
26const LPD_MAGIC_4096: i64 = 4096
27
28const LPD_PORT: i64 = 0x2107 // 8455, loopback
29const LPD_STORE: *u8 = "knowledge/legal_" // durable per-tenant store base (survives restart)
30
31func lpd_addr(out: *u8, port: i64) -> i64 {
32 out[0] = 2 as u8; out[1] = 0 as u8
33 out[2] = ((port >> 8) & 0xff) as u8; out[3] = (port & 0xff) as u8
34 out[4] = 127 as u8; out[5] = 0 as u8; out[6] = 0 as u8; out[7] = 1 as u8
35 var i: i64 = 8
36 while i < 16 { out[i] = 0 as u8; i = i + 1 }
37 return 0
38}
39func lpd_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
40
41func main() -> i64 {
42 // ---- durable tenant state: RELOAD on boot (D8); seed+persist the demo on first boot ----
43 let ecap: i64 = 16
44 let rcap: i64 = 32
45 let ncap: i64 = 16
46 let vcap: i64 = 16
47 let eflat: *i64 = sys_mmap(ecap * EF_STRIDE * 8) as *i64
48 let rflat: *i64 = sys_mmap(rcap * RF_STRIDE * 8) as *i64
49 let anflat: *i64 = sys_mmap(ncap * NF_STRIDE * 8) as *i64
50 let vflat: *i64 = sys_mmap(vcap * VF_STRIDE * 8) as *i64
51 let eidbuf: *i64 = sys_mmap(128) as *i64
52 let docb: *u8 = sys_mmap(64)
53 docb[0]=37; docb[1]=80; docb[2]=68; docb[3]=70; docb[4]=13; docb[5]=10; docb[6]=0; docb[7]=88
54
55 let ctx: *NxPortalCtx = sys_mmap(256) as *NxPortalCtx
56 ctx.user_level = 1
57 ctx.doc_id = LPD_MAGIC_8601; ctx.doc_bytes = docb; ctx.doc_len = 8; ctx.doc_fmt = DF_PDF
58 lp_boot_load(ctx, LPD_STORE, "andelinwest" as *u8, eflat, ecap, rflat, rcap, anflat, ncap, vflat, vcap, eidbuf)
59 if ctx.env_count == 0 {
60 // first boot: seed the demo fixture, then persist it so the next boot reloads it
61 var ne: i64 = 0
62 var nr: i64 = 0
63 var na: i64 = 0
64 var vc: i64 = 0
65 ne = nx_env_create(eflat, ne, ecap, LPD_MAGIC_9601, LPD_MAGIC_8601, "Services Agreement" as *u8, 1, 1000)
66 nr = nx_env_add_recipient(rflat, nr, rcap, LPD_MAGIC_9601, 101, ROLE_SIGNER, 1)
67 nx_env_send(eflat, ne, rflat, nr, LPD_MAGIC_9601)
68 ne = nx_env_create(eflat, ne, ecap, LPD_MAGIC_9602, LPD_MAGIC_8602, "Last Will and Testament" as *u8, 0, LPD_MAGIC_2000)
69 nr = nx_env_add_recipient(rflat, nr, rcap, LPD_MAGIC_9602, 201, ROLE_SIGNER, 1)
70 nx_env_send(eflat, ne, rflat, nr, LPD_MAGIC_9602)
71 vc = nx_vault_add(vflat, vc, vcap, LPD_MAGIC_8601, LPD_MAGIC_5001, 64, 1000)
72 na = nx_ann_add(anflat, na, ncap, 0, 1, LPD_MAGIC_8601, 1, AN_CHECK, 0, 700, ANF_REQUIRED, 1000)
73 ctx.ne = ne; ctx.nr = nr; ctx.na = na; ctx.vc = vc
74 eidbuf[0] = LPD_MAGIC_9601; eidbuf[1] = LPD_MAGIC_9602; ctx.env_ids = eidbuf; ctx.env_count = 2
75 lp_boot_save(ctx, LPD_STORE, "andelinwest" as *u8)
76 lpd_puts("first boot: seeded + persisted demo tenant 'andelinwest'\n" as *u8)
77 } else {
78 lpd_puts("reloaded persisted tenant 'andelinwest' from disk\n" as *u8)
79 }
80
81 // ---- doc BLOB: reload the document bytes (durable); first boot persists the demo doc ----
82 let blobp: *u8 = sys_mmap(512)
83 ls_path(blobp, LPD_STORE, "andelinwest" as *u8, "doc8601.blob" as *u8)
84 let docbuf: *u8 = sys_mmap(LPD_MAGIC_4096)
85 let blen: i64 = ls_blob_load(docbuf, LPD_MAGIC_4096, blobp)
86 if blen < 0 {
87 ls_blob_save(docb, 8, blobp)
88 } else {
89 ctx.doc_bytes = docbuf; ctx.doc_len = blen
90 }
91
92 // ---- bind loopback + accept loop ----
93 let addr: *u8 = sys_mmap(16)
94 lpd_addr(addr, LPD_PORT)
95 let lfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0)
96 if lfd < 0 { lpd_puts("socket fail\n" as *u8); sys_exit(1); return 1 }
97 let opt: *u8 = sys_mmap(4); opt[0] = 1 as u8; sys_setsockopt(lfd, 1, 2, opt, 4) // SO_REUSEADDR
98 if sys_bind(lfd, addr, 16) < 0 { lpd_puts("bind fail (port in use?)\n" as *u8); sys_exit(1); return 1 }
99 if sys_listen(lfd, 16) < 0 { lpd_puts("listen fail\n" as *u8); sys_exit(1); return 1 }
100 lpd_puts("nishi legal portal listening on http://127.0.0.1:8455/portal/envelopes\n" as *u8)
101 var running: i64 = 1
102 while running == 1 {
103 let scfd: i64 = sys_accept(lfd)
104 if scfd < 0 { running = 1 } else {
105 lp_serve_conn_rw(ctx, ncap, LPD_STORE, "andelinwest" as *u8, scfd)
106 sys_close(scfd)
107 }
108 }
109 return 0
110}