diff --git a/hubzilla/addon/vs01/config.json.template b/hubzilla/addon/vs01/config.json.template index 328897e..8fa68b5 100644 --- a/hubzilla/addon/vs01/config.json.template +++ b/hubzilla/addon/vs01/config.json.template @@ -1,6 +1,21 @@ { "_note": "Copy to config.json. Do not commit config.json — it contains secrets and installation-specific values.", - "corpus_builder_group_id": 0, - "listings_file": "REPLACE — absolute path to listings.json on the host", - "directory_default_tab": "core" + "receiver_url": "REPLACE — orchestrator receiver endpoint, e.g. https://orchestrator1.internal.diagnostics.kane-il.us/receive", + "node_token": "REPLACE — shared secret for node-to-orchestrator authentication", + "listings_file": "REPLACE — absolute path to listings.json on the host, e.g. /var/www/hubzilla/addon/vs01/listings.json", + "directory_default_tab": "core", + "associations": { + "REPLACE-SLUG": { + "_note": "Key is the URL slug — lowercase, hyphens only, matches argv(1) in the route", + "name": "REPLACE — association legal name", + "address": "REPLACE — association street address", + "channel_id": 0, + "channel_address": "REPLACE — channel@node address", + "groups": { + "public": 0, + "sase_participant": 0, + "corpus_builder": 0 + } + } + } } diff --git a/hubzilla/addon/vs01/vs01.php b/hubzilla/addon/vs01/vs01.php index 3635197..0d13347 100644 --- a/hubzilla/addon/vs01/vs01.php +++ b/hubzilla/addon/vs01/vs01.php @@ -3,13 +3,16 @@ /** * Name: VS-01 Vital Signs * Description: Public civic diagnostic — the ten structural preconditions of an HOA association. - * Version: 0.1.0 + * Version: 0.2.0 * MinVersion: 11.0 * MaxVersion: 12.0 */ use Zotlabs\Extend\Widget; +require_once 'addon/vs01/vs01_renderer.php'; +require_once 'addon/vs01/vs01_spool.php'; + function vs01_module() {} function vs01_load() { @@ -44,34 +47,71 @@ function vs01_h($value) { // ACCESS // ---------------------------------------------------------------------------- -function vs01_access_state() { +function vs01_access_state($association_slug = '') { if (!local_channel()) { return 'public'; } - $channel = App::get_channel(); + $config = vs01_load_config(); + // Operator check — site owner, not association channel owner + $channel = App::get_channel(); if (local_channel() === intval($channel['channel_id'])) { return 'operator'; } - $config = vs01_load_config(); - $gid = intval($config['corpus_builder_group_id'] ?? 0); + if (!$association_slug) { + return 'public'; + } - if ($gid && in_array(get_observer_hash(), group_get_members_xchan($gid))) { + $assoc = $config['associations'][$association_slug] ?? null; + if (!$assoc) return 'public'; + + $observer = get_observer_hash(); + $groups = $assoc['groups'] ?? []; + + // Corpus Builder — highest participant tier + $cb_gid = intval($groups['corpus_builder'] ?? 0); + if ($cb_gid && in_array($observer, group_get_members_xchan($cb_gid))) { return 'participant'; } - return 'denied'; + // SASE Participant + $sase_gid = intval($groups['sase_participant'] ?? 0); + if ($sase_gid && in_array($observer, group_get_members_xchan($sase_gid))) { + return 'participant'; + } + + return 'public'; } -function vs01_access_wall() { +function vs01_is_professional() { + if (!local_channel()) return false; + $observer = get_observer_hash(); + $listings = vs01_load_listings(); + foreach (['tier1', 'tier2'] as $tier) { + foreach ($listings[$tier] ?? [] as $entry) { + if (($entry['xchan'] ?? '') === $observer + && ($entry['status'] ?? '') === 'active') { + return true; + } + } + } + return false; +} + +function vs01_access_wall($association_slug = '') { + $config = vs01_load_config(); + $assoc = $association_slug + ? ($config['associations'][$association_slug] ?? null) + : null; + $name = $assoc ? vs01_h($assoc['name']) : 'this association'; return '
No associations registered.
Select an association to view or submit its diagnostic record.
'; + $out .= 'The ten structural preconditions of an HOA association.
'; + $out .= 'Vital Signs diagnostic record.
'; $out .= '' . vs01_h($meta['diagnostic_question'] ?? '') . '
'; + $out .= '' . vs01_h($perspective['instruction'] ?? '') . '
'; + $out .= ''; + + // VS navigation — previous / next + $out .= vs01_render_vs_nav($association_slug, $vs_code); + + $out .= 'TMP review forthcoming.
'; + $out .= '' . vs01_h($field['flag_note']) . '
' + : ''; + + return '' . $instruction . '
'; + $out .= '' . vs01_h($perspective['instruction'] ?? '') . '
'; + $out .= ''; + $out .= vs01_render_vs_nav($association_slug, $vs_code); + $out .= '