★★★★★
#앱별 실전 패턴 · claude-code
[we_are_tonged] 신고 + 차단 시스템
부적절한 사용자 신고 및 차단.
#we-are-tonged#report#block#moderation
부적절한 사용자 신고 및 차단.
구현:
```dart
class ReportAndBlockService {
static Future<void> reportUser({
required String reportedUserId,
required String reason,
required String details,
}) async {
await db.collection('reports').add({
'reportedUserId': reportedUserId,
'reporterUserId': currentUserId,
'reason': reason, // "inappropriate", "spam", "harassment" 등
'details': details,
'createdAt': DateTime.now(),
'status': 'pending', // pending, reviewed, action_taken
});
}
static Future<void> blockUser(String blockedUserId) async {
await db.collection('users').doc(currentUserId).update({
'blockedUsers': FieldValue.arrayUnion([blockedUserId]),
});
}
static Future<List<String>> getBlockedUsers(String userId) async {
final doc = await db.collection('users').doc(userId).get();
return List<String>.from(doc['blockedUsers'] ?? []);
}
static Future<bool> isUserBlocked(String userId, String otherUserId) async {
final blockedUsers = await getBlockedUsers(userId);
return blockedUsers.contains(otherUserId);
}
}
```
UI (신고 다이얼로그):
```dart
void _showReportDialog(String userId) {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('사용자 신고'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
DropdownButtonFormField(
items: [
DropdownMenuItem(value: 'inappropriate', child: Text('부적절한 콘텐츠')),
DropdownMenuItem(value: 'spam', child: Text('스팸')),
DropdownMenuItem(value: 'harassment', child: Text('괴롭힘')),
],
onChanged: (value) { /* reason = value */ },
),
TextField(
decoration: InputDecoration(labelText: '상세 이유'),
onChanged: (value) { /* details = value */ },
),
],
),
actions: [
TextButton(onPressed: () => Navigator.pop(context), child: Text('취소')),
ElevatedButton(
onPressed: () {
ReportAndBlockService.reportUser(
reportedUserId: userId,
reason: 'reason', // 위에서 선택한 값
details: 'details', // 입력한 값
);
Navigator.pop(context);
},
child: Text('신고'),
),
],
),
);
}
```
구현해줄까?
쓰는 법 — 위 칸에 본인 값을 채우면 아래 프롬프트에 바로 반영돼요. 복사 버튼을 누르면 채워진 그대로 클립보드에 담기니까, claude-code(또는 본인이 쓰는 AI)에 붙여넣기만 하면 됩니다. 변수가 없으면 그냥 복사해서 쓰세요.

