Skip to main content

qualia_client_core/api/
projects.rs

1//! Project collaborators
2
3#![allow(non_snake_case)]
4
5pub fn list_project_collaborators(project_id: Option<String>) -> Result<serde_json::Value, String> {
6    let rows = crate::project_collab::list(project_id.as_deref());
7    serde_json::to_value(rows).map_err(|e| e.to_string())
8}
9
10/// Local-first cooperative project list (works without vault).
11pub fn list_coop_projects() -> Result<serde_json::Value, String> {
12    serde_json::to_value(crate::project_collab::list_project_summaries()).map_err(|e| e.to_string())
13}
14
15/// Create a cooperative project on this device without requiring Sanctuary unlock.
16pub fn create_coop_project(name: String, description: String) -> Result<serde_json::Value, String> {
17    let p = crate::project_collab::create_local_project(&name, &description)?;
18    serde_json::to_value(p).map_err(|e| e.to_string())
19}
20
21/// Admit a person or agent DID to a project roster (always local). When vault is unlocked,
22/// the desktop also records Wellfair `ProjectMembership` via `wellfair_add_project_membership`.
23pub fn add_project_collaborator(
24    project_id: String,
25    project_name: String,
26    member_did: String,
27    display_name: String,
28    role: String,
29) -> Result<serde_json::Value, String> {
30    let row = crate::project_collab::add(
31        &project_id,
32        &project_name,
33        &member_did,
34        &display_name,
35        &role,
36    )?;
37    serde_json::to_value(row).map_err(|e| e.to_string())
38}
39
40pub fn remove_project_collaborator(
41    project_id: String,
42    member_did: String,
43) -> Result<serde_json::Value, String> {
44    crate::project_collab::remove(&project_id, &member_did)?;
45    Ok(serde_json::json!({ "removed": true, "project_id": project_id, "member_did": member_did }))
46}
47
48/// Answer a connection challenge — prove this node controls its identity key ("it's actually me").
49#[cfg(not(target_arch = "wasm32"))]
50pub fn answer_connection_challenge(
51    challenge_json: String,
52    my_did: String,
53) -> Result<serde_json::Value, String> {
54    let challenge: crate::handshake::Challenge =
55        serde_json::from_str(&challenge_json).map_err(|e| format!("bad challenge: {e}"))?;
56    let id = crate::node_identity::NodeIdentity::load_or_create()?;
57    let resp = crate::handshake::answer_challenge(&challenge, &my_did, &id.signing_key());
58    serde_json::to_value(resp).map_err(|e| e.to_string())
59}