diff --git a/backend/app/api/v1/routes/events.py b/backend/app/api/v1/routes/events.py index 349c81c..7d86c3d 100644 --- a/backend/app/api/v1/routes/events.py +++ b/backend/app/api/v1/routes/events.py @@ -171,9 +171,6 @@ def get_event_json_schema( include_descriptions: bool = Query( True, description="Include field descriptions in schema" ), - include_examples: bool = Query( - True, description="Include field examples in schema" - ), additional_properties: bool = Query( True, description="Allow additional properties in schema" ), @@ -193,7 +190,6 @@ def get_event_json_schema( schema = generate_json_schema_for_event( event, include_descriptions=include_descriptions, - include_examples=include_examples, additional_properties=additional_properties, ) return schema @@ -213,9 +209,6 @@ def get_event_yaml_schema( include_descriptions: bool = Query( True, description="Include field descriptions in schema" ), - include_examples: bool = Query( - True, description="Include field examples in schema" - ), additional_properties: bool = Query( True, description="Allow additional properties in schema" ), @@ -235,7 +228,6 @@ def get_event_yaml_schema( schema = generate_json_schema_for_event( event, include_descriptions=include_descriptions, - include_examples=include_examples, additional_properties=additional_properties, ) yaml_data = yaml.dump(schema, sort_keys=False) diff --git a/backend/app/modules/admin/io/schemas.py b/backend/app/modules/admin/io/schemas.py index e406234..4f37afa 100644 --- a/backend/app/modules/admin/io/schemas.py +++ b/backend/app/modules/admin/io/schemas.py @@ -1,4 +1,4 @@ -from typing import Any, List, Optional +from typing import List, Optional from pydantic import BaseModel @@ -14,7 +14,6 @@ class ExportField(BaseModel): name: str description: Optional[str] field_type: FieldType - example: Optional[Any] class ExportEvent(BaseModel): diff --git a/backend/app/modules/admin/io/service.py b/backend/app/modules/admin/io/service.py index eb515d8..1ec9d95 100644 --- a/backend/app/modules/admin/io/service.py +++ b/backend/app/modules/admin/io/service.py @@ -35,7 +35,6 @@ def export_bundle(db: Session) -> ExportBundle: name=field.name, description=field.description, field_type=field.field_type, - example=field.example, ) for field in fields ], @@ -78,7 +77,6 @@ def import_bundle(bundle: ImportBundle, db: Session): name=field_data.name, description=field_data.description, field_type=field_data.field_type, - example=field_data.example, ) db.add(field) db.flush() diff --git a/backend/app/modules/events/service.py b/backend/app/modules/events/service.py index 324a379..8e83188 100644 --- a/backend/app/modules/events/service.py +++ b/backend/app/modules/events/service.py @@ -17,7 +17,6 @@ def generate_json_schema_for_event( *, additional_properties: bool = True, include_descriptions: bool = True, - include_examples: bool = True, ) -> dict: schema = { "type": "object", @@ -36,9 +35,6 @@ def generate_json_schema_for_event( if include_descriptions and field.description: field_schema["description"] = field.description - if include_examples and field.example is not None: - field_schema["example"] = field.example - schema["properties"][field.name] = field_schema # if not field.optional: diff --git a/backend/app/modules/fields/crud.py b/backend/app/modules/fields/crud.py index f49b496..7891d1f 100644 --- a/backend/app/modules/fields/crud.py +++ b/backend/app/modules/fields/crud.py @@ -10,10 +10,7 @@ def create_field(db: Session, field: schemas.FieldCreate): db_field = models.Field( - name=field.name, - description=field.description, - field_type=field.field_type, - example=field.example, + name=field.name, description=field.description, field_type=field.field_type ) db.add(db_field) try: @@ -41,7 +38,6 @@ def update_field(db: Session, field_id: int, field: schemas.FieldCreate): db_field.name = field.name db_field.description = field.description db_field.field_type = field.field_type - db_field.example = field.example db.commit() db.refresh(db_field) return db_field diff --git a/backend/app/modules/fields/models.py b/backend/app/modules/fields/models.py index eff0e38..21e0a39 100644 --- a/backend/app/modules/fields/models.py +++ b/backend/app/modules/fields/models.py @@ -1,4 +1,4 @@ -from sqlalchemy import JSON, Column, Enum, Integer, String +from sqlalchemy import Column, Enum, Integer, String from sqlalchemy.orm import relationship from app.core.database import Base @@ -13,7 +13,6 @@ class Field(Base, TimestampMixin): name = Column(String, unique=True, index=True) description = Column(String, nullable=True) field_type = Column(Enum(FieldType), nullable=False) - example = Column(JSON, nullable=True) events = relationship( "Event", secondary="event_fields", back_populates="fields", viewonly=True diff --git a/backend/app/modules/fields/schemas.py b/backend/app/modules/fields/schemas.py index 537b603..c3d99fd 100644 --- a/backend/app/modules/fields/schemas.py +++ b/backend/app/modules/fields/schemas.py @@ -1,6 +1,6 @@ from datetime import datetime from enum import Enum -from typing import Any, Optional +from typing import Optional from pydantic import BaseModel, ConfigDict, Field @@ -20,7 +20,6 @@ class FieldBase(BaseModel): ) description: Optional[str] = None field_type: FieldType - example: Optional[Any] = None class FieldCreate(FieldBase): diff --git a/backend/app/modules/fields/seed/seeder.py b/backend/app/modules/fields/seed/seeder.py index abd1009..b95345f 100644 --- a/backend/app/modules/fields/seed/seeder.py +++ b/backend/app/modules/fields/seed/seeder.py @@ -97,26 +97,6 @@ def generate_field_description(): ) -def generate_field_example(field_type: FieldType): - if field_type == FieldType.string: - return fake.word() - elif field_type == FieldType.integer: - return random.randint(0, 1000000) - elif field_type == FieldType.number: - return random.uniform(0, 1000000) - elif field_type == FieldType.boolean: - return random.choice([True, False]) - elif field_type == FieldType.array: - return [fake.word() for _ in range(random.randint(1, 10))] - elif field_type == FieldType.object: - return { - fake.word(part_of_speech="noun"): fake.word(part_of_speech="adjective") - for _ in range(random.randint(1, 5)) - } - else: - return None - - def seed(db: Session, count: int = 20): existing_names = set() @@ -125,13 +105,9 @@ def seed(db: Session, count: int = 20): existing_names.add(name) field_type = random.choice(list(FieldType)) - example = generate_field_example(field_type) db_field = Field( - name=name, - description=generate_field_description(), - field_type=field_type, - example=example, + name=name, description=generate_field_description(), field_type=field_type ) db.add(db_field) diff --git a/backend/tests/test_events_extended.py b/backend/tests/test_events_extended.py index 787ae8e..bb289da 100644 --- a/backend/tests/test_events_extended.py +++ b/backend/tests/test_events_extended.py @@ -11,7 +11,6 @@ def sample_field_for_event(auth_client): name="user_id", description="Unique user identifier", field_type=FieldType.string, - example="user_12345", ) response = auth_client.post("/v1/fields/", json=field_data.model_dump()) return response.json() @@ -200,12 +199,6 @@ def test_export_schema_with_options(auth_client): ) assert response.status_code == 200 - # Test without examples - response = auth_client.get( - f"/v1/events/{event_id}/schema.json", params={"include_examples": False} - ) - assert response.status_code == 200 - def test_export_schema_nonexistent_event(auth_client): """Test schema export for nonexistent event""" diff --git a/backend/tests/test_fields_extended.py b/backend/tests/test_fields_extended.py index b7dab0b..0ddbd6d 100644 --- a/backend/tests/test_fields_extended.py +++ b/backend/tests/test_fields_extended.py @@ -10,7 +10,6 @@ def sample_field_complete(): name="transaction_amount", description="Monetary amount of transaction in cents", field_type=FieldType.number, - example=1299, ) @@ -21,7 +20,6 @@ def sample_boolean_field(): name="is_premium_user", description="Whether user has premium subscription", field_type=FieldType.boolean, - example=True, ) @@ -29,10 +27,7 @@ def sample_boolean_field(): def test_create_string_field(auth_client): """Test creating string field""" field_data = FieldCreate( - name="user_email", - description="User email address", - field_type=FieldType.string, - example="user@example.com", + name="user_email", description="User email address", field_type=FieldType.string ) response = auth_client.post("/v1/fields/", json=field_data.model_dump()) @@ -40,7 +35,6 @@ def test_create_string_field(auth_client): data = response.json() assert data["field_type"] == "string" - assert data["example"] == "user@example.com" def test_create_number_field(auth_client, sample_field_complete): @@ -50,7 +44,6 @@ def test_create_number_field(auth_client, sample_field_complete): data = response.json() assert data["field_type"] == "number" - assert data["example"] == 1299 def test_create_boolean_field(auth_client, sample_boolean_field): @@ -60,7 +53,6 @@ def test_create_boolean_field(auth_client, sample_boolean_field): data = response.json() assert data["field_type"] == "boolean" - assert data["example"] is True def test_create_array_field(auth_client): @@ -69,7 +61,6 @@ def test_create_array_field(auth_client): name="user_interests", description="List of user interests", field_type=FieldType.array, - example=["sports", "technology", "music"], ) response = auth_client.post("/v1/fields/", json=field_data.model_dump()) @@ -77,7 +68,6 @@ def test_create_array_field(auth_client): data = response.json() assert data["field_type"] == "array" - assert isinstance(data["example"], list) def test_create_object_field(auth_client): @@ -86,7 +76,6 @@ def test_create_object_field(auth_client): name="user_profile", description="User profile object", field_type=FieldType.object, - example={"name": "John", "age": 30}, ) response = auth_client.post("/v1/fields/", json=field_data.model_dump()) @@ -94,16 +83,12 @@ def test_create_object_field(auth_client): data = response.json() assert data["field_type"] == "object" - assert isinstance(data["example"], dict) def test_create_integer_field(auth_client): """Test creating integer field""" field_data = FieldCreate( - name="user_age", - description="User age in years", - field_type=FieldType.integer, - example=25, + name="user_age", description="User age in years", field_type=FieldType.integer ) response = auth_client.post("/v1/fields/", json=field_data.model_dump()) @@ -111,7 +96,6 @@ def test_create_integer_field(auth_client): data = response.json() assert data["field_type"] == "integer" - assert data["example"] == 25 # Test field operations @@ -130,7 +114,7 @@ def test_list_fields_returns_all(auth_client): fields = response.json() assert isinstance(fields, list) - assert len(fields) >= 2 # Should have at least our created fields + assert len(fields) >= 2 # Should have at least the previously created fields def test_get_field_with_event_count(auth_client): @@ -159,7 +143,6 @@ def test_update_field(auth_client): name="update_test_field", description="Field to be updated", field_type=FieldType.string, - example="original", ) create_response = auth_client.post("/v1/fields/", json=create_data.model_dump()) @@ -170,7 +153,6 @@ def test_update_field(auth_client): name="update_test_field", # Name should stay same due to unique constraint description="Updated description", field_type=FieldType.string, - example="updated", ) update_response = auth_client.put( @@ -180,7 +162,6 @@ def test_update_field(auth_client): data = update_response.json() assert data["description"] == "Updated description" - assert data["example"] == "updated" def test_delete_field(auth_client): @@ -294,21 +275,6 @@ def test_create_field_without_description(auth_client): assert data["description"] is None -def test_create_field_without_example(auth_client): - """Test creating field without optional example""" - field_data = FieldCreate( - name="no_example_field", - description="Field without example", - field_type=FieldType.string, - ) - - response = auth_client.post("/v1/fields/", json=field_data.model_dump()) - assert response.status_code == 201 - - data = response.json() - assert data["example"] is None - - # Test authentication def test_list_fields_requires_auth(client): """Test that listing fields requires authentication""" diff --git a/backend/tests/test_services.py b/backend/tests/test_services.py index 8857064..65a4b39 100644 --- a/backend/tests/test_services.py +++ b/backend/tests/test_services.py @@ -50,7 +50,6 @@ def sample_event_out(): name="user_id", description="Unique user identifier", field_type=FieldType.string, - example="user_12345", created_at="2024-01-01T00:00:00Z", updated_at="2024-01-01T00:00:00Z", ), @@ -59,7 +58,6 @@ def sample_event_out(): name="signup_method", description="How user signed up", field_type=FieldType.string, - example="email", created_at="2024-01-01T00:00:00Z", updated_at="2024-01-01T00:00:00Z", ), @@ -106,23 +104,6 @@ def test_generate_json_schema_without_descriptions(sample_event_out): assert "description" not in properties["user_id"] -def test_generate_json_schema_with_examples(sample_event_out): - """Test schema generation with examples enabled""" - schema = generate_json_schema_for_event(sample_event_out, include_examples=True) - - properties = schema["properties"] - assert "example" in properties["user_id"] - assert properties["user_id"]["example"] == "user_12345" - - -def test_generate_json_schema_without_examples(sample_event_out): - """Test schema generation with examples disabled""" - schema = generate_json_schema_for_event(sample_event_out, include_examples=False) - - properties = schema["properties"] - assert "example" not in properties["user_id"] - - def test_generate_json_schema_additional_properties_true(sample_event_out): """Test schema generation with additional properties allowed""" schema = generate_json_schema_for_event( diff --git a/frontend/src/modules/events/components/EventDetailsCard.vue b/frontend/src/modules/events/components/EventDetailsCard.vue index 6a6dbeb..437221c 100644 --- a/frontend/src/modules/events/components/EventDetailsCard.vue +++ b/frontend/src/modules/events/components/EventDetailsCard.vue @@ -6,20 +6,16 @@ import { Button } from '@/shared/ui/button' import { Badge } from '@/shared/ui/badge' import { Icon } from '@iconify/vue' import EventFieldsTable from './EventFieldsTable.vue' -import JsonPreview from '@/shared/components/JsonPreview.vue' import DetailsCardLayout from '@/shared/components/layout/DetailsCardLayout.vue' import DetailsCardAttribute from '@/shared/components/layout/DetailsCardAttribute.vue' import { getEventFieldsColumns } from '@/modules/events/components/eventFieldsColumns' import TagScrollArea from '@/modules/tags/components/TagScrollArea.vue' -import { useEventExample } from '@/modules/events/composables/useEventExample' import EventLinks from '@/modules/events/components/EventLinks.vue' const props = defineProps<{ event: Event }>() -const eventExample = useEventExample(props.event.fields) - const emit = defineEmits<{ (e: 'edit'): void (e: 'delete'): void @@ -79,13 +75,6 @@ const columns = getEventFieldsColumns() - - - { const params = { include_descriptions: settings.includeDescriptions, - include_examples: settings.includeExamples, additional_properties: settings.additionalProperties, } const format = settings.format @@ -100,11 +98,6 @@ watch( -
- - -
-
diff --git a/frontend/src/modules/events/composables/useEventExample.ts b/frontend/src/modules/events/composables/useEventExample.ts deleted file mode 100644 index 350d354..0000000 --- a/frontend/src/modules/events/composables/useEventExample.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { Field, JsonValue } from '@/modules/fields/types' -import { FieldType } from '@/modules/fields/types' -import { computed } from 'vue' - -const fallbackExamples: Record = { - [FieldType.STRING]: '', - [FieldType.INTEGER]: 0, - [FieldType.NUMBER]: 0.0, - [FieldType.BOOLEAN]: true, - [FieldType.ARRAY]: [], - [FieldType.OBJECT]: {}, -} - -export function useEventExample(fields: Field[]) { - return computed(() => { - const example: Record = {} - for (const field of fields) { - example[field.name] = field.example ?? fallbackExamples[field.field_type] - } - return example - }) -} diff --git a/frontend/src/modules/fields/components/FieldDetailsCard.vue b/frontend/src/modules/fields/components/FieldDetailsCard.vue index d2d5166..d92f824 100644 --- a/frontend/src/modules/fields/components/FieldDetailsCard.vue +++ b/frontend/src/modules/fields/components/FieldDetailsCard.vue @@ -2,7 +2,6 @@ import type { Field } from '@/modules/fields/types' import { Button } from '@/shared/ui/button' import { Icon } from '@iconify/vue' -import JsonPreview from '@/shared/components/JsonPreview.vue' import DetailsCardLayout from '@/shared/components/layout/DetailsCardLayout.vue' import DetailsCardAttribute from '@/shared/components/layout/DetailsCardAttribute.vue' import FieldTypeBadge from '@/modules/fields/components/FieldTypeBadge.vue' @@ -34,12 +33,6 @@ const emit = defineEmits(['edit-clicked', 'delete-clicked'])