diff --git a/hubzilla/addon/dsc01/dsc01_spool.php b/hubzilla/addon/dsc01/dsc01_spool.php
index e4e3453..ada14a3 100644
--- a/hubzilla/addon/dsc01/dsc01_spool.php
+++ b/hubzilla/addon/dsc01/dsc01_spool.php
@@ -12,7 +12,7 @@
// ---------------------------------------------------------------------------
function dsc01_handle_post($association_slug, $access) {
- $categories = dsc01_load_categories();
+ $categories = dsc01_load_categories();
$valid_codes = array_keys($categories);
$raw_codes = $_POST['dsc_codes'] ?? [];
@@ -38,26 +38,30 @@ function dsc01_handle_post($association_slug, $access) {
return $out;
}
- // Build spool envelope
+ // Load association config
$cfg_raw = @file_get_contents('addon/vs01/config.json');
$cfg = $cfg_raw ? json_decode($cfg_raw, true) : [];
$assoc = $cfg['associations'][$association_slug] ?? [];
+ // Load dsc01 config for receiver_url and node_token
+ $dsc_config = dsc01_load_config();
+
$envelope = dsc01_build_spool_envelope(
$codes,
$narrative,
$association_slug,
$assoc['channel_id'] ?? '',
- $access
+ $access,
+ $dsc_config['node_token'] ?? ''
);
- $result = dsc01_post_to_orchestrator($envelope);
+ $result = dsc01_post_to_orchestrator($envelope, $dsc_config);
if ($result === true) {
$assoc_name = dsc01_h($assoc['name'] ?? $association_slug);
return '
- Your checklist for ' . $assoc_name . ' has been submitted.
+ Your checklist for ' . $assoc_name . ' has been saved.
Return to ' . $assoc_name . '
@@ -75,29 +79,58 @@ function dsc01_handle_post($association_slug, $access) {
// ---------------------------------------------------------------------------
// SPOOL ENVELOPE
+// Matches contracts/dsc01/record-v1.json — _header / _payload shape.
// ---------------------------------------------------------------------------
-function dsc01_build_spool_envelope($dsc_codes, $narrative, $association_slug, $channel_id, $standing) {
+function dsc01_build_spool_envelope($dsc_codes, $narrative, $association_slug, $channel_id, $standing, $node_token) {
return [
- 'addon' => 'dsc01',
- 'contract_version' => '1.0',
- 'association_slug' => $association_slug,
- 'association_channel_id' => (string) $channel_id,
- 'submitted_at' => date('c'),
- 'standing' => $standing,
- 'dsc_codes' => $dsc_codes,
- 'narrative' => $narrative,
+ '_header' => [
+ 'addon' => 'dsc01',
+ 'contract_version' => '1.0',
+ 'association_slug' => $association_slug,
+ 'association_channel_id' => (string) $channel_id,
+ 'participant_id' => dsc01_get_participant_id(),
+ 'submitted_at' => date('c'),
+ 'standing' => $standing,
+ 'node_token_hash' => hash('sha256', $node_token),
+ ],
+ '_payload' => [
+ 'fields' => [
+ 'dsc_codes' => $dsc_codes,
+ 'narrative' => $narrative,
+ ],
+ ],
];
}
+// ---------------------------------------------------------------------------
+// PARTICIPANT ID
+// ---------------------------------------------------------------------------
+
+function dsc01_get_participant_id() {
+ $observer = get_observer_hash();
+ if (!$observer) return '';
+
+ $r = q("SELECT xchan_addr FROM xchan WHERE xchan_hash = '%s' LIMIT 1",
+ dbesc($observer)
+ );
+ if (!$r) return '';
+
+ $addr = $r[0]['xchan_addr'] ?? '';
+ $parts = explode('@', $addr);
+ return $parts[0] ?? '';
+}
+
// ---------------------------------------------------------------------------
// ORCHESTRATOR POST
// ---------------------------------------------------------------------------
-function dsc01_post_to_orchestrator($envelope) {
- $config = dsc01_load_config();
+function dsc01_post_to_orchestrator($envelope, $config = null) {
+ if ($config === null) {
+ $config = dsc01_load_config();
+ }
$receiver_url = $config['receiver_url'] ?? '';
- $node_token = $config['node_token'] ?? '';
+ $node_token = $config['node_token'] ?? '';
if (!$receiver_url) {
logger('dsc01_spool: receiver_url not configured');