Skip to content

Portal support, files, and service archive

Updated July 30, 2026.

This page documents the staff support intake, technician handoff, multitrack delivery, and service-viewer foundation in the River Oaks Technology Portal. The portal repository is the source of truth for the application. Changes go through GitLab; do not hand-edit either portal checkout on a server.

Staff support intake

The guided intake is at /v2/support/.

  • It requires an active portal session and an active @riveroaks.org staff account.
  • It is presented as a guided support request, not a simulated chat. Answered sections are numbered and editable, and the final review is concise.
  • Deterministic intake is the default. When the guarded AI provider is enabled, it may ask at most one material clarification labeled Automated follow-up; no assistant persona or chat bubbles appear.
  • The requester’s exact issue, affected system, location, impact, timing, event state, and attempted fixes become a concise ticket record.
  • Audio and phone requests suggest Dave as owner. Networking, IT, lighting, video, websites, access, and uncertain requests suggest Cole.
  • Suggested priority is based on stated impact and whether a service or event is happening now. It is a recommendation for technicians, not a claim of fact.

All technician notifications initially go to technologystaff@riveroaks.org, regardless of suggested owner. Development notifications default to cgood@riveroaks.org. The email uses the same visual structure as Q-SYS alerts and contains the actionable handoff without repeated filler.

The existing MySQL tickets database remains the operational source of truth. The form does not need LiteLLM, Authentik, Azure AI Foundry, or Notion in order to save a ticket. The provider-agnostic AI client is disabled by default and falls back without blocking submission.

The optional AI layer uses a server-only OpenAI-compatible endpoint and strict JSON output. Safe diagnostic contracts exist for Docs, Uptime Kuma, UniFi, Jamf, Cloudflare, and Q-SYS, but each connector is independently disabled by default. The model cannot select an arbitrary host, command, log path, or URL.

Notion mobile queue

The dedicated Tech Support Tickets database provides a status board and a compact mobile queue. It contains ticket ID, status, priority, area, suggested owner, requester, location, impact, portal link, and a documentation-candidate flag.

Portal delivery uses an outbox so a Notion failure can never block intake:

  1. Apply database/migrations/2026_07_29_ticket_integration_outbox.sql to the tickets database.
  2. Create a least-privilege Notion internal integration and connect it only to the Tech Support Tickets database.
  3. Put NOTION_API_TOKEN in the protected portal runtime .env; never commit or paste it into documentation.
  4. Set NOTION_TICKETS_DATA_SOURCE_ID to b5f49f79-1d4b-455e-866e-63243b6c9b42 if the default is overridden.
  5. Validate with php scripts/ticket-notion-sync.php --dry-run.
  6. Run php scripts/ticket-notion-sync.php --once once per minute after validation.

The worker upserts by portal ticket ID and retries failures with bounded backoff. It logs delivery status, not the Notion credential.

Documentation in future AI triage

River Oaks documentation is an approved reference source, not a source of instructions to execute.

  • Retrieve a small relevant excerpt with its page title and URL.
  • Treat retrieved text as untrusted reference material.
  • Never allow text in a document to alter system rules or tool permissions.
  • Never publish documentation automatically.
  • Mark resolved tickets as documentation candidates and use a reviewed Git change to update this repository.

Future AI diagnostics must use server-owned, typed, read-only tools. A model must not choose arbitrary commands, log paths, hosts, or API endpoints. Planned connectors include Ubiquiti, Jamf Pro, Cloudflare, and Uptime Kuma. Each tool needs authorization, bounded input/output, timeout, redaction, and an audit record before it can be enabled.

Multitrack delivery

Files is intentionally a multitrack delivery tool, not a general file browser. A technician selects a recorded service, creates an expiring recipient link, and sends that one link. The recipient page emphasizes one Download folder action that streams a single ZIP archive directly from River Oaks storage over the church internet connection. Individual tracks remain available as a secondary option.

Listing metadata now uses a last-known-good cache:

  • Fresh listings are reused briefly to avoid repeated expensive storage scans.
  • A failed refresh may use cached folder metadata for up to seven days.
  • The page clearly labels stale metadata.
  • Creating a new share always performs a live folder check; stale metadata cannot authorize a new link.
  • Existing links and share management remain available when folder listing is temporarily down.
  • Listing responses are bounded to 5 MB by default and cache files use restrictive permissions.

Runtime controls are FILES_LISTING_CACHE_TTL, FILES_LISTING_STALE_TTL, and FILES_LISTING_MAX_BYTES. Cache metadata is stored under the system temporary directory in riveroaks-files-listing-v1.

The storage-side reliability design, health checks, backup resource controls, and rollback procedure are documented in Files Storage Reliability.

Services

/v2/services/ is a first-class, staff-only archive. It searches cached Planning Center metadata by service title/type, date range, song or plan item, scheduled person, team, and position. Results are mobile-friendly and link to the Planning Center plan. Search results update in the background after a short pause in typing while preserving keyboard focus and a shareable query URL. The Search button remains as a non-JavaScript fallback.

The cache currently selects the Planning Center Worship Team service type and refreshes recent plans every six hours. Previously synced rows remain available, so supervised offset backfills can extend the archive without spending API quota during page views.

Recordings are deliberately separate one-to-many media rows. The verified OBS archive may ingest a recording before it is matched to a plan. Internal storage paths are never selected or rendered by the viewer. Scheduled-person records must never appear on a public share page.

See OBS Recording Archive for recording ingestion and the portal operations guide in Git for sync and backfill commands.

The primary navigation keeps Dashboard, Get Help, Services, Staff, Keys, Expenses, and Files visible when the user has access. Keys and Expenses remain top-level because office staff use them. Network, Ticket Queue, Users, Logs, and Links remain available under the permission-filtered Tech Tools menu.

Permissions are enforced on the destination page in addition to hiding unavailable navigation. A hidden link is never treated as authorization.