Files
ten31-database/start9/0.4/startos/actions/index.ts
T
Keysat 2758ac81d3 Add daily-digest Phase A: per-package SMTP send + admin test endpoint (v0.1.0:75)
Groundwork for the daily activity digest: give the CRM an outbound mail path.
Today nothing leaves the box (Gmail capture + drafts only), so this adds a
dedicated, per-package SMTP account independent of any StartOS system-wide SMTP.

- configureDigestSmtp Start9 action: writes host/port/from/username/password/
  security to /data/secrets/smtp/* (password piped over stdin, never argv/env;
  per-field files, owner-only) — mirrors the setAnthropicApiKey pattern.
- docker_entrypoint.sh reads those at boot and exports SMTP_* (operator env wins).
- backend/smtp_send.py: stdlib smtplib wrapper reading SMTP_* (one code path for
  dev .env and the box); starttls/tls/none modes.
- POST /api/admin/digest/test-email (admin-only): proves the pipe. Recipients are
  restricted to the active-admin set — an arbitrary `to` is rejected, so the
  endpoint is not an open relay; send failures are logged, not echoed (an SMTP
  auth error can carry the credential).
- Tests: test_smtp_send.py (sender), test_smtp_endpoint.py (gating + relay
  restriction + no-leak). 18/18 backend green; s9pk typechecks.

Analysis/summarization for the digest body (Phase B) will run on Spark, never
Claude — the digest is deliberately un-anonymized. Decisions + Phase B plan in
ROADMAP.md.
2026-06-15 18:33:06 -05:00

14 lines
519 B
TypeScript

import { sdk } from '../sdk'
import { buildSearchIndex } from './buildSearchIndex'
import { configureDigestSmtp } from './configureDigestSmtp'
import { refreshSearchIndex } from './refreshSearchIndex'
import { resolveDuplicates } from './resolveDuplicates'
import { setAnthropicApiKey } from './setAnthropicApiKey'
export const actions = sdk.Actions.of()
.addAction(buildSearchIndex)
.addAction(refreshSearchIndex)
.addAction(resolveDuplicates)
.addAction(setAnthropicApiKey)
.addAction(configureDigestSmtp)