Coverage for product_risk_suite/scraper/migrations/0001_initial.py: 100%
6 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-16 14:44 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-16 14:44 +0000
1# Generated by Django 6.0.6 on 2026-07-13 13:59
3import django.db.models.deletion
4from django.db import migrations, models
7class Migration(migrations.Migration):
9 initial = True
11 dependencies = [
12 ('risk_assessment', '0014_evidence_last_scrape_failed_and_more'),
13 ]
15 operations = [
16 migrations.CreateModel(
17 name='RemoteCredential',
18 fields=[
19 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20 ('name', models.CharField(help_text='Human identifier, referenced by Scrapers.', max_length=100, unique=True)),
21 ('url', models.URLField(help_text='Base URL of the remote system, e.g. https://openproject.example.com')),
22 ('auth_type', models.CharField(choices=[('basic', 'Username / password'), ('token', 'API token')], default='basic', max_length=10)),
23 ('username', models.CharField(blank=True, max_length=150)),
24 ('_password_enc', models.CharField(blank=True, db_column='password_enc', max_length=500)),
25 ('_api_token_enc', models.CharField(blank=True, db_column='api_token_enc', max_length=500)),
26 ],
27 ),
28 migrations.CreateModel(
29 name='Scraper',
30 fields=[
31 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
32 ('name', models.CharField(max_length=100, unique=True)),
33 ('response_format', models.CharField(choices=[('json', 'JSON'), ('html', 'HTML')], default='json', max_length=10)),
34 ('assignee_path', models.CharField(help_text="JSON: dotted/indexed path, e.g. 'assignee.name' or 'fields[0].assignee'. HTML: a CSS selector, optionally suffixed '::attr(name)' to read an attribute instead of text.", max_length=255)),
35 ('status_path', models.CharField(help_text='Same syntax as assignee path. The extracted raw value is mapped to a local Status via the mappings below.', max_length=255)),
36 ('extra_headers', models.JSONField(blank=True, default=dict, help_text='Optional extra HTTP headers.')),
37 ('credential', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='scrapers', to='scraper.remotecredential')),
38 ],
39 ),
40 migrations.CreateModel(
41 name='ScraperStatusMapping',
42 fields=[
43 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
44 ('remote_value', models.CharField(help_text='Exact status value as returned by the remote system.', max_length=255)),
45 ('scraper', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='status_mappings', to='scraper.scraper')),
46 ('status', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='risk_assessment.status')),
47 ],
48 options={
49 'unique_together': {('scraper', 'remote_value')},
50 },
51 ),
52 ]