Files
tower/apps/web/app/(chapter)/settings/rules/page.tsx
T
maaz519 73956fd1e3 feat: route-centric rules, approve popup, emoji picker, 5-column sync table
- Schema: SyncRouteRuleMap junction table, ruleIntent on TenantRule,
  ForwardFormat/Frequency/ApprovalMode columns on SyncRoute, INTEREST
  match type
- Worker: remove global AUTO_APPROVE forwarding; per-route rule evaluation
  in ingest processor — POSITIVE rules auto-forward that route, NEGATIVE
  rules block it, fallback to approvalMode
- API: PATCH /routes/:id, rule assign/unassign endpoints, approve now
  accepts targetGroupIds, new GET /messages/:id/routes for popup data
- Web: 5-column route table with settings + rules dialogs, ForwardTarget
  popup with rule-based pre-selection, ruleIntent toggle + emoji dropdown
  (👍/👎 only) + INTEREST type in rules manager

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 13:58:02 +05:30

38 lines
1.0 KiB
TypeScript

import { RuleManager } from './RuleManager';
import { apiFetch } from '@/app/_lib/api';
interface RuleData {
id: string;
matchType: 'HASHTAG' | 'PREFIX' | 'REACTION_EMOJI' | 'INTEREST';
matchValue: string;
action: 'FLAG' | 'AUTO_APPROVE' | 'SKIP' | 'REJECT';
ruleIntent: 'POSITIVE' | 'NEGATIVE';
priority: number;
isActive: boolean;
createdAt: string;
updatedAt: string;
}
export default async function RulesSettingsPage() {
let rules: RuleData[] = [];
try {
const res = await apiFetch('/admin/rules');
if (res.ok) {
rules = (await res.json()) as RuleData[];
}
} catch {
rules = [];
}
return (
<div className="max-w-2xl">
<h1 className="text-xl font-semibold mb-6">Rules Engine</h1>
<p className="text-sm text-gray-600 mb-4">
Configure which hashtags, prefixes, and reaction emojis trigger message processing
and what action TOWER should take. Rules are matched in priority order.
</p>
<RuleManager initial={rules} />
</div>
);
}