Initial commit: content-driven onboarding portal
Leptos/Axum app that renders a Question/Alternative/Feature schema loaded from a sibling content repo (portal-content). Kanidm OIDC login, content-driven authorization (Question.qualifies), a generic NATS KV-backed resource + state-transition mechanism (no bespoke "applicant" concept baked into the runtime - it's all content), a SHA-256 DAG chain tying submissions and decisions together, and the "YES - Rasterized Lines" piece (ported from the live uhhm.no site) as the landing hero.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
//! SHA-256 hashed DAG chain, ported from dodrenett's lib/challenge.ts.
|
||||
//! Kept deliberately plain: every submission hashes in its parent(s), but
|
||||
//! nothing here produces more than one parent yet - that only starts
|
||||
//! mattering once something (an LLM, or a human) posts follow-up
|
||||
//! questions back into a visitor's chain instead of the fixed content in
|
||||
//! ../portal-content. The DAG-shaped `parent_hashes` field exists so that
|
||||
//! can slot in later without a schema change; the hashing itself doesn't
|
||||
//! need to.
|
||||
#![cfg(feature = "ssr")]
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
/// Hashes one chain node from its question, its parent hash(es), the
|
||||
/// submitted responses, and a timestamp. Parents are sorted first so the
|
||||
/// hash doesn't depend on the order multiple parents happened to arrive
|
||||
/// in.
|
||||
pub fn hash_node(
|
||||
question_id: &str,
|
||||
parent_hashes: &[String],
|
||||
responses: &serde_json::Value,
|
||||
timestamp_ms: i64,
|
||||
) -> String {
|
||||
let mut parents = parent_hashes.to_vec();
|
||||
parents.sort();
|
||||
let payload = serde_json::json!({
|
||||
"questionId": question_id,
|
||||
"parentHashes": parents,
|
||||
"responses": responses,
|
||||
"timestamp": timestamp_ms,
|
||||
});
|
||||
let data = serde_json::to_vec(&payload).expect("json values always serialize");
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(&data);
|
||||
format!("{:x}", hasher.finalize())
|
||||
}
|
||||
Reference in New Issue
Block a user