plugin distribution system
This commit is contained in:
107
backend/igny8_core/plugins/migrations/0001_initial.py
Normal file
107
backend/igny8_core/plugins/migrations/0001_initial.py
Normal file
@@ -0,0 +1,107 @@
|
||||
# Generated by Django 5.2.10 on 2026-01-09 20:27
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('igny8_core_auth', '0020_fix_historical_account'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Plugin',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(help_text="Human-readable plugin name (e.g., 'IGNY8 WP Bridge')", max_length=100)),
|
||||
('slug', models.SlugField(help_text="URL-safe identifier (e.g., 'igny8-wp-bridge')", unique=True)),
|
||||
('platform', models.CharField(choices=[('wordpress', 'WordPress'), ('shopify', 'Shopify'), ('custom', 'Custom Site')], help_text='Target platform for this plugin', max_length=20)),
|
||||
('description', models.TextField(blank=True, help_text='Plugin description for display in download pages')),
|
||||
('homepage_url', models.URLField(blank=True, help_text='Plugin homepage or documentation URL')),
|
||||
('is_active', models.BooleanField(db_index=True, default=True, help_text='Whether this plugin is available for download')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Plugin',
|
||||
'verbose_name_plural': 'Plugins',
|
||||
'db_table': 'plugins',
|
||||
'ordering': ['name'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PluginVersion',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('version', models.CharField(help_text="Semantic version string (e.g., '1.0.0', '1.0.1')", max_length=20)),
|
||||
('version_code', models.IntegerField(help_text='Numeric version for comparison (1.0.1 -> 10001)')),
|
||||
('status', models.CharField(choices=[('draft', 'Draft'), ('testing', 'Testing'), ('staged', 'Staged'), ('released', 'Released'), ('update_ready', 'Update Ready'), ('deprecated', 'Deprecated')], db_index=True, default='draft', help_text='Release status of this version', max_length=20)),
|
||||
('file_path', models.CharField(help_text='Relative path to ZIP file in dist/ directory', max_length=500)),
|
||||
('file_size', models.IntegerField(default=0, help_text='File size in bytes')),
|
||||
('checksum', models.CharField(blank=True, help_text='SHA256 checksum for integrity verification', max_length=64)),
|
||||
('changelog', models.TextField(blank=True, help_text="What's new in this version (supports Markdown)")),
|
||||
('min_api_version', models.CharField(default='1.0', help_text='Minimum IGNY8 API version required', max_length=20)),
|
||||
('min_platform_version', models.CharField(blank=True, help_text='Minimum platform version (e.g., WordPress 5.0)', max_length=20)),
|
||||
('min_php_version', models.CharField(default='7.4', help_text='Minimum PHP version required (for WordPress plugins)', max_length=10)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('released_at', models.DateTimeField(blank=True, help_text='When this version was released', null=True)),
|
||||
('force_update', models.BooleanField(default=False, help_text='Force update for critical security fixes')),
|
||||
('plugin', models.ForeignKey(help_text='Plugin this version belongs to', on_delete=django.db.models.deletion.CASCADE, related_name='versions', to='plugins.plugin')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Plugin Version',
|
||||
'verbose_name_plural': 'Plugin Versions',
|
||||
'db_table': 'plugin_versions',
|
||||
'ordering': ['-version_code'],
|
||||
'unique_together': {('plugin', 'version')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PluginInstallation',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('is_active', models.BooleanField(db_index=True, default=True, help_text='Whether the plugin is currently active')),
|
||||
('last_health_check', models.DateTimeField(blank=True, help_text='Last successful health check timestamp', null=True)),
|
||||
('health_status', models.CharField(choices=[('healthy', 'Healthy'), ('outdated', 'Outdated'), ('error', 'Error'), ('unknown', 'Unknown')], default='unknown', help_text='Current health status', max_length=20)),
|
||||
('update_notified_at', models.DateTimeField(blank=True, help_text='When site was notified about pending update', null=True)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('plugin', models.ForeignKey(help_text='Installed plugin', on_delete=django.db.models.deletion.CASCADE, related_name='installations', to='plugins.plugin')),
|
||||
('site', models.ForeignKey(help_text='Site where plugin is installed', on_delete=django.db.models.deletion.CASCADE, related_name='plugin_installations', to='igny8_core_auth.site')),
|
||||
('current_version', models.ForeignKey(help_text='Currently installed version', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='current_installations', to='plugins.pluginversion')),
|
||||
('pending_update', models.ForeignKey(blank=True, help_text='Pending version update', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='pending_installations', to='plugins.pluginversion')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Plugin Installation',
|
||||
'verbose_name_plural': 'Plugin Installations',
|
||||
'db_table': 'plugin_installations',
|
||||
'ordering': ['-updated_at'],
|
||||
'unique_together': {('site', 'plugin')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PluginDownload',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('ip_address', models.GenericIPAddressField(blank=True, null=True)),
|
||||
('user_agent', models.CharField(blank=True, max_length=500)),
|
||||
('download_type', models.CharField(choices=[('manual', 'Manual Download'), ('update', 'Auto Update'), ('api', 'API Download')], default='manual', max_length=20)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('account', models.ForeignKey(blank=True, help_text='Account that initiated the download', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plugin_downloads', to='igny8_core_auth.account')),
|
||||
('plugin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='downloads', to='plugins.plugin')),
|
||||
('site', models.ForeignKey(blank=True, help_text='Site that initiated the download (if authenticated)', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plugin_downloads', to='igny8_core_auth.site')),
|
||||
('version', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='downloads', to='plugins.pluginversion')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Plugin Download',
|
||||
'verbose_name_plural': 'Plugin Downloads',
|
||||
'db_table': 'plugin_downloads',
|
||||
'ordering': ['-created_at'],
|
||||
'indexes': [models.Index(fields=['plugin', 'created_at'], name='plugin_down_plugin__5771ff_idx'), models.Index(fields=['version', 'created_at'], name='plugin_down_version_2bcf49_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
0
backend/igny8_core/plugins/migrations/__init__.py
Normal file
0
backend/igny8_core/plugins/migrations/__init__.py
Normal file
Reference in New Issue
Block a user