# CLIENT: IDAA — International Doctors in Alcoholics Anonymous **Client:** International Doctors in Alcoholics Anonymous (IDAA) **Module Path:** `src/routes/idaa/` **State Stores:** `src/lib/stores/ae_idaa_stores.ts` **Last Updated:** 2026-02-26 --- ## ⚠️ CRITICAL PRIVACY REQUIREMENT **ALL IDAA content is PRIVATE. Authentication is required for ALL modules.** IDAA serves a sensitive population — physicians in addiction recovery. Content exposure to the public is a **severe security failure** and a violation of member trust. - A previous AI agent accidentally exposed IDAA Bulletin Board content publicly. This must never happen again. - Every route, component, and API call in this module must enforce authentication. - When in doubt: **it's private**. **Required access level:** `trusted_access` or higher for all IDAA content. --- ## What IDAA Is IDAA is a private membership organization for physicians in recovery. They use the Aether platform for: - A private document archive (historical materials, meeting records) - A members-only bulletin board (community posts and discussion) - A searchable directory of in-person and virtual recovery meetings - Video conferencing (Jitsi-based) IDAA's Aether instance is embedded as an **iframe inside their existing Novi-powered website** (`idaa.org`). Novi is their external Association Management System (AMS) — it handles membership records and authentication. Aether receives the member context via URL parameters on iframe load. --- ## Architecture: Composite Module IDAA is **not a standalone module** — it is a **composition of three existing Aether modules**, access-gated and branded for the IDAA client. | IDAA Feature | Aether Module Used | Library | |---|---|---| | Archives | Archives module | `src/lib/ae_archives/` | | Bulletin Board (BB) | Posts module | `src/lib/ae_posts/` | | Recovery Meetings | Events module (repurposed) | `src/lib/ae_events/` | | Video Conferences | Jitsi (external embed) | External | There is **no `src/lib/ae_idaa/`** library directory. IDAA-specific state and logic lives in `ae_idaa_stores.ts` and the route components only. This design allows the IDAA module to be removed or updated without touching core modules. --- ## Route Structure ``` src/routes/idaa/ ├── +layout.svelte # Root layout: Novi UUID extraction, iframe height sync ├── (idaa)/ │ ├── +layout.svelte # Access gate: blocks render if unauthorized; permission upgrade │ ├── +page.svelte # IDAA dashboard — 3-module selector │ ├── archives/ # Archives submodule │ │ ├── +page.svelte # Archive list (LiveQuery) │ │ └── [archive_id]/ │ │ ├── +page.svelte # Archive detail + content viewer │ │ ├── ae_idaa_comp__archive_obj_id_view.svelte │ │ ├── ae_idaa_comp__archive_obj_id_edit.svelte │ │ ├── ae_idaa_comp__archive_content_obj_id_edit.svelte │ │ └── ae_idaa_comp__modal_media_player.svelte │ ├── bb/ # Bulletin Board (Posts) submodule │ │ ├── +page.svelte # Post list (LiveQuery, archive-filtered) │ │ └── [post_id]/ │ │ ├── +page.svelte # Post detail + comments │ │ ├── ae_idaa_comp__post_obj_id_view.svelte │ │ ├── ae_idaa_comp__post_obj_id_edit.svelte │ │ └── ae_idaa_comp__post_comment_obj_id_edit.svelte │ ├── recovery_meetings/ # Recovery Meetings (Events repurposed) │ │ ├── +page.svelte # Meeting list + search filters │ │ └── [event_id]/ │ │ ├── +page.svelte # Meeting detail │ │ ├── ae_idaa_comp__event_obj_id_view.svelte │ │ └── ae_idaa_comp__event_obj_id_edit.svelte │ └── video_conferences/ # Jitsi video conference integration └── jitsi_reports/ # External Jitsi reporting ``` --- ## Authentication: Novi UUID System IDAA members do not log in through Aether — they log in through Novi (idaa.org), and Novi passes their identity to the Aether iframe via URL parameters. ### URL Parameters (on iframe load) ``` ?uuid=<36-char-uuid> &email= &full_name= &iframe=true ``` ### Permission Levels (Ascending) | Level | Condition | Access | |---|---|---| | Anonymous | No UUID or unrecognized | No access | | Authenticated | Valid UUID (36 chars) | View own content, limited actions | | Trusted | UUID in `novi_trusted_li` | Full member access to all IDAA content | | Administrator | UUID in `novi_admin_li` | Full access + edit/manage | `novi_trusted_li` and `novi_admin_li` are managed in Aether site config (not in Novi directly). ### Permission Upgrade Rule ``` // RULE: Only UPGRADE to Novi-based permissions, NEVER downgrade. // If a user has a higher global Aether role (site manager, super), // their global role is preserved and not overwritten by Novi auth. ``` This ensures that OSIT staff with `super` or `manager` roles retain full access regardless of Novi UUID status. ### Access Gate (`(idaa)/+layout.svelte`) The inner layout blocks ALL rendering if the user is not authorized: - Anonymous → "Access Denied" error page - Access check runs before any child routes render --- ## Module 1: Archives **Route:** `/idaa/archives/` **Library:** `src/lib/ae_archives/` **Types:** `ae_Archive`, `ae_ArchiveContent` The Archives module stores IDAA historical content — meeting records, conference proceedings, historical documents, and media. ### Object Types **Archive (Container)** - Represents a collection (e.g., "2019 Conference Proceedings") - Key fields: `name`, `description`, `original_datetime`, `original_location`, `archive_on` - `archive_on` — date when this archive collection is auto-hidden (scheduled visibility control) **ArchiveContent (Items)** - Individual items within an archive - Supports multiple content types: `'text'`, `'file'`, `'url'`, `'video'` - Key fields: `archive_content_type`, `content_html`, `url`, `hosted_file_id`, `duration` - Video/audio content has a dedicated media player component ### Database (Dexie) ``` db_archives.archive — Archive containers db_archives.content — Archive content items (linked by archive_id) ``` ### Demo / Test IDs - Archive: `nAA2bHLv8RK` (id: 1) "One Sky Test Archive" - Archive Content: `UjKzrk-GKu5` (id: 1) "Hosted File Test" --- ## Module 2: Bulletin Board (BB) **Route:** `/idaa/bb/` **Library:** `src/lib/ae_posts/` **Types:** `ae_Post`, `ae_PostComment` The BB is the IDAA members-only community discussion board. It is the **most sensitive module** — public exposure must never occur. ### Object Types **Post (Thread)** - Key fields: `title`, `content`, `anonymous`, `full_name`, `email` - `archive_on` — date after which the post is hidden from all views - `archive` — boolean flag for immediate archival - `enable_comments` — controls whether replies are allowed - `post_comment_count` — cached count of replies **PostComment (Reply)** - Key fields: `post_id`, `content`, `anonymous`, `full_name`, `email` - Replies inherit the parent post's visibility rules ### Post Visibility / Archival Filter Posts with `archive_on` set to a past date are **automatically hidden** from all queries. This is enforced at the component level via a LiveQuery filter: ```typescript // This filter is REQUIRED — do not remove it filter((x) => !x.archive_on || archiveDate > now) ``` Archived posts are soft-deleted — they remain in the database for audit purposes but are not shown to members. Most recent first (sorted `updated_on DESC`). ### Database (Dexie) ``` db_posts.post — Posts (threads) db_posts.comment — Post comments (linked by post_id) ``` --- ## Module 3: Recovery Meetings **Route:** `/idaa/recovery_meetings/` **Library:** `src/lib/ae_events/` (standard Events module, repurposed) **Types:** `ae_Event` (standard event type, filtered for meeting context) Recovery Meetings reuses the Aether Events object to represent AA recovery meetings. These are NOT conferences — they are regular ongoing meetings (weekly, monthly, etc.) available to IDAA members. ### Search Filters Members can filter meetings by: - **Fulltext search** — name, location - **Physical** — in-person meetings - **Virtual** — online meetings (Zoom, Google Meet, etc.) - **Meeting type** — specific meeting format categories Search is debounced (250ms) and uses the standard Aether SWR pattern. ### Jitsi Integration Some virtual meetings are hosted via Jitsi. Members with a Jitsi moderator UUID (`novi_jitsi_mod_li`) have elevated permissions in video sessions. ### Demo / Test IDs No dedicated IDAA recovery meeting demo records — uses the standard Event demo record for dev: - Event: `pjrcghqwert` (id: 1) "Demo One Sky IT Conference" --- ## Module 4: Video Conferences (Jitsi) **Route:** `/idaa/video_conferences/` Embeds Jitsi video conferences directly in the IDAA module. Separate from Recovery Meetings — this is for IDAA board meetings or special sessions, not regular AA meetings. Moderation permissions are controlled by `novi_jitsi_mod_li` in the IDAA store. --- ## State Management (`ae_idaa_stores.ts`) Four stores manage all IDAA state: ### `idaa_loc` (localStorage — persistent across sessions) Stores Novi auth context and per-submodule query settings: ```typescript { novi_uuid: string | null // Member UUID from Novi novi_email: string | null novi_full_name: string | null novi_admin_li: string[] // Admin UUID list (from site config) novi_trusted_li: string[] // Trusted member UUID list novi_jitsi_mod_li: string[] // Jitsi moderator UUIDs archives: { enabled, hidden, limit, offset, edit__archive_obj, edit__archive_content_obj } bb: { enabled, hidden, limit, offset, edit__post_obj, edit__post_comment_obj } recovery_meetings: { qry__fulltext_str, qry__physical, qry__virtual, qry__type, qry__limit, edit__event_obj } } ``` ### `idaa_sess` (sessionStorage — cleared on tab close) UI state per submodule: ```typescript { archives: { qry__status, show__modal_edit__archive_id, show__modal_view__archive_id, obj_changed } bb: { qry__status, show__modal_edit__post_id, show__modal_view__post_id, obj_changed } recovery_meetings: { qry__status, show__modal_edit, show__modal_view, attend_platform, obj_changed } } ``` ### `idaa_slct` (sessionStorage — selection tracking) ```typescript { event_id: string | null archive_id: string | null archive_content_id: string | null post_id: string | null post_comment_id: string | null } ``` ### `idaa_trig` / `idaa_prom` Trigger flags and promise tracking for async operations (standard Aether pattern). --- ## Iframe Integration The IDAA module is embedded in `idaa.org` via iframe. This requires: 1. **Height sync** — The root layout posts `message` events to the parent frame for dynamic height adjustment (content length varies) 2. **URL parameter auth** — Novi passes member context via query string on load 3. **No standard navigation** — Members navigate within the iframe; Aether's nav chrome is hidden or minimal in this context --- ## Testing Requirements ### Auth Gate Tests Come First **For every IDAA submodule, the first test written must be an authentication enforcement test.** ```typescript // ✅ Required test pattern for each IDAA module test('Archives - unauthenticated user cannot access content', async ({ page }) => { // Inject localStorage WITHOUT trusted_access // Navigate to /idaa/archives/ // Assert: access denied message shown, no archive content visible }); test('Archives - trusted member can access content', async ({ page }) => { // Inject localStorage WITH trusted_access + novi_uuid // Navigate to /idaa/archives/ // Assert: archive list renders }); ``` ### Privacy in Test Data - Never use real member data in test fixtures - Use canonical demo IDs from `tests/_helpers/env.ts` only - Test names should document the privacy rule being enforced, not just the behavior ### Trusted Access State Injection Tests that need authenticated IDAA access must set `trusted_access: true` and `novi_uuid` in the injected `ae_loc` localStorage: ```typescript // In addInitScript or env helper ae_loc.trusted_access = true; ae_loc.idaa_loc = { novi_uuid: 'test-uuid-value', ... }; ``` ### Current Test Coverage (as of 2026-02-26) | Module | State | Notes | |---|---|---| | Archives | ⚠️ Smoke only | `archive_content.test.ts` — no auth gate test | | Bulletin Board | ❌ None | Priority — most sensitive module | | Recovery Meetings | ❌ None | — | | Video Conferences | ❌ None | Jitsi complexity, lower priority | --- ## External Links (idaa.org) - Archives: `https://www.idaa.org/idaa-archives` - Bulletin Board: `https://www.idaa.org/idaa-bulletin-board` - Meetings: `https://www.idaa.org/idaa-meetings` --- ## Related Documentation - [AE API V3 for Frontend](./GUIDE__AE_API_V3_for_Frontend.md) - [Development Guide](./GUIDE__Development.md) - [Naming Conventions](./AE__Naming_Conventions.md) - [Playwright Test README](../tests/README.md) --- **Document Status:** ✅ Complete (initial) **Last Verified:** 2026-02-26 — reverse-engineered from source code