ikinci temizlik tamamlandı

This commit is contained in:
Ümit Tunç
2026-04-28 21:15:09 +03:00
parent f80443aec0
commit 37e7296527
8313 changed files with 2400677 additions and 0 deletions
@@ -0,0 +1,474 @@
# PDF Editor - Database Schema & Data Flow
## Database Table: `annotations`
### Location
- **Migration File**: `database/migrations/2025_09_29_104240_create_annotations_table.php`
- **Updated Migration**: `database/migrations/2025_10_16_131634_update_annotations_shape_type_enum.php`
### Table Structure
```sql
CREATE TABLE annotations (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
pdf_file VARCHAR(255),
page_number INT,
shape_type ENUM('rect', 'circle', 'triangle', 'spool', 'weld', 'shop_weld', 'leader_line', 'text'),
x_coordinate DECIMAL(10,2),
y_coordinate DECIMAL(10,2),
width DECIMAL(10,2),
height DECIMAL(10,2),
shape_id VARCHAR(100),
spool_no VARCHAR(100),
joint_type TEXT,
classification VARCHAR(50),
created_by BIGINT,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
```
### Field Descriptions
| Field | Type | Description | Used For |
|-------|------|-------------|----------|
| `id` | BIGINT | Primary key | Unique identifier |
| `pdf_file` | VARCHAR(255) | PDF file path | Linking annotations to specific PDFs |
| `page_number` | INT | Page number | Multi-page PDF support |
| `shape_type` | ENUM | Type of annotation | rect, circle, triangle, spool, weld, shop_weld, leader_line, text |
| `x_coordinate` | DECIMAL(10,2) | X position | Canvas coordinate (for shapes: top-left, for lines: start point) |
| `y_coordinate` | DECIMAL(10,2) | Y position | Canvas coordinate |
| `width` | DECIMAL(10,2) | Width/Delta X | Shape width or line X distance |
| `height` | DECIMAL(10,2) | Height/Delta Y | Shape height or line Y distance |
| `shape_id` | VARCHAR(100) | Unique shape ID | Cross-referencing (leader lines to shapes, QR codes) |
| `spool_no` | VARCHAR(100) | Spool number | Business data for welding |
| `joint_type` | TEXT | Joint type or text content | Business data for welding OR free text content |
| `classification` | VARCHAR(50) | Annotation category | 'shape_text', 'free_text', etc. |
| `created_by` | BIGINT | User ID | Audit trail |
| `created_at` | TIMESTAMP | Creation time | Audit trail |
| `updated_at` | TIMESTAMP | Update time | Audit trail |
### Special Field Usage
#### Leader Lines
- `shape_type`: 'leader_line'
- `x_coordinate`, `y_coordinate`: Start point (click point)
- `width`: Delta X (x2 - x1)
- `height`: Delta Y (y2 - y1)
- Additional metadata stored in backend:
- `connectedShapeId`: The shape this line connects to
- `originalStartPoint`: Original click coordinates for reconnection
#### Text Annotations
- `shape_type`: 'text'
- `joint_type`: Contains the actual text content
- `classification`:
- 'shape_text': Text inside shapes (red, bold, 28px)
- 'free_text': Standalone notes (black, normal, 16px)
#### Shapes (rect, circle, triangle, etc.)
- Standard coordinate and dimension fields
- `spool_no`: **Business identifier - populated from Spool Number dropdown**
- Rectangle shapes: Display spool_no as text inside shape
- Source: MTO (Material Take-Off) data or manually generated
- Dropdown ID: `#spool-select`
- `joint_type`: **Joint/Weld classification - populated from Weld Number dropdown**
- Triangle/Circle shapes: Display joint_type (weld number) as text inside shape
- Source: MTO welders data or manually entered
- Dropdown ID: `#weld-select`
- `shape_id`: Used for QR code generation and leader line connection
**Shape Type → Data Mapping:**
- **Rectangle** → Uses `spool_no` for text content
- **Triangle** → Uses `joint_type` (weld number) for text content
- **Circle** → Uses `joint_type` (weld number) for text content
---
## Data Population System
### Spool Number (`spool_no` field)
#### What is it?
Spool number is a unique identifier for a spool in piping/welding systems. In the PDF Editor, this value is used to label rectangle shapes.
#### How it's populated:
1. **From MTO Data** (Material Take-Off):
```javascript
// Function: populateMtoForms()
// Populates dropdown from mtoData.spools array
spoolSelect.innerHTML = '<option value="">Select Spool</option>';
mtoData.spools.forEach(spool => {
option.value = spool.spool_number; // e.g., "SP001"
option.textContent = spool.spool_number;
});
```
2. **Auto-Generate**:
- Button: "Generate" next to Spool Number dropdown
- API Call: `GET /api/mto/spools/generate-number`
- Returns: New unique spool number (e.g., "SP123")
3. **Manual Selection**:
- User selects from dropdown: `<select id="spool-select">`
- Value is stored when shape is created
#### When it's used:
- **Rectangle shapes**: Display spool_no inside the shape as red text
- **Shape creation**: Value is read from dropdown and assigned to `shape.spoolNo`
- **Database save**: Stored in `annotations.spool_no` column
#### Code Flow:
```javascript
// 1. User selects spool from dropdown
<select id="spool-select">
<option value="SP001">SP001</option>
<option value="SP002">SP002</option>
</select>
// 2. User draws rectangle with leader line
const spoolSelect = document.getElementById('spool-select');
const spoolNo = spoolSelect.value; // "SP001"
// 3. Shape is created with spool number
shape.set('spoolNo', spoolNo);
// 4. Text is added inside rectangle
textContent = (spoolNo && spoolNo.trim() !== '') ? spoolNo : 'N/A';
// Result: "SP001" displayed in red inside rectangle
// 5. Save to database
annotation = {
spool_no: obj.spoolNo, // "SP001"
shape_type: 'rect',
...
};
```
---
### Weld/Joint Number (`joint_type` field)
#### What is it?
Weld/Joint number is a unique identifier for a weld joint in piping systems. In the PDF Editor, this value is used to label triangle and circle shapes.
#### How it's populated:
1. **From MTO Welders Data**:
```javascript
// Function: populateMtoForms()
// Populates dropdown from mtoData.welders array
weldSelect.innerHTML = '<option value="">Select Weld</option>';
mtoData.welders.forEach(welder => {
option.value = welder.welder_code; // e.g., "W001"
option.textContent = welder.welder_code;
});
```
2. **Auto-Generate**:
- Button: "Generate" next to Weld Number dropdown
- API Call: `GET /api/mto/joints/generate-number?spool_no={spoolNo}`
- Returns: New joint number based on spool (e.g., "J-SP001-001")
3. **Manual Selection**:
- User selects from dropdown: `<select id="weld-select">`
- Value is stored when shape is created
#### When it's used:
- **Triangle shapes**: Display joint_type inside the shape as red text
- **Circle shapes**: Display joint_type inside the shape as red text
- **Shape creation**: Value is read from dropdown and assigned to `shape.weldNo`
- **Database save**: Stored in `annotations.joint_type` column
#### Code Flow:
```javascript
// 1. User selects weld from dropdown
<select id="weld-select">
<option value="W001">W001</option>
<option value="W002">W002</option>
</select>
// 2. User draws triangle with leader line
const weldSelect = document.getElementById('weld-select');
const weldNo = weldSelect.value; // "W001"
// 3. Shape is created with weld number
shape.set('weldNo', weldNo);
// 4. Text is added inside triangle
textContent = (weldNo && weldNo.trim() !== '') ? weldNo : 'N/A';
// Result: "W001" displayed in red inside triangle
// 5. Save to database
annotation = {
joint_type: obj.weldNo, // "W001"
shape_type: 'triangle',
...
};
```
---
### Current Status Issue
**Problem**: `spool_no` field is currently empty in database
**Possible Reasons**:
1. **MTO Data Not Loaded**: `mtoData.spools` array is empty or not fetched
2. **Dropdown Not Selected**: User is creating shapes without selecting spool/weld number
3. **Sample Data**: System falls back to sample data (SP001, SP002, SP003) if MTO data is missing
4. **API Integration**: MTO API endpoints might not be returning data
**How to Fix**:
1. Check MTO data loading in browser console
2. Ensure dropdown has options before creating shapes
3. Select spool/weld number from dropdown before drawing
4. Verify API endpoints are working:
- `/api/mto/spools/generate-number`
- `/api/mto/joints/generate-number`
**Testing**:
```javascript
// Open browser console on PDF Editor page
console.log('MTO Data:', mtoData);
console.log('Spools:', mtoData.spools);
console.log('Welders:', mtoData.welders);
// Check dropdown values
const spoolSelect = document.getElementById('spool-select');
console.log('Spool options:', Array.from(spoolSelect.options).map(o => o.value));
```
---
## API Endpoints
### 1. Save/Sync Annotations
**Endpoint**: `POST /api/pdf-editor/annotations/sync`
**Controller**: `app/Http/Controllers/Api/AnnotationController.php` → `syncAnnotations()`
**Request Body**:
```json
{
"pdf_file": "path/to/file.pdf",
"page_number": 1,
"annotations": [
{
"shape_id": "shape-1729612345678",
"spool_no": "SP-001",
"joint_type": "Butt Weld",
"classification": "",
"page_number": 1,
"x_coordinate": 100,
"y_coordinate": 200,
"width": 140,
"height": 70,
"shape_type": "rect",
"pdf_file_path": "path/to/file.pdf",
"created_by": 1
},
{
"shape_id": "leader-1729612345680",
"shape_type": "leader_line",
"x_coordinate": 150,
"y_coordinate": 180,
"width": 0,
"height": 50,
"connectedShapeId": "shape-1729612345678",
"originalStartPoint": {"x": 150, "y": 180}
}
]
}
```
**Response**:
```json
{
"success": true,
"message": "Annotations synced successfully",
"data": {
"deleted": 2,
"created": 5
}
}
```
**Logic**:
1. Deletes all existing annotations for the specific PDF page
2. Inserts all new annotations from the request
3. Transaction-based for data integrity
---
### 2. Load Annotations
**Endpoint**: `GET /api/pdf-editor/annotations?pdf_file={path}&page_number={num}`
**Controller**: `app/Http/Controllers/Api/AnnotationController.php` → `index()`
**Response**:
```json
{
"success": true,
"data": [
{
"id": 123,
"pdf_file": "path/to/file.pdf",
"page_number": 1,
"shape_type": "triangle",
"x_coordinate": 300,
"y_coordinate": 400,
"width": 140,
"height": 140,
"shape_id": "shape-1729612345690",
"spool_no": "SP-002",
"joint_type": "Fillet",
"classification": "",
"created_by": 1,
"created_at": "2025-10-22 10:30:00",
"updated_at": "2025-10-22 10:30:00"
}
]
}
```
---
### 3. Generate QR Code
**Endpoint**: `GET /api/pdf-editor/qr-code/{shapeId}`
**Controller**: `app/Http/Controllers/Api/AnnotationController.php` → `generateQRCode()`
**Response**: PNG image data (base64 or binary)
**Used For**: Generating QR codes for shape annotations
---
## Data Flow Diagram
```
┌─────────────────────────────────────────────────────────────┐
│ PDF EDITOR FRONTEND │
│ (pdf-editor.blade.php) │
└─────────────────────────────────────────────────────────────┘
│ User draws shapes,
│ adds text, creates
│ leader lines
┌─────────────────────────────────────────────────────────────┐
│ FABRIC.JS CANVAS │
│ - Shapes (rect, circle, triangle) │
│ - Leader Lines (connecting click point to shape edge) │
│ - Text Objects (free text notes + shape text) │
│ - QR Codes (linked to shapes) │
└─────────────────────────────────────────────────────────────┘
│ Save button clicked
┌─────────────────────────────────────────────────────────────┐
│ saveCurrentPageAnnotations() │
│ - Iterates through all canvas objects │
│ - Skips QR codes (not saved) │
│ - Converts shapes, lines, text to annotation format │
│ - Prepares JSON payload │
└─────────────────────────────────────────────────────────────┘
│ POST /api/pdf-editor/annotations/sync
┌─────────────────────────────────────────────────────────────┐
│ API: AnnotationController@syncAnnotations │
│ 1. Validates request data │
│ 2. Starts database transaction │
│ 3. Deletes old annotations for this page │
│ 4. Inserts new annotations │
│ 5. Commits transaction │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ DATABASE TABLE │
│ `annotations` │
│ - All annotations stored with coordinates, types, metadata │
└─────────────────────────────────────────────────────────────┘
│ Page reload or PDF selection
│ GET /api/pdf-editor/annotations
┌─────────────────────────────────────────────────────────────┐
│ API: AnnotationController@index │
│ - Fetches annotations for specified PDF + page │
│ - Returns JSON array │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ loadExistingAnnotations() │
│ - Receives annotation data from API │
│ - Calls loadAnnotationToCanvas() for each │
│ - Recreates shapes, lines, text on canvas │
│ - Calls reconnectLeaderLines() to re-establish connections │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ FABRIC.JS CANVAS │
│ - All annotations restored │
│ - Leader lines connected to shapes │
│ - QR codes regenerated via API │
└─────────────────────────────────────────────────────────────┘
```
---
## Key Implementation Details
### Triangle Leader Line Connection
- **Challenge**: Triangles have different geometry than rectangles/circles
- **Solution**: Custom `calculateEdgePoint()` function in `setupConnectedMovement()`
- Calculates triangle vertices and edges
- Determines closest edge/vertex based on original click position
- Connects leader line to appropriate edge point
- Handles rotation, scaling, and movement events
### Unique Shape IDs
- Generated using `Date.now()` to ensure uniqueness across page reloads
- Format: `shape-{timestamp}`, `leader-{timestamp}`, `text-{timestamp}`
- Prevents database conflicts when saving new annotations
### Text Handling
- **Shape Text**: Red, bold, 28px, positioned inside shapes, non-selectable
- **Free Text**: Black, normal, 16px, standalone notes, selectable
- Both saved to same table with different `classification` values
### Leader Line Storage
- Start point stored as `x_coordinate`, `y_coordinate`
- End point calculated using `width` and `height` deltas
- Metadata (`connectedShapeId`, `originalStartPoint`) preserved for reconnection
---
## Validation Rules
```php
// app/Http/Controllers/Api/AnnotationController.php
'annotations' => 'required|array',
'annotations.*.shape_type' => 'required|in:rect,circle,triangle,spool,weld,shop_weld,leader_line,text',
'annotations.*.x_coordinate' => 'required|numeric',
'annotations.*.y_coordinate' => 'required|numeric',
'annotations.*.width' => 'nullable|numeric',
'annotations.*.height' => 'nullable|numeric',
'annotations.*.shape_id' => 'required|string',
'annotations.*.page_number' => 'required|integer',
```
---
## Future Enhancements
- Add annotation history/versioning
- Implement collaborative editing with user tracking
- Add annotation comments/notes
- Support for more shape types
- Advanced leader line routing (avoid overlaps)