ikinci temizlik tamamlandı
This commit is contained in:
@@ -0,0 +1,764 @@
|
||||
# PDF Editor Step 3 - Joint Widget & Weldmap Entegrasyonu Roadmap
|
||||
|
||||
## 📋 Görev Özeti
|
||||
|
||||
**Amaç:** PDF çizimlerinde interaktif joint veri girişi sağlamak ve PDF Editor, Base Weldmap ve Weldlog veritabanları arasında iki yönlü entegrasyon kurmak.
|
||||
|
||||
**Temel Gereksinimler:**
|
||||
1. Veri girişi için interaktif joint widget (popup)
|
||||
2. Kayıt edilene kadar geçici veri depolama
|
||||
3. Base Weldmap ve Weldlog ile SQL entegrasyonu
|
||||
4. İki yönlü veri senkronizasyonu
|
||||
5. Document Revision entegrasyonu (Spool Iso / As-Build)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Fonksiyonel Gereksinimler Özeti
|
||||
|
||||
### Senaryo 1: Engineering Iso + Adding Joints
|
||||
- Kullanıcı PDF üzerine üçgen (Field) veya yuvarlak (Shop) çizer
|
||||
- Veri girişi için widget otomatik açılır
|
||||
- Veriler kayıt edilene kadar hafızada tutulur
|
||||
- Kayıt sırasında: SQL ile Base Weldmap'e ekleme
|
||||
- Çizimi Document Revision "Spool Iso" kısmına kaydet
|
||||
|
||||
### Senaryo 2: Spool Iso/Asbuild Iso + Adding Joints & Welder
|
||||
- Kullanıcı mevcut joint üzerine gelir
|
||||
- Widget önceden girilmiş verilerle açılır (Welder1-2 boş)
|
||||
- Welder1-2 dropdown'larında uygun kaynakçıları listele
|
||||
- PDF görüntüsünü güncelle: joint no (üstte), welder ID (altta), ayırıcı çizgi
|
||||
- Kayıt sırasında: SQL ile Weldlog'u güncelle
|
||||
- Çizimi Document Revision "As-Build" kısmına kaydet
|
||||
|
||||
### Senaryo 3: Veri Var ama Çizim Eksik
|
||||
- Base Weldmap/Welder verisi var ama çizim eksik mi kontrol et
|
||||
- Sol paneli aktifleştir: Spool No, Joint No, Welder ID bölümleri
|
||||
- Kullanıcı Spool No seçer → Joint listesi
|
||||
- Kullanıcı Joint + F/S şekli seçer → Çizim görünür
|
||||
- Kullanıcı Joint + Welder + F/S şekli seçer → Welder ile çizim görünür
|
||||
- Document Revision'a kaydet (Spool Iso veya As-Build)
|
||||
|
||||
---
|
||||
|
||||
## 🗺️ Geliştirme Roadmap'i
|
||||
|
||||
### Faz 1: Temel Yapı & Veri Yapısı (Hafta 1)
|
||||
|
||||
#### 1.1 Geçici Veri Depolama Sistemi
|
||||
**Hedef:** Kaydedilmemiş joint verileri için hafıza içi veri depolama sistemi oluştur
|
||||
|
||||
**Görevler:**
|
||||
- [ ] Geçici depolama için `JointDataManager` JavaScript sınıfı oluştur
|
||||
- [ ] Veri yapısını uygula: `Map<shapeId, jointData>`
|
||||
- [ ] Depolamadan önce veri doğrulama ekle
|
||||
- [ ] Tarayıcı sessionStorage'da veri kalıcılığı (yedek)
|
||||
- [ ] Sayfa kapanışında veri temizleme oluştur
|
||||
|
||||
**En İyi Uygulamalar:**
|
||||
- O(1) arama performansı için Map kullan
|
||||
- Çakışma çözümü için veri versiyonlama uygula
|
||||
- Depolamadan önce veri doğrulama katmanı ekle
|
||||
- Sayfa yenilemede hayatta kalması için sessionStorage kullan
|
||||
|
||||
**Oluşturulacak/Değiştirilecek Dosyalar:**
|
||||
- `resources/views/admin/type/pdf-editor.blade.php` (JointDataManager sınıfı ekle)
|
||||
- Oluştur: `public/js/pdf-editor/joint-data-manager.js` (opsiyonel ayrım)
|
||||
|
||||
#### 1.2 Widget Modal Geliştirmesi
|
||||
**Hedef:** Mevcut joint widget modal'ını tüm gerekli alanlarla geliştir
|
||||
|
||||
**Görevler:**
|
||||
- [ ] `joint-widget-modal.blade.php` dosyasını gözden geçir ve geliştir
|
||||
- [ ] Edit type'a göre koşullu alan gösterimi ekle
|
||||
- [ ] IC Log member seçimi uygula (Member1, Member2)
|
||||
- [ ] IC Log'dan Material, Dia, NPS, Thickness için otomatik doldurma mantığı ekle
|
||||
- [ ] Yeterliliğe göre welder dropdown filtreleme uygula
|
||||
- [ ] Form doğrulama ekle
|
||||
|
||||
**En İyi Uygulamalar:**
|
||||
- Dropdown'lar için Select2 kullan (projede mevcut)
|
||||
- Member seçimi için debounced API çağrıları uygula
|
||||
- Kademeli dropdown'lar uygula (member → material detayları)
|
||||
- Asenkron işlemler için yükleme durumları ekle
|
||||
- Bootstrap 5 form doğrulama kullan
|
||||
|
||||
**Değiştirilecek Dosyalar:**
|
||||
- `resources/views/components/modals/joint-widget-modal.blade.php`
|
||||
- `resources/views/admin/type/pdf-editor.blade.php` (widget entegrasyonu)
|
||||
|
||||
**Önemli Not:** Widget açılışı için **double-click** kullanılacak. Mevcut double-click silme özelliği kaldırılmalı veya farklı bir tuş kombinasyonu ile değiştirilmelidir.
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: Shape Interaction & Widget Integration (Week 1-2)
|
||||
|
||||
#### 2.1 Shape Click/Hover Event Handling
|
||||
**Goal:** Open widget when user interacts with joint shapes
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Add click event listener to triangle/circle shapes
|
||||
- [ ] Add hover event listener for existing joints (Scenario 2)
|
||||
- [ ] Position widget near clicked shape
|
||||
- [ ] Load existing data if joint already has data
|
||||
- [ ] Handle shape creation event (Scenario 1)
|
||||
|
||||
**Best Practices:**
|
||||
- Use Fabric.js event delegation for performance
|
||||
- Implement debouncing for hover events
|
||||
- Calculate optimal widget position (avoid screen edges)
|
||||
- Use requestAnimationFrame for smooth animations
|
||||
- Add visual feedback (highlight shape on hover)
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Shape click handler
|
||||
fabricCanvas.on('mouse:down', (e) => {
|
||||
if (e.target && (e.target.type === 'triangle' || e.target.type === 'circle')) {
|
||||
if (currentEditType === 'adding_joints' || currentEditType === 'adding_joints_welder') {
|
||||
openJointWidget(e.target, e.e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Hover handler for existing joints
|
||||
fabricCanvas.on('mouse:over', (e) => {
|
||||
if (e.target && e.target.shapeId && hasExistingData(e.target.shapeId)) {
|
||||
showHoverTooltip(e.target);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 2.2 Widget Data Binding
|
||||
**Goal:** Connect widget form with shape data
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Load shape data into widget form
|
||||
- [ ] Save widget data to temporary storage
|
||||
- [ ] Update shape label display (joint no, welder ID)
|
||||
- [ ] Handle form field changes (real-time updates)
|
||||
- [ ] Implement cancel/close behavior
|
||||
|
||||
**Best Practices:**
|
||||
- Use two-way data binding pattern
|
||||
- Implement reactive updates (update shape when form changes)
|
||||
- Add unsaved changes warning
|
||||
- Use event-driven architecture
|
||||
|
||||
**Files to Modify:**
|
||||
- `resources/views/admin/type/pdf-editor.blade.php`
|
||||
- `resources/views/components/modals/joint-widget-modal.blade.php`
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: API Development & Database Integration (Week 2)
|
||||
|
||||
#### 3.1 API Endpoints for Joint Data
|
||||
**Goal:** Create RESTful API endpoints for joint operations
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Create `saveJointData` endpoint (already exists, enhance)
|
||||
- [ ] Create `getJointData` endpoint
|
||||
- [ ] Create `checkExistingWeldmapData` endpoint (already exists)
|
||||
- [ ] Create `getQualifiedWelders` endpoint
|
||||
- [ ] Create `getICLogMembers` endpoint (already exists)
|
||||
- [ ] Create `getICLogMemberDetails` endpoint (already exists)
|
||||
|
||||
**Best Practices:**
|
||||
- Use Laravel Resource classes for consistent responses
|
||||
- Implement proper validation rules
|
||||
- Add error handling and logging
|
||||
- Use database transactions for data integrity
|
||||
- Implement rate limiting for API calls
|
||||
|
||||
**Files to Create/Modify:**
|
||||
- `app/Http/Controllers/Api/AnnotationController.php` (enhance existing)
|
||||
- `app/Http/Controllers/Api/PdfEditorLookupController.php` (enhance existing)
|
||||
- `routes/web.php` (add routes if needed)
|
||||
|
||||
#### 3.2 Base Weldmap Integration
|
||||
**Goal:** Insert/update joint data in Base Weldmap
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Map widget form data to weld_logs table structure
|
||||
- [ ] Implement insert logic for new joints
|
||||
- [ ] Implement update logic for existing joints
|
||||
- [ ] Handle field mapping (widget → database)
|
||||
- [ ] Add validation for required fields
|
||||
- [ ] Implement batch insert for multiple joints
|
||||
|
||||
**Database Mapping:**
|
||||
```
|
||||
Widget Field → weld_logs Column
|
||||
- joint_no → no_of_the_joint_as_per_as_built_survey
|
||||
- type_of_joint → type_of_joint (F/S)
|
||||
- welding_date → welding_date
|
||||
- spool_no1 → spool_number_1
|
||||
- spool_no2 → spool_number_2
|
||||
- pose_no1 → pose_number_1
|
||||
- pose_no2 → pose_number_2
|
||||
- member1 → member_1
|
||||
- member2 → member_2
|
||||
- material → material_1, material_2
|
||||
- dia1 → dia_1
|
||||
- dia2 → dia_2
|
||||
- nps1 → nps_1
|
||||
- nps2 → nps_2
|
||||
- thickness1 → thickness_1
|
||||
- thickness2 → thickness_2
|
||||
- welder_id1 → welder_1
|
||||
- welder_id2 → welder_2
|
||||
```
|
||||
|
||||
**Best Practices:**
|
||||
- Use Eloquent models for database operations
|
||||
- Implement database transactions
|
||||
- Add rollback on error
|
||||
- Use bulk insert for performance
|
||||
- Validate data before database operations
|
||||
|
||||
**Files to Modify:**
|
||||
- `app/Http/Controllers/Api/AnnotationController.php`
|
||||
- `app/Models/WeldLog.php` (if needed)
|
||||
|
||||
#### 3.3 Weldlog Integration
|
||||
**Goal:** Update welder assignments in Weldlog
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Implement welder assignment update logic
|
||||
- [ ] Handle real_welder_1 and real_welder_2 fields
|
||||
- [ ] Update joint display on PDF after assignment
|
||||
- [ ] Validate welder qualifications before assignment
|
||||
|
||||
**Best Practices:**
|
||||
- Use updateOrCreate for idempotent operations
|
||||
- Implement soft validation (warnings, not errors)
|
||||
- Add audit trail for welder changes
|
||||
- Use database transactions
|
||||
|
||||
**Files to Modify:**
|
||||
- `app/Http/Controllers/Api/AnnotationController.php`
|
||||
- `app/Models/WeldLog.php`
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: Two-Way Data Synchronization (Week 2-3)
|
||||
|
||||
#### 4.1 Data Existence Check
|
||||
**Goal:** Check if Base Weldmap/Welder data exists but drawing is missing
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Create API endpoint to check data existence
|
||||
- [ ] Implement left panel activation logic
|
||||
- [ ] Create Spool No dropdown population
|
||||
- [ ] Create Joint No dropdown (filtered by Spool)
|
||||
- [ ] Create Welder ID dropdown (filtered by Joint)
|
||||
|
||||
**API Endpoint:**
|
||||
```php
|
||||
GET /api/pdf-editor/check-existing-weldmap
|
||||
Query: drawing_number
|
||||
Response: {
|
||||
has_data: true/false,
|
||||
spools: [...],
|
||||
joints: [...],
|
||||
welders: [...]
|
||||
}
|
||||
```
|
||||
|
||||
**Best Practices:**
|
||||
- Cache API responses for performance
|
||||
- Implement pagination for large datasets
|
||||
- Use eager loading for relationships
|
||||
- Add loading states in UI
|
||||
|
||||
**Files to Create/Modify:**
|
||||
- `app/Http/Controllers/Api/PdfEditorLookupController.php`
|
||||
- `resources/views/admin/type/pdf-editor.blade.php` (left panel)
|
||||
|
||||
#### 4.2 Drawing Generation from Data
|
||||
**Goal:** Generate PDF drawing shapes from existing database data
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Implement shape creation from joint data
|
||||
- [ ] Position shapes based on joint relationships
|
||||
- [ ] Add welder labels if welder data exists
|
||||
- [ ] Handle F/S shape selection
|
||||
- [ ] Update annotation storage
|
||||
|
||||
**Best Practices:**
|
||||
- Use Fabric.js for shape creation
|
||||
- Implement smart positioning algorithm
|
||||
- Add collision detection
|
||||
- Use canvas grouping for related shapes
|
||||
|
||||
**Files to Modify:**
|
||||
- `resources/views/admin/type/pdf-editor.blade.php`
|
||||
|
||||
---
|
||||
|
||||
### Phase 5: Document Revision Integration (Week 3)
|
||||
|
||||
#### 5.1 Save to Spool Iso
|
||||
**Goal:** Save annotated PDF to Document Revision "Spool Iso"
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Implement PDF export with annotations
|
||||
- [ ] Save to Document Revision pdf_spool_iso column
|
||||
- [ ] Update revision metadata
|
||||
- [ ] Handle versioning
|
||||
|
||||
**Best Practices:**
|
||||
- Use existing PDF export functionality
|
||||
- Implement async save operation
|
||||
- Add progress indicator
|
||||
- Handle save errors gracefully
|
||||
|
||||
**Files to Modify:**
|
||||
- `app/Http/Controllers/Api/AnnotationController.php`
|
||||
- `app/Http/Controllers/Api/PdfEditorLookupController.php` (updateDocumentStage)
|
||||
|
||||
#### 5.2 Save to As-Build
|
||||
**Goal:** Save annotated PDF to Document Revision "As-Build"
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Similar to Spool Iso but for pdf_as_build column
|
||||
- [ ] Include welder information in saved PDF
|
||||
- [ ] Update revision metadata
|
||||
|
||||
**Files to Modify:**
|
||||
- Same as 5.1
|
||||
|
||||
---
|
||||
|
||||
### Phase 6: Welder Qualification Filtering (Week 3)
|
||||
|
||||
#### 6.1 Welder Qualification System
|
||||
**Goal:** Filter welders based on qualifications and validity
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Integrate with existing Welder Assignment system
|
||||
- [ ] Implement qualification filtering logic
|
||||
- [ ] Check welder expiry dates
|
||||
- [ ] Filter by material compatibility
|
||||
- [ ] Filter by welding method
|
||||
|
||||
**Best Practices:**
|
||||
- Reuse existing welder assignment logic
|
||||
- Cache qualification data
|
||||
- Implement client-side filtering for performance
|
||||
- Add server-side validation
|
||||
|
||||
**Files to Modify:**
|
||||
- `app/Http/Controllers/Api/PdfEditorLookupController.php`
|
||||
- `app/Http/Controllers/AutoCompleteType/welder-assignment/welder_1.php` (reference)
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Technical Architecture
|
||||
|
||||
### Frontend Architecture
|
||||
|
||||
```
|
||||
PDF Editor Canvas (Fabric.js)
|
||||
↓
|
||||
Shape Event Handlers
|
||||
↓
|
||||
Joint Data Manager (Temporary Storage)
|
||||
↓
|
||||
Widget Modal (Form)
|
||||
↓
|
||||
API Calls (AJAX)
|
||||
↓
|
||||
Backend Controllers
|
||||
↓
|
||||
Database (weld_logs, annotations, document_revisions)
|
||||
```
|
||||
|
||||
### Data Flow
|
||||
|
||||
**Scenario 1: New Joint Creation**
|
||||
```
|
||||
User draws shape → Widget opens → User fills form →
|
||||
Data stored in memory → User clicks Save →
|
||||
Batch insert to weld_logs → Save PDF to Document Revision
|
||||
```
|
||||
|
||||
**Scenario 2: Welder Assignment**
|
||||
```
|
||||
User hovers joint → Widget opens (pre-filled) →
|
||||
User selects welders → Update memory →
|
||||
User clicks Save → Update weld_logs →
|
||||
Update PDF display → Save PDF to Document Revision
|
||||
```
|
||||
|
||||
**Scenario 3: Drawing from Data**
|
||||
```
|
||||
Check data exists → Activate left panel →
|
||||
User selects Spool → Joints list →
|
||||
User selects Joint + Shape → Create shape on PDF →
|
||||
Save PDF to Document Revision
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Best Practices & Recommendations
|
||||
|
||||
### 1. Temporary Data Storage
|
||||
|
||||
**Option A: In-Memory (Recommended)**
|
||||
- Use JavaScript Map/Object for fast access
|
||||
- Store in component state
|
||||
- Clear on page unload
|
||||
- **Pros:** Fast, no persistence needed
|
||||
- **Cons:** Lost on page refresh
|
||||
|
||||
**Option B: SessionStorage**
|
||||
- Use browser sessionStorage API
|
||||
- Survives page refresh
|
||||
- Auto-clears on tab close
|
||||
- **Pros:** Persistence
|
||||
- **Cons:** Limited size, string serialization
|
||||
|
||||
**Recommendation:** Use in-memory storage with sessionStorage backup
|
||||
|
||||
```javascript
|
||||
class JointDataManager {
|
||||
constructor() {
|
||||
this.data = new Map();
|
||||
this.loadFromSession();
|
||||
}
|
||||
|
||||
save(shapeId, jointData) {
|
||||
this.data.set(shapeId, jointData);
|
||||
this.saveToSession();
|
||||
}
|
||||
|
||||
saveToSession() {
|
||||
const data = Object.fromEntries(this.data);
|
||||
sessionStorage.setItem('jointData', JSON.stringify(data));
|
||||
}
|
||||
|
||||
loadFromSession() {
|
||||
const stored = sessionStorage.getItem('jointData');
|
||||
if (stored) {
|
||||
const data = JSON.parse(stored);
|
||||
this.data = new Map(Object.entries(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Widget Positioning
|
||||
|
||||
**Option A: Fixed Position (Current)**
|
||||
- Modal in center of screen
|
||||
- **Pros:** Simple, consistent
|
||||
- **Cons:** May cover important content
|
||||
|
||||
**Option B: Dynamic Positioning (Recommended)**
|
||||
- Position near clicked shape
|
||||
- Calculate based on shape coordinates
|
||||
- **Pros:** Better UX, doesn't cover content
|
||||
- **Cons:** More complex
|
||||
|
||||
**Recommendation:** Use dynamic positioning with fallback to center
|
||||
|
||||
```javascript
|
||||
function calculateWidgetPosition(shape, canvas) {
|
||||
const shapeBounds = shape.getBoundingRect();
|
||||
const canvasOffset = canvas.getElement().getBoundingClientRect();
|
||||
|
||||
const x = canvasOffset.left + shapeBounds.left + shapeBounds.width;
|
||||
const y = canvasOffset.top + shapeBounds.top;
|
||||
|
||||
// Check if fits on screen
|
||||
const windowWidth = window.innerWidth;
|
||||
const windowHeight = window.innerHeight;
|
||||
const widgetWidth = 600; // Modal width
|
||||
const widgetHeight = 500; // Estimated modal height
|
||||
|
||||
let finalX = x;
|
||||
let finalY = y;
|
||||
|
||||
if (x + widgetWidth > windowWidth) {
|
||||
finalX = x - widgetWidth - 20; // Position to left
|
||||
}
|
||||
|
||||
if (y + widgetHeight > windowHeight) {
|
||||
finalY = windowHeight - widgetHeight - 20;
|
||||
}
|
||||
|
||||
return { x: finalX, y: finalY };
|
||||
}
|
||||
```
|
||||
|
||||
### 3. API Design
|
||||
|
||||
**RESTful Endpoints:**
|
||||
```
|
||||
POST /api/pdf-editor/joint-data - Save joint data
|
||||
GET /api/pdf-editor/joint-data/{id} - Get joint data
|
||||
PUT /api/pdf-editor/joint-data/{id} - Update joint data
|
||||
DELETE /api/pdf-editor/joint-data/{id} - Delete joint data
|
||||
GET /api/pdf-editor/qualified-welders - Get qualified welders
|
||||
GET /api/pdf-editor/check-weldmap - Check existing weldmap data
|
||||
```
|
||||
|
||||
**Request/Response Format:**
|
||||
```json
|
||||
// POST /api/pdf-editor/joint-data
|
||||
{
|
||||
"drawing_number": "CW-800-AH01JL-FA00.001",
|
||||
"joints": [
|
||||
{
|
||||
"shape_id": "J-001",
|
||||
"joint_no": "53A",
|
||||
"type_of_joint": "F",
|
||||
"welding_date": "2025-01-15",
|
||||
"spool_no1": "SP01",
|
||||
"spool_no2": "SP02",
|
||||
// ... other fields
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// Response
|
||||
{
|
||||
"success": true,
|
||||
"message": "Joint data saved successfully",
|
||||
"data": {
|
||||
"saved_count": 1,
|
||||
"joints": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Database Transactions
|
||||
|
||||
**Best Practice:** Use database transactions for data integrity
|
||||
|
||||
```php
|
||||
public function saveJointData(Request $request): JsonResponse
|
||||
{
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
foreach ($request->joints as $jointData) {
|
||||
WeldLog::updateOrCreate(
|
||||
[
|
||||
'iso_number' => $request->drawing_number,
|
||||
'no_of_the_joint_as_per_as_built_survey' => $jointData['joint_no'],
|
||||
],
|
||||
[
|
||||
// ... field mappings
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
return response()->json(['success' => true]);
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
Log::error('Failed to save joint data', ['error' => $e->getMessage()]);
|
||||
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Welder Qualification Filtering
|
||||
|
||||
**Integration with Existing System:**
|
||||
- Reuse `welder_1.php` autocomplete logic
|
||||
- Filter by material compatibility (MaterialGroupMap)
|
||||
- Filter by welding method
|
||||
- Check expiry dates
|
||||
- Filter by qualification status
|
||||
|
||||
**Implementation:**
|
||||
```php
|
||||
public function getQualifiedWelders(Request $request): JsonResponse
|
||||
{
|
||||
$request->validate([
|
||||
'material_1' => 'required|string',
|
||||
'material_2' => 'required|string',
|
||||
'welding_method' => 'required|string',
|
||||
'joint_type' => 'nullable|string',
|
||||
]);
|
||||
|
||||
// Use existing welder assignment logic
|
||||
$qualifiedWelders = $this->filterQualifiedWelders(
|
||||
$request->material_1,
|
||||
$request->material_2,
|
||||
$request->welding_method
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $qualifiedWelders
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Performance Optimization
|
||||
|
||||
**Client-Side:**
|
||||
- Debounce API calls (300ms)
|
||||
- Cache API responses
|
||||
- Use virtual scrolling for large lists
|
||||
- Lazy load widget modal
|
||||
- Use requestAnimationFrame for animations
|
||||
|
||||
**Server-Side:**
|
||||
- Use database indexes
|
||||
- Implement query caching
|
||||
- Use eager loading for relationships
|
||||
- Implement pagination
|
||||
- Use database transactions efficiently
|
||||
|
||||
### 7. Error Handling
|
||||
|
||||
**Client-Side:**
|
||||
```javascript
|
||||
async function saveJointData(jointData) {
|
||||
try {
|
||||
const response = await fetch('/api/pdf-editor/joint-data', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': csrfToken
|
||||
},
|
||||
body: JSON.stringify(jointData)
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (!result.success) {
|
||||
throw new Error(result.message || 'Failed to save joint data');
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('Error saving joint data:', error);
|
||||
Swal.fire('Error', error.message, 'error');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Server-Side:**
|
||||
```php
|
||||
try {
|
||||
// ... operation
|
||||
} catch (ValidationException $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validation failed',
|
||||
'errors' => $e->errors()
|
||||
], 422);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Joint data save failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'An error occurred while saving joint data'
|
||||
], 500);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
- JointDataManager class methods
|
||||
- API endpoint validation
|
||||
- Database operations
|
||||
- Data mapping functions
|
||||
|
||||
### Integration Tests
|
||||
- Widget open/close flow
|
||||
- Data save/load cycle
|
||||
- API endpoint integration
|
||||
- Database transaction rollback
|
||||
|
||||
### E2E Tests
|
||||
- Complete joint creation flow
|
||||
- Welder assignment flow
|
||||
- Drawing generation from data
|
||||
- Document Revision save
|
||||
|
||||
---
|
||||
|
||||
## 📝 Implementation Checklist
|
||||
|
||||
### Phase 1: Foundation
|
||||
- [ ] Create JointDataManager class
|
||||
- [ ] Enhance joint widget modal
|
||||
- [ ] Add IC Log member selection
|
||||
- [ ] Implement auto-fill logic
|
||||
|
||||
### Phase 2: Integration
|
||||
- [ ] Add shape click handlers
|
||||
- [ ] Implement widget positioning
|
||||
- [ ] Connect widget to data manager
|
||||
- [ ] Update shape labels
|
||||
|
||||
### Phase 3: Backend
|
||||
- [ ] Enhance saveJointData endpoint
|
||||
- [ ] Create getQualifiedWelders endpoint
|
||||
- [ ] Implement Base Weldmap integration
|
||||
- [ ] Implement Weldlog integration
|
||||
|
||||
### Phase 4: Two-Way Sync
|
||||
- [ ] Create check-existing-weldmap endpoint
|
||||
- [ ] Implement left panel activation
|
||||
- [ ] Create drawing from data
|
||||
- [ ] Handle welder display
|
||||
|
||||
### Phase 5: Document Revision
|
||||
- [ ] Implement Spool Iso save
|
||||
- [ ] Implement As-Build save
|
||||
- [ ] Add versioning support
|
||||
|
||||
### Phase 6: Welder Filtering
|
||||
- [ ] Integrate qualification system
|
||||
- [ ] Implement material filtering
|
||||
- [ ] Add expiry date checking
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Next Steps
|
||||
|
||||
1. **Review and approve roadmap**
|
||||
2. **Set up development branch:** `feature/pdf-editor-step3-joint-widget`
|
||||
3. **Start with Phase 1:** Foundation & Data Structure
|
||||
4. **Iterative development:** Test each phase before moving to next
|
||||
5. **Code review:** After each phase completion
|
||||
|
||||
---
|
||||
|
||||
## 📖 References
|
||||
|
||||
- Existing Code:
|
||||
- `app/Http/Controllers/Api/AnnotationController.php`
|
||||
- `app/Http/Controllers/Api/PdfEditorLookupController.php`
|
||||
- `resources/views/components/modals/joint-widget-modal.blade.php`
|
||||
- `app/Http/Controllers/AutoCompleteType/welder-assignment/welder_1.php`
|
||||
|
||||
- Database Tables:
|
||||
- `weld_logs` - Main joint and welder data
|
||||
- `annotations` - PDF shape data
|
||||
- `document_revisions` - PDF file storage
|
||||
- `incoming_control` - IC Log member data
|
||||
- `material_group_map` - Material compatibility
|
||||
- `welder_tests` - Welder qualifications
|
||||
|
||||
---
|
||||
|
||||
**Document Version:** 1.0
|
||||
**Last Updated:** 2025-01-XX
|
||||
**Author:** Development Team
|
||||
|
||||
Reference in New Issue
Block a user