# Linker Module

**Last Verified:** December 25, 2025  
**Status:** ⏸️ Inactive (Disabled by Default)  
**Backend Path:** `backend/igny8_core/modules/linker/`  
**Frontend Path:** `frontend/src/pages/Linker/`

---

## Module Status

| Aspect | Current State | Notes |
|--------|---------------|-------|
| Backend API | ✅ Implemented | Endpoints functional |
| Frontend Pages | ✅ Implemented | UI exists |
| Sidebar Nav | ⚠️ Conditional | Hidden when disabled |
| Route Protection | ❌ Not Protected | Direct URL access still works |
| Dashboard References | ❌ Not Hidden | May show in dashboard |
| Default State | Disabled | `linker_enabled = True` in model, but typically disabled |

**⚠️ Pending Implementation:** Extend module disable to route-level protection and all page references.

---

## Quick Reference

| What | File | Key Items |
|------|------|-----------|
| Views | `modules/linker/views.py` | `LinkerViewSet` |
| API | `modules/linker/urls.py` | Linker endpoints |
| Frontend Pages | `pages/Linker/index.tsx` | Linker overview |
| Frontend Pages | `pages/Linker/LinkerContent.tsx` | Content for linking |
| API Client | `api/linker.api.ts` | `linkerApi` |
| Module Control | `modules/system/settings_models.py` | `ModuleEnableSettings.linker_enabled` |

---

## Purpose

The Linker module provides internal linking automation:
- Identify link opportunities in content
- Suggest relevant internal links
- Auto-inject links into content body

---

## API Endpoints

| Method | Path | Handler | Purpose |
|--------|------|---------|---------|
| POST | `/api/v1/linker/process/` | `LinkerViewSet.process` | Process single content for linking |
| POST | `/api/v1/linker/batch_process/` | `LinkerViewSet.batch_process` | Process multiple content items |

### Process Request

```json
{
  "content_id": 123,
  "max_links": 5,
  "anchor_strategy": "exact_match"
}
```

### Process Response

```json
{
  "content_id": 123,
  "links_added": 3,
  "link_opportunities": [
    {
      "anchor_text": "SEO optimization",
      "target_url": "/blog/seo-guide/",
      "target_content_id": 456,
      "position": 234,
      "confidence": 0.85
    }
  ]
}
```

---

## Business Logic

### Link Candidate Discovery

**Trigger:** User initiates linking process  
**Flow:**
1. Load source content body
2. Extract potential anchor phrases
3. Find matching content by:
   - Keyword overlap
   - Title similarity
   - Same sector/industry
4. Score candidates by relevance
5. Filter to avoid over-linking

### Link Injection

**Trigger:** User approves link suggestions  
**Flow:**
1. Locate anchor text in content
2. Wrap in `<a>` tag with target URL
3. Ensure no nested links
4. Save updated content body

---

## Module Enable Control

### Backend Model

```python
# modules/system/settings_models.py
class ModuleEnableSettings(AccountBaseModel):
    linker_enabled = models.BooleanField(default=True)
```

### Frontend Check

```typescript
// layout/AppSidebar.tsx
if (isModuleEnabled('linker')) {
  workflowItems.push({
    name: "Linker",
    path: "/linker/content",
  });
}
```

### Current Limitation

Direct URL access to `/linker/*` routes still works even when module is disabled.

---

## Frontend Pages

### Linker Overview (`/linker`)

- Module overview
- Quick stats
- Start linking action

### Content for Linking (`/linker/content`)

- List of content available for linking
- Link status indicators
- Process button per content
- Batch processing action

---

## Integration Points

| From | To | Trigger |
|------|----|---------| 
| Content | Linker | Manual process |
| Linker | Content | Link injection |
| Automation | Linker | Automated linking (future) |

---

## Common Issues

| Issue | Cause | Fix |
|-------|-------|-----|
| Module visible when disabled | Only sidebar hidden | Pending: route protection |
| No link candidates | No matching content | Create more related content |
| Links broken | Target content deleted | Validate target exists |

---

## Planned Changes

| Feature | Status | Description |
|---------|--------|-------------|
| Route-level protection | 🔜 Pending | Block access when module disabled |
| Dashboard card hiding | 🔜 Pending | Hide from dashboard when disabled |
| Automation integration | 🔜 Planned | Add to automation pipeline |
| Link density control | 🔜 Planned | Prevent over-linking |
| External link support | 🔜 Planned | Add outbound links |
