# app/api/v1/vendor/onboarding.py """ Vendor onboarding API endpoints. Provides endpoints for the 4-step mandatory onboarding wizard: 1. Company Profile Setup 2. Letzshop API Configuration 3. Product & Order Import Configuration 4. Order Sync (historical import) Vendor Context: Uses token_vendor_id from JWT token (authenticated vendor API pattern). """ import logging from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from app.api.deps import get_current_vendor_api from app.core.database import get_db from app.services.onboarding_service import OnboardingService from models.database.user import User from models.schema.onboarding import ( CompanyProfileRequest, CompanyProfileResponse, LetzshopApiConfigRequest, LetzshopApiConfigResponse, LetzshopApiTestRequest, LetzshopApiTestResponse, OnboardingStatusResponse, OrderSyncCompleteRequest, OrderSyncCompleteResponse, OrderSyncProgressResponse, OrderSyncTriggerRequest, OrderSyncTriggerResponse, ProductImportConfigRequest, ProductImportConfigResponse, ) router = APIRouter(prefix="/onboarding") logger = logging.getLogger(__name__) # ============================================================================= # Status Endpoint # ============================================================================= @router.get("/status", response_model=OnboardingStatusResponse) def get_onboarding_status( current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """ Get current onboarding status. Returns full status including all step completion states and progress. """ service = OnboardingService(db) status = service.get_status_response(current_user.token_vendor_id) return status # ============================================================================= # Step 1: Company Profile # ============================================================================= @router.get("/step/company-profile") def get_company_profile( current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """ Get current company profile data for editing. Returns pre-filled data from vendor and company records. """ service = OnboardingService(db) return service.get_company_profile_data(current_user.token_vendor_id) @router.post("/step/company-profile", response_model=CompanyProfileResponse) def save_company_profile( request: CompanyProfileRequest, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """ Save company profile and complete Step 1. Updates vendor and company records with provided data. """ service = OnboardingService(db) result = service.complete_company_profile( vendor_id=current_user.token_vendor_id, company_name=request.company_name, brand_name=request.brand_name, description=request.description, contact_email=request.contact_email, contact_phone=request.contact_phone, website=request.website, business_address=request.business_address, tax_number=request.tax_number, default_language=request.default_language, dashboard_language=request.dashboard_language, ) db.commit() # Commit at API level for transaction control return result # ============================================================================= # Step 2: Letzshop API Configuration # ============================================================================= @router.post("/step/letzshop-api/test", response_model=LetzshopApiTestResponse) def test_letzshop_api( request: LetzshopApiTestRequest, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """ Test Letzshop API connection without saving. Use this to validate API key before saving credentials. """ service = OnboardingService(db) return service.test_letzshop_api( api_key=request.api_key, shop_slug=request.shop_slug, ) @router.post("/step/letzshop-api", response_model=LetzshopApiConfigResponse) def save_letzshop_api( request: LetzshopApiConfigRequest, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """ Save Letzshop API credentials and complete Step 2. Tests connection first, only saves if successful. """ service = OnboardingService(db) result = service.complete_letzshop_api( vendor_id=current_user.token_vendor_id, api_key=request.api_key, shop_slug=request.shop_slug, letzshop_vendor_id=request.vendor_id, ) db.commit() # Commit at API level for transaction control return result # ============================================================================= # Step 3: Product & Order Import Configuration # ============================================================================= @router.get("/step/product-import") def get_product_import_config( current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """ Get current product import configuration. Returns pre-filled CSV URLs and Letzshop feed settings. """ service = OnboardingService(db) return service.get_product_import_config(current_user.token_vendor_id) @router.post("/step/product-import", response_model=ProductImportConfigResponse) def save_product_import_config( request: ProductImportConfigRequest, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """ Save product import configuration and complete Step 3. At least one CSV URL must be provided. """ service = OnboardingService(db) result = service.complete_product_import( vendor_id=current_user.token_vendor_id, csv_url_fr=request.csv_url_fr, csv_url_en=request.csv_url_en, csv_url_de=request.csv_url_de, default_tax_rate=request.default_tax_rate, delivery_method=request.delivery_method, preorder_days=request.preorder_days, ) db.commit() # Commit at API level for transaction control return result # ============================================================================= # Step 4: Order Sync # ============================================================================= @router.post("/step/order-sync/trigger", response_model=OrderSyncTriggerResponse) def trigger_order_sync( request: OrderSyncTriggerRequest, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """ Trigger historical order import. Creates a background job that imports orders from Letzshop. """ service = OnboardingService(db) result = service.trigger_order_sync( vendor_id=current_user.token_vendor_id, user_id=current_user.id, days_back=request.days_back, include_products=request.include_products, ) db.commit() # Commit at API level for transaction control return result @router.get( "/step/order-sync/progress/{job_id}", response_model=OrderSyncProgressResponse, ) def get_order_sync_progress( job_id: int, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """ Get order sync job progress. Poll this endpoint to show progress bar during import. """ service = OnboardingService(db) return service.get_order_sync_progress( vendor_id=current_user.token_vendor_id, job_id=job_id, ) @router.post("/step/order-sync/complete", response_model=OrderSyncCompleteResponse) def complete_order_sync( request: OrderSyncCompleteRequest, current_user: User = Depends(get_current_vendor_api), db: Session = Depends(get_db), ): """ Mark order sync step as complete. Called after the import job finishes (success or failure). This also marks the entire onboarding as complete. """ service = OnboardingService(db) result = service.complete_order_sync( vendor_id=current_user.token_vendor_id, job_id=request.job_id, ) db.commit() # Commit at API level for transaction control return result