Hamdast1/TEAMMATES_INDEPENDENCE.md
2026-05-20 12:31:48 +03:30

283 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# استقلال کامل بخش Teammates از Media
## تضمین استقلال ✅
بخش teammates در هر دو فرم (`ImageForm` و `ImageVideoForm`) **کاملاً مستقل** از بخش انتخاب رسانه (تصویر/ویدیو) است.
---
## State Management
### ✅ Teammates State (مستقل)
```typescript
const [teammates, setTeammates] = useState<string[]>([""]);
```
**ویژگی‌ها:**
- هیچ وابستگی به `mediaType` ندارد
- هیچ وابستگی به `uploadedImage` ندارد
- هیچ وابستگی به `uploadedVideo` ندارد
- هیچ وابستگی به `videoCover` ندارد
- هیچگاه reset نمی‌شود مگر توسط خود کاربر
---
## Handlers (هندلرها)
### ✅ handleAddTeammate
```typescript
const handleAddTeammate = () => setTeammates([...teammates, ""]);
```
- **فقط** به `teammates` دسترسی دارد
- هیچ وابستگی به media ندارد
### ✅ handleRemoveTeammate
```typescript
const handleRemoveTeammate = (index: number) => {
const next = teammates.filter((_, i) => i !== index);
setTeammates(next.length > 0 ? next : [""]);
};
```
- **فقط** به `teammates` دسترسی دارد
- هیچ وابستگی به media ندارد
### ✅ handleTeammateChange
```typescript
const handleTeammateChange = (index: number, value: string) => {
const next = [...teammates];
next[index] = value;
setTeammates(next);
};
```
- **فقط** به `teammates` دسترسی دارد
- هیچ وابستگی به media ندارد
---
## Media Handlers (هندلرهای رسانه)
### ✅ handleSwitchMediaType (ImageVideoForm)
```typescript
const handleSwitchMediaType = (type: "image" | "video") => {
setMediaType(type); // ✅ فقط media
setUploadedImage(null); // ✅ فقط media
setUploadedVideo(null); // ✅ فقط media
setVideoCover(null); // ✅ فقط media
// ❌ teammates لمس نمی‌شود!
};
```
**تضمین:** teammates هیچگاه reset نمی‌شود
### ✅ handleImageUpload
```typescript
const handleImageUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
const reader = new FileReader();
reader.onloadend = () => setUploadedImage(reader.result as string);
reader.readAsDataURL(file);
}
// ❌ teammates لمس نمی‌شود!
};
```
### ✅ handleVideoUpload
```typescript
const handleVideoUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
const url = URL.createObjectURL(file);
setUploadedVideo({ url, name: file.name });
setVideoCover(null);
}
// ❌ teammates لمس نمی‌شود!
};
```
---
## Rendering (رندر)
### ✅ TeammatesSection - مشروط اما مستقل
```typescript
{topicConfig.requiresTeammates && (
<TeammatesSection
teammates={teammates}
onAdd={handleAddTeammate}
onRemove={handleRemoveTeammate}
onChange={handleTeammateChange}
/>
)}
```
**ویژگی‌ها:**
- فقط بر اساس `topicConfig.requiresTeammates` نمایش داده می‌شود
- هیچ ارتباطی با `mediaType` ندارد
- هیچ ارتباطی با media uploads ندارد
- اگر نمایش داده شود، کاملاً مستقل عمل می‌کند
---
## سناریوهای تست
### ✅ سناریو 1: تعویض Media Type
```
1. کاربر 3 هم‌تیمی اضافه می‌کند
2. کاربر از "عکس" به "ویدیو" تغییر می‌دهد
3. نتیجه: هم‌تیمی‌ها حفظ می‌شوند ✅
```
### ✅ سناریو 2: آپلود تصویر
```
1. کاربر 2 هم‌تیمی اضافه می‌کند
2. کاربر یک تصویر آپلود می‌کند
3. نتیجه: هم‌تیمی‌ها حفظ می‌شوند ✅
```
### ✅ سناریو 3: حذف تصویر
```
1. کاربر هم‌تیمی وارد می‌کند
2. کاربر تصویر آپلود و سپس حذف می‌کند
3. نتیجه: اطلاعات هم‌تیمی حفظ می‌شود ✅
```
### ✅ سناریو 4: آپلود ویدیو + کاور
```
1. کاربر 4 هم‌تیمی با شماره تلفن وارد می‌کند
2. کاربر ویدیو آپلود می‌کند
3. کاربر کاور ویدیو آپلود می‌کند
4. نتیجه: تمام اطلاعات هم‌تیمی‌ها حفظ می‌شوند ✅
```
### ✅ سناریو 5: تعویض چند باره
```
1. کاربر هم‌تیمی اضافه می‌کند
2. کاربر 10 بار بین عکس/ویدیو تعویض می‌کند
3. نتیجه: هم‌تیمی‌ها دست‌نخورده باقی می‌مانند ✅
```
---
## کد بررسی سریع
### ❌ الگوهای ممنوع (که وجود ندارند):
```typescript
// ❌ این الگوها در کد وجود ندارند:
const handleSwitchMediaType = () => {
setTeammates([""]); // ❌ NEVER!
};
const handleImageUpload = () => {
setTeammates([]); // ❌ NEVER!
};
useEffect(() => {
if (mediaType === "video") {
setTeammates([""]); // ❌ NEVER!
}
}, [mediaType]);
```
### ✅ الگوهای صحیح (که پیاده‌سازی شده):
```typescript
// ✅ teammates فقط توسط teammate handlers تغییر می‌کند
const handleAddTeammate = () => setTeammates([...teammates, ""]);
const handleRemoveTeammate = (index) => { /* ... */ };
const handleTeammateChange = (index, value) => { /* ... */ };
// ✅ media handlers فقط media state را تغییر می‌دهند
const handleSwitchMediaType = () => {
setMediaType(type);
setUploadedImage(null);
setUploadedVideo(null);
setVideoCover(null);
// teammates untouched!
};
```
---
## دیاگرام استقلال
```
┌─────────────────────────────────────────┐
│ Form Component │
├─────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Media State │ │Teammates State│ │
│ │ │ │ │ │
│ │ mediaType │ │ teammates[] │ │
│ │ uploadedImage│ │ │ │
│ │ uploadedVideo│ │ │ │
│ │ videoCover │ │ │ │
│ └──────┬───────┘ └───────┬───────┘ │
│ │ NO │ │
│ │ INTERACTION │ │
│ │ ✘ │ │
│ └─────────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │Media Handlers│ │Teammate │ │
│ │ │ │Handlers │ │
│ │ handleSwitch │ │ handleAdd │ │
│ │ handleImage │ │ handleRemove │ │
│ │ handleVideo │ │ handleChange │ │
│ │ handleCover │ │ │ │
│ └──────────────┘ └──────────────┘ │
│ ↓ ↓ │
│ ONLY Media ONLY Teammates │
│ │
└─────────────────────────────────────────┘
```
---
## تضمین‌های معماری
### ✅ تضمین 1: State Isolation
- State های media و teammates جدا از هم هستند
- هیچ shared state وجود ندارد
### ✅ تضمین 2: Handler Isolation
- Media handlers فقط media state را تغییر می‌دهند
- Teammate handlers فقط teammate state را تغییر می‌دهند
### ✅ تضمین 3: No Side Effects
- تغییر mediaType هیچ side effect روی teammates ندارد
- آپلود/حذف media هیچ side effect روی teammates ندارد
### ✅ تضمین 4: Independent Rendering
- نمایش TeammatesSection فقط به config بستگی دارد
- نه به mediaType، نه به uploaded files
### ✅ تضمین 5: Data Integrity
- اطلاعات teammates تا زمان submit حفظ می‌شود
- فقط کاربر می‌تواند teammates را تغییر دهد
- هیچ کد دیگری teammates را reset نمی‌کند
---
## نتیجه‌گیری
**بخش teammates کاملاً مستقل است**
- ❌ هیچ وابستگی به media type
- ❌ هیچ وابستگی به uploaded files
- ❌ هیچ reset خودکار
- ❌ هیچ side effect
- ✅ کنترل کامل توسط کاربر
- ✅ Data integrity تضمین شده
- ✅ معماری تمیز و قابل نگهداری
---
**این استقلال باعث می‌شود:**
- کاربر بتواند آزادانه بین media type ها تعویض کند
- اطلاعات هم‌تیمی‌ها هیچوقت از دست نرود
- فرم رفتار قابل پیش‌بینی داشته باشد
- باگ‌های مربوط به state management کاهش یابد
**تست شده و تضمین شده**