← back to Jill Website
docs/LINK_VALIDATION.md
289 lines
# Link Validation System
## Overview
The Link Validation System automatically checks all external links in the application to ensure they remain functional. It monitors property Airbnb URLs, property images, and activity website/maps/review links.
## Features
- **Automated Daily Checks**: Script can be run via cron to check all links daily
- **HTTP Status Tracking**: Records HTTP status codes for each link
- **Error Reporting**: Captures detailed error messages for broken links
- **Performance Monitoring**: Tracks response time for each link check
- **Manual Re-check**: API endpoints allow on-demand link validation
- **Admin Interface Ready**: Results stored in database for display in admin dashboard
## Database Schema
The `link_checks` table stores validation results:
```sql
- id: Primary key
- url: The URL being checked
- source_type: Type of source (property, activity_website, property_image, etc.)
- source_id: ID of the source record
- http_status: HTTP status code (200, 404, etc.)
- is_valid: Boolean indicating if link is accessible
- error_message: Error description if check failed
- response_time_ms: Response time in milliseconds
- last_checked_at: Timestamp of last check
- created_at: Record creation timestamp
- updated_at: Record update timestamp
```
## API Endpoints
### GET /api/link-validation/stats
Get overall link validation statistics.
**Response:**
```json
{
"success": true,
"data": {
"total": 150,
"valid": 145,
"invalid": 5,
"avgResponseTime": 342.5
}
}
```
### GET /api/link-validation/broken
Get all broken links with pagination.
**Query Parameters:**
- `limit` (default: 100): Number of results to return
- `offset` (default: 0): Number of results to skip
**Response:**
```json
{
"success": true,
"data": [
{
"id": 1,
"url": "https://example.com/broken",
"source_type": "property",
"source_id": 1,
"http_status": 404,
"is_valid": false,
"error_message": "HTTP 404: Not Found",
"response_time_ms": 234,
"last_checked_at": "2025-01-14T12:00:00Z"
}
],
"count": 5
}
```
### GET /api/link-validation/all
Get all link check records with pagination.
**Query Parameters:**
- `limit` (default: 100)
- `offset` (default: 0)
### POST /api/link-validation/check-all
Manually trigger a full validation check of all links in the system.
**Response:**
```json
{
"success": true,
"message": "Link validation completed",
"data": {
"total": 150,
"valid": 145,
"invalid": 5,
"results": [...]
}
}
```
### POST /api/link-validation/check-url
Check a single URL on demand.
**Request Body:**
```json
{
"url": "https://example.com/page"
}
```
**Response:**
```json
{
"success": true,
"data": {
"url": "https://example.com/page",
"isValid": true,
"httpStatus": 200,
"responseTimeMs": 234
}
}
```
## Automated Script
### Running Manually
Check all links manually:
```bash
ts-node scripts/check-links.ts
```
### Setting Up Daily Automation
Add to crontab for daily execution at 2 AM:
```bash
crontab -e
```
Add this line:
```
0 2 * * * cd /root/Projects/jill-website && ts-node scripts/check-links.ts >> /var/log/link-checks.log 2>&1
```
Or using Node directly (after build):
```
0 2 * * * cd /root/Projects/jill-website && node dist/scripts/check-links.js >> /var/log/link-checks.log 2>&1
```
### Script Output
The script provides detailed console output:
```
🔍 Starting link validation...
📦 Checking property links...
- Property: Casita del Sol (ID: 1)
✅ Airbnb URL valid (200)
- Property: Ocean View Villa (ID: 2)
❌ Airbnb URL failed: Connection timeout
🎯 Checking activity links...
- Activity: Surfing Lessons (ID: 1)
✅ Website valid (200)
✅ Maps link valid (200)
============================================================
📊 LINK VALIDATION SUMMARY
============================================================
Total links checked: 150
Valid links: 145 (96.7%)
Invalid links: 5 (3.3%)
Duration: 45.2s
Breakdown by source:
property:
Total: 10
Valid: 10
Invalid: 0
property_image:
Total: 120
Valid: 115
Invalid: 5
activity_website:
Total: 20
Valid: 20
Invalid: 0
============================================================
```
## Link Types Checked
### Properties
- **Airbnb URLs** (`source_type: 'property'`)
- **Image URLs** (`source_type: 'property_image'`)
### Activities
- **Website URLs** (`source_type: 'activity_website'`)
- **Google Maps Links** (`source_type: 'activity_maps'`)
- **Review Links** (`source_type: 'activity_review'`)
## Error Handling
The system captures various types of errors:
- **Connection timeout**: Link took too long to respond
- **Domain not found**: DNS lookup failed
- **Connection refused**: Server refused connection
- **HTTP 4xx/5xx**: Server returned error status
- **Network error**: General network issues
## Performance Considerations
- Links are checked sequentially to avoid overwhelming servers
- Default timeout: 10 seconds per link
- Maximum redirects: 5
- Uses HEAD requests (lighter than GET)
- Includes user agent to avoid bot blocking
## Future Enhancements
Potential improvements for future iterations:
1. **Email Notifications**: Send alerts when broken links are detected
2. **Admin Dashboard**: Visual interface showing link health
3. **Link History**: Track link status changes over time
4. **Bulk Operations**: Pause/resume link checking
5. **Priority Checking**: Check critical links more frequently
6. **Retry Logic**: Automatic retries for transient failures
7. **Integration Tests**: Verify link checking functionality
## Migration
To set up the database table, run:
```bash
npm run migrate
```
This will execute `src/migrations/005_create_link_checks_table.sql`.
## Testing
The link validation service can be tested independently:
```typescript
import { linkValidationService } from './services/linkValidationService';
// Check single URL
const result = await linkValidationService.checkLink('https://example.com');
console.log(result);
// { url: '...', isValid: true, httpStatus: 200, responseTimeMs: 234 }
// Check multiple URLs
const results = await linkValidationService.checkLinks([
'https://example1.com',
'https://example2.com'
]);
```
## Troubleshooting
### Script Not Running
- Check cron job is configured: `crontab -l`
- Verify TypeScript is installed: `npm install -g ts-node`
- Check logs: `tail -f /var/log/link-checks.log`
### Database Connection Errors
- Ensure `.env` has correct database credentials
- Verify database is running: `sudo systemctl status postgresql`
- Run migrations: `npm run migrate`
### Timeouts on All Links
- Check network connectivity
- Verify firewall allows outbound HTTPS requests
- Increase timeout in `linkValidationService.ts` if needed
## Support
For issues or questions about the link validation system, contact the development team or check the main project documentation.