Add plugin platform with modular backend and frontend registry.

Split graph/import/meta into Django apps, add API v1 with OpenAPI and pytest, and introduce plugin registry with the tags reference plugin on both FE and BE.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-25 09:35:51 +03:00
co-authored by Cursor
parent b694a596b8
commit cafc7335ad
77 changed files with 1801 additions and 490 deletions
+1
View File
@@ -0,0 +1 @@
+24
View File
@@ -0,0 +1,24 @@
import pytest
from django.urls import reverse
@pytest.mark.django_db
def test_contacts_list(api_client, sample_contact):
response = api_client.get('/api/v1/contacts/')
assert response.status_code == 200
assert response.data['count'] == 1
assert response.data['results'][0]['name'] == 'Иван Иванов'
@pytest.mark.django_db
def test_contact_create(api_client):
response = api_client.post('/api/v1/contacts/', {'name': 'Новый контакт'}, format='json')
assert response.status_code == 201
assert response.data['name'] == 'Новый контакт'
@pytest.mark.django_db
def test_relations_list(api_client, sample_relation):
response = api_client.get('/api/v1/relations/')
assert response.status_code == 200
assert response.data['count'] == 1
+22
View File
@@ -0,0 +1,22 @@
import pytest
@pytest.mark.django_db
def test_graph_empty(api_client):
response = api_client.get('/api/v1/graph/')
assert response.status_code == 200
assert response.data == {'nodes': [], 'edges': []}
@pytest.mark.django_db
def test_graph_with_data(api_client, sample_contact, sample_relation):
response = api_client.get('/api/v1/graph/')
assert response.status_code == 200
assert len(response.data['nodes']) == 2
assert len(response.data['edges']) == 1
@pytest.mark.django_db
def test_legacy_api_path(api_client):
response = api_client.get('/api/graph/')
assert response.status_code == 200
+20
View File
@@ -0,0 +1,20 @@
import pytest
@pytest.mark.django_db
def test_meta_choices(api_client):
response = api_client.get('/api/v1/meta/choices/')
assert response.status_code == 200
data = response.data
assert 'relation_types' in data
assert 'life_spheres' in data
assert 'network_circles' in data
assert 'interaction_intensities' in data
assert any(x['value'] == 'friend' for x in data['relation_types'])
@pytest.mark.django_db
def test_relation_types_legacy(api_client):
response = api_client.get('/api/v1/relation-types/')
assert response.status_code == 200
assert len(response.data) >= 1
+27
View File
@@ -0,0 +1,27 @@
import pytest
@pytest.mark.django_db
def test_plugin_manifest(api_client):
response = api_client.get('/api/v1/plugins/')
assert response.status_code == 200
ids = [p['id'] for p in response.data]
assert 'tags' in ids
@pytest.mark.django_db
def test_tags_crud(api_client, sample_contact):
create = api_client.post(
'/api/v1/plugins/tags/contact-tags/',
{'contact': sample_contact.id, 'label': 'коллеги'},
format='json',
)
assert create.status_code == 201
tag_id = create.data['id']
listing = api_client.get(f'/api/v1/plugins/tags/contact-tags/?contact_id={sample_contact.id}')
assert listing.status_code == 200
assert listing.data['count'] == 1
delete = api_client.delete(f'/api/v1/plugins/tags/contact-tags/{tag_id}/')
assert delete.status_code == 204