T-HUB/apps/web/package.json
hacklab ad0f1be6cf feat: outreach contacts — track hand-written DMs per collective
A list of public accounts a collective wants to write to (artists,
collectives, public figures), with a drafted message per contact and the
state of the conversation: todo, sent, replied, declined.

The Hub does not send these messages. "Copy & open profile" puts the
draft on the clipboard and opens the profile; a person sends it from the
platform's own DM box and marks it sent. Unsolicited bulk DMs break the
terms of every commercial platform and get accounts restricted, and
Instagram's API cannot open a conversation at all.

API (OutreachModule):
- migration 041: outreach_contacts, RLS enabled + forced with WITH CHECK,
  unique per (workspace, platform, lower(handle)); permissions
  outreach.view (Owner/Admin/Editor/Moderator) and outreach.manage
  (Owner/Admin/Editor).
- GET/POST/PATCH/DELETE /outreach/contacts; bulk import up to 500 rows,
  known accounts skipped. Audit records list changes and status moves,
  never the message text.

Web: /outreach page (sidebar + More), CSV import, {name}/{handle}
template for pending contacts, status filters, a daily counter that
warns past 20 first messages.

Tests: service and request parsing with the DB faked; the migration and
every service query were also run against PGlite as the non-superuser
app role (tenant isolation, conflict skip, status timestamps).
2026-10-15 14:15:03 +02:00

37 lines
1.3 KiB
JSON

{
"name": "@tactical-media-broadcast-hub/web",
"private": true,
"version": "0.1.0",
"scripts": {
"dev": "next dev",
"build": "next build",
"lint": "eslint src",
"typecheck": "tsc --noEmit",
"test:manual": "node --require ./scripts/control-room-register.cjs --test src/lib/participation-manual.test.ts",
"test:register": "node --require ./scripts/control-room-register.cjs --test src/lib/register-form.test.ts",
"test:outreach": "node --require ./scripts/control-room-register.cjs --test src/lib/outreach-types.test.ts"
},
"dependencies": {
"@tactical-media-broadcast-hub/connector-sdk": "workspace:^",
"@tactical-media-broadcast-hub/core": "workspace:^",
"@tailwindcss/postcss": "^4.3.3",
"@tanstack/react-virtual": "^3.14.13",
"@tiptap/extension-character-count": "^3.31.4",
"@tiptap/extension-placeholder": "^3.31.4",
"@tiptap/react": "^3.31.4",
"@tiptap/starter-kit": "^3.31.4",
"cmdk": "^1.1.1",
"next": "^14.2.5",
"postcss": "^8.5.29",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"tailwindcss": "^4.3.3"
},
"devDependencies": {
"@types/node": "^22.5.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"playwright": "^1.63.0",
"typescript": "^5.5.4"
}
}