forked from yvv/decision
v3 : le vote par la chaîne Ğ1, côté moteur et serveur
Le bulletin scellé (ld1: + blake2b-256 du bulletin canonique, sel de 128 bits), l'ordre de la chaîne (bloc, puis rang de l'événement : le dernier fait foi), les adresses SS58 comparées par clé (ld-engine, pur). trustin-access : Monnaie libre vote par la chaîne, les groupes gérés sur le serveur ; le droit de vote se lit à la confirmation. Serveur : bulletins en attente, confirmation sur l'indexeur (virement, auteur, identité, membre), identité idty:<index> créée au besoin, tâche de fond toutes les 10 s, expiration à 24 h, vote groupé en une écriture dans les groupes gérés. Migration additive 0006. Sans LD_VOTE_ACCOUNT, le vote par la chaîne est éteint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
|
||||
use crate::AppState;
|
||||
use crate::auth::{IdentityRow, User};
|
||||
use crate::ballots::{self, MyBallot, MyVote};
|
||||
use crate::error::{AppError, AppResult};
|
||||
use crate::participation;
|
||||
use crate::util::{self, LangMap};
|
||||
@@ -515,21 +516,15 @@ pub async fn translations_for(
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow)]
|
||||
struct MyVote {
|
||||
proposal_id: String,
|
||||
choice: String,
|
||||
revision: i64,
|
||||
}
|
||||
|
||||
fn proposal_json(
|
||||
st: &DocState,
|
||||
unit: &UnitRow,
|
||||
p: &ProposalRow,
|
||||
mine: Option<&MyVote>,
|
||||
mine: (Option<&MyVote>, Option<&MyBallot>),
|
||||
translations: Option<&BTreeMap<String, serde_json::Value>>,
|
||||
me: &str,
|
||||
) -> serde_json::Value {
|
||||
let (mine, ballot) = mine;
|
||||
let eval = st.evaluation(unit, p);
|
||||
let (kind, target) = match p.kind() {
|
||||
ProposalKind::Text => ("text", None),
|
||||
@@ -554,6 +549,8 @@ fn proposal_json(
|
||||
"signals": st.signal_counts.get(&p.id).copied().unwrap_or(0),
|
||||
"myVote": mine.map(|v| v.choice.as_str()),
|
||||
"myVoteStale": mine.is_some_and(|v| v.revision != p.revision),
|
||||
"myVoteChain": mine.is_some_and(|v| v.source == "chain"),
|
||||
"myBallot": ballot,
|
||||
"translations": translations.cloned().unwrap_or_default(),
|
||||
})
|
||||
}
|
||||
@@ -571,17 +568,8 @@ pub async fn document(
|
||||
let visible: Vec<&ProposalRow> =
|
||||
st.proposals.iter().filter(|p| p.status != "draft" || p.author_id.as_deref() == Some(&user.id)).collect();
|
||||
let translations = translations_for(&state, &visible).await?;
|
||||
let mine: HashMap<String, MyVote> = sqlx::query_as::<_, MyVote>(
|
||||
"SELECT v.proposal_id, v.choice, v.revision FROM votes v JOIN proposals p ON p.id = v.proposal_id
|
||||
JOIN units u ON u.id = p.unit_id WHERE u.doc_id = ? AND v.identity_id = ?",
|
||||
)
|
||||
.bind(&id)
|
||||
.bind(&user.id)
|
||||
.fetch_all(&state.db)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|v| (v.proposal_id.clone(), v))
|
||||
.collect();
|
||||
let mine = ballots::my_votes(&state, &user.id, &id).await?;
|
||||
let pending = ballots::my_ballots(&state, &user.id, &id).await?;
|
||||
|
||||
let changes = inertia_changes(&state, &id).await?;
|
||||
let units: Vec<_> = st
|
||||
@@ -591,7 +579,10 @@ pub async fn document(
|
||||
let of_unit: Vec<_> = visible
|
||||
.iter()
|
||||
.filter(|p| p.unit_id == u.id)
|
||||
.map(|p| proposal_json(&st, u, p, mine.get(&p.id), translations.get(&p.id), &user.id))
|
||||
.map(|p| {
|
||||
let of = (mine.get(&p.id), pending.get(&p.id));
|
||||
proposal_json(&st, u, p, of, translations.get(&p.id), &user.id)
|
||||
})
|
||||
.collect();
|
||||
let in_force = u
|
||||
.in_force_id
|
||||
@@ -607,9 +598,10 @@ pub async fn document(
|
||||
.collect();
|
||||
|
||||
let publication = publication_status(&state, &id).await?;
|
||||
let can_vote = may_vote(&state, &user, &st.group).await?;
|
||||
let vote = ballots::access(&state, &user, &st.group).await?;
|
||||
Ok(Json(json!({
|
||||
"canVote": can_vote,
|
||||
"canVote": vote["open"],
|
||||
"vote": vote,
|
||||
"doc": {
|
||||
"id": st.doc.id, "slug": st.doc.slug, "groupSlug": st.group.slug, "groupName": st.group.name,
|
||||
"title": util::parse_lang(&st.doc.title), "summary": util::parse_lang(&st.doc.summary),
|
||||
|
||||
Reference in New Issue
Block a user