Storylines: the same site told several ways, one per visitor, counted
Any text a person reads may be a list, one entry per storyline, every list the same length. A visitor is given one storyline for the whole site and reads it on every page and in every mail about their case. Records and events carry the storyline; GET /report gives counts per bucket, storyline and state, and nothing else. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GT37Z1Xtfd9pUuQtMTg6Yt
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
cc3107e502
commit
f395ace556
+13
-6
@@ -2358,8 +2358,9 @@ pub async fn get_question(
|
||||
use crate::content::{fill_from_user, path_matches, resolve_question};
|
||||
use crate::server::AppState;
|
||||
let state = expect_context::<AppState>();
|
||||
let questions = state.questions.load();
|
||||
let Some(mut question) = resolve_question(&questions, &path) else {
|
||||
let storylines = state.questions.load();
|
||||
let questions = storylines.at(crate::server::storyline::current().await);
|
||||
let Some(mut question) = resolve_question(questions, &path) else {
|
||||
return Ok(None);
|
||||
};
|
||||
let session: tower_sessions::Session = leptos_axum::extract().await?;
|
||||
@@ -2401,7 +2402,7 @@ pub async fn get_question(
|
||||
pub async fn get_site() -> Result<SiteConfig, ServerFnError> {
|
||||
use crate::server::AppState;
|
||||
let state = expect_context::<AppState>();
|
||||
let mut site = state.site.load().as_ref().clone();
|
||||
let mut site = state.site.load().at(crate::server::storyline::current().await).clone();
|
||||
// Not content: whether this instance can serve tiles at all is its
|
||||
// own configuration, and the browser has to know before it decides
|
||||
// whether to draw a map or ask for two numbers.
|
||||
@@ -2435,7 +2436,8 @@ pub async fn list_qualifying_questions(
|
||||
.map_err(|e| ServerFnError::new(e.to_string()))?;
|
||||
|
||||
let now_ms = chrono::Utc::now().timestamp_millis();
|
||||
let questions = state.questions.load();
|
||||
let storylines = state.questions.load();
|
||||
let questions = storylines.at(crate::server::storyline::current().await);
|
||||
// What the chain verifiably answered - the same lookup a
|
||||
// `requires_chain` gate does, so a forged or foreign hash resolves
|
||||
// to nothing - and therefore where it sent the visitor.
|
||||
@@ -2583,6 +2585,7 @@ pub async fn suggest_page_edit(question_id: String, text: String) -> Result<(),
|
||||
SUGGESTION_ALTERNATIVE,
|
||||
&responses,
|
||||
now_ms,
|
||||
0,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| ServerFnError::new(e.to_string()))?;
|
||||
@@ -2593,6 +2596,7 @@ pub async fn suggest_page_edit(question_id: String, text: String) -> Result<(),
|
||||
alternative: SUGGESTION_ALTERNATIVE.to_string(),
|
||||
responses: responses.clone(),
|
||||
timestamp_ms: now_ms,
|
||||
storyline: 0,
|
||||
};
|
||||
if let Err(e) = emit_answer_submitted(&state.nats, &event).await {
|
||||
tracing::warn!(question_id, "the suggestion is on file but was not announced: {e}");
|
||||
@@ -2679,7 +2683,8 @@ pub async fn submit_answer(
|
||||
// resolve_question, not a plain map get: a dynamic page's concrete
|
||||
// path (what the client holds as its question id) resolves to the
|
||||
// pattern page it came from.
|
||||
let question = crate::content::resolve_question(&state.questions.load(), &question_id)
|
||||
let storyline = crate::server::storyline::current().await;
|
||||
let question = crate::content::resolve_question(state.questions.load().at(storyline), &question_id)
|
||||
.ok_or_else(|| ServerFnError::new("unknown question"))?;
|
||||
|
||||
let session: tower_sessions::Session = leptos_axum::extract().await?;
|
||||
@@ -2796,6 +2801,7 @@ pub async fn submit_answer(
|
||||
alternative: alternative.clone(),
|
||||
responses: responses.clone(),
|
||||
timestamp_ms,
|
||||
storyline: storyline as u32,
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -2821,6 +2827,7 @@ pub async fn submit_answer(
|
||||
&alternative,
|
||||
&responses,
|
||||
timestamp_ms,
|
||||
storyline as u32,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -2829,7 +2836,7 @@ pub async fn submit_answer(
|
||||
// Arrival is a state too: what the schema says the first
|
||||
// state sends, it sends now.
|
||||
if let Some(initial) = state.aggregates.load().get(bucket).map(|s| s.initial.clone()) {
|
||||
crate::mail::on_state(&state, bucket, &chain_hash, &initial, &responses).await;
|
||||
crate::mail::on_state(&state, bucket, &chain_hash, &initial, &responses, storyline as u32).await;
|
||||
crate::people::on_state(&state, bucket, &chain_hash, &initial, &responses).await;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user