diff --git a/backend/api/v1/modules/core/permissions/routes.py b/backend/api/v1/modules/core/permissions/routes.py index 31a55e21..7d38370c 100644 --- a/backend/api/v1/modules/core/permissions/routes.py +++ b/backend/api/v1/modules/core/permissions/routes.py @@ -78,6 +78,7 @@ async def get_my_permissions( """ # 1. Validar acceso básico a la compañía # Nota: pass None en required_permissions permite el paso al bootstrap + print(f"DEBUG: get_my_permissions: cia={company_id} user={current_user.get('preferred_username')}") tenant_id = validate_access_to_resource(db, company_id, current_user) user_id = current_user.get("sub") or current_user.get("id") diff --git a/backend/core/security.py b/backend/core/security.py index c2e12023..5d88da67 100644 --- a/backend/core/security.py +++ b/backend/core/security.py @@ -632,18 +632,21 @@ def validate_access_to_resource( """ tenant_id = resolve_effective_tenant_id_from_user(current_user) + print(f"DEBUG: validate_access_to_resource: tid={tenant_id} user={current_user.get('preferred_username')}") # Admin global Keycloak / master: lista ``roles`` del Hub (/auth/me), con fallback JWT. all_user_roles = collect_user_role_names(current_user) is_keycloak_admin = "admin" in all_user_roles + print(f"DEBUG: validate_access_to_resource: is_admin={is_keycloak_admin} roles={all_user_roles}") # 🚪 EXCEPCIÓN ESPECIAL: Si es el endpoint /me, permitimos el paso para el Bootstrap # Detectamos si no se requieren permisos (típico de /me) is_me_endpoint = required_permissions is None + print(f"DEBUG: validate_access_to_resource: is_me={is_me_endpoint} required={required_permissions}") if not is_keycloak_admin and not is_me_endpoint: if not validate_company_access(db, company_id, current_user): - print(f"DEBUG: Acceso denegado a compañía {company_id}") + print(f"DEBUG: validate_access_to_resource: ACCESO DENEGADO a cia {company_id}") raise HTTPException(status_code=403, detail="Access denied to this company") # Si no hay tenant_id, intentamos recuperarlo de la empresa @@ -693,7 +696,9 @@ def validate_access_to_resource( print(f"DEBUG: Error en auto-bootstrap de seguridad: {e}") if not has_access: - print(f"DEBUG: Permiso denegado. Faltan: {required_permissions}") + print(f"DEBUG: validate_access_to_resource: PERMISO DENEGADO. Faltan: {required_permissions}") raise HTTPException(status_code=403, detail="Permission denied") + + print(f"DEBUG: validate_access_to_resource: ACCESO CONCEDIDO") return tenant_id or 1 diff --git a/backend/main.py b/backend/main.py index 8af725a5..2fc08859 100644 --- a/backend/main.py +++ b/backend/main.py @@ -65,8 +65,8 @@ async def on_startup(): if settings.DEBUG: app.add_middleware(RequestLoggingMiddleware) -app.add_middleware(LicenseValidationMiddleware) app.add_middleware(TenantMiddleware) +app.add_middleware(LicenseValidationMiddleware) app.add_middleware(UserContextMiddleware) # CORS debe ser el último en añadirse para que sea el más externo diff --git a/backend_logs.txt b/backend_logs.txt new file mode 100644 index 00000000..04a08880 --- /dev/null +++ b/backend_logs.txt @@ -0,0 +1,290 @@ +anexo76-backend | Esperando a que PostgreSQL esté disponible en postgres-a76:5432... +anexo76-backend | ✓ PostgreSQL está listo y accesible +anexo76-backend | Iniciando proceso: uvicorn main:app --host 0.0.0.0 --port 8000 --reload --log-level info +anexo76-backend | INFO: Will watch for changes in these directories: ['/app'] +anexo76-backend | INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) +anexo76-backend | INFO: Started reloader process [1] using WatchFiles +anexo76-backend | DEBUG: Celery Broker URL: redis://valkey:6379/0 +anexo76-backend | INFO: Started server process [9] +anexo76-backend | INFO: Waiting for application startup. +anexo76-backend | 2026-05-06 21:36:55,160 - main - INFO - Iniciando la aplicación Anexo76... +anexo76-backend | INFO [alembic.runtime.migration] Context impl PostgresqlImpl. +anexo76-backend | INFO [alembic.runtime.migration] Will assume transactional DDL. +anexo76-backend | 2026-05-06 21:36:57,014 - botocore.hooks - DEBUG - Changing event name from creating-client-class.iot-data to creating-client-class.iot-data-plane +anexo76-backend | 2026-05-06 21:36:57,015 - botocore.hooks - DEBUG - Changing event name from before-call.apigateway to before-call.api-gateway +anexo76-backend | 2026-05-06 21:36:57,016 - botocore.hooks - DEBUG - Changing event name from request-created.machinelearning.Predict to request-created.machine-learning.Predict +anexo76-backend | 2026-05-06 21:36:57,016 - botocore.hooks - DEBUG - Changing event name from before-parameter-build.autoscaling.CreateLaunchConfiguration to before-parameter-build.auto-scaling.CreateLaunchConfiguration +anexo76-backend | 2026-05-06 21:36:57,016 - botocore.hooks - DEBUG - Changing event name from before-parameter-build.route53 to before-parameter-build.route-53 +anexo76-backend | 2026-05-06 21:36:57,016 - botocore.hooks - DEBUG - Changing event name from request-created.cloudsearchdomain.Search to request-created.cloudsearch-domain.Search +anexo76-backend | 2026-05-06 21:36:57,017 - botocore.hooks - DEBUG - Changing event name from docs.*.autoscaling.CreateLaunchConfiguration.complete-section to docs.*.auto-scaling.CreateLaunchConfiguration.complete-section +anexo76-backend | 2026-05-06 21:36:57,018 - botocore.hooks - DEBUG - Changing event name from before-parameter-build.logs.CreateExportTask to before-parameter-build.cloudwatch-logs.CreateExportTask +anexo76-backend | 2026-05-06 21:36:57,018 - botocore.hooks - DEBUG - Changing event name from docs.*.logs.CreateExportTask.complete-section to docs.*.cloudwatch-logs.CreateExportTask.complete-section +anexo76-backend | 2026-05-06 21:36:57,018 - botocore.hooks - DEBUG - Changing event name from before-parameter-build.cloudsearchdomain.Search to before-parameter-build.cloudsearch-domain.Search +anexo76-backend | 2026-05-06 21:36:57,018 - botocore.hooks - DEBUG - Changing event name from docs.*.cloudsearchdomain.Search.complete-section to docs.*.cloudsearch-domain.Search.complete-section +anexo76-backend | 2026-05-06 21:36:57,019 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/endpoints.json +anexo76-backend | 2026-05-06 21:36:57,029 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/sdk-default-configuration.json +anexo76-backend | 2026-05-06 21:36:57,030 - botocore.hooks - DEBUG - Event choose-service-name: calling handler +anexo76-backend | 2026-05-06 21:36:57,044 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/s3/2006-03-01/service-2.json.gz +anexo76-backend | 2026-05-06 21:36:57,049 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/s3/2006-03-01/service-2.sdk-extras.json +anexo76-backend | 2026-05-06 21:36:57,058 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/s3/2006-03-01/endpoint-rule-set-1.json.gz +anexo76-backend | 2026-05-06 21:36:57,060 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/partitions.json +anexo76-backend | 2026-05-06 21:36:57,062 - botocore.hooks - DEBUG - Event creating-client-class.s3: calling handler +anexo76-backend | 2026-05-06 21:36:57,062 - botocore.hooks - DEBUG - Event creating-client-class.s3: calling handler ._handler at 0x7da3be72fd80> +anexo76-backend | 2026-05-06 21:36:57,079 - botocore.hooks - DEBUG - Event creating-client-class.s3: calling handler +anexo76-backend | 2026-05-06 21:36:57,080 - botocore.endpoint - DEBUG - Setting s3 timeout as (60, 60) +anexo76-backend | 2026-05-06 21:36:57,082 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/_retry.json +anexo76-backend | 2026-05-06 21:36:57,083 - botocore.client - DEBUG - Registering retry handlers for service: s3 +anexo76-backend | 2026-05-06 21:36:57,087 - botocore.utils - DEBUG - Registering S3 region redirector handler +anexo76-backend | 2026-05-06 21:36:57,087 - botocore.utils - DEBUG - Registering S3Express Identity Resolver +anexo76-backend | 2026-05-06 21:36:57,087 - botocore.hooks - DEBUG - Event before-parameter-build.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,087 - botocore.hooks - DEBUG - Event before-parameter-build.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,087 - botocore.hooks - DEBUG - Event before-parameter-build.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:36:57,087 - botocore.hooks - DEBUG - Event before-parameter-build.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:36:57,088 - botocore.hooks - DEBUG - Event before-parameter-build.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,088 - botocore.hooks - DEBUG - Event before-endpoint-resolution.s3: calling handler +anexo76-backend | 2026-05-06 21:36:57,088 - botocore.hooks - DEBUG - Event before-endpoint-resolution.s3: calling handler > +anexo76-backend | 2026-05-06 21:36:57,088 - botocore.regions - DEBUG - Calling endpoint provider with parameters: {'Bucket': 'anexo76', 'Region': 'us-east-1', 'UseFIPS': False, 'UseDualStack': False, 'Endpoint': 'http://anexo76-minio:9000', 'ForcePathStyle': True, 'Accelerate': False, 'UseGlobalEndpoint': True, 'DisableMultiRegionAccessPoints': False, 'UseArnRegion': True} +anexo76-backend | 2026-05-06 21:36:57,088 - botocore.regions - DEBUG - Endpoint provider result: http://anexo76-minio:9000/anexo76 +anexo76-backend | 2026-05-06 21:36:57,088 - botocore.regions - DEBUG - Selecting from endpoint provider's list of auth schemes: "sigv4". User selected auth scheme is: "s3v4" +anexo76-backend | 2026-05-06 21:36:57,088 - botocore.regions - DEBUG - Selected auth type "v4" as "s3v4" with signing context params: {'region': 'us-east-1', 'signing_name': 's3', 'disableDoubleEncoding': True} +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.hooks - DEBUG - Event before-call.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.hooks - DEBUG - Event before-call.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.hooks - DEBUG - Event before-call.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.hooks - DEBUG - Event before-call.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.hooks - DEBUG - Event before-call.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.endpoint - DEBUG - Making request for OperationModel(name=HeadBucket) with params: {'url_path': '', 'query_string': {}, 'method': 'HEAD', 'headers': {'User-Agent': 'Boto3/1.35.36 md/Botocore#1.35.99 ua/2.0 os/linux#6.6.87.2-microsoft-standard-WSL2 md/arch#x86_64 lang/python#3.11.15 md/pyimpl#CPython cfg/retry-mode#legacy Botocore/1.35.99'}, 'body': b'', 'auth_path': '/anexo76/', 'url': 'http://anexo76-minio:9000/anexo76', 'context': {'client_region': 'us-east-1', 'client_config': , 'has_streaming_input': False, 'auth_type': 's3v4', 'unsigned_payload': None, 's3_redirect': {'redirected': False, 'bucket': 'anexo76', 'params': {'Bucket': 'anexo76'}}, 'input_params': {'Bucket': 'anexo76'}, 'signing': {'region': 'us-east-1', 'signing_name': 's3', 'disableDoubleEncoding': True}, 'endpoint_properties': {'authSchemes': [{'disableDoubleEncoding': True, 'name': 'sigv4', 'signingName': 's3', 'signingRegion': 'us-east-1'}]}}} +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.hooks - DEBUG - Event request-created.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.hooks - DEBUG - Event choose-signer.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.hooks - DEBUG - Event before-sign.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.hooks - DEBUG - Event before-sign.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.auth - DEBUG - Calculating signature using v4 auth. +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.auth - DEBUG - CanonicalRequest: +anexo76-backend | HEAD +anexo76-backend | /anexo76 +anexo76-backend | +anexo76-backend | host:anexo76-minio:9000 +anexo76-backend | x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +anexo76-backend | x-amz-date:20260506T213657Z +anexo76-backend | +anexo76-backend | host;x-amz-content-sha256;x-amz-date +anexo76-backend | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.auth - DEBUG - StringToSign: +anexo76-backend | AWS4-HMAC-SHA256 +anexo76-backend | 20260506T213657Z +anexo76-backend | 20260506/us-east-1/s3/aws4_request +anexo76-backend | 78f951a26193833ad927530efec5410bb55c4a7f8201543949aeeea0681e2809 +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.auth - DEBUG - Signature: +anexo76-backend | d6d66e8b6373a1ce555bba3571cf99e4819f2ca5d56772a4dde668a36d0c5b13 +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.hooks - DEBUG - Event request-created.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,089 - botocore.endpoint - DEBUG - Sending http request: +anexo76-backend | 2026-05-06 21:36:57,090 - urllib3.connectionpool - DEBUG - Starting new HTTP connection (1): anexo76-minio:9000 +anexo76-backend | 2026-05-06 21:36:57,092 - urllib3.connectionpool - DEBUG - http://anexo76-minio:9000 "HEAD /anexo76 HTTP/1.1" 200 0 +anexo76-backend | 2026-05-06 21:36:57,093 - botocore.hooks - DEBUG - Event before-parse.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,093 - botocore.hooks - DEBUG - Event before-parse.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,093 - botocore.parsers - DEBUG - Response headers: {'Accept-Ranges': 'bytes', 'Content-Length': '0', 'Content-Type': 'application/xml', 'Server': 'MinIO', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 'Vary': 'Origin, Accept-Encoding', 'X-Amz-Id-2': 'dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8', 'X-Amz-Request-Id': '18AD17A315A8843E', 'X-Content-Type-Options': 'nosniff', 'X-Ratelimit-Limit': '3115', 'X-Ratelimit-Remaining': '3115', 'X-Xss-Protection': '1; mode=block', 'Date': 'Wed, 06 May 2026 21:36:57 GMT'} +anexo76-backend | 2026-05-06 21:36:57,093 - botocore.parsers - DEBUG - Response body: +anexo76-backend | b'' +anexo76-backend | 2026-05-06 21:36:57,093 - botocore.hooks - DEBUG - Event needs-retry.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,093 - botocore.hooks - DEBUG - Event needs-retry.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:36:57,093 - botocore.retryhandler - DEBUG - No retry needed. +anexo76-backend | 2026-05-06 21:36:57,093 - botocore.hooks - DEBUG - Event needs-retry.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:36:57,093 - core.storage_s3 - INFO - S3 bucket anexo76 exists +anexo76-backend | 2026-05-06 21:36:57,094 - main - INFO - Base de datos inicializada correctamente. +anexo76-backend | INFO: Application startup complete. +anexo76-backend | INFO: 127.0.0.1:33668 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | INFO: 172.21.0.3:57858 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | INFO: 127.0.0.1:33954 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | 2026-05-06 21:37:31,535 - httpcore.connection - DEBUG - connect_tcp.started host='workspace.aduanasoft.com' port=443 local_address=None timeout=5.0 socket_options=None +anexo76-backend | 2026-05-06 21:37:31,566 - httpcore.connection - DEBUG - connect_tcp.complete return_value= +anexo76-backend | 2026-05-06 21:37:31,566 - httpcore.connection - DEBUG - start_tls.started ssl_context= server_hostname='workspace.aduanasoft.com' timeout=5.0 +anexo76-backend | 2026-05-06 21:37:31,597 - httpcore.connection - DEBUG - start_tls.complete return_value= +anexo76-backend | 2026-05-06 21:37:31,597 - httpcore.http11 - DEBUG - send_request_headers.started request= +anexo76-backend | 2026-05-06 21:37:31,598 - httpcore.http11 - DEBUG - send_request_headers.complete +anexo76-backend | 2026-05-06 21:37:31,598 - httpcore.http11 - DEBUG - send_request_body.started request= +anexo76-backend | 2026-05-06 21:37:31,598 - httpcore.http11 - DEBUG - send_request_body.complete +anexo76-backend | 2026-05-06 21:37:31,598 - httpcore.http11 - DEBUG - receive_response_headers.started request= +anexo76-backend | 2026-05-06 21:37:31,662 - httpcore.http11 - DEBUG - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Server', b'nginx/1.22.1'), (b'Date', b'Wed, 06 May 2026 21:37:34 GMT'), (b'Content-Type', b'application/json'), (b'Content-Length', b'250'), (b'Connection', b'keep-alive'), (b'x-request-id', b'296211c5-34bd-4c02-9cfb-176e09897234')]) +anexo76-backend | 2026-05-06 21:37:31,663 - httpx - INFO - HTTP Request: GET https://workspace.aduanasoft.com/api/v1/auth/me "HTTP/1.1 200 OK" +anexo76-backend | 2026-05-06 21:37:31,663 - httpcore.http11 - DEBUG - receive_response_body.started request= +anexo76-backend | 2026-05-06 21:37:31,663 - httpcore.http11 - DEBUG - receive_response_body.complete +anexo76-backend | 2026-05-06 21:37:31,664 - httpcore.http11 - DEBUG - response_closed.started +anexo76-backend | 2026-05-06 21:37:31,664 - httpcore.http11 - DEBUG - response_closed.complete +anexo76-backend | 2026-05-06 21:37:31,664 - httpcore.connection - DEBUG - close.started +anexo76-backend | 2026-05-06 21:37:31,664 - httpcore.connection - DEBUG - close.complete +anexo76-backend | 2026-05-06 21:37:31,665 - core.middleware - INFO - [license] tenant override propagated to Hub: 11 +anexo76-backend | 2026-05-06 21:37:31,670 - httpcore.connection - DEBUG - connect_tcp.started host='workspace.aduanasoft.com' port=443 local_address=None timeout=5.0 socket_options=None +anexo76-backend | 2026-05-06 21:37:31,700 - httpcore.connection - DEBUG - connect_tcp.complete return_value= +anexo76-backend | 2026-05-06 21:37:31,700 - httpcore.connection - DEBUG - start_tls.started ssl_context= server_hostname='workspace.aduanasoft.com' timeout=5.0 +anexo76-backend | 2026-05-06 21:37:31,730 - httpcore.connection - DEBUG - start_tls.complete return_value= +anexo76-backend | 2026-05-06 21:37:31,730 - httpcore.http11 - DEBUG - send_request_headers.started request= +anexo76-backend | 2026-05-06 21:37:31,731 - httpcore.http11 - DEBUG - send_request_headers.complete +anexo76-backend | 2026-05-06 21:37:31,731 - httpcore.http11 - DEBUG - send_request_body.started request= +anexo76-backend | 2026-05-06 21:37:31,731 - httpcore.http11 - DEBUG - send_request_body.complete +anexo76-backend | 2026-05-06 21:37:31,731 - httpcore.http11 - DEBUG - receive_response_headers.started request= +anexo76-backend | 2026-05-06 21:37:31,824 - httpcore.http11 - DEBUG - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Server', b'nginx/1.22.1'), (b'Date', b'Wed, 06 May 2026 21:37:35 GMT'), (b'Content-Type', b'application/json'), (b'Content-Length', b'224'), (b'Connection', b'keep-alive'), (b'x-request-id', b'f4bfac19-d54b-4216-bbd4-011f9ff783e8')]) +anexo76-backend | 2026-05-06 21:37:31,825 - httpx - INFO - HTTP Request: GET https://workspace.aduanasoft.com/api/v1/auth/verify-license "HTTP/1.1 200 OK" +anexo76-backend | 2026-05-06 21:37:31,825 - httpcore.http11 - DEBUG - receive_response_body.started request= +anexo76-backend | 2026-05-06 21:37:31,825 - httpcore.http11 - DEBUG - receive_response_body.complete +anexo76-backend | 2026-05-06 21:37:31,825 - httpcore.http11 - DEBUG - response_closed.started +anexo76-backend | 2026-05-06 21:37:31,825 - httpcore.http11 - DEBUG - response_closed.complete +anexo76-backend | 2026-05-06 21:37:31,825 - httpcore.connection - DEBUG - close.started +anexo76-backend | 2026-05-06 21:37:31,826 - httpcore.connection - DEBUG - close.complete +anexo76-backend | 2026-05-06 21:37:31,826 - core.middleware - INFO - 🔑 verify-license → status=200 body={"valid":true,"message":"Licencia activa y válida","tenant_slug":"aduanasoft","tenant_name":"aduanasoft","product_name":null,"expires_at":"2027-04-29T17:32:31.670550","plan":"basic","max_users":20,"features":["api_access"]} +anexo76-backend | 2026-05-06 21:37:31,826 - core.middleware - INFO - Request: GET /api/v1/a76/company/my-companies +anexo76-backend | 2026-05-06 21:37:31,836 - core.security - INFO - [get_current_user] X-Tenant-Override='11' +anexo76-backend | 2026-05-06 21:37:31,843 - httpcore.connection - DEBUG - connect_tcp.started host='workspace.aduanasoft.com' port=443 local_address=None timeout=5.0 socket_options=None +anexo76-backend | 2026-05-06 21:37:31,872 - httpcore.connection - DEBUG - connect_tcp.complete return_value= +anexo76-backend | 2026-05-06 21:37:31,873 - httpcore.connection - DEBUG - start_tls.started ssl_context= server_hostname='workspace.aduanasoft.com' timeout=5.0 +anexo76-backend | 2026-05-06 21:37:31,902 - httpcore.connection - DEBUG - start_tls.complete return_value= +anexo76-backend | 2026-05-06 21:37:31,903 - httpcore.http11 - DEBUG - send_request_headers.started request= +anexo76-backend | 2026-05-06 21:37:31,903 - httpcore.http11 - DEBUG - send_request_headers.complete +anexo76-backend | 2026-05-06 21:37:31,903 - httpcore.http11 - DEBUG - send_request_body.started request= +anexo76-backend | 2026-05-06 21:37:31,903 - httpcore.http11 - DEBUG - send_request_body.complete +anexo76-backend | 2026-05-06 21:37:31,903 - httpcore.http11 - DEBUG - receive_response_headers.started request= +anexo76-backend | 2026-05-06 21:37:31,983 - httpcore.http11 - DEBUG - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Server', b'nginx/1.22.1'), (b'Date', b'Wed, 06 May 2026 21:37:35 GMT'), (b'Content-Type', b'application/json'), (b'Content-Length', b'250'), (b'Connection', b'keep-alive'), (b'x-request-id', b'9f3faac1-6e02-4160-87b4-22af7df1ef11')]) +anexo76-backend | 2026-05-06 21:37:31,984 - httpx - INFO - HTTP Request: GET https://workspace.aduanasoft.com/api/v1/auth/me "HTTP/1.1 200 OK" +anexo76-backend | 2026-05-06 21:37:31,984 - httpcore.http11 - DEBUG - receive_response_body.started request= +anexo76-backend | 2026-05-06 21:37:31,984 - httpcore.http11 - DEBUG - receive_response_body.complete +anexo76-backend | 2026-05-06 21:37:31,984 - httpcore.http11 - DEBUG - response_closed.started +anexo76-backend | 2026-05-06 21:37:31,984 - httpcore.http11 - DEBUG - response_closed.complete +anexo76-backend | 2026-05-06 21:37:31,985 - httpcore.connection - DEBUG - close.started +anexo76-backend | 2026-05-06 21:37:31,985 - httpcore.connection - DEBUG - close.complete +anexo76-backend | 2026-05-06 21:37:32,585 - core.middleware - INFO - Response: GET /api/v1/a76/company/my-companies Status: 200 Duration: 0.759s +anexo76-backend | INFO: 172.21.0.3:45462 - "GET /api/v1/a76/company/my-companies HTTP/1.1" 200 OK +anexo76-backend | 2026-05-06 21:37:32,590 - core.middleware - INFO - Request: GET /api/v1/auth/me +anexo76-backend | 2026-05-06 21:37:32,591 - core.middleware - INFO - Response: GET /api/v1/auth/me Status: 200 Duration: 0.001s +anexo76-backend | INFO: 172.21.0.3:45470 - "GET /api/v1/auth/me HTTP/1.1" 200 OK +anexo76-backend | 2026-05-06 21:37:32,595 - core.middleware - INFO - [license] tenant override propagated to Hub: 11 +anexo76-backend | 2026-05-06 21:37:32,601 - httpcore.connection - DEBUG - connect_tcp.started host='workspace.aduanasoft.com' port=443 local_address=None timeout=5.0 socket_options=None +anexo76-backend | 2026-05-06 21:37:32,631 - httpcore.connection - DEBUG - connect_tcp.complete return_value= +anexo76-backend | 2026-05-06 21:37:32,631 - httpcore.connection - DEBUG - start_tls.started ssl_context= server_hostname='workspace.aduanasoft.com' timeout=5.0 +anexo76-backend | 2026-05-06 21:37:32,661 - httpcore.connection - DEBUG - start_tls.complete return_value= +anexo76-backend | 2026-05-06 21:37:32,662 - httpcore.http11 - DEBUG - send_request_headers.started request= +anexo76-backend | 2026-05-06 21:37:32,662 - httpcore.http11 - DEBUG - send_request_headers.complete +anexo76-backend | 2026-05-06 21:37:32,662 - httpcore.http11 - DEBUG - send_request_body.started request= +anexo76-backend | 2026-05-06 21:37:32,663 - httpcore.http11 - DEBUG - send_request_body.complete +anexo76-backend | 2026-05-06 21:37:32,663 - httpcore.http11 - DEBUG - receive_response_headers.started request= +anexo76-backend | 2026-05-06 21:37:32,756 - httpcore.http11 - DEBUG - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Server', b'nginx/1.22.1'), (b'Date', b'Wed, 06 May 2026 21:37:36 GMT'), (b'Content-Type', b'application/json'), (b'Content-Length', b'224'), (b'Connection', b'keep-alive'), (b'x-request-id', b'b99812fe-d833-46f2-9008-b3fd669d9972')]) +anexo76-backend | 2026-05-06 21:37:32,757 - httpx - INFO - HTTP Request: GET https://workspace.aduanasoft.com/api/v1/auth/verify-license "HTTP/1.1 200 OK" +anexo76-backend | 2026-05-06 21:37:32,757 - httpcore.http11 - DEBUG - receive_response_body.started request= +anexo76-backend | 2026-05-06 21:37:32,757 - httpcore.http11 - DEBUG - receive_response_body.complete +anexo76-backend | 2026-05-06 21:37:32,757 - httpcore.http11 - DEBUG - response_closed.started +anexo76-backend | 2026-05-06 21:37:32,757 - httpcore.http11 - DEBUG - response_closed.complete +anexo76-backend | 2026-05-06 21:37:32,758 - httpcore.connection - DEBUG - close.started +anexo76-backend | 2026-05-06 21:37:32,758 - httpcore.connection - DEBUG - close.complete +anexo76-backend | 2026-05-06 21:37:32,758 - core.middleware - INFO - 🔑 verify-license → status=200 body={"valid":true,"message":"Licencia activa y válida","tenant_slug":"aduanasoft","tenant_name":"aduanasoft","product_name":null,"expires_at":"2027-04-29T17:32:31.670550","plan":"basic","max_users":20,"features":["api_access"]} +anexo76-backend | 2026-05-06 21:37:32,758 - core.middleware - INFO - Request: GET /api/v1/core/users/me/profile +anexo76-backend | 2026-05-06 21:37:32,759 - core.security - INFO - [get_current_user] X-Tenant-Override='11' +anexo76-backend | 2026-05-06 21:37:32,770 - core.middleware - INFO - Response: GET /api/v1/core/users/me/profile Status: 200 Duration: 0.011s +anexo76-backend | INFO: 172.21.0.3:45462 - "GET /api/v1/core/users/me/profile HTTP/1.1" 200 OK +anexo76-backend | INFO: 127.0.0.1:35456 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | 2026-05-06 21:37:47,554 - core.middleware - INFO - Request: GET /api/avatars/default.jpg +anexo76-backend | 2026-05-06 21:37:47,558 - core.middleware - INFO - Response: GET /api/avatars/default.jpg Status: 404 Duration: 0.004s +anexo76-backend | INFO: 172.21.0.3:53544 - "GET /api/avatars/default.jpg HTTP/1.1" 404 Not Found +anexo76-backend | INFO: 172.21.0.3:53560 - "POST /api-sveltekit/auth/silent-refresh HTTP/1.1" 401 Unauthorized +anexo76-backend | INFO: 172.21.0.3:53566 - "POST /api-sveltekit/company/set-active HTTP/1.1" 401 Unauthorized +anexo76-backend | 2026-05-06 21:37:49,296 - core.middleware - INFO - Request: GET /api/avatars/default.jpg +anexo76-backend | 2026-05-06 21:37:49,298 - core.middleware - INFO - Response: GET /api/avatars/default.jpg Status: 404 Duration: 0.002s +anexo76-backend | INFO: 172.21.0.3:53576 - "GET /api/avatars/default.jpg HTTP/1.1" 404 Not Found +anexo76-backend | INFO: 127.0.0.1:37842 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | INFO: 127.0.0.1:60858 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | INFO: 127.0.0.1:47212 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | INFO: 127.0.0.1:38264 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | INFO: 127.0.0.1:45138 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | INFO: 127.0.0.1:54772 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | INFO: 127.0.0.1:39924 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | WARNING: WatchFiles detected changes in 'api/v1/modules/core/permissions/routes.py'. Reloading... +anexo76-backend | INFO: Shutting down +anexo76-backend | INFO: Waiting for application shutdown. +anexo76-backend | INFO: Application shutdown complete. +anexo76-backend | INFO: Finished server process [9] +anexo76-backend | DEBUG: Celery Broker URL: redis://valkey:6379/0 +anexo76-backend | INFO: Started server process [94] +anexo76-backend | INFO: Waiting for application startup. +anexo76-backend | 2026-05-06 21:40:24,734 - main - INFO - Iniciando la aplicación Anexo76... +anexo76-backend | INFO [alembic.runtime.migration] Context impl PostgresqlImpl. +anexo76-backend | INFO [alembic.runtime.migration] Will assume transactional DDL. +anexo76-backend | 2026-05-06 21:40:26,311 - botocore.hooks - DEBUG - Changing event name from creating-client-class.iot-data to creating-client-class.iot-data-plane +anexo76-backend | 2026-05-06 21:40:26,312 - botocore.hooks - DEBUG - Changing event name from before-call.apigateway to before-call.api-gateway +anexo76-backend | 2026-05-06 21:40:26,313 - botocore.hooks - DEBUG - Changing event name from request-created.machinelearning.Predict to request-created.machine-learning.Predict +anexo76-backend | 2026-05-06 21:40:26,313 - botocore.hooks - DEBUG - Changing event name from before-parameter-build.autoscaling.CreateLaunchConfiguration to before-parameter-build.auto-scaling.CreateLaunchConfiguration +anexo76-backend | 2026-05-06 21:40:26,313 - botocore.hooks - DEBUG - Changing event name from before-parameter-build.route53 to before-parameter-build.route-53 +anexo76-backend | 2026-05-06 21:40:26,313 - botocore.hooks - DEBUG - Changing event name from request-created.cloudsearchdomain.Search to request-created.cloudsearch-domain.Search +anexo76-backend | 2026-05-06 21:40:26,314 - botocore.hooks - DEBUG - Changing event name from docs.*.autoscaling.CreateLaunchConfiguration.complete-section to docs.*.auto-scaling.CreateLaunchConfiguration.complete-section +anexo76-backend | 2026-05-06 21:40:26,315 - botocore.hooks - DEBUG - Changing event name from before-parameter-build.logs.CreateExportTask to before-parameter-build.cloudwatch-logs.CreateExportTask +anexo76-backend | 2026-05-06 21:40:26,315 - botocore.hooks - DEBUG - Changing event name from docs.*.logs.CreateExportTask.complete-section to docs.*.cloudwatch-logs.CreateExportTask.complete-section +anexo76-backend | 2026-05-06 21:40:26,315 - botocore.hooks - DEBUG - Changing event name from before-parameter-build.cloudsearchdomain.Search to before-parameter-build.cloudsearch-domain.Search +anexo76-backend | 2026-05-06 21:40:26,315 - botocore.hooks - DEBUG - Changing event name from docs.*.cloudsearchdomain.Search.complete-section to docs.*.cloudsearch-domain.Search.complete-section +anexo76-backend | 2026-05-06 21:40:26,320 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/endpoints.json +anexo76-backend | 2026-05-06 21:40:26,331 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/sdk-default-configuration.json +anexo76-backend | 2026-05-06 21:40:26,331 - botocore.hooks - DEBUG - Event choose-service-name: calling handler +anexo76-backend | 2026-05-06 21:40:26,364 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/s3/2006-03-01/service-2.json.gz +anexo76-backend | 2026-05-06 21:40:26,386 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/s3/2006-03-01/service-2.sdk-extras.json +anexo76-backend | 2026-05-06 21:40:26,395 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/s3/2006-03-01/endpoint-rule-set-1.json.gz +anexo76-backend | 2026-05-06 21:40:26,415 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/partitions.json +anexo76-backend | 2026-05-06 21:40:26,416 - botocore.hooks - DEBUG - Event creating-client-class.s3: calling handler +anexo76-backend | 2026-05-06 21:40:26,417 - botocore.hooks - DEBUG - Event creating-client-class.s3: calling handler ._handler at 0x7e12d5327e20> +anexo76-backend | 2026-05-06 21:40:26,450 - botocore.hooks - DEBUG - Event creating-client-class.s3: calling handler +anexo76-backend | 2026-05-06 21:40:26,451 - botocore.endpoint - DEBUG - Setting s3 timeout as (60, 60) +anexo76-backend | 2026-05-06 21:40:26,455 - botocore.loaders - DEBUG - Loading JSON file: /usr/local/lib/python3.11/site-packages/botocore/data/_retry.json +anexo76-backend | 2026-05-06 21:40:26,455 - botocore.client - DEBUG - Registering retry handlers for service: s3 +anexo76-backend | 2026-05-06 21:40:26,455 - botocore.utils - DEBUG - Registering S3 region redirector handler +anexo76-backend | 2026-05-06 21:40:26,456 - botocore.utils - DEBUG - Registering S3Express Identity Resolver +anexo76-backend | 2026-05-06 21:40:26,456 - botocore.hooks - DEBUG - Event before-parameter-build.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,456 - botocore.hooks - DEBUG - Event before-parameter-build.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,456 - botocore.hooks - DEBUG - Event before-parameter-build.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:40:26,456 - botocore.hooks - DEBUG - Event before-parameter-build.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:40:26,456 - botocore.hooks - DEBUG - Event before-parameter-build.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,456 - botocore.hooks - DEBUG - Event before-endpoint-resolution.s3: calling handler +anexo76-backend | 2026-05-06 21:40:26,456 - botocore.hooks - DEBUG - Event before-endpoint-resolution.s3: calling handler > +anexo76-backend | 2026-05-06 21:40:26,456 - botocore.regions - DEBUG - Calling endpoint provider with parameters: {'Bucket': 'anexo76', 'Region': 'us-east-1', 'UseFIPS': False, 'UseDualStack': False, 'Endpoint': 'http://anexo76-minio:9000', 'ForcePathStyle': True, 'Accelerate': False, 'UseGlobalEndpoint': True, 'DisableMultiRegionAccessPoints': False, 'UseArnRegion': True} +anexo76-backend | 2026-05-06 21:40:26,457 - botocore.regions - DEBUG - Endpoint provider result: http://anexo76-minio:9000/anexo76 +anexo76-backend | 2026-05-06 21:40:26,457 - botocore.regions - DEBUG - Selecting from endpoint provider's list of auth schemes: "sigv4". User selected auth scheme is: "s3v4" +anexo76-backend | 2026-05-06 21:40:26,457 - botocore.regions - DEBUG - Selected auth type "v4" as "s3v4" with signing context params: {'region': 'us-east-1', 'signing_name': 's3', 'disableDoubleEncoding': True} +anexo76-backend | 2026-05-06 21:40:26,458 - botocore.hooks - DEBUG - Event before-call.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,458 - botocore.hooks - DEBUG - Event before-call.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:40:26,458 - botocore.hooks - DEBUG - Event before-call.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,458 - botocore.hooks - DEBUG - Event before-call.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,458 - botocore.hooks - DEBUG - Event before-call.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,458 - botocore.endpoint - DEBUG - Making request for OperationModel(name=HeadBucket) with params: {'url_path': '', 'query_string': {}, 'method': 'HEAD', 'headers': {'User-Agent': 'Boto3/1.35.36 md/Botocore#1.35.99 ua/2.0 os/linux#6.6.87.2-microsoft-standard-WSL2 md/arch#x86_64 lang/python#3.11.15 md/pyimpl#CPython cfg/retry-mode#legacy Botocore/1.35.99'}, 'body': b'', 'auth_path': '/anexo76/', 'url': 'http://anexo76-minio:9000/anexo76', 'context': {'client_region': 'us-east-1', 'client_config': , 'has_streaming_input': False, 'auth_type': 's3v4', 'unsigned_payload': None, 's3_redirect': {'redirected': False, 'bucket': 'anexo76', 'params': {'Bucket': 'anexo76'}}, 'input_params': {'Bucket': 'anexo76'}, 'signing': {'region': 'us-east-1', 'signing_name': 's3', 'disableDoubleEncoding': True}, 'endpoint_properties': {'authSchemes': [{'disableDoubleEncoding': True, 'name': 'sigv4', 'signingName': 's3', 'signingRegion': 'us-east-1'}]}}} +anexo76-backend | 2026-05-06 21:40:26,458 - botocore.hooks - DEBUG - Event request-created.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:40:26,458 - botocore.hooks - DEBUG - Event choose-signer.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,458 - botocore.hooks - DEBUG - Event before-sign.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,458 - botocore.hooks - DEBUG - Event before-sign.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:40:26,459 - botocore.auth - DEBUG - Calculating signature using v4 auth. +anexo76-backend | 2026-05-06 21:40:26,459 - botocore.auth - DEBUG - CanonicalRequest: +anexo76-backend | HEAD +anexo76-backend | /anexo76 +anexo76-backend | +anexo76-backend | host:anexo76-minio:9000 +anexo76-backend | x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +anexo76-backend | x-amz-date:20260506T214026Z +anexo76-backend | +anexo76-backend | host;x-amz-content-sha256;x-amz-date +anexo76-backend | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +anexo76-backend | 2026-05-06 21:40:26,459 - botocore.auth - DEBUG - StringToSign: +anexo76-backend | AWS4-HMAC-SHA256 +anexo76-backend | 20260506T214026Z +anexo76-backend | 20260506/us-east-1/s3/aws4_request +anexo76-backend | 9c598ef422ed5a1f958ce1e61ea627a1c47025c80840ef18d19d1417b9d5c0b8 +anexo76-backend | 2026-05-06 21:40:26,459 - botocore.auth - DEBUG - Signature: +anexo76-backend | 4b5dcb6959901de692d7e3377b48be53bbf6665daf7be709a25af49ee8561df3 +anexo76-backend | 2026-05-06 21:40:26,459 - botocore.hooks - DEBUG - Event request-created.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,459 - botocore.endpoint - DEBUG - Sending http request: +anexo76-backend | 2026-05-06 21:40:26,461 - urllib3.connectionpool - DEBUG - Starting new HTTP connection (1): anexo76-minio:9000 +anexo76-backend | 2026-05-06 21:40:26,463 - urllib3.connectionpool - DEBUG - http://anexo76-minio:9000 "HEAD /anexo76 HTTP/1.1" 200 0 +anexo76-backend | 2026-05-06 21:40:26,463 - botocore.hooks - DEBUG - Event before-parse.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,463 - botocore.hooks - DEBUG - Event before-parse.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,463 - botocore.parsers - DEBUG - Response headers: {'Accept-Ranges': 'bytes', 'Content-Length': '0', 'Content-Type': 'application/xml', 'Server': 'MinIO', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 'Vary': 'Origin, Accept-Encoding', 'X-Amz-Id-2': 'dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8', 'X-Amz-Request-Id': '18AD17D3D5264B2C', 'X-Content-Type-Options': 'nosniff', 'X-Ratelimit-Limit': '3115', 'X-Ratelimit-Remaining': '3115', 'X-Xss-Protection': '1; mode=block', 'Date': 'Wed, 06 May 2026 21:40:26 GMT'} +anexo76-backend | 2026-05-06 21:40:26,463 - botocore.parsers - DEBUG - Response body: +anexo76-backend | b'' +anexo76-backend | 2026-05-06 21:40:26,464 - botocore.hooks - DEBUG - Event needs-retry.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,464 - botocore.hooks - DEBUG - Event needs-retry.s3.HeadBucket: calling handler +anexo76-backend | 2026-05-06 21:40:26,464 - botocore.retryhandler - DEBUG - No retry needed. +anexo76-backend | 2026-05-06 21:40:26,464 - botocore.hooks - DEBUG - Event needs-retry.s3.HeadBucket: calling handler > +anexo76-backend | 2026-05-06 21:40:26,464 - core.storage_s3 - INFO - S3 bucket anexo76 exists +anexo76-backend | 2026-05-06 21:40:26,464 - main - INFO - Base de datos inicializada correctamente. +anexo76-backend | INFO: Application startup complete. +anexo76-backend | INFO: 127.0.0.1:49166 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | INFO: 127.0.0.1:39678 - "GET /api/health HTTP/1.1" 200 OK +anexo76-backend | INFO: 127.0.0.1:59246 - "GET /api/health HTTP/1.1" 200 OK diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 730bd4d6..5dd317c5 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -1,6 +1,7 @@ { "$schema": "https://inlang.com/schema/inlang-message-format", "hello_world": "Hello, {name} from en!", + "exchange_rate_error_title": "Exchange Rate Error", "dashboard": { "greeting_morning": "Good morning", "greeting_afternoon": "Good afternoon", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index d8c653db..b6bbd48e 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -1,6 +1,7 @@ { "$schema": "https://inlang.com/schema/inlang-message-format", "hello_world": "Hello, {name} from es!", + "exchange_rate_error_title": "Error de Tipo de Cambio", "dashboard": { "greeting_morning": "Buenos días", "greeting_afternoon": "Buenas tardes", diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index cd036ea2..cda4698a 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -16,6 +16,7 @@ function normalizeAbsoluteApiBaseUrl(raw: string): string { if (s.startsWith('https:') && !s.startsWith('https://')) { s = 'https://' + s.slice('https:'.length).replace(/^\/+/, ''); } + if (s.startsWith('/')) return s; if (/^https?:\/\//i.test(s)) return s; return `http://${s.replace(/^\/+/, '')}`; } diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 5603d80f..c2a032c1 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -51,7 +51,7 @@ export default defineConfig({ // 'otro-host.com' si necesitas más ], proxy: { - '/api': { + '/api/': { target: 'http://backend:8000', changeOrigin: true },