From 754d61e6226df627f93c027560ed786f5e4de323 Mon Sep 17 00:00:00 2001 From: Babak Alizadeh Date: Sun, 21 Sep 2025 20:31:52 +0330 Subject: [PATCH] progress in file service --- .../adapters/api/v1/admin/file_storage.py | 4 +-- hesabixAPI/adapters/api/v1/health.py | 2 +- .../adapters/api/v1/schema_models/__init__.py | 10 +++++++ .../file_storage.py | 0 .../adapters/api/v1/schemas/__init__.py | 2 -- hesabixAPI/adapters/db/models/file_storage.py | 21 +++++++------ .../repositories/file_storage_repository.py | 2 +- hesabixAPI/app/core/permissions.py | 5 ++++ hesabixAPI/hesabix_api.egg-info/SOURCES.txt | 5 ++-- hesabixAPI/locales/en/LC_MESSAGES/messages.mo | Bin 4881 -> 5007 bytes hesabixAPI/locales/fa/LC_MESSAGES/messages.mo | Bin 6171 -> 6324 bytes .../8bf0dbb9fba9_add_file_storage_tables.py | 28 ------------------ hesabixUI/hesabix_ui/lib/l10n/app_en.arb | 1 - hesabixUI/hesabix_ui/lib/l10n/app_fa.arb | 1 - .../lib/l10n/app_localizations.dart | 6 ---- .../lib/l10n/app_localizations_en.dart | 3 -- .../lib/l10n/app_localizations_fa.dart | 3 -- 17 files changed, 31 insertions(+), 62 deletions(-) create mode 100644 hesabixAPI/adapters/api/v1/schema_models/__init__.py rename hesabixAPI/adapters/api/v1/{schemas => schema_models}/file_storage.py (100%) delete mode 100644 hesabixAPI/adapters/api/v1/schemas/__init__.py delete mode 100644 hesabixAPI/migrations/versions/8bf0dbb9fba9_add_file_storage_tables.py diff --git a/hesabixAPI/adapters/api/v1/admin/file_storage.py b/hesabixAPI/adapters/api/v1/admin/file_storage.py index f8e9852..71b5c35 100644 --- a/hesabixAPI/adapters/api/v1/admin/file_storage.py +++ b/hesabixAPI/adapters/api/v1/admin/file_storage.py @@ -7,12 +7,12 @@ from adapters.db.session import get_db from app.core.auth_dependency import get_current_user from app.core.permissions import require_permission from app.core.responses import success_response -from app.core.error_handlers import ApiError +from app.core.responses import ApiError from app.core.i18n import locale_dependency from app.services.file_storage_service import FileStorageService from adapters.db.repositories.file_storage_repository import StorageConfigRepository, FileStorageRepository from adapters.db.models.user import User -from adapters.api.v1.schemas.file_storage import ( +from adapters.api.v1.schema_models.file_storage import ( StorageConfigCreateRequest, StorageConfigUpdateRequest, FileUploadRequest, diff --git a/hesabixAPI/adapters/api/v1/health.py b/hesabixAPI/adapters/api/v1/health.py index 6f1cb59..fc9c8c8 100644 --- a/hesabixAPI/adapters/api/v1/health.py +++ b/hesabixAPI/adapters/api/v1/health.py @@ -1,5 +1,5 @@ from fastapi import APIRouter -from .schemas import SuccessResponse +from adapters.api.v1.schemas import SuccessResponse router = APIRouter(prefix="/health", tags=["health"]) diff --git a/hesabixAPI/adapters/api/v1/schema_models/__init__.py b/hesabixAPI/adapters/api/v1/schema_models/__init__.py new file mode 100644 index 0000000..03f73ed --- /dev/null +++ b/hesabixAPI/adapters/api/v1/schema_models/__init__.py @@ -0,0 +1,10 @@ +# This file makes the directory a Python package + +# Import from file_storage module +from .file_storage import * + +# Re-export from parent schemas module +import sys +import os +sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) +from schemas import * diff --git a/hesabixAPI/adapters/api/v1/schemas/file_storage.py b/hesabixAPI/adapters/api/v1/schema_models/file_storage.py similarity index 100% rename from hesabixAPI/adapters/api/v1/schemas/file_storage.py rename to hesabixAPI/adapters/api/v1/schema_models/file_storage.py diff --git a/hesabixAPI/adapters/api/v1/schemas/__init__.py b/hesabixAPI/adapters/api/v1/schemas/__init__.py deleted file mode 100644 index 5f4296c..0000000 --- a/hesabixAPI/adapters/api/v1/schemas/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Import all schemas -from .file_storage import * diff --git a/hesabixAPI/adapters/db/models/file_storage.py b/hesabixAPI/adapters/db/models/file_storage.py index e6a1ee5..e52ef85 100644 --- a/hesabixAPI/adapters/db/models/file_storage.py +++ b/hesabixAPI/adapters/db/models/file_storage.py @@ -1,5 +1,4 @@ -from sqlalchemy import Column, String, Integer, DateTime, Boolean, Text, ForeignKey, JSON -from sqlalchemy.dialects.postgresql import UUID +from sqlalchemy import Column, String, Integer, DateTime, Boolean, Text, ForeignKey, JSON, BigInteger from sqlalchemy.orm import relationship from sqlalchemy.sql import func import uuid @@ -10,17 +9,17 @@ from adapters.db.session import Base class FileStorage(Base): __tablename__ = "file_storage" - id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) original_name = Column(String(255), nullable=False) stored_name = Column(String(255), nullable=False) file_path = Column(String(500), nullable=False) file_size = Column(Integer, nullable=False) mime_type = Column(String(100), nullable=False) storage_type = Column(String(20), nullable=False) # local, ftp - storage_config_id = Column(UUID(as_uuid=True), ForeignKey("storage_configs.id"), nullable=True) - uploaded_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False) + storage_config_id = Column(String(36), ForeignKey("storage_configs.id"), nullable=True) + uploaded_by = Column(Integer, ForeignKey("users.id"), nullable=False) module_context = Column(String(50), nullable=False) # tickets, accounting, business_logo, etc. - context_id = Column(UUID(as_uuid=True), nullable=True) # ticket_id, document_id, etc. + context_id = Column(String(36), nullable=True) # ticket_id, document_id, etc. developer_data = Column(JSON, nullable=True) checksum = Column(String(64), nullable=True) is_active = Column(Boolean, default=True, nullable=False) @@ -41,13 +40,13 @@ class FileStorage(Base): class StorageConfig(Base): __tablename__ = "storage_configs" - id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) name = Column(String(100), nullable=False) storage_type = Column(String(20), nullable=False) # local, ftp is_default = Column(Boolean, default=False, nullable=False) is_active = Column(Boolean, default=True, nullable=False) config_data = Column(JSON, nullable=False) - created_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False) + created_by = Column(Integer, ForeignKey("users.id"), nullable=False) created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False) @@ -58,12 +57,12 @@ class StorageConfig(Base): class FileVerification(Base): __tablename__ = "file_verifications" - id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) - file_id = Column(UUID(as_uuid=True), ForeignKey("file_storage.id"), nullable=False) + id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) + file_id = Column(String(36), ForeignKey("file_storage.id"), nullable=False) module_name = Column(String(50), nullable=False) verification_token = Column(String(100), nullable=False) verified_at = Column(DateTime(timezone=True), nullable=True) - verified_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True) + verified_by = Column(Integer, ForeignKey("users.id"), nullable=True) verification_data = Column(JSON, nullable=True) created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) diff --git a/hesabixAPI/adapters/db/repositories/file_storage_repository.py b/hesabixAPI/adapters/db/repositories/file_storage_repository.py index f0bffae..0f434ff 100644 --- a/hesabixAPI/adapters/db/repositories/file_storage_repository.py +++ b/hesabixAPI/adapters/db/repositories/file_storage_repository.py @@ -5,7 +5,7 @@ from sqlalchemy import and_, or_, desc, func from datetime import datetime, timedelta from adapters.db.models.file_storage import FileStorage, StorageConfig, FileVerification -from adapters.db.repositories.base import BaseRepository +from adapters.db.repositories.base_repo import BaseRepository class FileStorageRepository(BaseRepository[FileStorage]): diff --git a/hesabixAPI/app/core/permissions.py b/hesabixAPI/app/core/permissions.py index 32c938d..1750002 100644 --- a/hesabixAPI/app/core/permissions.py +++ b/hesabixAPI/app/core/permissions.py @@ -137,3 +137,8 @@ def require_business_management(): def require_system_settings(): """دسترسی تنظیمات سیستم""" return require_app_permission("system_settings") + + +def require_permission(permission: str): + """Decorator عمومی برای بررسی دسترسی - wrapper برای require_app_permission""" + return require_app_permission(permission) diff --git a/hesabixAPI/hesabix_api.egg-info/SOURCES.txt b/hesabixAPI/hesabix_api.egg-info/SOURCES.txt index e134326..f9b73d8 100644 --- a/hesabixAPI/hesabix_api.egg-info/SOURCES.txt +++ b/hesabixAPI/hesabix_api.egg-info/SOURCES.txt @@ -9,8 +9,8 @@ adapters/api/v1/health.py adapters/api/v1/schemas.py adapters/api/v1/users.py adapters/api/v1/admin/file_storage.py -adapters/api/v1/schemas/__init__.py -adapters/api/v1/schemas/file_storage.py +adapters/api/v1/schema_models/__init__.py +adapters/api/v1/schema_models/file_storage.py adapters/api/v1/support/__init__.py adapters/api/v1/support/categories.py adapters/api/v1/support/operator.py @@ -87,7 +87,6 @@ migrations/versions/20250117_000007_create_business_permissions_table.py migrations/versions/20250915_000001_init_auth_tables.py migrations/versions/20250916_000002_add_referral_fields.py migrations/versions/5553f8745c6e_add_support_tables.py -migrations/versions/8bf0dbb9fba9_add_file_storage_tables.py tests/__init__.py tests/test_health.py tests/test_permissions.py \ No newline at end of file diff --git a/hesabixAPI/locales/en/LC_MESSAGES/messages.mo b/hesabixAPI/locales/en/LC_MESSAGES/messages.mo index b49073d4993eb59b9f12143abca0921654623239..4beb188931e5a83643954be61217d20678167b82 100644 GIT binary patch delta 1526 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 p#d(G5|K#e^uKoj+KpIPQiWl None: - # ### commands auto generated by Alembic - please adjust! ### - pass - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - pass - # ### end Alembic commands ### diff --git a/hesabixUI/hesabix_ui/lib/l10n/app_en.arb b/hesabixUI/hesabix_ui/lib/l10n/app_en.arb index 4d91189..282bf91 100644 --- a/hesabixUI/hesabix_ui/lib/l10n/app_en.arb +++ b/hesabixUI/hesabix_ui/lib/l10n/app_en.arb @@ -392,7 +392,6 @@ "apply": "Apply", "reset": "Reset", "page": "Page", - "of": "of", "itemsPerPage": "Items per page", "previous": "Previous", "next": "Next", diff --git a/hesabixUI/hesabix_ui/lib/l10n/app_fa.arb b/hesabixUI/hesabix_ui/lib/l10n/app_fa.arb index 80955e8..8e33397 100644 --- a/hesabixUI/hesabix_ui/lib/l10n/app_fa.arb +++ b/hesabixUI/hesabix_ui/lib/l10n/app_fa.arb @@ -391,7 +391,6 @@ "apply": "اعمال", "reset": "بازنشانی", "page": "صفحه", - "of": "از", "itemsPerPage": "آیتم در هر صفحه", "previous": "قبلی", "next": "بعدی", diff --git a/hesabixUI/hesabix_ui/lib/l10n/app_localizations.dart b/hesabixUI/hesabix_ui/lib/l10n/app_localizations.dart index 6488f47..1e2e0c7 100644 --- a/hesabixUI/hesabix_ui/lib/l10n/app_localizations.dart +++ b/hesabixUI/hesabix_ui/lib/l10n/app_localizations.dart @@ -2198,12 +2198,6 @@ abstract class AppLocalizations { /// **'Reset'** String get reset; - /// No description provided for @of. - /// - /// In en, this message translates to: - /// **'of'** - String get of; - /// No description provided for @itemsPerPage. /// /// In en, this message translates to: diff --git a/hesabixUI/hesabix_ui/lib/l10n/app_localizations_en.dart b/hesabixUI/hesabix_ui/lib/l10n/app_localizations_en.dart index aa08f01..45cabef 100644 --- a/hesabixUI/hesabix_ui/lib/l10n/app_localizations_en.dart +++ b/hesabixUI/hesabix_ui/lib/l10n/app_localizations_en.dart @@ -1089,9 +1089,6 @@ class AppLocalizationsEn extends AppLocalizations { @override String get reset => 'Reset'; - @override - String get of => 'of'; - @override String get itemsPerPage => 'Items per page'; diff --git a/hesabixUI/hesabix_ui/lib/l10n/app_localizations_fa.dart b/hesabixUI/hesabix_ui/lib/l10n/app_localizations_fa.dart index 4d5cb11..e8e2e63 100644 --- a/hesabixUI/hesabix_ui/lib/l10n/app_localizations_fa.dart +++ b/hesabixUI/hesabix_ui/lib/l10n/app_localizations_fa.dart @@ -1083,9 +1083,6 @@ class AppLocalizationsFa extends AppLocalizations { @override String get reset => 'بازنشانی'; - @override - String get of => 'از'; - @override String get itemsPerPage => 'آیتم در هر صفحه';