自動アカウント制限システム
このドキュメントはNotionの内容を拡張したものです。詳細な実装仕様やTypeScriptコード例が追加されています。
概要
通報システムによる自動アカウント制限の詳細な点数計算システムの仕様です。ユーザーの違反行為に対する点数付与、毎日の点数減少、閾値超過時の制限期間計算、同一卓での複数通報時の傾斜係数適用について定義します。
システム設定値
基本パラメーター
typescript
interface AutoRestrictionConfig {
thresholdPoint: number; // 制限発動閾値点数
reductionRate: number; // 日次点数低減率(%)
restrictionBaseDays: number; // 制限基本日数
maxRestrictionDays: number; // 最大制限日数
}
// デフォルト設定
const DEFAULT_CONFIG: AutoRestrictionConfig = {
thresholdPoint: 100, // 100点で制限発動
reductionRate: 5, // 毎日5%低減
restrictionBaseDays: 3, // 基本3日間の制限
maxRestrictionDays: 30 // 最大30日間の制限
};違反行為の点数設定
typescript
interface ViolationPoints {
[key: string]: number;
}
const VIOLATION_POINTS: ViolationPoints = {
// 軽微な違反
'inappropriate_language': 15, // 不適切な言葉遣い
'spam_message': 10, // スパムメッセージ
'off_topic_discussion': 8, // 無関係な話題
// 中程度の違反
'harassment': 25, // ハラスメント
'cheating_attempt': 30, // 不正行為の試み
'rule_violation': 20, // ルール違反
// 重大な違反
'severe_harassment': 50, // 深刻なハラスメント
'hate_speech': 45, // ヘイトスピーチ
'doxxing': 60, // 個人情報の暴露
'real_money_trading': 40, // リアルマネートレーディング
// 極めて重大な違反
'threatening_behavior': 80, // 脅迫行為
'illegal_content': 100, // 違法コンテンツ
'account_selling': 70 // アカウント売買
};点数計算システム
基本点数計算
typescript
interface ReportInfo {
reporterId: string;
violationType: string;
tableId: string;
timestamp: Date;
evidenceUrls?: string[];
}
interface PointCalculation {
basePoints: number;
slopeCoefficient: number;
finalPoints: number;
reportCount: number;
}
function calculateViolationPoints(
reports: ReportInfo[],
violationType: string,
tableId: string
): PointCalculation {
const basePoints = VIOLATION_POINTS[violationType] || 0;
// 同一卓での通報数を計算
const sameTableReports = reports.filter(r =>
r.tableId === tableId &&
r.violationType === violationType
);
const reportCount = sameTableReports.length;
// 傾斜係数の計算
const slopeCoefficient = calculateSlopeCoefficient(reportCount);
// 最終点数の計算
const finalPoints = Math.round(basePoints * slopeCoefficient);
return {
basePoints,
slopeCoefficient,
finalPoints,
reportCount
};
}傾斜係数の計算
同一卓で複数の通報があった場合の傾斜係数適用ロジック:
typescript
function calculateSlopeCoefficient(reportCount: number): number {
// 通報数に応じた係数テーブル
const coefficientTable: { [key: number]: number } = {
1: 1.0, // 1件: 100%
2: 1.5, // 2件: 150%
3: 1.8, // 3件: 180%
4: 2.0, // 4件: 200%
5: 2.2, // 5件: 220%
6: 2.4, // 6件: 240%
7: 2.5, // 7件: 250%
};
// 8件以上は2.5倍で固定
if (reportCount >= 8) {
return 2.5;
}
return coefficientTable[reportCount] || 1.0;
}日次点数低減システム
typescript
interface UserPointHistory {
userId: string;
currentPoints: number;
lastUpdated: Date;
pointHistory: PointEntry[];
}
interface PointEntry {
date: Date;
pointsAdded: number;
pointsReduced: number;
violationType?: string;
remainingPoints: number;
}
function applyDailyReduction(
userPoints: UserPointHistory,
config: AutoRestrictionConfig
): UserPointHistory {
const now = new Date();
const daysSinceUpdate = Math.floor(
(now.getTime() - userPoints.lastUpdated.getTime()) / (1000 * 60 * 60 * 24)
);
if (daysSinceUpdate === 0) {
return userPoints; // 同日内は処理しない
}
let currentPoints = userPoints.currentPoints;
// 日数分の低減を適用
for (let i = 0; i < daysSinceUpdate; i++) {
const reductionAmount = Math.ceil(currentPoints * (config.reductionRate / 100));
currentPoints = Math.max(0, currentPoints - reductionAmount);
// 履歴に記録
const reductionDate = new Date(userPoints.lastUpdated);
reductionDate.setDate(reductionDate.getDate() + i + 1);
userPoints.pointHistory.push({
date: reductionDate,
pointsAdded: 0,
pointsReduced: reductionAmount,
remainingPoints: currentPoints
});
if (currentPoints === 0) break;
}
return {
...userPoints,
currentPoints,
lastUpdated: now
};
}制限期間の計算
制限期間決定ロジック
typescript
interface RestrictionCalculation {
shouldRestrict: boolean;
restrictionDays: number;
excessPoints: number;
restrictionLevel: 'light' | 'moderate' | 'severe' | 'extreme';
}
function calculateRestrictionPeriod(
totalPoints: number,
config: AutoRestrictionConfig
): RestrictionCalculation {
if (totalPoints < config.thresholdPoint) {
return {
shouldRestrict: false,
restrictionDays: 0,
excessPoints: 0,
restrictionLevel: 'light'
};
}
const excessPoints = totalPoints - config.thresholdPoint;
// 制限期間の計算式
// 基本日数 + (超過点数 * 0.2)日
let restrictionDays = config.restrictionBaseDays + Math.floor(excessPoints * 0.2);
// 最大制限日数の適用
restrictionDays = Math.min(restrictionDays, config.maxRestrictionDays);
// 制限レベルの判定
let restrictionLevel: 'light' | 'moderate' | 'severe' | 'extreme' = 'light';
if (restrictionDays <= 7) {
restrictionLevel = 'light';
} else if (restrictionDays <= 14) {
restrictionLevel = 'moderate';
} else if (restrictionDays <= 21) {
restrictionLevel = 'severe';
} else {
restrictionLevel = 'extreme';
}
return {
shouldRestrict: true,
restrictionDays,
excessPoints,
restrictionLevel
};
}制限レベル別の機能制限
制限内容の定義
typescript
interface RestrictionFeatures {
canCreateEvent: boolean;
canJoinEvent: boolean;
canSendMessage: boolean;
canAddFriend: boolean;
canUseShop: boolean;
canWriteReview: boolean;
maxDailyEvents: number;
messageThrottleSeconds: number;
}
const RESTRICTION_FEATURES: { [key: string]: RestrictionFeatures } = {
light: {
canCreateEvent: false,
canJoinEvent: true,
canSendMessage: true,
canAddFriend: true,
canUseShop: true,
canWriteReview: false,
maxDailyEvents: 3,
messageThrottleSeconds: 5
},
moderate: {
canCreateEvent: false,
canJoinEvent: true,
canSendMessage: true,
canAddFriend: false,
canUseShop: false,
canWriteReview: false,
maxDailyEvents: 1,
messageThrottleSeconds: 10
},
severe: {
canCreateEvent: false,
canJoinEvent: false,
canSendMessage: true,
canAddFriend: false,
canUseShop: false,
canWriteReview: false,
maxDailyEvents: 0,
messageThrottleSeconds: 30
},
extreme: {
canCreateEvent: false,
canJoinEvent: false,
canSendMessage: false,
canAddFriend: false,
canUseShop: false,
canWriteReview: false,
maxDailyEvents: 0,
messageThrottleSeconds: 0
}
};管理者用ダッシュボード
監視対象メトリクス
typescript
interface RestrictionMetrics {
totalRestrictedUsers: number;
newRestrictionsToday: number;
averageRestrictionDays: number;
mostCommonViolation: string;
falsePositiveRate: number;
appealsToday: number;
}
interface UserRestrictionStatus {
userId: string;
username: string;
currentPoints: number;
restrictionLevel: string;
restrictionStartDate: Date;
restrictionEndDate: Date;
totalViolations: number;
recentViolations: ViolationSummary[];
}実装注意事項
- データ整合性: 点数計算時の同期処理
- パフォーマンス: 大量ユーザーの日次低減処理の最適化
- 監査ログ: 全ての制限適用の詳細ログ保存
- 異議申し立て: 制限に対する適切な異議申し立てプロセス
- プライバシー: 通報者の匿名性保護