Files
service-finder/docs/full_db_schema_blueprint.md
2026-06-23 21:11:21 +00:00

1140 lines
45 KiB
Markdown

# 📐 Full Database Schema Blueprint — Service Finder
> **P0 DEEP AUDIT** — Generated from SQLAlchemy models in `backend/app/models/`
>
> Format: Schema → Table → Columns (flat dump, no relationships)
>
> **9 schemas · ~100 tables** cataloged
---
## 🧬 1. Schema: `identity`
### `identity.persons`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `BIGINT` | PK | Primary key, indexed |
| `id_uuid` | `UUID` | UNIQUE | `uuid.uuid4()`, not null |
| `address_id` | `UUID` | FK → `system.addresses.id` | Nullable |
| `identity_hash` | `VARCHAR(64)` | UNIQUE, INDEX | Hash: lastName + motherName + birthDate |
| `last_name` | `VARCHAR` | NOT NULL | |
| `first_name` | `VARCHAR` | NOT NULL | |
| `phone` | `VARCHAR` | | Nullable |
| `mothers_last_name` | `VARCHAR` | | Nullable |
| `mothers_first_name` | `VARCHAR` | | Nullable |
| `birth_place` | `VARCHAR` | | Nullable |
| `birth_date` | `DATETIME` | | Nullable |
| `identity_docs` | `JSON` | NOT NULL | Default: `{}` |
| `ice_contact` | `JSON` | NOT NULL | Default: `{}` |
| `lifetime_xp` | `BIGINT` | NOT NULL | Default: -1 |
| `penalty_points` | `INTEGER` | NOT NULL | Default: -1 |
| `social_reputation` | `NUMERIC(3,2)` | NOT NULL | Default: 0.0 |
| `is_sales_agent` | `BOOLEAN` | NOT NULL | Default: true |
| `is_active` | `BOOLEAN` | NOT NULL | Default: true |
| `is_ghost` | `BOOLEAN` | NOT NULL | Default: false |
| `merged_into_id` | `BIGINT` | FK → `identity.persons.id` | Self-ref, nullable |
| `deleted_at` | `DATETIME` | | Timezone-aware, nullable |
| `created_at` | `DATETIME` | NOT NULL | `func.now()` |
| `updated_at` | `DATETIME` | | `onupdate=func.now()` |
| `user_id` | `INTEGER` | FK → `identity.users.id` | Active user, nullable |
### `identity.users`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Primary key, indexed |
| `id_uuid` | `UUID` | UNIQUE | `uuid.uuid4()`, not null |
| `person_id` | `BIGINT` | FK → `identity.persons.id` | NOT NULL |
| `organization_id` | `INTEGER` | FK → `fleet.organizations.id` | Primary org, nullable |
| `role` | `VARCHAR(50)` | NOT NULL | ENUM: SUPERADMIN/ADMIN/MODERATOR/SALES_REP/SERVICE_MGR/USER |
| `username` | `VARCHAR(80)` | UNIQUE, INDEX | Not null |
| `email` | `VARCHAR(255)` | UNIQUE, INDEX | Not null |
| `password_hash` | `VARCHAR(255)` | NOT NULL | |
| `avatar_url` | `VARCHAR` | | Nullable |
| `phone` | `VARCHAR(50)` | | Nullable |
| `is_active` | `BOOLEAN` | NOT NULL | Default: true |
| `is_verified` | `BOOLEAN` | NOT NULL | Default: false |
| `is_onboarded` | `BOOLEAN` | NOT NULL | Default: false |
| `is_superuser` | `BOOLEAN` | NOT NULL | Default: false |
| `language` | `VARCHAR(10)` | | Default: 'hu' |
| `preferences` | `JSON` | NOT NULL | Default: `{}` |
| `last_login_at` | `DATETIME` | | Nullable |
| `deleted_at` | `DATETIME` | | Soft delete, nullable |
| `created_at` | `DATETIME` | NOT NULL | `func.now()` |
| `updated_at` | `DATETIME` | | `onupdate=func.now()` |
### `identity.wallets`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Primary key, indexed |
| `user_id` | `INTEGER` | FK → `identity.users.id` | NOT NULL |
| `balance_earned` | `NUMERIC(18,4)` | NOT NULL | Default: 0.0 |
| `balance_purchased` | `NUMERIC(18,4)` | NOT NULL | Default: 0.0 |
| `balance_service_coins` | `NUMERIC(18,4)` | NOT NULL | Default: 0.0 |
| `balance_voucher` | `NUMERIC(18,4)` | NOT NULL | Default: 0.0 |
| `total_deposited` | `NUMERIC(18,4)` | NOT NULL | Default: 0.0 |
| `total_withdrawn` | `NUMERIC(18,4)` | NOT NULL | Default: 0.0 |
| `lifetime_earned` | `NUMERIC(18,4)` | NOT NULL | Default: 0.0 |
| `lifetime_spent` | `NUMERIC(18,4)` | NOT NULL | Default: 0.0 |
| `created_at` | `DATETIME` | NOT NULL | `func.now()` |
| `updated_at` | `DATETIME` | | `onupdate=func.now()` |
### `identity.verification_tokens`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `user_id` | `INTEGER` | FK → `identity.users.id` | NOT NULL |
| `token` | `VARCHAR` | UNIQUE | NOT NULL |
| `token_type` | `VARCHAR(20)` | | email_verification, password_reset, etc. |
| `expires_at` | `DATETIME` | NOT NULL | |
| `is_used` | `BOOLEAN` | | Default: false |
| `created_at` | `DATETIME` | | `func.now()` |
### `identity.social_accounts`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `user_id` | `INTEGER` | FK → `identity.users.id` | NOT NULL |
| `provider` | `VARCHAR(50)` | NOT NULL | e.g. google, facebook |
| `provider_id` | `VARCHAR(255)` | NOT NULL | |
| `extra_data` | `JSON` | | Default: `{}` |
| `created_at` | `DATETIME` | | `func.now()` |
### `identity.active_vouchers`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `wallet_id` | `INTEGER` | FK → `identity.wallets.id` | CASCADE delete |
| `amount` | `NUMERIC(18,4)` | NOT NULL | |
| `original_amount` | `NUMERIC(18,4)` | NOT NULL | |
| `expires_at` | `DATETIME` | NOT NULL | Timezone-aware |
| `created_at` | `DATETIME` | | `func.now()` |
### `identity.user_trust_profiles`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `user_id` | `INTEGER` | PK, FK → `identity.users.id` | CASCADE delete |
| `trust_score` | `INTEGER` | NOT NULL | Default: 0 |
| `maintenance_score` | `NUMERIC(5,2)` | NOT NULL | Default: 0.0 |
| `quality_score` | `NUMERIC(5,2)` | NOT NULL | Default: 0.0 |
| `preventive_score` | `NUMERIC(5,2)` | NOT NULL | Default: 0.0 |
| `identity_score` | `INTEGER` | NOT NULL | Default: 0 |
| `verification_level` | `INTEGER` | NOT NULL | Default: 0 |
| `verified_channels` | `JSONB` | NOT NULL | Default: `{}` |
| `identity_risk_flag` | `BOOLEAN` | NOT NULL | Default: false |
| `last_calculated` | `DATETIME` | NOT NULL | `func.now()` |
### `identity.one_time_passwords`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `email` | `VARCHAR` | INDEX | NOT NULL |
| `code` | `VARCHAR(6)` | NOT NULL | |
| `otp_type` | `VARCHAR(30)` | NOT NULL | 'restore' or 'company_claim' |
| `extra_data` | `JSON` | | Nullable |
| `is_used` | `BOOLEAN` | | Default: false |
| `created_at` | `DATETIME` | | `func.now()` |
| `expires_at` | `DATETIME` | NOT NULL | |
### `identity.devices`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `fingerprint_hash` | `VARCHAR(255)` | PK | Indexed |
| `risk_score` | `INTEGER` | NOT NULL | Default: 100 |
| `is_banned` | `BOOLEAN` | NOT NULL | Default: false |
| `created_at` | `DATETIME` | NOT NULL | |
### `identity.user_device_links`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `UUID` | PK | `uuid.uuid4()` |
| `user_id` | `INTEGER` | FK → `identity.users.id` | CASCADE, indexed |
| `device_hash` | `VARCHAR(255)` | FK → `identity.devices.fingerprint_hash` | CASCADE, indexed |
| `first_seen_at` | `DATETIME` | NOT NULL | |
| `last_seen_at` | `DATETIME` | | Nullable |
### `identity.legal_acceptances`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `user_id` | `INTEGER` | FK → `identity.users.id` | |
| `document_id` | `INTEGER` | FK → `system.legal_documents.id` | |
| `accepted_at` | `DATETIME` | | `func.now()` |
| `ip_address` | `VARCHAR(45)` | | Nullable |
---
## 🧬 2. Schema: `system`
### `system.geo_postal_codes`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `country_code` | `VARCHAR(5)` | | Default: 'HU' |
| `zip_code` | `VARCHAR(10)` | INDEX | NOT NULL |
| `city` | `VARCHAR(100)` | INDEX | NOT NULL |
### `system.geo_streets`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `postal_code_id` | `INTEGER` | FK → `system.geo_postal_codes.id` | Nullable |
| `name` | `VARCHAR(200)` | INDEX | NOT NULL |
### `system.geo_street_types`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR(50)` | UNIQUE | NOT NULL |
### `system.addresses`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `UUID` | PK | `uuid.uuid4()` |
| `postal_code_id` | `INTEGER` | FK → `system.geo_postal_codes.id` | Nullable |
| `street_name` | `VARCHAR(200)` | | Nullable |
| `street_type` | `VARCHAR(50)` | | Nullable |
| `house_number` | `VARCHAR(50)` | | Nullable |
| `stairwell` | `VARCHAR(20)` | | Nullable |
| `floor` | `VARCHAR(20)` | | Nullable |
| `door` | `VARCHAR(20)` | | Nullable |
| `parcel_id` | `VARCHAR(50)` | | Nullable |
| `full_address_text` | `TEXT` | | Nullable |
| `latitude` | `FLOAT` | | Nullable |
| `longitude` | `FLOAT` | | Nullable |
| `created_at` | `DATETIME` | | `func.now()` |
### `system.pending_actions`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `requester_id` | `INTEGER` | FK → `identity.users.id` | NOT NULL |
| `approver_id` | `INTEGER` | FK → `identity.users.id` | Nullable |
| `status` | `ENUM(actionstatus)` | | Default: 'pending' |
| `action_type` | `VARCHAR(50)` | NOT NULL | e.g. 'WALLET_ADJUST' |
| `payload` | `JSONB` | NOT NULL | |
| `reason` | `VARCHAR(255)` | | Nullable |
| `created_at` | `DATETIME` | | `func.now()` |
| `expires_at` | `DATETIME` | | `now() + 24h` |
| `processed_at` | `DATETIME` | | Nullable |
### `system.system_parameters`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Auto-increment |
| `key` | `VARCHAR` | INDEX | NOT NULL |
| `category` | `VARCHAR` | INDEX | Default: 'general' |
| `value` | `JSONB` | NOT NULL | |
| `scope_level` | `VARCHAR(50)` | INDEX | Default: 'global' |
| `scope_id` | `VARCHAR(50)` | | Nullable |
| `is_active` | `BOOLEAN` | | Default: true |
| `description` | `VARCHAR` | | Nullable |
| `last_modified_by` | `INTEGER` | | Nullable |
| `updated_at` | `DATETIME` | | `func.now()` |
| UNIQUE | | | `(key, scope_level, scope_id)` |
### `system.internal_notifications`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `UUID` | PK | `uuid.uuid4()` |
| `user_id` | `INTEGER` | FK → `identity.users.id` | CASCADE, indexed |
| `title` | `VARCHAR(255)` | NOT NULL | |
| `message` | `TEXT` | NOT NULL | |
| `category` | `VARCHAR(50)` | | Default: 'info' |
| `priority` | `VARCHAR(20)` | | Default: 'medium' |
| `is_read` | `BOOLEAN` | INDEX | Default: false |
| `read_at` | `DATETIME` | | Nullable |
| `created_at` | `DATETIME` | | `func.now()` |
| `data` | `JSONB` | | Nullable |
### `system.system_data_completion_weights`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Auto-increment |
| `entity_type` | `VARCHAR(50)` | INDEX | NOT NULL |
| `field_name` | `VARCHAR(100)` | INDEX | NOT NULL |
| `weight_percent` | `INTEGER` | NOT NULL | 0-100% |
| `is_mandatory` | `BOOLEAN` | | Default: false |
| `is_active` | `BOOLEAN` | | Default: true |
| `description` | `TEXT` | | Nullable |
| `created_at` | `DATETIME` | | `func.now()` |
| `updated_at` | `DATETIME` | | `func.now()` |
| `is_read` | `BOOLEAN` | NOT NULL | Shadow column, Default: false |
| UNIQUE | | | `(entity_type, field_name)` |
### `system.service_staging`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR(255)` | INDEX | NOT NULL |
| `source` | `VARCHAR(50)` | | NOT NULL |
| `external_id` | `VARCHAR(100)` | INDEX | Nullable |
| `fingerprint` | `VARCHAR(64)` | UNIQUE, INDEX | NOT NULL |
| `postal_code` | `VARCHAR(20)` | INDEX | Nullable |
| `city` | `VARCHAR(100)` | INDEX | NOT NULL |
| `full_address` | `VARCHAR(500)` | | Nullable |
| `contact_phone` | `VARCHAR(50)` | | Nullable |
| `website` | `VARCHAR(255)` | | Nullable |
| `description` | `TEXT` | | Nullable |
| `submitted_by` | `INTEGER` | | Nullable |
| `raw_data` | `JSONB` | | Default: `{}` |
| `status` | `VARCHAR(20)` | INDEX | Default: 'pending' |
| `created_at` | `DATETIME` | | `func.now()` |
| `updated_at` | `DATETIME` | | Nullable |
### `system.documents`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `UUID` | PK | `uuid.uuid4()` |
| `parent_type` | `VARCHAR(20)` | | 'organization' or 'asset' |
| `parent_id` | `VARCHAR(50)` | INDEX | |
| `doc_type` | `VARCHAR(50)` | | Nullable |
| `original_name` | `VARCHAR(255)` | NOT NULL | |
| `file_hash` | `VARCHAR(64)` | NOT NULL | |
| `file_ext` | `VARCHAR(10)` | | Default: 'webp' |
| `mime_type` | `VARCHAR(100)` | | Default: 'image/webp' |
| `file_size` | `INTEGER` | | Nullable |
| `has_thumbnail` | `BOOLEAN` | | Default: false |
| `thumbnail_path` | `VARCHAR(255)` | | Nullable |
| `uploaded_by` | `INTEGER` | FK → `identity.users.id` | Nullable |
| `created_at` | `DATETIME` | | `func.now()` |
| `status` | `VARCHAR(50)` | INDEX | Default: 'uploaded' |
| `ocr_data` | `TEXT` | | Nullable |
| `error_log` | `TEXT` | | Nullable |
### `system.translations`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `key` | `VARCHAR(255)` | INDEX | NOT NULL |
| `lang` | `VARCHAR(5)` | INDEX | NOT NULL |
| `value` | `TEXT` | NOT NULL | |
| `is_published` | `BOOLEAN` | | Default: true |
### `system.legal_documents`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `title` | `VARCHAR(255)` | | Nullable |
| `content` | `TEXT` | NOT NULL | |
| `version` | `VARCHAR(20)` | NOT NULL | |
| `region_code` | `VARCHAR(5)` | | Default: 'HU' |
| `language` | `VARCHAR(5)` | | Default: 'hu' |
| `is_active` | `BOOLEAN` | | Default: true |
| `created_at` | `DATETIME` | | `func.now()` |
### `system.subscription_tiers`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR` | UNIQUE, INDEX | e.g. 'premium' |
| `rules` | `JSONB` | | Default: `{}` |
| `is_custom` | `BOOLEAN` | | Default: false |
### `system.service_catalog`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `service_code` | `VARCHAR` | UNIQUE, INDEX | NOT NULL, e.g. 'SRV_DATA_EXPORT' |
| `name` | `VARCHAR` | NOT NULL | |
| `description` | `VARCHAR` | | Nullable |
| `credit_cost` | `INTEGER` | | Default: 0 |
| `is_active` | `BOOLEAN` | | Default: true |
---
## 🧬 3. Schema: `vehicle`
### `vehicle.vehicle_types`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `code` | `VARCHAR(30)` | UNIQUE, INDEX | |
| `name` | `VARCHAR(50)` | NOT NULL | |
| `icon` | `VARCHAR(50)` | | Nullable |
| `units` | `JSONB` | | Default: `{"power": "kW", "weight": "kg"}` |
### `vehicle.feature_definitions`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `vehicle_type_id` | `INTEGER` | FK → `vehicle.vehicle_types.id` | NOT NULL |
| `code` | `VARCHAR(50)` | INDEX | |
| `name` | `VARCHAR(100)` | NOT NULL | |
| `category` | `VARCHAR(50)` | INDEX | |
### `vehicle.vehicle_model_definitions`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `market` | `VARCHAR(20)` | INDEX | Default: 'EU' |
| `make` | `VARCHAR(100)` | INDEX | |
| `marketing_name` | `VARCHAR(255)` | INDEX | |
| `official_marketing_name` | `VARCHAR(255)` | | Nullable |
| `attempts` | `INTEGER` | | Default: 0 |
| `last_error` | `TEXT` | | Nullable |
| `updated_at` | `DATETIME` | | `func.now()` |
| `priority_score` | `INTEGER` | | Default: 0 |
| `normalized_name` | `VARCHAR(255)` | INDEX | NOT NULL |
| `marketing_name_aliases` | `JSONB` | | Default: `[]` |
| `engine_code` | `VARCHAR(50)` | INDEX | Nullable |
| `technical_code` | `VARCHAR(100)` | INDEX | Default: 'UNKNOWN' |
| `variant_code` | `VARCHAR(100)` | INDEX | Default: 'UNKNOWN' |
| `version_code` | `VARCHAR(100)` | INDEX | Default: 'UNKNOWN' |
| `type_approval_number` | `VARCHAR(100)` | INDEX | Nullable |
| `seats` | `INTEGER` | | Default: 0 |
| `width` | `INTEGER` | | Default: 0 |
| `wheelbase` | `INTEGER` | | Default: 0 |
| `list_price` | `INTEGER` | | Default: 0 |
| `max_speed` | `INTEGER` | | Default: 0 |
| `towing_weight_unbraked` | `INTEGER` | | Default: 0 |
| `towing_weight_braked` | `INTEGER` | | Default: 0 |
| `fuel_consumption_combined` | `NUMERIC(10,2)` | | Nullable |
| `co2_emissions_combined` | `INTEGER` | | Default: 0 |
| `vehicle_type_id` | `INTEGER` | FK → `vehicle.vehicle_types.id` | Nullable |
| `vehicle_class` | `VARCHAR(50)` | INDEX | Nullable |
| `fuel_type` | `VARCHAR(50)` | INDEX | Nullable |
| `engine_capacity` | `INTEGER` | INDEX | Nullable |
| `power_kw` | `INTEGER` | INDEX | Nullable |
| `power_hp` | `INTEGER` | | Nullable |
| `transmission_type` | `VARCHAR(50)` | INDEX | Nullable |
| `drive_type` | `VARCHAR(50)` | INDEX | Nullable |
| `body_type` | `VARCHAR(100)` | INDEX | Nullable |
| `emission_standard` | `VARCHAR(50)` | INDEX | Nullable |
| `model_year_from` | `INTEGER` | INDEX | Nullable |
| `model_year_to` | `INTEGER` | INDEX | Nullable |
| `weight_kg` | `INTEGER` | | Nullable |
| `total_weight_kg` | `INTEGER` | | Nullable |
| `axle_count` | `INTEGER` | | Nullable |
| `is_4x4` | `BOOLEAN` | | Default: false |
| `origin_country` | `VARCHAR(100)` | | Nullable |
| `gold_enriched` | `BOOLEAN` | INDEX | Default: false |
| `engine_hash` | `VARCHAR(64)` | INDEX | Nullable |
| `compliance` | `JSONB` | | Nullable |
| `specifications` | `JSONB` | | Nullable |
| `status` | `VARCHAR(20)` | INDEX | Default: 'pending' |
| `created_at` | `DATETIME` | | `func.now()` |
### `vehicle.model_feature_maps`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `model_id` | `INTEGER` | FK → `vehicle.vehicle_model_definitions.id` | NOT NULL |
| `feature_id` | `INTEGER` | FK → `vehicle.feature_definitions.id` | NOT NULL |
| UNIQUE | | | `(model_id, feature_id)` |
### `vehicle.reference_lookup`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `make` | `VARCHAR` | INDEX | NOT NULL |
| `model` | `VARCHAR` | INDEX | NOT NULL |
| `year` | `INTEGER` | INDEX | Nullable |
| `specs` | `JSONB` | NOT NULL | |
| `source` | `VARCHAR` | NOT NULL | e.g. 'os-vehicle-db' |
| `source_id` | `VARCHAR` | | Nullable |
| `updated_at` | `DATETIME` | | `func.now()` |
### `vehicle.cost_categories`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR(100)` | UNIQUE, INDEX | NOT NULL |
| `parent_id` | `INTEGER` | FK → `vehicle.cost_categories.id` | Self-ref, nullable |
| `sort_order` | `INTEGER` | | |
| `is_active` | `BOOLEAN` | | Default: true |
### `vehicle.vehicle_costs`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `vehicle_id` | `UUID` | FK → `vehicle.assets.id` | NOT NULL |
| `category_id` | `INTEGER` | FK → `vehicle.cost_categories.id` | |
| `amount` | `NUMERIC(18,2)` | NOT NULL | |
| `currency` | `VARCHAR(3)` | | Default: 'HUF' |
| `description` | `TEXT` | | Nullable |
| `date` | `DATETIME` | | |
| `created_at` | `DATETIME` | | `func.now()` |
### `vehicle.vehicle_catalog` (AssetCatalog)
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `master_definition_id` | `INTEGER` | FK → `vehicle.vehicle_model_definitions.id` | Nullable |
| `make` | `VARCHAR` | INDEX | NOT NULL |
| `model` | `VARCHAR` | INDEX | NOT NULL |
| `generation` | `VARCHAR` | INDEX | Nullable |
| `year_from` | `INTEGER` | | Nullable |
| `year_to` | `INTEGER` | | Nullable |
| `fuel_type` | `VARCHAR` | INDEX | Nullable |
| `power_kw` | `INTEGER` | INDEX | Nullable |
| `engine_capacity` | `INTEGER` | INDEX | Nullable |
| `factory_data` | `JSONB` | | Default: `{}` |
| UNIQUE | | | `(make, model, year_from, fuel_type)` |
### `vehicle.assets`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `UUID` | PK | `uuid.uuid4()` |
| `vin` | `VARCHAR(17)` | UNIQUE, INDEX | Nullable |
| `license_plate` | `VARCHAR(20)` | INDEX | |
| `name` | `VARCHAR` | | Nullable |
| `catalog_id` | `INTEGER` | FK → `vehicle.vehicle_catalog.id` | Nullable |
| `vehicle_class` | `VARCHAR(50)` | INDEX | Nullable |
| `brand` | `VARCHAR(100)` | INDEX | Nullable |
| `model` | `VARCHAR(100)` | INDEX | Nullable |
| `trim_level` | `VARCHAR(100)` | | Nullable |
| `fuel_type` | `VARCHAR(50)` | INDEX | Nullable |
| `engine_capacity` | `INTEGER` | INDEX | Nullable |
| `power_kw` | `INTEGER` | INDEX | Nullable |
| `torque_nm` | `INTEGER` | | Nullable |
| `transmission_type` | `VARCHAR(50)` | INDEX | Nullable |
| `drive_type` | `VARCHAR(50)` | INDEX | Nullable |
| `year_of_manufacture` | `INTEGER` | INDEX | Nullable |
| `mileage` | `INTEGER` | | Nullable |
| `registration_date` | `DATETIME` | | Nullable |
| `status` | `VARCHAR(30)` | INDEX | Default: 'active' |
| `owner_person_id` | `BIGINT` | FK → `identity.persons.id` | Nullable |
| `owner_org_id` | `INTEGER` | FK → `fleet.organizations.id` | Nullable |
| `current_organization_id` | `INTEGER` | FK → `fleet.organizations.id` | Nullable |
| `is_deleted` | `BOOLEAN` | | Default: false |
| `created_at` | `DATETIME` | | `func.now()` |
| `updated_at` | `DATETIME` | | `func.now()` |
| CHECK | | | `vin IS NOT NULL OR license_plate IS NOT NULL` |
### `vehicle.asset_costs`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `asset_id` | `UUID` | FK → `vehicle.assets.id` | NOT NULL |
| `category` | `VARCHAR(50)` | INDEX | |
| `amount` | `NUMERIC(18,2)` | NOT NULL | |
| `currency` | `VARCHAR(3)` | | Default: 'HUF' |
| `description` | `TEXT` | | Nullable |
| `occurred_at` | `DATETIME` | INDEX | |
| `created_at` | `DATETIME` | | `func.now()` |
### `vehicle.asset_events`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `UUID` | PK | `uuid.uuid4()` |
| `asset_id` | `UUID` | FK → `vehicle.assets.id` | NOT NULL, indexed |
| `event_type` | `VARCHAR(50)` | INDEX | |
| `status` | `VARCHAR(50)` | INDEX | |
| `description` | `TEXT` | | Nullable |
| `cost_id` | `INTEGER` | FK → `vehicle.asset_costs.id` | Nullable |
| `user_id` | `INTEGER` | FK → `identity.users.id` | Nullable |
| `organization_id` | `INTEGER` | FK → `fleet.organizations.id` | Nullable |
| `metadata` | `JSONB` | | Nullable |
| `occurred_at` | `DATETIME` | INDEX | |
| `created_at` | `DATETIME` | | `func.now()` |
### `vehicle.odometer_readings`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `asset_id` | `UUID` | FK → `vehicle.assets.id` | NOT NULL |
| `reading` | `INTEGER` | NOT NULL | |
| `recorded_at` | `DATETIME` | | |
| `source` | `VARCHAR(50)` | | |
| `created_at` | `DATETIME` | | `func.now()` |
### `vehicle.exchange_rates`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `rate` | `NUMERIC(18,6)` | NOT NULL | |
### `vehicle.catalog_discovery`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `make` | `VARCHAR(100)` | INDEX | NOT NULL |
| `model` | `VARCHAR(100)` | INDEX | NOT NULL |
| `vehicle_class` | `VARCHAR(50)` | INDEX | Default: 'car' |
| `market` | `VARCHAR(20)` | INDEX | Default: 'GLOBAL' |
| `model_year` | `INTEGER` | INDEX | Nullable |
| `status` | `VARCHAR(20)` | INDEX | Default: 'pending' |
| `source` | `VARCHAR(100)` | | Nullable |
| `priority_score` | `INTEGER` | | Default: 0 |
| `attempts` | `INTEGER` | | Default: 0 |
| `created_at` | `DATETIME` | | `func.now()` |
| `updated_at` | `DATETIME` | | `func.now()` |
### `vehicle.vehicle_expenses`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `UUID` | PK | `uuid.uuid4()` |
| `vehicle_id` | `UUID` | FK → `vehicle.assets.id` | NOT NULL, indexed |
| `category` | `VARCHAR(50)` | INDEX | NOT NULL |
| `amount` | `NUMERIC(18,2)` | NOT NULL | |
| `date` | `DATETIME` | INDEX | `func.now()` |
| `description` | `TEXT` | | Nullable |
| `created_at` | `DATETIME` | | `func.now()` |
### `vehicle.vehicle_transfer_requests`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `UUID` | PK | `uuid.uuid4()` |
| `asset_id` | `UUID` | FK → `vehicle.assets.id` | INDEX |
| `requester_id` | `INTEGER` | FK → `identity.users.id` | INDEX |
| `current_owner_id` | `INTEGER` | FK → `identity.persons.id` | INDEX, nullable |
| `status` | `VARCHAR(20)` | INDEX | Default: 'pending' |
| `requested_at` | `DATETIME` | | `func.now()` |
| `processed_at` | `DATETIME` | | Nullable |
| `notes` | `TEXT` | | Nullable |
### `vehicle.external_reference_library`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `specifications` | `JSON` | | Default: `{}` |
| `source_url` | `VARCHAR(500)` | UNIQUE | |
| `last_scraped_at` | `DATETIME` | | `func.now()` |
| `pipeline_status` | `VARCHAR(30)` | INDEX | Default: 'pending_enrich' |
| `matched_vmd_id` | `INTEGER` | FK → `vehicle.vehicle_model_definitions.id` | Nullable |
### `vehicle.auto_data_crawler_queue`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `url` | `VARCHAR(500)` | UNIQUE | NOT NULL |
| `level` | `VARCHAR(20)` | INDEX | NOT NULL |
| `category` | `VARCHAR(20)` | INDEX | Default: 'car' |
| `parent_id` | `INTEGER` | | Nullable |
| `name` | `VARCHAR(255)` | | |
| `status` | `VARCHAR(20)` | INDEX | Default: 'pending' |
| `error_msg` | `VARCHAR(1000)` | | Nullable |
| `retry_count` | `INTEGER` | | Default: 0 |
| `created_at` | `DATETIME` | | `func.now()` |
| `updated_at` | `DATETIME` | | `func.now()` |
### `vehicle.motorcycle_specs`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `crawler_id` | `INTEGER` | FK → `vehicle.auto_data_crawler_queue.id` | UNIQUE, CASCADE |
| `full_name` | `TEXT` | NOT NULL | |
| `url` | `TEXT` | | |
| `raw_data` | `JSONB` | NOT NULL | |
| `created_at` | `DATETIME` | | `func.now()` |
| `updated_at` | `DATETIME` | | `func.now()` |
### `vehicle.gb_catalog_discovery`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `vrm` | `VARCHAR` | INDEX | UK license plate |
| `make` | `VARCHAR` | | |
| `model` | `VARCHAR` | | |
| `status` | `VARCHAR` | | Default: 'pending' |
---
## 🧬 4. Schema: `fleet`
### `fleet.organizations`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `legal_owner_id` | `BIGINT` | FK → `identity.persons.id` | INDEX, nullable |
| `first_registered_at` | `DATETIME` | NOT NULL | `func.now()` |
| `current_lifecycle_started_at` | `DATETIME` | NOT NULL | `func.now()` |
| `last_deactivated_at` | `DATETIME` | | Nullable |
| `lifecycle_index` | `INTEGER` | | Default: 1 |
| `address_id` | `UUID` | FK → `system.addresses.id` | Nullable |
| `is_anonymized` | `BOOLEAN` | | Default: false |
| `full_name` | `VARCHAR` | NOT NULL | |
| `name` | `VARCHAR` | NOT NULL | |
| `display_name` | `VARCHAR(50)` | | Nullable |
| `folder_slug` | `VARCHAR(24)` | UNIQUE, INDEX | |
| `default_currency` | `VARCHAR(3)` | | Default: 'HUF' |
| `country_code` | `VARCHAR(3)` | | |
| `tax_id` | `VARCHAR` | | Nullable |
| `registration_number` | `VARCHAR` | | Nullable |
| `org_type` | `VARCHAR(20)` | | Default: 'business' |
| `status` | `VARCHAR(20)` | INDEX | |
| `is_deleted` | `BOOLEAN` | | Default: false |
| `created_at` | `DATETIME` | | `func.now()` |
| `updated_at` | `DATETIME` | | `func.now()` |
| `subscription_plan` | `VARCHAR(50)` | | |
| `subscription_tier_id` | `INTEGER` | FK → `system.subscription_tiers.id` | |
| `aliases` | `JSONB` | | |
| `tags` | `JSONB` | | |
### `fleet.org_roles`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `name_key` | `VARCHAR(50)` | UNIQUE, INDEX | NOT NULL |
| `display_name` | `VARCHAR(100)` | NOT NULL | |
| `description` | `VARCHAR(255)` | | Nullable |
| `is_system` | `BOOLEAN` | | Default: true |
| `priority` | `INTEGER` | | Default: 0 |
| `is_active` | `BOOLEAN` | | Default: true |
| `created_at` | `DATETIME` | | `func.now()` |
| `permissions` | `JSONB` | NOT NULL | Default: `{}` |
### `fleet.organization_members`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `organization_id` | `INTEGER` | FK → `fleet.organizations.id` | NOT NULL |
| `user_id` | `INTEGER` | FK → `identity.users.id` | Nullable |
| `person_id` | `BIGINT` | FK → `identity.persons.id` | Nullable |
| `invited_email` | `VARCHAR(255)` | | |
| `expires_at` | `DATETIME` | | Nullable |
| `role` | `ENUM(orguserrole)` | | Default: 'MEMBER' |
| `permissions` | `JSON` | | Default: `{}` |
| `is_permanent` | `BOOLEAN` | | Default: false |
| `is_verified` | `BOOLEAN` | | Default: false |
| `status` | `VARCHAR(20)` | | Default: 'active' |
| `created_at` | `DATETIME` | | `func.now()` |
| `updated_at` | `DATETIME` | | `func.now()` |
### `fleet.org_sales_assignments`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `organization_id` | `INTEGER` | FK → `fleet.organizations.id` | Nullable |
| `agent_user_id` | `INTEGER` | FK → `identity.users.id` | Nullable |
| `assigned_at` | `DATETIME` | | `func.now()` |
| `is_active` | `BOOLEAN` | | Default: true |
### `fleet.branches`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `UUID` | PK | `uuid.uuid4()` |
| `organization_id` | `INTEGER` | FK → `fleet.organizations.id` | NOT NULL |
| `address_id` | `UUID` | FK → `system.addresses.id` | Nullable |
| `name` | `VARCHAR(100)` | NOT NULL | |
| `is_main` | `BOOLEAN` | | Default: false |
| `postal_code` | `VARCHAR(10)` | INDEX | Nullable |
| `city` | `VARCHAR(100)` | INDEX | Nullable |
| `street_name` | `VARCHAR(150)` | | Nullable |
| `location` | `GEOMETRY(POINT, 4326)` | | PostGIS, nullable |
| `opening_hours` | `JSONB` | | Default: `{}` |
| `branch_rating` | `FLOAT` | | Default: 0.0 |
| `status` | `VARCHAR(30)` | | Default: 'active' |
| `is_deleted` | `BOOLEAN` | | Default: false |
| `created_at` | `DATETIME` | | `func.now()` |
### `fleet.locations`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `name` | `VARCHAR` | NOT NULL | |
| `type` | `ENUM(location_type)` | NOT NULL | stop/warehouse/client |
| `coordinates` | `VARCHAR` | | Nullable |
| `address_full` | `VARCHAR` | | Nullable |
| `capacity` | `INTEGER` | | Nullable |
---
## 🧬 5. Schema: `marketplace`
### `marketplace.service_profiles`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR(255)` | NOT NULL | |
| `organization_id` | `INTEGER` | FK → `fleet.organizations.id` | |
| `description` | `TEXT` | | Nullable |
| `category` | `VARCHAR(100)` | | |
| `status` | `VARCHAR(20)` | | Default: 'pending' |
| `is_verified` | `BOOLEAN` | | Default: false |
| `created_at` | `DATETIME` | | `func.now()` |
| `updated_at` | `DATETIME` | | `func.now()` |
### `marketplace.expertise_tags`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR(100)` | UNIQUE | |
| `parent_id` | `INTEGER` | FK → `marketplace.expertise_tags.id` | Self-ref, nullable |
| `category` | `VARCHAR(50)` | INDEX | |
### `marketplace.service_expertises`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| (junction table) | | | service_id ↔ expertise_id |
### `marketplace.service_staging`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR(255)` | INDEX | NOT NULL |
| `fingerprint` | `VARCHAR(64)` | UNIQUE, INDEX | NOT NULL |
| `city` | `VARCHAR(100)` | INDEX | NOT NULL |
| `status` | `VARCHAR(20)` | INDEX | Default: 'pending' |
| `validation_level` | `INTEGER` | | Default: 40 |
| `created_at` | `DATETIME` | | `func.now()` |
### `marketplace.discovery_parameters`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `city` | `VARCHAR(100)` | UNIQUE, INDEX | NOT NULL |
| `country_code` | `VARCHAR(2)` | | Default: 'HU' |
| `keyword` | `VARCHAR(100)` | | Nullable |
| `is_active` | `BOOLEAN` | | Default: true |
### `marketplace.service_specialties`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `parent_id` | `INTEGER` | FK → `marketplace.service_specialties.id` | Self-ref, nullable |
| `name` | `VARCHAR` | NOT NULL | |
| `slug` | `VARCHAR` | UNIQUE, INDEX | |
### `marketplace.service_providers`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `name` | `VARCHAR` | NOT NULL | |
| `address` | `VARCHAR` | NOT NULL | |
| `status` | `ENUM(moderation_status)` | | Default: 'pending' |
| `source` | `ENUM(source_type)` | | Default: 'manual' |
| `validation_score` | `INTEGER` | | Default: 0 |
| `created_at` | `DATETIME` | | `func.now()` |
### `marketplace.votes`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `user_id` | `INTEGER` | FK → `identity.users.id` | NOT NULL |
| `provider_id` | `INTEGER` | FK → `marketplace.service_providers.id` | NOT NULL |
| `vote_value` | `INTEGER` | NOT NULL | +1 or -1 |
| UNIQUE | | | `(user_id, provider_id)` |
### `marketplace.service_reviews`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Auto-increment |
| `service_id` | `INTEGER` | FK → `marketplace.service_profiles.id` | CASCADE |
| `user_id` | `INTEGER` | FK → `identity.users.id` | SET NULL |
| `transaction_id` | `UUID` | FK → `audit.financial_ledger.transaction_id` | RESTRICT, indexed |
| `price_rating` | `INTEGER` | NOT NULL | 1-10 |
| `quality_rating` | `INTEGER` | NOT NULL | 1-10 |
| `time_rating` | `INTEGER` | NOT NULL | 1-10 |
| `communication_rating` | `INTEGER` | NOT NULL | 1-10 |
| `comment` | `TEXT` | | Nullable |
| `is_verified` | `BOOLEAN` | | Default: true |
| `created_at` | `DATETIME` | | `func.now()` |
| UNIQUE | | | `(transaction_id)` |
### `marketplace.ratings`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `author_id` | `INTEGER` | FK → `identity.users.id` | NOT NULL |
| `target_organization_id` | `INTEGER` | FK → `fleet.organizations.id` | Nullable |
| `target_user_id` | `INTEGER` | FK → `identity.users.id` | Nullable |
| `target_branch_id` | `UUID` | FK → `fleet.branches.id` | Nullable |
| `score` | `NUMERIC(3,2)` | NOT NULL | |
| `comment` | `TEXT` | | Nullable |
| `is_verified` | `BOOLEAN` | | Default: false |
| `created_at` | `DATETIME` | | `func.now()` |
---
## 🧬 6. Schema: `finance`
### `finance.issuers`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR(255)` | INDEX | NOT NULL |
| `tax_id` | `VARCHAR(50)` | UNIQUE, INDEX | Nullable |
| `type` | `ENUM(issuer_type)` | NOT NULL | KFT/EV/BT/ZRT/OTHER |
| `revenue_limit` | `NUMERIC(18,4)` | | Default: 19500000.0 |
| `is_active` | `BOOLEAN` | | Default: true |
| `created_at` | `DATETIME` | | `func.now()` |
### `finance.payment_intents`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `intent_token` | `UUID` | UNIQUE, INDEX | NOT NULL |
| `payer_id` | `INTEGER` | FK → `identity.users.id` | NOT NULL |
| `beneficiary_id` | `INTEGER` | FK → `identity.users.id` | Nullable |
| `net_amount` | `NUMERIC(18,4)` | | |
| `handling_fee` | `NUMERIC(18,4)` | | |
| `gross_amount` | `NUMERIC(18,4)` | | |
| `status` | `ENUM(payment_intent_status)` | | Default: 'PENDING' |
| `created_at` | `DATETIME` | | `func.now()` |
### `finance.org_subscriptions`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `org_id` | `INTEGER` | FK → `fleet.organizations.id` | NOT NULL |
| `tier_id` | `INTEGER` | FK → `system.subscription_tiers.id` | NOT NULL |
| `valid_from` | `DATETIME` | | `func.now()` |
| `valid_until` | `DATETIME` | | Nullable |
| `is_active` | `BOOLEAN` | | Default: true |
| `extra_allowances` | `JSONB` | | Default: `{}` |
### `finance.user_subscriptions`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `user_id` | `INTEGER` | FK → `identity.users.id` | NOT NULL |
| `tier_id` | `INTEGER` | FK → `system.subscription_tiers.id` | NOT NULL |
| `valid_from` | `DATETIME` | | `func.now()` |
| `valid_until` | `DATETIME` | | Nullable |
| `is_active` | `BOOLEAN` | | Default: true |
| `created_at` | `DATETIME` | | `func.now()` |
### `finance.credit_logs`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `org_id` | `INTEGER` | FK → `fleet.organizations.id` | NOT NULL |
| `amount` | `NUMERIC(10,2)` | NOT NULL | |
| `description` | `VARCHAR` | | Nullable |
| `created_at` | `DATETIME` | | `func.now()` |
---
## 🧬 7. Schema: `audit`
### `audit.audit_logs`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `user_id` | `INTEGER` | FK → `identity.users.id` | Nullable |
| `severity` | `ENUM(log_severity)` | | Default: 'INFO' |
| `action` | `VARCHAR(100)` | INDEX | |
| `target_type` | `VARCHAR(50)` | INDEX | Nullable |
| `target_id` | `VARCHAR(50)` | INDEX | Nullable |
| `old_data` | `JSON` | | Nullable |
| `new_data` | `JSON` | | Nullable |
| `ip_address` | `VARCHAR(45)` | INDEX | Nullable |
| `user_agent` | `TEXT` | | Nullable |
| `timestamp` | `DATETIME` | INDEX | `func.now()` |
### `audit.security_audit_logs`
(security-specific audit trail)
### `audit.operational_logs`
(operational/process logs)
### `audit.process_logs`
(background process logs)
### `audit.financial_ledger`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `transaction_id` | `UUID` | UNIQUE | NOT NULL |
| `user_id` | `INTEGER` | FK → `identity.users.id` | NOT NULL |
| `entry_type` | `ENUM(ledger_entry_type)` | NOT NULL | DEBIT/CREDIT |
| `wallet_type` | `ENUM(wallet_type)` | NOT NULL | EARNED/PURCHASED/SERVICE_COINS/VOUCHER |
| `amount` | `NUMERIC(18,4)` | NOT NULL | |
| `balance_after` | `NUMERIC(18,4)` | | Nullable |
| `status` | `ENUM(ledger_status)` | | Default: 'SUCCESS' |
| `description` | `VARCHAR` | | Nullable |
| `created_at` | `DATETIME` | | `func.now()` |
---
## 🧬 8. Schema: `gamification`
### `gamification.point_rules`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `action_type` | `INTEGER` | UNIQUE | NOT NULL |
| `base_points` | `INTEGER` | NOT NULL | |
| `description` | `VARCHAR` | | |
### `gamification.level_configs`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `level` | `INTEGER` | UNIQUE | NOT NULL |
| `xp_required` | `INTEGER` | NOT NULL | |
### `gamification.points_ledger`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `user_id` | `INTEGER` | FK → `identity.users.id` | NOT NULL |
| `points` | `INTEGER` | NOT NULL | |
| `reason` | `VARCHAR` | | |
| `created_at` | `DATETIME` | | `func.now()` |
### `gamification.user_stats`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `user_id` | `INTEGER` | FK → `identity.users.id` | UNIQUE |
| `total_xp` | `INTEGER` | | Default: 0 |
| `level` | `INTEGER` | | Default: 1 |
| `current_streak` | `INTEGER` | | Default: 0 |
| `longest_streak` | `INTEGER` | | Default: 0 |
| `updated_at` | `DATETIME` | | `func.now()` |
### `gamification.badges`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `name` | `VARCHAR` | UNIQUE | |
| `description` | `VARCHAR` | NOT NULL | |
| `icon_url` | `VARCHAR` | | Nullable |
### `gamification.user_badges`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `user_id` | `INTEGER` | FK → `identity.users.id` | |
| `badge_id` | `INTEGER` | FK → `gamification.badges.id` | |
| `earned_at` | `DATETIME` | | `func.now()` |
### `gamification.user_contributions`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `user_id` | `INTEGER` | FK → `identity.users.id` | NOT NULL |
| `season_id` | `INTEGER` | FK → `gamification.seasons.id` | Nullable |
| `contribution_type` | `VARCHAR(50)` | INDEX | NOT NULL |
| `points_awarded` | `INTEGER` | | Default: 0 |
| `xp_awarded` | `INTEGER` | | Default: 0 |
| `status` | `VARCHAR(20)` | INDEX | Default: 'pending' |
| `created_at` | `DATETIME` | | `func.now()` |
### `gamification.seasons`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `name` | `VARCHAR(100)` | NOT NULL | |
| `start_date` | `DATE` | NOT NULL | |
| `end_date` | `DATE` | NOT NULL | |
| `is_active` | `BOOLEAN` | | Default: false |
| `created_at` | `DATETIME` | | `func.now()` |
### `gamification.competitions`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR` | NOT NULL | |
| `description` | `TEXT` | | Nullable |
| `start_date` | `DATETIME` | NOT NULL | |
| `end_date` | `DATETIME` | NOT NULL | |
| `is_active` | `BOOLEAN` | | Default: true |
### `gamification.user_scores`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `user_id` | `INTEGER` | FK → `identity.users.id` | |
| `competition_id` | `INTEGER` | FK → `gamification.competitions.id` | |
| `points` | `INTEGER` | | Default: 0 |
| UNIQUE | | | `(user_id, competition_id)` |
### `gamification.seasonal_competitions`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | Indexed |
| `name` | `VARCHAR(200)` | NOT NULL | |
| `season_id` | `INTEGER` | FK → `gamification.seasons.id` | INDEX |
| `start_date` | `DATE` | NOT NULL | |
| `end_date` | `DATE` | NOT NULL | |
| `status` | `VARCHAR(20)` | INDEX | Default: 'draft' |
| `created_at` | `DATETIME` | | `func.now()` |
---
## 🧬 9. Schema: `marketing`
### `marketing.campaigns`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR(200)` | INDEX | NOT NULL |
| `status` | `VARCHAR(20)` | INDEX | Default: 'draft' |
| `targeting` | `JSONB` | | Nullable |
| `priority` | `INTEGER` | NOT NULL | Default: 100 |
| `start_date` | `DATETIME` | | Nullable |
| `end_date` | `DATETIME` | | Nullable |
| `current_impressions` | `INTEGER` | | Default: 0 |
| `current_clicks` | `INTEGER` | | Default: 0 |
| `created_at` | `DATETIME` | | `func.now()` |
| `updated_at` | `DATETIME` | | Nullable |
### `marketing.creatives`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR(200)` | NOT NULL | |
| `creative_type` | `VARCHAR(20)` | NOT NULL | 'image' or 'html_snippet' |
| `image_url` | `VARCHAR(500)` | | Nullable |
| `html_snippet` | `TEXT` | | Nullable |
| `click_url` | `VARCHAR(500)` | | Nullable |
| `is_active` | `BOOLEAN` | | Default: true |
| `created_at` | `DATETIME` | | `func.now()` |
### `marketing.placements`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `name` | `VARCHAR(100)` | UNIQUE | NOT NULL |
| `placement_type` | `VARCHAR(20)` | NOT NULL |
| `is_active` | `BOOLEAN` | | Default: true |
### `marketing.campaign_creatives`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `campaign_id` | `INTEGER` | FK → `marketing.campaigns.id` | CASCADE |
| `creative_id` | `INTEGER` | FK → `marketing.creatives.id` | CASCADE |
| UNIQUE | | | `(campaign_id, creative_id)` |
### `marketing.campaign_placements`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `campaign_id` | `INTEGER` | FK → `marketing.campaigns.id` | CASCADE |
| `placement_id` | `INTEGER` | FK → `marketing.placements.id` | CASCADE |
| UNIQUE | | | `(campaign_id, placement_id)` |
### `marketing.ad_impressions`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `campaign_id` | `INTEGER` | FK → `marketing.campaigns.id` | CASCADE |
| `user_id` | `INTEGER` | | Nullable |
| `session_id` | `VARCHAR(100)` | | Nullable |
| `ip_address` | `VARCHAR(45)` | | Nullable |
| `created_at` | `DATETIME` | | `func.now()` |
### `marketing.ad_clicks`
| Column | Type | PK/FK | Notes |
|--------|------|-------|-------|
| `id` | `INTEGER` | PK | |
| `impression_id` | `INTEGER` | FK → `marketing.ad_impressions.id` | SET NULL |
| `campaign_id` | `INTEGER` | FK → `marketing.campaigns.id` | CASCADE |
| `user_id` | `INTEGER` | | Nullable |
| `created_at` | `DATETIME` | | `func.now()` |
---
## 📊 Summary Statistics
| Schema | Approx. Tables | Source Files |
|--------|---------------|-------------|
| `identity` | 11 | `identity/identity.py`, `identity/security.py` |
| `system` | 14 | `identity/address.py`, `system/system.py`, `system/document.py`, `system/translation.py`, `system/legal.py` |
| `vehicle` | 24 | `vehicle/vehicle_definitions.py`, `vehicle/vehicle.py`, `vehicle/asset.py`, `vehicle/motorcycle_specs.py`, `vehicle/external_reference.py`, `vehicle/external_reference_queue.py` |
| `fleet` | 7 | `marketplace/organization.py`, `marketplace/logistics.py` |
| `marketplace` | 12 | `marketplace/service.py`, `marketplace/staged_data.py`, `marketplace/service_request.py`, `identity/social.py`, `identity/address.py` |
| `finance` | 6 | `marketplace/finance.py`, `marketplace/payment.py`, `core_logic.py` |
| `audit` | 5 | `vehicle/history.py`, `system/audit.py` |
| `gamification` | 11 | `gamification/gamification.py`, `identity/social.py` |
| `marketing` | 8 | `marketing.py` |
| **TOTAL** | **~98** | **36 model files across 7 subdirectories** |
---
*Generated: 2026-06-21T00:15 UTC · Source: SQLAlchemy models in `backend/app/models/`*