Phase 3.3: topic sensitivity + Phase 3.4: auth foundation
Phase 3.3 — Session Topic Sensitivity (complete): - Backend: topic_sensitivity column + session_sensitivity_log, sensitivity service (flip with one-way-latch + audit), PATCH /api/shared/chat/sessions/:id/topic, topic carried in pairing + extension WS payloads, CC filter + sensitive stats + per-mitra sensitive columns on activity page - client_app: TopicSelectionBottomSheet before pricing, topic flows through pairing request, silent WS handler for session_topic_updated - mitra_app: SensitivityBadge + SensitivityTheme + sensitivityConfigProvider, overlay badge + yellow accent, chat screen app-bar toggle with configurable confirmation + latch, extension card shows current flag, history + transcript yellow theme - control_center: Sensitivitas Topik settings section, topic filter + column with inline audit log, sensitive stats dashboard card, mitra activity sensitive columns with QC flag Phase 3.4 — Self-Managed Auth (foundation only): - Migration: auth_sessions + otp_requests tables, social identity columns on customers, password_hash + lockout on control_center_users, OTP + CC lockout app_config keys - New services: password (bcrypt + complexity), token (JWT HS256 + refresh rotation, session_id claim pre-wires future Valkey revocation), social-identity (Google + Apple JWKS), OTP (Fazpass stub — real API TBD) - Constants: AuthProvider + OtpChannel - Middleware, auth route rewrites, WS auth update, Firebase → FCM isolation still pending (next chunk); Fazpass docs + Apple Developer setup still required before E2E testing Docs: - requirement/phase3.3.md, phase3.3-plan.md, phase3.3-testing.md - requirement/phase3.4.md, phase3.4-plan.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -63,6 +63,17 @@ const updateEarlyEndConfig = async (data) => {
|
||||
return res.data.data
|
||||
}
|
||||
|
||||
// Phase 3.3: Topic Sensitivity
|
||||
const fetchSensitivityConfig = async () => {
|
||||
const res = await apiClient.get('/internal/config/sensitivity')
|
||||
return res.data.data
|
||||
}
|
||||
|
||||
const updateSensitivityConfig = async (data) => {
|
||||
const res = await apiClient.patch('/internal/config/sensitivity', data)
|
||||
return res.data.data
|
||||
}
|
||||
|
||||
export default function SettingsPage() {
|
||||
const queryClient = useQueryClient()
|
||||
const { data, isLoading } = useQuery({ queryKey: ['config-anonymity'], queryFn: fetchAnonymityConfig })
|
||||
@@ -122,7 +133,17 @@ export default function SettingsPage() {
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['config-mitra-ping'] }),
|
||||
})
|
||||
|
||||
if (isLoading || maxLoading || ftLoading || etLoading || eeLoading || mpLoading) return <div>Loading...</div>
|
||||
// Phase 3.3: Topic Sensitivity
|
||||
const { data: senData, isLoading: senLoading } = useQuery({
|
||||
queryKey: ['config-sensitivity'],
|
||||
queryFn: fetchSensitivityConfig,
|
||||
})
|
||||
const senMutation = useMutation({
|
||||
mutationFn: updateSensitivityConfig,
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['config-sensitivity'] }),
|
||||
})
|
||||
|
||||
if (isLoading || maxLoading || ftLoading || etLoading || eeLoading || mpLoading || senLoading) return <div>Loading...</div>
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -269,6 +290,36 @@ export default function SettingsPage() {
|
||||
</div>
|
||||
{mpMutation.isError && <p style={{ color: 'red' }}>Gagal menyimpan.</p>}
|
||||
</section>
|
||||
|
||||
<section style={{ marginBottom: 24 }}>
|
||||
<h2>Sensitivitas Topik</h2>
|
||||
<p>Konfigurasi untuk fitur penandaan sesi sebagai topik sensitif oleh Mitra.</p>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={senData?.flip_confirmation_enabled ?? true}
|
||||
onChange={e => senMutation.mutate({ flip_confirmation_enabled: e.target.checked })}
|
||||
disabled={senMutation.isPending}
|
||||
/>
|
||||
Aktifkan dialog konfirmasi saat Mitra menandai topik sensitif
|
||||
</label>
|
||||
<p style={{ fontSize: 12, color: '#666', marginBottom: 8 }}>
|
||||
Jika dinonaktifkan, Mitra langsung menandai tanpa dialog konfirmasi.
|
||||
</p>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={senData?.one_way_latch ?? false}
|
||||
onChange={e => senMutation.mutate({ one_way_latch: e.target.checked })}
|
||||
disabled={senMutation.isPending}
|
||||
/>
|
||||
Kunci searah — Mitra tidak bisa membatalkan tanda topik sensitif
|
||||
</label>
|
||||
<p style={{ fontSize: 12, color: '#666' }}>
|
||||
Jika diaktifkan, setelah sesi ditandai sensitif Mitra tidak dapat mengembalikannya ke topik umum.
|
||||
</p>
|
||||
{senMutation.isError && <p style={{ color: 'red' }}>Gagal menyimpan.</p>}
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user