fix(schema): 입금자명 길이 제한 50자 → 15자로 조정
근거: - SMS 입금자명: 한글 7자 제한 (은행 시스템) - 사용자 수동 입력: 15자로 충분한 여유 - 매칭 로직: 앞 7자만 사용 변경사항: - CHECK (length(depositor_name) <= 50) → 15 - 데이터 복원 시 truncate: 50자 → 15자 - SCHEMA_MIGRATION_GUIDE.md 업데이트 - MIGRATION_SUMMARY.md 업데이트 로컬 테스트 결과: - ✅ 15자 이하: 정상 입력 - 숫자 15자: "123456789012345" ✓ - 한글 15자: "홍길동아버지어머니할머님고모고" ✓ - ✅ 16자 이상: 거부됨 - 숫자 16자: "1234567890123456" ✗ (CHECK 제약조건) - 한글 16자: "홍길동아버지어머니할머님고모고모" ✗ (CHECK 제약조건) 실용성: - SMS 7자 보장 + 사용자 입력 여유 - 불필요한 긴 이름 방지 - 매칭 로직과 완벽 호환 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,7 @@ Database migration to add critical data integrity constraints and audit logging
|
||||
| Component | Change | Impact |
|
||||
|-----------|--------|--------|
|
||||
| `user_deposits.balance` | Add CHECK (balance >= 0) | Prevents negative balances |
|
||||
| `deposit_transactions.depositor_name` | Add CHECK (length <= 50) | Enforces name length limit |
|
||||
| `deposit_transactions.depositor_name` | Add CHECK (length <= 15) | Enforces name length limit |
|
||||
| `audit_logs` | New table | Tracks all critical operations |
|
||||
|
||||
### Risk Assessment
|
||||
@@ -50,7 +50,7 @@ telegram-bot-workers/
|
||||
- [ ] Read `SCHEMA_MIGRATION_GUIDE.md` completely
|
||||
- [ ] Backup production database
|
||||
- [ ] Check for negative balances in production
|
||||
- [ ] Check for long depositor names (> 50 chars) in production
|
||||
- [ ] Check for long depositor names (> 15 chars) in production
|
||||
- [ ] Verify rollback script is accessible
|
||||
- [ ] Schedule deployment window (< 5 min)
|
||||
- [ ] Notify stakeholders (optional)
|
||||
@@ -209,18 +209,18 @@ balance INTEGER NOT NULL DEFAULT 0 CHECK (balance >= 0)
|
||||
CHECK constraint failed: balance >= 0
|
||||
```
|
||||
|
||||
### Depositor Name Length <= 50 (deposit_transactions)
|
||||
### Depositor Name Length <= 15 (deposit_transactions)
|
||||
|
||||
**Why**: Bank SMS truncates names at 7 chars, but we allow 50 for edge cases
|
||||
**Why**: Bank SMS truncates names at 7 chars, but we allow 15 for flexibility
|
||||
|
||||
**Implementation**:
|
||||
```sql
|
||||
depositor_name TEXT CHECK (length(depositor_name) <= 50)
|
||||
depositor_name TEXT CHECK (length(depositor_name) <= 15)
|
||||
```
|
||||
|
||||
**Effect**: Names longer than 50 chars will be rejected:
|
||||
```
|
||||
CHECK constraint failed: length(depositor_name) <= 50
|
||||
CHECK constraint failed: length(depositor_name) <= 15
|
||||
```
|
||||
|
||||
---
|
||||
@@ -282,7 +282,7 @@ wrangler d1 execute telegram-conversations \
|
||||
# Check for long names
|
||||
wrangler d1 execute telegram-conversations \
|
||||
--command "SELECT id, depositor_name, length(depositor_name) as len
|
||||
FROM deposit_transactions WHERE length(depositor_name) > 50"
|
||||
FROM deposit_transactions WHERE length(depositor_name) > 15"
|
||||
```
|
||||
|
||||
3. **Prepare Backup**
|
||||
|
||||
@@ -13,7 +13,7 @@ This migration adds critical data integrity constraints and audit logging capabi
|
||||
| Change | Purpose | Risk Level |
|
||||
|--------|---------|------------|
|
||||
| `user_deposits.balance` CHECK constraint | Prevent negative balances | Medium |
|
||||
| `deposit_transactions.depositor_name` length limit | Enforce 50 character max | Low |
|
||||
| `deposit_transactions.depositor_name` length limit | Enforce 15 character max | Low |
|
||||
| `audit_logs` table | Track all important operations | None (new table) |
|
||||
|
||||
---
|
||||
@@ -46,20 +46,20 @@ INSERT INTO user_deposits (user_id, balance) VALUES (999999, -1000);
|
||||
|
||||
### 2. Depositor Name Length (`deposit_transactions`)
|
||||
|
||||
**Goal**: Limit `depositor_name` to 50 characters max
|
||||
**Goal**: Limit `depositor_name` to 15 characters max
|
||||
|
||||
**Implementation**:
|
||||
```sql
|
||||
CREATE TABLE deposit_transactions (
|
||||
...
|
||||
depositor_name TEXT CHECK (length(depositor_name) <= 50),
|
||||
depositor_name TEXT CHECK (length(depositor_name) <= 15),
|
||||
...
|
||||
);
|
||||
```
|
||||
|
||||
**Impact**:
|
||||
- ✅ Prevents excessively long names
|
||||
- 📏 Truncates existing names >50 chars (logs truncated records)
|
||||
- 📏 Truncates existing names >15 chars (logs truncated records)
|
||||
- 🔧 Requires table recreation (SQLite limitation)
|
||||
|
||||
**Verification**:
|
||||
@@ -137,7 +137,7 @@ wrangler d1 execute telegram-conversations \
|
||||
|
||||
# Check for long depositor names (will be truncated)
|
||||
wrangler d1 execute telegram-conversations \
|
||||
--command "SELECT id, depositor_name, length(depositor_name) as len FROM deposit_transactions WHERE length(depositor_name) > 50"
|
||||
--command "SELECT id, depositor_name, length(depositor_name) as len FROM deposit_transactions WHERE length(depositor_name) > 15"
|
||||
```
|
||||
|
||||
### 3. Notify Users (if downtime expected)
|
||||
@@ -496,7 +496,7 @@ wrangler d1 execute telegram-conversations \
|
||||
After migration, verify:
|
||||
|
||||
- [ ] All user_deposits records have `balance >= 0`
|
||||
- [ ] All deposit_transactions have `depositor_name` length <= 50
|
||||
- [ ] All deposit_transactions have `depositor_name` length <= 15
|
||||
- [ ] audit_logs table exists with correct schema
|
||||
- [ ] All indexes recreated successfully
|
||||
- [ ] Record counts match pre-migration
|
||||
|
||||
@@ -59,7 +59,7 @@ CREATE TABLE deposit_transactions (
|
||||
type TEXT NOT NULL CHECK(type IN ('deposit', 'withdrawal', 'refund')),
|
||||
amount INTEGER NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'confirmed', 'rejected', 'cancelled')),
|
||||
depositor_name TEXT CHECK (length(depositor_name) <= 50),
|
||||
depositor_name TEXT CHECK (length(depositor_name) <= 15),
|
||||
description TEXT,
|
||||
confirmed_at DATETIME,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
@@ -78,7 +78,7 @@ SELECT
|
||||
status,
|
||||
CASE
|
||||
WHEN depositor_name IS NULL THEN NULL
|
||||
WHEN length(depositor_name) > 50 THEN substr(depositor_name, 1, 50)
|
||||
WHEN length(depositor_name) > 15 THEN substr(depositor_name, 1, 15)
|
||||
ELSE depositor_name
|
||||
END as depositor_name,
|
||||
description,
|
||||
@@ -89,7 +89,7 @@ FROM deposit_transactions_backup;
|
||||
-- 2.5 Log truncated records (if any)
|
||||
SELECT 'TRUNCATED DEPOSITOR NAME:' as warning, id, depositor_name, length(depositor_name) as original_length
|
||||
FROM deposit_transactions_backup
|
||||
WHERE depositor_name IS NOT NULL AND length(depositor_name) > 50;
|
||||
WHERE depositor_name IS NOT NULL AND length(depositor_name) > 15;
|
||||
|
||||
-- 2.6 Drop backup table
|
||||
DROP TABLE deposit_transactions_backup;
|
||||
|
||||
Reference in New Issue
Block a user