# Associated Tags Controller Documentation

**File**: `/controllers/associatedtag.php`  
**Purpose**: Manages product and document tags for categorization and search functionality  
**Last Updated**: December 20, 2024  
**Total Functions**: 7 actions  
**Lines of Code**: ~104

---

## 📋 Overview

The Associated Tags Controller is a lightweight tagging system that enables flexible categorization and labeling of products, documents, or other entities. It provides:
- Simple tag creation and management
- Tag search and autocomplete functionality  
- Soft delete capability (conditions-based)
- AJAX-powered tag suggestions
- JSON API endpoints for frontend integration
- User-specific tag ownership tracking

### Primary Functions
- [x] Create new tags with names
- [x] Edit existing tag names
- [x] Soft delete tags (set conditions = 1)
- [x] List all active tags
- [x] AJAX autocomplete search API
- [x] User ownership tracking
- [x] Date stamping for audit trails

### Related Controllers
- [productController.php](productController.md) - Product tagging
- [sellbillController.php](sellbillController.md) - Document tagging
- [buyBillController.php](buyBillController.md) - Purchase order tagging

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **associatedtags** | Tag master data | id, tagname, today, conditions, userid |

### Table Structure
```sql
CREATE TABLE associatedtags (
    id INT PRIMARY KEY AUTO_INCREMENT,
    tagname VARCHAR(255) NOT NULL,
    today DATETIME NOT NULL,
    conditions TINYINT DEFAULT 0,  -- 0=active, 1=deleted
    userid INT NOT NULL
);
```

---

## 🔑 Key Functions

### 1. **Default Action** - Add Tag Form  
**Location**: Lines 18-22  
**Purpose**: Display simple form to create new tags

**Process Flow**:
1. Load header template
2. Display add form template
3. Load footer template
4. No authentication required (open access)

**Template**: `associatedtagview/add.html`

---

### 2. **show** - List All Tags
**Location**: Lines 22-28  
**Purpose**: Display all active tags in tabular format

**Process Flow**:
1. Authenticate user access
2. Query all tags where `conditions = 0`
3. Assign tags to template
4. Display with header/footer

**SQL Query**:
```sql
SELECT associatedtags.* FROM `associatedtags` WHERE conditions = 0
```

**Template**: `associatedtagview/show.html`

---

### 3. **edit** - Load Tag for Editing
**Location**: Lines 29-36  
**Purpose**: Load specific tag data for modification

**Process Flow**:
1. Authenticate user access  
2. Get tag ID from GET parameter with filtering
3. Load tag record using RedBean ORM
4. Assign to edit template
5. Display edit form

**Security**: Uses `filter_input(INPUT_GET, 'id')` for sanitization

**Template**: `associatedtagview/edit.html`

---

### 4. **add** - Create New Tag
**Location**: Lines 37-50  
**Purpose**: Process new tag creation from form submission

**Process Flow**:
1. Extract tag name from POST with filtering
2. Create new RedBean dispense object
3. Set tag properties (name, date, user, status)
4. Store in database
5. Redirect to success or error page

**RedBean Operations**:
```php
$associatedtags = R::dispense('associatedtags');
$associatedtags->today = $today;
$associatedtags->conditions = 0;        
$associatedtags->userid = $userid;
$associatedtags->tagname = $tagname;
R::store($associatedtags);
```

---

### 5. **update** - Modify Existing Tag  
**Location**: Lines 51-64  
**Purpose**: Update tag name and metadata

**Process Flow**:
1. Get tag name and ID from POST with filtering
2. Load existing tag record
3. Update properties (name, date, user)
4. Store changes to database
5. Redirect to success or error page

**Key Difference**: Preserves original `conditions` value, only updates name and audit fields

---

### 6. **del** - Soft Delete Tag
**Location**: Lines 65-75  
**Purpose**: Deactivate tag without removing historical data

**Process Flow**:
1. Get tag ID from GET parameter
2. Load tag record  
3. Set `conditions = 1` (soft delete)
4. Store updated record
5. Redirect to success or error page

**Soft Delete Logic**:
```php
$associatedtags = R::load('associatedtags', $id);
$associatedtags->conditions = 1;    
R::store($associatedtags);
```

---

### 7. **getTags** - AJAX Autocomplete API
**Location**: Lines 76-89  
**Purpose**: Provide JSON API for tag search and autocomplete

**Function Signature**:
```php
// GET Parameters:
// term - Search term for tag name
// page_limit - Maximum results to return (integer)
```

**Process Flow**:
1. Extract search term and limit from GET
2. Query tags with LIKE matching on name
3. Format results as JSON array with id/text pairs
4. Return JSON response for frontend consumption

**SQL Query**:
```sql
SELECT * FROM associatedtags 
WHERE conditions = 0 
AND tagname LIKE "%{term}%" 
LIMIT {page_limit}
```

**JSON Response Format**:
```json
[
    {"id": 1, "text": "Electronics"},
    {"id": 2, "text": "Clothing"},  
    {"id": 3, "text": "Books"}
]
```

---

## 🔄 Workflows

### Workflow 1: Tag Creation and Usage
```
┌─────────────────────────────────────────────────────────────┐
│                 START: Need New Tag                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Access Tag Management                                   │
│     - Navigate to associatedtag.php                        │
│     - View simple add form                                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Create Tag                                              │
│     - Enter descriptive tag name                           │
│     - Submit form (do=add)                                  │
│     - System auto-assigns userid and timestamp             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Tag Available for Use                                   │
│     - Tag appears in listings (do=show)                    │
│     - Available in autocomplete APIs                       │
│     - Can be associated with products/documents            │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: AJAX Tag Search Integration
```
┌─────────────────────────────────────────────────────────────┐
│            START: Frontend Needs Tag Suggestions           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. User Types in Search Field                             │
│     - Frontend JavaScript captures keystrokes              │
│     - Builds search term from user input                   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. AJAX Request to getTags                                 │
│     - GET: ?do=getTags&term=searchtext&page_limit=10       │
│     - Controller queries database with LIKE match          │
│     - Returns JSON array of matching tags                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Frontend Displays Suggestions                          │
│     - Parse JSON response                                   │
│     - Populate dropdown/autocomplete list                  │
│     - Allow user selection                                  │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Description | Authentication | Response |
|---------------|------------|----------------|----------|
| `do=` (empty) | Show add tag form | No | HTML form |
| `do=show` | List all active tags | Yes | HTML table |
| `do=edit&id=X` | Edit specific tag | Yes | HTML form |
| `do=add` | Create new tag | No | Redirect |
| `do=update` | Update existing tag | No | Redirect |
| `do=del&id=X` | Soft delete tag | No | Redirect |
| `do=getTags&term=X&page_limit=N` | AJAX search API | No | JSON |
| `do=sucess` | Success message | No | HTML |
| `do=error` | Error message | No | HTML |

### Required Parameters by Action

**Create Tag** (`do=add`):
- `tagname` - Tag name/label

**Update Tag** (`do=update`):
- `tagname` - Updated tag name
- `id` - Tag ID to update

**Delete Tag** (`do=del`):
- `id` - Tag ID to deactivate

**Search Tags** (`do=getTags`):
- `term` - Search string for tag name matching
- `page_limit` - Maximum results (integer)

---

## 🔒 Security & Permissions

### Authentication Matrix
```
Action          | Auth Required | User Restrictions
----------------|---------------|------------------
Add Form        | No            | Open access
Show Tags       | Yes           | View all tags  
Edit Tag        | Yes           | Edit any tag
Create Tag      | No            | Auto-assign userid
Update Tag      | No            | No ownership check
Delete Tag      | No            | Delete any tag
AJAX Search     | No            | Public API
```

### Input Sanitization
- **GET Parameters**: Uses `filter_input()` for ID and search terms
- **POST Parameters**: Uses `filter_input(INPUT_POST)` for tag names
- **SQL Injection**: Protected by RedBean ORM parameterized queries

### Business Rules
1. **Tag Names**: No length limits enforced in code
2. **Soft Delete**: Uses conditions flag instead of physical deletion
3. **User Ownership**: Records creating user but no access restrictions
4. **Public API**: AJAX search endpoint has no authentication

---

## 🧮 Integration Points

### Frontend Integration
```javascript
// Example autocomplete integration
$.ajax({
    url: 'associatedtag.php?do=getTags',
    data: {
        term: searchTerm,
        page_limit: 10
    },
    success: function(data) {
        // data is array of {id, text} objects
        populateDropdown(JSON.parse(data));
    }
});
```

### Product Tagging Integration
```php
// Example usage in product forms
$tagIds = $_POST['tagids']; // Array of selected tag IDs
$tagString = is_array($tagIds) ? implode(',', $tagIds) : '';
$product->tags = $tagString; // Store as comma-separated IDs
```

---

## 📊 Performance Considerations

### Database Optimization
1. **Indexes Needed**:
   - `associatedtags(conditions)` - For active tag filtering
   - `associatedtags(tagname)` - For search performance  
   - `associatedtags(userid)` - For user-specific queries

2. **Query Optimization**:
   - LIKE queries can be slow on large datasets
   - Consider full-text indexing for better search
   - Limit results with reasonable page_limit values

### Caching Opportunities
- Frequently used tags could be cached
- AJAX search results suitable for browser caching
- Tag dropdown lists can be cached per user session

---

## 🐛 Common Issues & Troubleshooting

### 1. **AJAX Search Not Working**
**Issue**: Autocomplete returns no results  
**Cause**: Search term contains special characters or query limit too low

**Debug**:
```sql
-- Test search query manually
SELECT * FROM associatedtags 
WHERE conditions = 0 
AND tagname LIKE '%searchterm%' 
LIMIT 10;
```

### 2. **Tags Disappear from Lists**
**Issue**: Tags not showing in dropdown  
**Cause**: Tags soft-deleted (conditions = 1)

**Fix**:
```sql
-- Check tag status
SELECT id, tagname, conditions FROM associatedtags WHERE id = ?;

-- Reactivate if needed
UPDATE associatedtags SET conditions = 0 WHERE id = ?;
```

### 3. **Duplicate Tags Created**
**Issue**: Multiple tags with same name  
**Cause**: No uniqueness constraint in database

**Prevention**:
```sql
-- Add unique constraint
ALTER TABLE associatedtags 
ADD CONSTRAINT uk_tagname_active 
UNIQUE KEY (tagname, conditions);
```

---

## 🧪 Testing Scenarios

### Test Case 1: Basic Tag Management
```
1. Access tag add form (no auth required)
2. Create tag with descriptive name
3. Verify tag appears in listing (requires auth)
4. Edit tag name
5. Verify changes saved
6. Soft delete tag
7. Confirm tag no longer appears in active lists
```

### Test Case 2: AJAX Search API
```
1. Create several test tags with related names
2. Test search with partial matches
3. Verify JSON response format
4. Test with special characters in search
5. Test pagination with page_limit parameter
6. Verify only active tags returned
```

### Test Case 3: Integration Testing
```
1. Create tags via management interface
2. Test tag selection in product forms
3. Verify tag associations save correctly
4. Test tag search in product filters
5. Confirm tag deletion doesn't break references
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [productController.php](productController.md) - Product tagging integration
- [Database Schema Documentation](#) - Table relationships

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When major changes occur