{isVerified ? 'ANALYSIS METRICS' : 'TOP CONCERNS'}
-- Sign up to access overall analysis report -
-diff --git a/app.json b/app.json new file mode 100644 index 0000000..bdee2d6 --- /dev/null +++ b/app.json @@ -0,0 +1 @@ +{"uuid":"4uq3ri0vmsh82v0xb4zc28hr","name":"limelite-faceanalyzer","additional_networks_count":0,"additional_servers":[],"additional_servers_count":0,"base_directory":"\/","build_command":null,"build_pack":"dockercompose","compose_parsing_version":"5","config_hash":"9b4499e4d7561ba4e29d082c26859f01","container_present":false,"custom_docker_run_options":null,"custom_healthcheck_found":false,"custom_labels":"traefik.enable=true\ntraefik.http.middlewares.gzip.compress=true\ntraefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https\ntraefik.http.routers.http-0-4uq3ri0vmsh82v0xb4zc28hr.entryPoints=http\ntraefik.http.routers.http-0-4uq3ri0vmsh82v0xb4zc28hr.middlewares=gzip\ntraefik.http.routers.http-0-4uq3ri0vmsh82v0xb4zc28hr.rule=Host(`4uq3ri0vmsh82v0xb4zc28hr.91.203.135.27.sslip.io`) && PathPrefix(`\/`)\ntraefik.http.routers.http-0-4uq3ri0vmsh82v0xb4zc28hr.service=http-0-4uq3ri0vmsh82v0xb4zc28hr\ntraefik.http.services.http-0-4uq3ri0vmsh82v0xb4zc28hr.loadbalancer.server.port=80\ncaddy_0.encode=zstd gzip\ncaddy_0.handle_path.0_reverse_proxy={{upstreams 80}}\ncaddy_0.handle_path=\/*\ncaddy_0.header=-Server\ncaddy_0.try_files={path} \/index.html \/index.php\ncaddy_0=http:\/\/4uq3ri0vmsh82v0xb4zc28hr.91.203.135.27.sslip.io\ncaddy_ingress_network=coolify","custom_network_aliases":null,"custom_nginx_configuration":null,"deleted_at":null,"description":null,"destination":{"id":1,"name":"coolify","uuid":"aqyq2o4oubmgulktfusatwqm","network":"coolify","server_id":1,"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-08-19T05:37:20.000000Z","server":{"id":1,"uuid":"jrcjtobvncyba40v3vi6pzqe","name":"DigifoxServer-Prod","description":"","ip":"91.203.135.27","port":22,"user":"coolify-user","team_id":0,"private_key_id":0,"proxy":{"redirect_enabled":true,"last_saved_proxy_configuration":"name: coolify-proxy\nnetworks:\n coolify:\n external: true\nservices:\n traefik:\n container_name: coolify-proxy\n image: 'traefik:v3.7'\n restart: unless-stopped\n extra_hosts:\n - 'host.docker.internal:host-gateway'\n networks:\n - coolify\n ports:\n - '80:80'\n - '443:443'\n - '443:443\/udp'\n - '8080:8080'\n healthcheck:\n test: 'wget -qO- http:\/\/localhost:80\/ping || exit 1'\n interval: 4s\n timeout: 2s\n retries: 5\n volumes:\n - '\/var\/run\/docker.sock:\/var\/run\/docker.sock:ro'\n - '\/data\/coolify\/proxy\/:\/traefik'\n command:\n - '--ping=true'\n - '--ping.entrypoint=http'\n - '--api.dashboard=true'\n - '--entrypoints.http.address=:80'\n - '--entrypoints.https.address=:443'\n - '--entrypoints.http.http.encodequerysemicolons=true'\n - '--entryPoints.http.http2.maxConcurrentStreams=250'\n - '--entrypoints.https.http.encodequerysemicolons=true'\n - '--entryPoints.https.http2.maxConcurrentStreams=250'\n - '--entrypoints.https.http3'\n - '--providers.file.directory=\/traefik\/dynamic\/'\n - '--providers.file.watch=true'\n - '--certificatesresolvers.letsencrypt.acme.httpchallenge=true'\n - '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http'\n - '--certificatesresolvers.letsencrypt.acme.storage=\/traefik\/acme.json'\n - '--api.insecure=false'\n - '--providers.docker=true'\n - '--providers.docker.exposedbydefault=false'\n labels:\n - traefik.enable=true\n - traefik.http.routers.traefik.entrypoints=http\n - traefik.http.routers.traefik.service=api@internal\n - traefik.http.services.traefik.loadbalancer.server.port=8080\n - coolify.managed=true\n - coolify.proxy=true","type":"TRAEFIK","status":"created","last_saved_settings":"3b2fb10ec80cfa819e51625efa249fe1","last_applied_settings":"3b2fb10ec80cfa819e51625efa249fe1"},"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-09-22T11:27:09.000000Z","unreachable_notification_sent":false,"unreachable_count":0,"high_disk_usage_notification_sent":false,"log_drain_notification_sent":false,"swarm_cluster":null,"validation_logs":null,"sentinel_updated_at":"2026-09-18 07:27:07","deleted_at":null,"ip_previous":null,"hetzner_server_id":null,"cloud_provider_token_id":null,"hetzner_server_status":null,"is_validating":false,"detected_traefik_version":null,"traefik_outdated_info":null,"server_metadata":{"os":"Ubuntu 22.04.5 LTS","arch":"x86_64","kernel":"5.15.0-187-generic","cpus":4,"memory_bytes":12239319040,"uptime_since":"2026-08-20 15:20:39","collected_at":"2026-08-20T13:37:08+00:00"},"vultr_instance_id":null,"vultr_instance_status":null,"digitalocean_droplet_id":null,"digitalocean_droplet_status":null,"sentinel_waiting_since":"2026-09-22T11:27:09.000000Z","is_coolify_host":false,"settings":{"id":2,"is_swarm_manager":false,"is_jump_server":false,"is_build_server":false,"is_reachable":true,"is_usable":true,"server_id":1,"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-09-22T11:27:04.000000Z","wildcard_domain":null,"is_cloudflare_tunnel":false,"is_logdrain_newrelic_enabled":false,"logdrain_newrelic_license_key":null,"logdrain_newrelic_base_uri":null,"is_logdrain_highlight_enabled":false,"logdrain_highlight_project_id":null,"is_logdrain_axiom_enabled":false,"logdrain_axiom_dataset_name":null,"logdrain_axiom_api_key":null,"is_swarm_worker":false,"is_logdrain_custom_enabled":false,"logdrain_custom_config":null,"logdrain_custom_config_parser":null,"concurrent_builds":2,"dynamic_timeout":3600,"force_disabled":false,"is_metrics_enabled":false,"generate_exact_labels":false,"force_docker_cleanup":true,"docker_cleanup_frequency":"0 0 * * *","docker_cleanup_threshold":80,"server_timezone":"UTC","delete_unused_volumes":false,"delete_unused_networks":false,"is_sentinel_enabled":true,"sentinel_token":"eyJpdiI6InhiRVYvTjcrY2grN293a0tWZkV1WFE9PSIsInZhbHVlIjoiaVFMZW5KTzY4QlZWYW82WmFnZmdBL0VwN3pJeEVRcjQzZ082T1NzT2xoMzVBVk9LQXJ4cXJkRUhZN0p2ZzcwQ3RFclg4WFlLOHVuTW0yU2pwcXR3aGc9PSIsIm1hYyI6IjdiMzFiOWU2MDhhN2RlNjhlZDJlYjRkMGQ3ZGU2YjlkMzI4MDY1ODk3YTY2NTgwZTdmOWM3Y2E0YjM3MTg3YzIiLCJ0YWciOiIifQ==","sentinel_metrics_refresh_rate_seconds":10,"sentinel_metrics_history_days":7,"sentinel_push_interval_seconds":60,"sentinel_custom_url":"https:\/\/deploy.digifox.live","server_disk_usage_notification_threshold":80,"is_sentinel_debug_enabled":false,"server_disk_usage_check_frequency":"0 23 * * *","is_terminal_enabled":true,"deployment_queue_limit":25,"disable_application_image_retention":false,"connection_timeout":10,"docker_version":"29.8.1","docker_version_checked_at":"2026-09-22T11:27:03.000000Z","compose_version":"5.5.1","compose_version_checked_at":"2026-09-22T11:27:04.000000Z","backup_compression_cpu_percentage":25}}},"destination_id":1,"destination_type":"App\\Models\\StandaloneDocker","docker_compose":null,"docker_compose_custom_build_command":null,"docker_compose_custom_start_command":null,"docker_compose_domains":null,"docker_compose_location":"\/docker-compose.yml","docker_compose_raw":null,"docker_registry_image_name":null,"docker_registry_image_tag":null,"dockerfile":null,"dockerfile_location":null,"dockerfile_target_build":null,"environment":{"id":23,"name":"production","project_id":17,"created_at":"2026-08-12T05:23:25.000000Z","updated_at":"2026-08-12T05:23:25.000000Z","description":null,"uuid":"ijga3o6m6arup69yohj2ecyw","project":{"id":17,"uuid":"kozt3dmpa63penhin84sb8r0","name":"limelite-smartmirror","description":"","team_id":0,"created_at":"2026-08-12T05:23:25.000000Z","updated_at":"2026-08-18T11:28:25.000000Z","icon_path":null,"icon_storage_type":null,"icon_s3_storage_id":null,"team":{"id":0,"name":"Root Team","description":"The root team","personal_team":true,"created_at":"2026-06-05T23:01:55.000000Z","updated_at":"2026-06-05T23:11:01.000000Z","show_boarding":false,"custom_server_limit":null,"is_mcp_server_enabled":true}}},"environment_id":23,"fqdn":"http:\/\/4uq3ri0vmsh82v0xb4zc28hr.91.203.135.27.sslip.io","git_branch":"master","git_commit_sha":"HEAD","git_full_url":null,"git_repository":"https:\/\/mohanki:48d38a221949649fdf1b470bbd037de9a5e6c564@git.digifox.live\/mohanki\/limelite_faceanalyzer.git","health_check_command":null,"health_check_enabled":false,"health_check_host":"localhost","health_check_interval":5,"health_check_method":"GET","health_check_path":"\/","health_check_port":null,"health_check_response_text":null,"health_check_retries":10,"health_check_return_code":200,"health_check_scheme":"http","health_check_start_period":5,"health_check_timeout":5,"health_check_type":"http","http_basic_auth_password":null,"http_basic_auth_username":null,"install_command":null,"is_http_basic_auth_enabled":false,"last_online_at":"2026-06-05 23:01:53","last_restart_at":null,"last_restart_type":null,"limits_cpu_shares":1024,"limits_cpus":"0","limits_cpuset":null,"limits_memory":"0","limits_memory_reservation":"0","limits_memory_swap":"0","limits_memory_swappiness":60,"manual_webhook_secret_bitbucket":"yvbVnb9T2y7Zru3Jskw1UODFEermE2E6VhQ2M6QM","manual_webhook_secret_gitea":"tO5bHwa6rGYE5l8zByJzYXxionKHLRPkLgDbCTFj","manual_webhook_secret_github":"wGAJtfx6YmuDZF2jv1KaVdbT7S79uMogT8njpo7B","manual_webhook_secret_gitlab":"YmGawM1NqN2hHiMbFm8QYTadhZkqtYZF0HqBByOf","max_restart_count":0,"noindex_domains":null,"ports_exposes":"80","ports_mappings":null,"post_deployment_command":null,"post_deployment_command_container":null,"pre_deployment_command":null,"pre_deployment_command_container":null,"preview_url_template":"{{pr_id}}.{{domain}}","private_key_id":null,"publish_directory":null,"redirect":"both","repository_project_id":null,"restart_count":0,"restart_limit_reached":false,"server_status":true,"settings":{"is_static":false,"is_git_submodules_enabled":true,"is_git_lfs_enabled":true,"is_auto_deploy_enabled":true,"is_force_https_enabled":true,"is_debug_enabled":false,"is_preview_deployments_enabled":false,"is_log_drain_enabled":false,"is_gpu_enabled":false,"gpu_driver":"nvidia","gpu_count":null,"gpu_device_ids":null,"gpu_options":null,"is_include_timestamps":false,"is_swarm_only_worker_nodes":true,"is_raw_compose_deployment_enabled":false,"is_build_server_enabled":false,"is_consistent_container_name_enabled":false,"is_gzip_enabled":true,"is_stripprefix_enabled":true,"connect_to_docker_network":false,"custom_internal_name":null,"is_container_label_escape_enabled":true,"is_env_sorting_enabled":false,"is_container_label_readonly_enabled":true,"is_preserve_repository_enabled":false,"disable_build_cache":false,"is_spa":false,"is_git_shallow_clone_enabled":true,"is_pr_deployments_public_enabled":false,"use_build_secrets":false,"stop_grace_period":null,"inject_build_args_to_dockerfile":true,"include_source_commit_in_build":false,"docker_images_to_keep":2},"source_id":null,"source_type":null,"start_command":null,"static_image":"nginx:alpine","status":"exited:unhealthy","swarm_placement_constraints":null,"swarm_replicas":1,"watch_paths":null,"created_at":"2026-09-22T11:20:53.000000Z","updated_at":"2026-09-22T11:25:19.000000Z"} \ No newline at end of file diff --git a/app2.json b/app2.json new file mode 100644 index 0000000..6f4b2b0 --- /dev/null +++ b/app2.json @@ -0,0 +1 @@ +{"uuid":"4uq3ri0vmsh82v0xb4zc28hr","name":"limelite-faceanalyzer","additional_networks_count":0,"additional_servers":[],"additional_servers_count":0,"base_directory":"\/","build_command":null,"build_pack":"dockercompose","compose_parsing_version":"5","config_hash":"9b4499e4d7561ba4e29d082c26859f01","container_present":false,"custom_docker_run_options":null,"custom_healthcheck_found":false,"custom_labels":"traefik.enable=true\ntraefik.http.middlewares.gzip.compress=true\ntraefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https\ntraefik.http.routers.http-0-4uq3ri0vmsh82v0xb4zc28hr.entryPoints=http\ntraefik.http.routers.http-0-4uq3ri0vmsh82v0xb4zc28hr.middlewares=gzip\ntraefik.http.routers.http-0-4uq3ri0vmsh82v0xb4zc28hr.rule=Host(`4uq3ri0vmsh82v0xb4zc28hr.91.203.135.27.sslip.io`) && PathPrefix(`\/`)\ntraefik.http.routers.http-0-4uq3ri0vmsh82v0xb4zc28hr.service=http-0-4uq3ri0vmsh82v0xb4zc28hr\ntraefik.http.services.http-0-4uq3ri0vmsh82v0xb4zc28hr.loadbalancer.server.port=80\ncaddy_0.encode=zstd gzip\ncaddy_0.handle_path.0_reverse_proxy={{upstreams 80}}\ncaddy_0.handle_path=\/*\ncaddy_0.header=-Server\ncaddy_0.try_files={path} \/index.html \/index.php\ncaddy_0=http:\/\/4uq3ri0vmsh82v0xb4zc28hr.91.203.135.27.sslip.io\ncaddy_ingress_network=coolify","custom_network_aliases":null,"custom_nginx_configuration":null,"deleted_at":null,"description":null,"destination":{"id":1,"name":"coolify","uuid":"aqyq2o4oubmgulktfusatwqm","network":"coolify","server_id":1,"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-08-19T05:37:20.000000Z","server":{"id":1,"uuid":"jrcjtobvncyba40v3vi6pzqe","name":"DigifoxServer-Prod","description":"","ip":"91.203.135.27","port":22,"user":"coolify-user","team_id":0,"private_key_id":0,"proxy":{"redirect_enabled":true,"last_saved_proxy_configuration":"name: coolify-proxy\nnetworks:\n coolify:\n external: true\nservices:\n traefik:\n container_name: coolify-proxy\n image: 'traefik:v3.7'\n restart: unless-stopped\n extra_hosts:\n - 'host.docker.internal:host-gateway'\n networks:\n - coolify\n ports:\n - '80:80'\n - '443:443'\n - '443:443\/udp'\n - '8080:8080'\n healthcheck:\n test: 'wget -qO- http:\/\/localhost:80\/ping || exit 1'\n interval: 4s\n timeout: 2s\n retries: 5\n volumes:\n - '\/var\/run\/docker.sock:\/var\/run\/docker.sock:ro'\n - '\/data\/coolify\/proxy\/:\/traefik'\n command:\n - '--ping=true'\n - '--ping.entrypoint=http'\n - '--api.dashboard=true'\n - '--entrypoints.http.address=:80'\n - '--entrypoints.https.address=:443'\n - '--entrypoints.http.http.encodequerysemicolons=true'\n - '--entryPoints.http.http2.maxConcurrentStreams=250'\n - '--entrypoints.https.http.encodequerysemicolons=true'\n - '--entryPoints.https.http2.maxConcurrentStreams=250'\n - '--entrypoints.https.http3'\n - '--providers.file.directory=\/traefik\/dynamic\/'\n - '--providers.file.watch=true'\n - '--certificatesresolvers.letsencrypt.acme.httpchallenge=true'\n - '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http'\n - '--certificatesresolvers.letsencrypt.acme.storage=\/traefik\/acme.json'\n - '--api.insecure=false'\n - '--providers.docker=true'\n - '--providers.docker.exposedbydefault=false'\n labels:\n - traefik.enable=true\n - traefik.http.routers.traefik.entrypoints=http\n - traefik.http.routers.traefik.service=api@internal\n - traefik.http.services.traefik.loadbalancer.server.port=8080\n - coolify.managed=true\n - coolify.proxy=true","type":"TRAEFIK","status":"starting","last_saved_settings":"3b2fb10ec80cfa819e51625efa249fe1","last_applied_settings":"3b2fb10ec80cfa819e51625efa249fe1"},"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-09-22T11:29:13.000000Z","unreachable_notification_sent":false,"unreachable_count":0,"high_disk_usage_notification_sent":false,"log_drain_notification_sent":false,"swarm_cluster":null,"validation_logs":null,"sentinel_updated_at":"2026-09-18 07:29:10","deleted_at":null,"ip_previous":null,"hetzner_server_id":null,"cloud_provider_token_id":null,"hetzner_server_status":null,"is_validating":false,"detected_traefik_version":null,"traefik_outdated_info":null,"server_metadata":{"os":"Ubuntu 22.04.5 LTS","arch":"x86_64","kernel":"5.15.0-187-generic","cpus":4,"memory_bytes":12239319040,"uptime_since":"2026-08-20 15:20:39","collected_at":"2026-08-20T13:37:08+00:00"},"vultr_instance_id":null,"vultr_instance_status":null,"digitalocean_droplet_id":null,"digitalocean_droplet_status":null,"sentinel_waiting_since":"2026-09-22T11:29:11.000000Z","is_coolify_host":false,"settings":{"id":2,"is_swarm_manager":false,"is_jump_server":false,"is_build_server":false,"is_reachable":true,"is_usable":true,"server_id":1,"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-09-22T11:29:20.000000Z","wildcard_domain":null,"is_cloudflare_tunnel":false,"is_logdrain_newrelic_enabled":false,"logdrain_newrelic_license_key":null,"logdrain_newrelic_base_uri":null,"is_logdrain_highlight_enabled":false,"logdrain_highlight_project_id":null,"is_logdrain_axiom_enabled":false,"logdrain_axiom_dataset_name":null,"logdrain_axiom_api_key":null,"is_swarm_worker":false,"is_logdrain_custom_enabled":false,"logdrain_custom_config":null,"logdrain_custom_config_parser":null,"concurrent_builds":2,"dynamic_timeout":3600,"force_disabled":false,"is_metrics_enabled":false,"generate_exact_labels":false,"force_docker_cleanup":true,"docker_cleanup_frequency":"0 0 * * *","docker_cleanup_threshold":80,"server_timezone":"UTC","delete_unused_volumes":false,"delete_unused_networks":false,"is_sentinel_enabled":true,"sentinel_token":"eyJpdiI6InhiRVYvTjcrY2grN293a0tWZkV1WFE9PSIsInZhbHVlIjoiaVFMZW5KTzY4QlZWYW82WmFnZmdBL0VwN3pJeEVRcjQzZ082T1NzT2xoMzVBVk9LQXJ4cXJkRUhZN0p2ZzcwQ3RFclg4WFlLOHVuTW0yU2pwcXR3aGc9PSIsIm1hYyI6IjdiMzFiOWU2MDhhN2RlNjhlZDJlYjRkMGQ3ZGU2YjlkMzI4MDY1ODk3YTY2NTgwZTdmOWM3Y2E0YjM3MTg3YzIiLCJ0YWciOiIifQ==","sentinel_metrics_refresh_rate_seconds":10,"sentinel_metrics_history_days":7,"sentinel_push_interval_seconds":60,"sentinel_custom_url":"https:\/\/deploy.digifox.live","server_disk_usage_notification_threshold":80,"is_sentinel_debug_enabled":false,"server_disk_usage_check_frequency":"0 23 * * *","is_terminal_enabled":true,"deployment_queue_limit":25,"disable_application_image_retention":false,"connection_timeout":10,"docker_version":"29.8.1","docker_version_checked_at":"2026-09-22T11:29:20.000000Z","compose_version":"5.5.1","compose_version_checked_at":"2026-09-22T11:29:05.000000Z","backup_compression_cpu_percentage":25}}},"destination_id":1,"destination_type":"App\\Models\\StandaloneDocker","docker_compose":null,"docker_compose_custom_build_command":null,"docker_compose_custom_start_command":null,"docker_compose_domains":null,"docker_compose_location":"\/docker-compose.yaml","docker_compose_raw":null,"docker_registry_image_name":null,"docker_registry_image_tag":null,"dockerfile":null,"dockerfile_location":null,"dockerfile_target_build":null,"environment":{"id":23,"name":"production","project_id":17,"created_at":"2026-08-12T05:23:25.000000Z","updated_at":"2026-08-12T05:23:25.000000Z","description":null,"uuid":"ijga3o6m6arup69yohj2ecyw","project":{"id":17,"uuid":"kozt3dmpa63penhin84sb8r0","name":"limelite-smartmirror","description":"","team_id":0,"created_at":"2026-08-12T05:23:25.000000Z","updated_at":"2026-08-18T11:28:25.000000Z","icon_path":null,"icon_storage_type":null,"icon_s3_storage_id":null,"team":{"id":0,"name":"Root Team","description":"The root team","personal_team":true,"created_at":"2026-06-05T23:01:55.000000Z","updated_at":"2026-06-05T23:11:01.000000Z","show_boarding":false,"custom_server_limit":null,"is_mcp_server_enabled":true}}},"environment_id":23,"fqdn":"http:\/\/4uq3ri0vmsh82v0xb4zc28hr.91.203.135.27.sslip.io","git_branch":"master","git_commit_sha":"HEAD","git_full_url":null,"git_repository":"https:\/\/mohanki:48d38a221949649fdf1b470bbd037de9a5e6c564@git.digifox.live\/mohanki\/limelite_faceanalyzer.git","health_check_command":null,"health_check_enabled":false,"health_check_host":"localhost","health_check_interval":5,"health_check_method":"GET","health_check_path":"\/","health_check_port":null,"health_check_response_text":null,"health_check_retries":10,"health_check_return_code":200,"health_check_scheme":"http","health_check_start_period":5,"health_check_timeout":5,"health_check_type":"http","http_basic_auth_password":null,"http_basic_auth_username":null,"install_command":null,"is_http_basic_auth_enabled":false,"last_online_at":"2026-06-05 23:01:53","last_restart_at":null,"last_restart_type":null,"limits_cpu_shares":1024,"limits_cpus":"0","limits_cpuset":null,"limits_memory":"0","limits_memory_reservation":"0","limits_memory_swap":"0","limits_memory_swappiness":60,"manual_webhook_secret_bitbucket":"yvbVnb9T2y7Zru3Jskw1UODFEermE2E6VhQ2M6QM","manual_webhook_secret_gitea":"tO5bHwa6rGYE5l8zByJzYXxionKHLRPkLgDbCTFj","manual_webhook_secret_github":"wGAJtfx6YmuDZF2jv1KaVdbT7S79uMogT8njpo7B","manual_webhook_secret_gitlab":"YmGawM1NqN2hHiMbFm8QYTadhZkqtYZF0HqBByOf","max_restart_count":0,"noindex_domains":null,"ports_exposes":"80","ports_mappings":null,"post_deployment_command":null,"post_deployment_command_container":null,"pre_deployment_command":null,"pre_deployment_command_container":null,"preview_url_template":"{{pr_id}}.{{domain}}","private_key_id":null,"publish_directory":null,"redirect":"both","repository_project_id":null,"restart_count":0,"restart_limit_reached":false,"server_status":true,"settings":{"is_static":false,"is_git_submodules_enabled":true,"is_git_lfs_enabled":true,"is_auto_deploy_enabled":true,"is_force_https_enabled":true,"is_debug_enabled":false,"is_preview_deployments_enabled":false,"is_log_drain_enabled":false,"is_gpu_enabled":false,"gpu_driver":"nvidia","gpu_count":null,"gpu_device_ids":null,"gpu_options":null,"is_include_timestamps":false,"is_swarm_only_worker_nodes":true,"is_raw_compose_deployment_enabled":false,"is_build_server_enabled":false,"is_consistent_container_name_enabled":false,"is_gzip_enabled":true,"is_stripprefix_enabled":true,"connect_to_docker_network":false,"custom_internal_name":null,"is_container_label_escape_enabled":true,"is_env_sorting_enabled":false,"is_container_label_readonly_enabled":true,"is_preserve_repository_enabled":false,"disable_build_cache":false,"is_spa":false,"is_git_shallow_clone_enabled":true,"is_pr_deployments_public_enabled":false,"use_build_secrets":false,"stop_grace_period":null,"inject_build_args_to_dockerfile":true,"include_source_commit_in_build":false,"docker_images_to_keep":2},"source_id":null,"source_type":null,"start_command":null,"static_image":"nginx:alpine","status":"exited:unhealthy","swarm_placement_constraints":null,"swarm_replicas":1,"watch_paths":null,"created_at":"2026-09-22T11:20:53.000000Z","updated_at":"2026-09-22T11:29:16.000000Z"} \ No newline at end of file diff --git a/app3.json b/app3.json new file mode 100644 index 0000000..700f21c --- /dev/null +++ b/app3.json @@ -0,0 +1 @@ +{"uuid":"4uq3ri0vmsh82v0xb4zc28hr","name":"limelite-faceanalyzer","additional_networks_count":0,"additional_servers":[],"additional_servers_count":0,"base_directory":"\/","build_command":null,"build_pack":"dockercompose","compose_parsing_version":"5","config_hash":"9b4499e4d7561ba4e29d082c26859f01","container_present":false,"custom_docker_run_options":null,"custom_healthcheck_found":false,"custom_labels":"dHJhZWZpay5lbmFibGU9dHJ1ZQp0cmFlZmlrLmh0dHAubWlkZGxld2FyZXMuZ3ppcC5jb21wcmVzcz10cnVlCnRyYWVmaWsuaHR0cC5taWRkbGV3YXJlcy5yZWRpcmVjdC10by1odHRwcy5yZWRpcmVjdHNjaGVtZS5zY2hlbWU9aHR0cHMKdHJhZWZpay5odHRwLnJvdXRlcnMuaHR0cC0wLTR1cTNyaTB2bXNoODJ2MHhiNHpjMjhoci5lbnRyeVBvaW50cz1odHRwCnRyYWVmaWsuaHR0cC5yb3V0ZXJzLmh0dHAtMC00dXEzcmkwdm1zaDgydjB4YjR6YzI4aHIubWlkZGxld2FyZXM9Z3ppcAp0cmFlZmlrLmh0dHAucm91dGVycy5odHRwLTAtNHVxM3JpMHZtc2g4MnYweGI0emMyOGhyLnJ1bGU9SG9zdChgNHVxM3JpMHZtc2g4MnYweGI0emMyOGhyLjkxLjIwMy4xMzUuMjcuc3NsaXAuaW9gKSAmJiBQYXRoUHJlZml4KGAvYCkKdHJhZWZpay5odHRwLnJvdXRlcnMuaHR0cC0wLTR1cTNyaTB2bXNoODJ2MHhiNHpjMjhoci5zZXJ2aWNlPWh0dHAtMC00dXEzcmkwdm1zaDgydjB4YjR6YzI4aHIKdHJhZWZpay5odHRwLnNlcnZpY2VzLmh0dHAtMC00dXEzcmkwdm1zaDgydjB4YjR6YzI4aHIubG9hZGJhbGFuY2VyLnNlcnZlci5wb3J0PTgwCmNhZGR5XzAuZW5jb2RlPXpzdGQgZ3ppcApjYWRkeV8wLmhhbmRsZV9wYXRoLjBfcmV2ZXJzZV9wcm94eT17e3Vwc3RyZWFtcyA4MH19CmNhZGR5XzAuaGFuZGxlX3BhdGg9LyoKY2FkZHlfMC5oZWFkZXI9LVNlcnZlcgpjYWRkeV8wLnRyeV9maWxlcz17cGF0aH0gL2luZGV4Lmh0bWwgL2luZGV4LnBocApjYWRkeV8wPWh0dHA6Ly80dXEzcmkwdm1zaDgydjB4YjR6YzI4aHIuOTEuMjAzLjEzNS4yNy5zc2xpcC5pbwpjYWRkeV9pbmdyZXNzX25ldHdvcms9Y29vbGlmeQ==","custom_network_aliases":null,"custom_nginx_configuration":null,"deleted_at":null,"description":null,"destination":{"id":1,"name":"coolify","uuid":"aqyq2o4oubmgulktfusatwqm","network":"coolify","server_id":1,"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-08-19T05:37:20.000000Z","server":{"id":1,"uuid":"jrcjtobvncyba40v3vi6pzqe","name":"DigifoxServer-Prod","description":"","ip":"91.203.135.27","port":22,"user":"coolify-user","team_id":0,"private_key_id":0,"proxy":{"redirect_enabled":true,"last_saved_proxy_configuration":"name: coolify-proxy\nnetworks:\n coolify:\n external: true\nservices:\n traefik:\n container_name: coolify-proxy\n image: 'traefik:v3.7'\n restart: unless-stopped\n extra_hosts:\n - 'host.docker.internal:host-gateway'\n networks:\n - coolify\n ports:\n - '80:80'\n - '443:443'\n - '443:443\/udp'\n - '8080:8080'\n healthcheck:\n test: 'wget -qO- http:\/\/localhost:80\/ping || exit 1'\n interval: 4s\n timeout: 2s\n retries: 5\n volumes:\n - '\/var\/run\/docker.sock:\/var\/run\/docker.sock:ro'\n - '\/data\/coolify\/proxy\/:\/traefik'\n command:\n - '--ping=true'\n - '--ping.entrypoint=http'\n - '--api.dashboard=true'\n - '--entrypoints.http.address=:80'\n - '--entrypoints.https.address=:443'\n - '--entrypoints.http.http.encodequerysemicolons=true'\n - '--entryPoints.http.http2.maxConcurrentStreams=250'\n - '--entrypoints.https.http.encodequerysemicolons=true'\n - '--entryPoints.https.http2.maxConcurrentStreams=250'\n - '--entrypoints.https.http3'\n - '--providers.file.directory=\/traefik\/dynamic\/'\n - '--providers.file.watch=true'\n - '--certificatesresolvers.letsencrypt.acme.httpchallenge=true'\n - '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http'\n - '--certificatesresolvers.letsencrypt.acme.storage=\/traefik\/acme.json'\n - '--api.insecure=false'\n - '--providers.docker=true'\n - '--providers.docker.exposedbydefault=false'\n labels:\n - traefik.enable=true\n - traefik.http.routers.traefik.entrypoints=http\n - traefik.http.routers.traefik.service=api@internal\n - traefik.http.services.traefik.loadbalancer.server.port=8080\n - coolify.managed=true\n - coolify.proxy=true","type":"TRAEFIK","status":"created","last_saved_settings":"3b2fb10ec80cfa819e51625efa249fe1","last_applied_settings":"3b2fb10ec80cfa819e51625efa249fe1"},"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-09-22T11:36:08.000000Z","unreachable_notification_sent":false,"unreachable_count":0,"high_disk_usage_notification_sent":false,"log_drain_notification_sent":false,"swarm_cluster":null,"validation_logs":null,"sentinel_updated_at":"2026-09-18 07:36:07","deleted_at":null,"ip_previous":null,"hetzner_server_id":null,"cloud_provider_token_id":null,"hetzner_server_status":null,"is_validating":false,"detected_traefik_version":null,"traefik_outdated_info":null,"server_metadata":{"os":"Ubuntu 22.04.5 LTS","arch":"x86_64","kernel":"5.15.0-187-generic","cpus":4,"memory_bytes":12239319040,"uptime_since":"2026-08-20 15:20:39","collected_at":"2026-08-20T13:37:08+00:00"},"vultr_instance_id":null,"vultr_instance_status":null,"digitalocean_droplet_id":null,"digitalocean_droplet_status":null,"sentinel_waiting_since":"2026-09-22T11:36:08.000000Z","is_coolify_host":false,"settings":{"id":2,"is_swarm_manager":false,"is_jump_server":false,"is_build_server":false,"is_reachable":true,"is_usable":true,"server_id":1,"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-09-22T11:36:05.000000Z","wildcard_domain":null,"is_cloudflare_tunnel":false,"is_logdrain_newrelic_enabled":false,"logdrain_newrelic_license_key":null,"logdrain_newrelic_base_uri":null,"is_logdrain_highlight_enabled":false,"logdrain_highlight_project_id":null,"is_logdrain_axiom_enabled":false,"logdrain_axiom_dataset_name":null,"logdrain_axiom_api_key":null,"is_swarm_worker":false,"is_logdrain_custom_enabled":false,"logdrain_custom_config":null,"logdrain_custom_config_parser":null,"concurrent_builds":2,"dynamic_timeout":3600,"force_disabled":false,"is_metrics_enabled":false,"generate_exact_labels":false,"force_docker_cleanup":true,"docker_cleanup_frequency":"0 0 * * *","docker_cleanup_threshold":80,"server_timezone":"UTC","delete_unused_volumes":false,"delete_unused_networks":false,"is_sentinel_enabled":true,"sentinel_token":"eyJpdiI6InhiRVYvTjcrY2grN293a0tWZkV1WFE9PSIsInZhbHVlIjoiaVFMZW5KTzY4QlZWYW82WmFnZmdBL0VwN3pJeEVRcjQzZ082T1NzT2xoMzVBVk9LQXJ4cXJkRUhZN0p2ZzcwQ3RFclg4WFlLOHVuTW0yU2pwcXR3aGc9PSIsIm1hYyI6IjdiMzFiOWU2MDhhN2RlNjhlZDJlYjRkMGQ3ZGU2YjlkMzI4MDY1ODk3YTY2NTgwZTdmOWM3Y2E0YjM3MTg3YzIiLCJ0YWciOiIifQ==","sentinel_metrics_refresh_rate_seconds":10,"sentinel_metrics_history_days":7,"sentinel_push_interval_seconds":60,"sentinel_custom_url":"https:\/\/deploy.digifox.live","server_disk_usage_notification_threshold":80,"is_sentinel_debug_enabled":false,"server_disk_usage_check_frequency":"0 23 * * *","is_terminal_enabled":true,"deployment_queue_limit":25,"disable_application_image_retention":false,"connection_timeout":10,"docker_version":"29.8.1","docker_version_checked_at":"2026-09-22T11:36:04.000000Z","compose_version":"5.5.1","compose_version_checked_at":"2026-09-22T11:36:05.000000Z","backup_compression_cpu_percentage":25}}},"destination_id":1,"destination_type":"App\\Models\\StandaloneDocker","docker_compose":null,"docker_compose_custom_build_command":null,"docker_compose_custom_start_command":null,"docker_compose_domains":null,"docker_compose_location":"\/docker-compose.yaml","docker_compose_raw":null,"docker_registry_image_name":null,"docker_registry_image_tag":null,"dockerfile":null,"dockerfile_location":null,"dockerfile_target_build":null,"environment":{"id":23,"name":"production","project_id":17,"created_at":"2026-08-12T05:23:25.000000Z","updated_at":"2026-08-12T05:23:25.000000Z","description":null,"uuid":"ijga3o6m6arup69yohj2ecyw","project":{"id":17,"uuid":"kozt3dmpa63penhin84sb8r0","name":"limelite-smartmirror","description":"","team_id":0,"created_at":"2026-08-12T05:23:25.000000Z","updated_at":"2026-08-18T11:28:25.000000Z","icon_path":null,"icon_storage_type":null,"icon_s3_storage_id":null,"team":{"id":0,"name":"Root Team","description":"The root team","personal_team":true,"created_at":"2026-06-05T23:01:55.000000Z","updated_at":"2026-06-05T23:11:01.000000Z","show_boarding":false,"custom_server_limit":null,"is_mcp_server_enabled":true}}},"environment_id":23,"fqdn":null,"git_branch":"master","git_commit_sha":"HEAD","git_full_url":null,"git_repository":"https:\/\/mohanki:48d38a221949649fdf1b470bbd037de9a5e6c564@git.digifox.live\/mohanki\/limelite_faceanalyzer.git","health_check_command":null,"health_check_enabled":false,"health_check_host":"localhost","health_check_interval":5,"health_check_method":"GET","health_check_path":"\/","health_check_port":null,"health_check_response_text":null,"health_check_retries":10,"health_check_return_code":200,"health_check_scheme":"http","health_check_start_period":5,"health_check_timeout":5,"health_check_type":"http","http_basic_auth_password":null,"http_basic_auth_username":null,"install_command":null,"is_http_basic_auth_enabled":false,"last_online_at":"2026-06-05 23:01:53","last_restart_at":null,"last_restart_type":null,"limits_cpu_shares":1024,"limits_cpus":"0","limits_cpuset":null,"limits_memory":"0","limits_memory_reservation":"0","limits_memory_swap":"0","limits_memory_swappiness":60,"manual_webhook_secret_bitbucket":"yvbVnb9T2y7Zru3Jskw1UODFEermE2E6VhQ2M6QM","manual_webhook_secret_gitea":"tO5bHwa6rGYE5l8zByJzYXxionKHLRPkLgDbCTFj","manual_webhook_secret_github":"wGAJtfx6YmuDZF2jv1KaVdbT7S79uMogT8njpo7B","manual_webhook_secret_gitlab":"YmGawM1NqN2hHiMbFm8QYTadhZkqtYZF0HqBByOf","max_restart_count":0,"noindex_domains":null,"ports_exposes":"80","ports_mappings":null,"post_deployment_command":null,"post_deployment_command_container":null,"pre_deployment_command":null,"pre_deployment_command_container":null,"preview_url_template":"{{pr_id}}.{{domain}}","private_key_id":null,"publish_directory":null,"redirect":"both","repository_project_id":null,"restart_count":0,"restart_limit_reached":false,"server_status":true,"settings":{"is_static":false,"is_git_submodules_enabled":true,"is_git_lfs_enabled":true,"is_auto_deploy_enabled":true,"is_force_https_enabled":true,"is_debug_enabled":false,"is_preview_deployments_enabled":false,"is_log_drain_enabled":false,"is_gpu_enabled":false,"gpu_driver":"nvidia","gpu_count":null,"gpu_device_ids":null,"gpu_options":null,"is_include_timestamps":false,"is_swarm_only_worker_nodes":true,"is_raw_compose_deployment_enabled":false,"is_build_server_enabled":false,"is_consistent_container_name_enabled":false,"is_gzip_enabled":true,"is_stripprefix_enabled":true,"connect_to_docker_network":false,"custom_internal_name":null,"is_container_label_escape_enabled":true,"is_env_sorting_enabled":false,"is_container_label_readonly_enabled":true,"is_preserve_repository_enabled":false,"disable_build_cache":false,"is_spa":false,"is_git_shallow_clone_enabled":true,"is_pr_deployments_public_enabled":false,"use_build_secrets":false,"stop_grace_period":null,"inject_build_args_to_dockerfile":true,"include_source_commit_in_build":false,"docker_images_to_keep":2},"source_id":null,"source_type":null,"start_command":null,"static_image":"nginx:alpine","status":"exited:unhealthy","swarm_placement_constraints":null,"swarm_replicas":1,"watch_paths":null,"created_at":"2026-09-22T11:20:53.000000Z","updated_at":"2026-09-22T11:35:14.000000Z"} \ No newline at end of file diff --git a/app4.json b/app4.json new file mode 100644 index 0000000..7207870 --- /dev/null +++ b/app4.json @@ -0,0 +1 @@ +{"uuid":"vn0t5yt9sbzirnd0qjlmte4j","name":"limelite-faceanalyzer-v2","additional_networks_count":0,"additional_servers":[],"additional_servers_count":0,"base_directory":"\/","build_command":null,"build_pack":"dockercompose","compose_parsing_version":"5","config_hash":"a72f07ac4f3e56c3cf98290f152a8e06","container_present":null,"custom_docker_run_options":null,"custom_healthcheck_found":false,"custom_labels":"traefik.enable=true\ntraefik.http.middlewares.gzip.compress=true\ntraefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https\ntraefik.http.routers.http-0-vn0t5yt9sbzirnd0qjlmte4j.entryPoints=http\ntraefik.http.routers.http-0-vn0t5yt9sbzirnd0qjlmte4j.middlewares=gzip\ntraefik.http.routers.http-0-vn0t5yt9sbzirnd0qjlmte4j.rule=Host(`vn0t5yt9sbzirnd0qjlmte4j.91.203.135.27.sslip.io`) && PathPrefix(`\/`)\ntraefik.http.routers.http-0-vn0t5yt9sbzirnd0qjlmte4j.service=http-0-vn0t5yt9sbzirnd0qjlmte4j\ntraefik.http.services.http-0-vn0t5yt9sbzirnd0qjlmte4j.loadbalancer.server.port=80\ncaddy_0.encode=zstd gzip\ncaddy_0.handle_path.0_reverse_proxy={{upstreams 80}}\ncaddy_0.handle_path=\/*\ncaddy_0.header=-Server\ncaddy_0.try_files={path} \/index.html \/index.php\ncaddy_0=http:\/\/vn0t5yt9sbzirnd0qjlmte4j.91.203.135.27.sslip.io\ncaddy_ingress_network=coolify","custom_network_aliases":null,"custom_nginx_configuration":null,"deleted_at":null,"description":null,"destination":{"id":1,"name":"coolify","uuid":"aqyq2o4oubmgulktfusatwqm","network":"coolify","server_id":1,"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-08-19T05:37:20.000000Z","server":{"id":1,"uuid":"jrcjtobvncyba40v3vi6pzqe","name":"DigifoxServer-Prod","description":"","ip":"91.203.135.27","port":22,"user":"coolify-user","team_id":0,"private_key_id":0,"proxy":{"redirect_enabled":true,"last_saved_proxy_configuration":"name: coolify-proxy\nnetworks:\n coolify:\n external: true\nservices:\n traefik:\n container_name: coolify-proxy\n image: 'traefik:v3.7'\n restart: unless-stopped\n extra_hosts:\n - 'host.docker.internal:host-gateway'\n networks:\n - coolify\n ports:\n - '80:80'\n - '443:443'\n - '443:443\/udp'\n - '8080:8080'\n healthcheck:\n test: 'wget -qO- http:\/\/localhost:80\/ping || exit 1'\n interval: 4s\n timeout: 2s\n retries: 5\n volumes:\n - '\/var\/run\/docker.sock:\/var\/run\/docker.sock:ro'\n - '\/data\/coolify\/proxy\/:\/traefik'\n command:\n - '--ping=true'\n - '--ping.entrypoint=http'\n - '--api.dashboard=true'\n - '--entrypoints.http.address=:80'\n - '--entrypoints.https.address=:443'\n - '--entrypoints.http.http.encodequerysemicolons=true'\n - '--entryPoints.http.http2.maxConcurrentStreams=250'\n - '--entrypoints.https.http.encodequerysemicolons=true'\n - '--entryPoints.https.http2.maxConcurrentStreams=250'\n - '--entrypoints.https.http3'\n - '--providers.file.directory=\/traefik\/dynamic\/'\n - '--providers.file.watch=true'\n - '--certificatesresolvers.letsencrypt.acme.httpchallenge=true'\n - '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http'\n - '--certificatesresolvers.letsencrypt.acme.storage=\/traefik\/acme.json'\n - '--api.insecure=false'\n - '--providers.docker=true'\n - '--providers.docker.exposedbydefault=false'\n labels:\n - traefik.enable=true\n - traefik.http.routers.traefik.entrypoints=http\n - traefik.http.routers.traefik.service=api@internal\n - traefik.http.services.traefik.loadbalancer.server.port=8080\n - coolify.managed=true\n - coolify.proxy=true","type":"TRAEFIK","status":"created","last_saved_settings":"3b2fb10ec80cfa819e51625efa249fe1","last_applied_settings":"3b2fb10ec80cfa819e51625efa249fe1"},"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-09-22T11:42:08.000000Z","unreachable_notification_sent":false,"unreachable_count":0,"high_disk_usage_notification_sent":false,"log_drain_notification_sent":false,"swarm_cluster":null,"validation_logs":null,"sentinel_updated_at":"2026-09-18 07:42:07","deleted_at":null,"ip_previous":null,"hetzner_server_id":null,"cloud_provider_token_id":null,"hetzner_server_status":null,"is_validating":false,"detected_traefik_version":null,"traefik_outdated_info":null,"server_metadata":{"os":"Ubuntu 22.04.5 LTS","arch":"x86_64","kernel":"5.15.0-187-generic","cpus":4,"memory_bytes":12239319040,"uptime_since":"2026-08-20 15:20:39","collected_at":"2026-08-20T13:37:08+00:00"},"vultr_instance_id":null,"vultr_instance_status":null,"digitalocean_droplet_id":null,"digitalocean_droplet_status":null,"sentinel_waiting_since":"2026-09-22T11:42:08.000000Z","is_coolify_host":false,"settings":{"id":2,"is_swarm_manager":false,"is_jump_server":false,"is_build_server":false,"is_reachable":true,"is_usable":true,"server_id":1,"created_at":"2026-08-19T05:37:20.000000Z","updated_at":"2026-09-22T11:42:05.000000Z","wildcard_domain":null,"is_cloudflare_tunnel":false,"is_logdrain_newrelic_enabled":false,"logdrain_newrelic_license_key":null,"logdrain_newrelic_base_uri":null,"is_logdrain_highlight_enabled":false,"logdrain_highlight_project_id":null,"is_logdrain_axiom_enabled":false,"logdrain_axiom_dataset_name":null,"logdrain_axiom_api_key":null,"is_swarm_worker":false,"is_logdrain_custom_enabled":false,"logdrain_custom_config":null,"logdrain_custom_config_parser":null,"concurrent_builds":2,"dynamic_timeout":3600,"force_disabled":false,"is_metrics_enabled":false,"generate_exact_labels":false,"force_docker_cleanup":true,"docker_cleanup_frequency":"0 0 * * *","docker_cleanup_threshold":80,"server_timezone":"UTC","delete_unused_volumes":false,"delete_unused_networks":false,"is_sentinel_enabled":true,"sentinel_token":"eyJpdiI6InhiRVYvTjcrY2grN293a0tWZkV1WFE9PSIsInZhbHVlIjoiaVFMZW5KTzY4QlZWYW82WmFnZmdBL0VwN3pJeEVRcjQzZ082T1NzT2xoMzVBVk9LQXJ4cXJkRUhZN0p2ZzcwQ3RFclg4WFlLOHVuTW0yU2pwcXR3aGc9PSIsIm1hYyI6IjdiMzFiOWU2MDhhN2RlNjhlZDJlYjRkMGQ3ZGU2YjlkMzI4MDY1ODk3YTY2NTgwZTdmOWM3Y2E0YjM3MTg3YzIiLCJ0YWciOiIifQ==","sentinel_metrics_refresh_rate_seconds":10,"sentinel_metrics_history_days":7,"sentinel_push_interval_seconds":60,"sentinel_custom_url":"https:\/\/deploy.digifox.live","server_disk_usage_notification_threshold":80,"is_sentinel_debug_enabled":false,"server_disk_usage_check_frequency":"0 23 * * *","is_terminal_enabled":true,"deployment_queue_limit":25,"disable_application_image_retention":false,"connection_timeout":10,"docker_version":"29.8.1","docker_version_checked_at":"2026-09-22T11:42:05.000000Z","compose_version":"5.5.1","compose_version_checked_at":"2026-09-22T11:42:05.000000Z","backup_compression_cpu_percentage":25}}},"destination_id":1,"destination_type":"App\\Models\\StandaloneDocker","docker_compose":null,"docker_compose_custom_build_command":null,"docker_compose_custom_start_command":null,"docker_compose_domains":null,"docker_compose_location":"\/docker-compose.yaml","docker_compose_raw":null,"docker_registry_image_name":null,"docker_registry_image_tag":null,"dockerfile":null,"dockerfile_location":null,"dockerfile_target_build":null,"environment":{"id":23,"name":"production","project_id":17,"created_at":"2026-08-12T05:23:25.000000Z","updated_at":"2026-08-12T05:23:25.000000Z","description":null,"uuid":"ijga3o6m6arup69yohj2ecyw","project":{"id":17,"uuid":"kozt3dmpa63penhin84sb8r0","name":"limelite-smartmirror","description":"","team_id":0,"created_at":"2026-08-12T05:23:25.000000Z","updated_at":"2026-08-18T11:28:25.000000Z","icon_path":null,"icon_storage_type":null,"icon_s3_storage_id":null,"team":{"id":0,"name":"Root Team","description":"The root team","personal_team":true,"created_at":"2026-06-05T23:01:55.000000Z","updated_at":"2026-06-05T23:11:01.000000Z","show_boarding":false,"custom_server_limit":null,"is_mcp_server_enabled":true}}},"environment_id":23,"fqdn":"http:\/\/vn0t5yt9sbzirnd0qjlmte4j.91.203.135.27.sslip.io","git_branch":"master","git_commit_sha":"HEAD","git_full_url":null,"git_repository":"https:\/\/mohanki:48d38a221949649fdf1b470bbd037de9a5e6c564@git.digifox.live\/mohanki\/limelite_faceanalyzer.git","health_check_command":null,"health_check_enabled":false,"health_check_host":"localhost","health_check_interval":5,"health_check_method":"GET","health_check_path":"\/","health_check_port":null,"health_check_response_text":null,"health_check_retries":10,"health_check_return_code":200,"health_check_scheme":"http","health_check_start_period":5,"health_check_timeout":5,"health_check_type":"http","http_basic_auth_password":null,"http_basic_auth_username":null,"install_command":null,"is_http_basic_auth_enabled":false,"last_online_at":"2026-06-05 23:01:53","last_restart_at":null,"last_restart_type":null,"limits_cpu_shares":1024,"limits_cpus":"0","limits_cpuset":null,"limits_memory":"0","limits_memory_reservation":"0","limits_memory_swap":"0","limits_memory_swappiness":60,"manual_webhook_secret_bitbucket":"fOAnt5ryuTAKiNFAt3nEfxREceCyUENbfaSRUD9P","manual_webhook_secret_gitea":"4wQTj8a4mUfSdna7o8CQdKSCawPWf39DPhvqeztR","manual_webhook_secret_github":"aJKfuyscFa2krCyO1kOYmNYzFS1qKckywv0pOd2O","manual_webhook_secret_gitlab":"ovN0g1yBvUwYR2rnWsAQHzQnDlzh5GPTIi2GLc38","max_restart_count":0,"noindex_domains":null,"ports_exposes":"80","ports_mappings":null,"post_deployment_command":null,"post_deployment_command_container":null,"pre_deployment_command":null,"pre_deployment_command_container":null,"preview_url_template":"{{pr_id}}.{{domain}}","private_key_id":null,"publish_directory":null,"redirect":"both","repository_project_id":null,"restart_count":0,"restart_limit_reached":false,"server_status":true,"settings":{"is_static":false,"is_git_submodules_enabled":true,"is_git_lfs_enabled":true,"is_auto_deploy_enabled":true,"is_force_https_enabled":true,"is_debug_enabled":false,"is_preview_deployments_enabled":false,"is_log_drain_enabled":false,"is_gpu_enabled":false,"gpu_driver":"nvidia","gpu_count":null,"gpu_device_ids":null,"gpu_options":null,"is_include_timestamps":false,"is_swarm_only_worker_nodes":true,"is_raw_compose_deployment_enabled":false,"is_build_server_enabled":false,"is_consistent_container_name_enabled":false,"is_gzip_enabled":true,"is_stripprefix_enabled":true,"connect_to_docker_network":false,"custom_internal_name":null,"is_container_label_escape_enabled":true,"is_env_sorting_enabled":false,"is_container_label_readonly_enabled":true,"is_preserve_repository_enabled":false,"disable_build_cache":false,"is_spa":false,"is_git_shallow_clone_enabled":true,"is_pr_deployments_public_enabled":false,"use_build_secrets":false,"stop_grace_period":null,"inject_build_args_to_dockerfile":true,"include_source_commit_in_build":false,"docker_images_to_keep":2},"source_id":null,"source_type":null,"start_command":null,"static_image":"nginx:alpine","status":"exited:unhealthy","swarm_placement_constraints":null,"swarm_replicas":1,"watch_paths":null,"created_at":"2026-09-22T11:42:15.000000Z","updated_at":"2026-09-22T11:42:15.000000Z"} \ No newline at end of file diff --git a/backend/controllers/analysisController.js b/backend/controllers/analysisController.js index fbd2bb7..e3c347f 100644 --- a/backend/controllers/analysisController.js +++ b/backend/controllers/analysisController.js @@ -132,6 +132,9 @@ exports.analyzeImage = async (req, res) => { } catch (error) { console.error('Error analyzing image:', error.response ? JSON.stringify(error.response.data) : error.message); - res.status(500).json({ error: error.message || 'Failed to analyze image' }); + res.status(500).json({ + error: error.message || 'Failed to analyze image', + details: error.response ? error.response.data : null + }); } }; diff --git a/backend/scripts/seedKeys.js b/backend/scripts/seedKeys.js index 667b4c9..60b64c2 100644 --- a/backend/scripts/seedKeys.js +++ b/backend/scripts/seedKeys.js @@ -7,8 +7,8 @@ dotenv.config({ path: path.join(__dirname, '../.env') }); const Config = require('../models/Config'); const { encrypt } = require('../utils/crypto'); -const PERFECT_CORP_API_KEY = 'sk-tHtPU8rst9cifrM6RhkjCKy9EpNfXBdcoCbzP0QDRhIkHr_InBYPS6g_6XGSumbm'; -const PERFECT_CORP_SECRET_KEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCKexD/nyLrGq7jXCxYi/Tjwr297cZS5EUFQbCV9NO2XQU/sJitsT2WBHHS8AYAQrzM56hPgnwpt/B+EuSuLfVbM/ympBUvSrULUNlrJF5lW96JMd1KF8RWC9fICZJuCE2iGpGAd0l9pOCUmYM4JZ/n26HxZxSSramkoOYxmhFYhQIDAQAB'; +const PERFECT_CORP_API_KEY = 'sk-cKf0TV79X6Fp3CZwKfsnHv1Rq9GOK6nFCAXyDG9CvnIFKGYiTtSdOnjyadBaYc5y'; +const PERFECT_CORP_SECRET_KEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAiLqa5kyq7FR9WmK++HCPNjGLsljLfvJQq+JZzCx7pfLlVD5KzRb17iglHQJkFkSHxfqxtYNwosA54oT9uD1kA96TJy+uOLRwxry7BMPTFQyDdIoloJCI/Bl+SEnSxjDoYpU8zA3S4GDkmLH3A7vHkxhMydgB8B1EOxJahQsF7QIDAQAB'; async function seedKeys() { try { @@ -38,3 +38,10 @@ async function seedKeys() { } module.exports = seedKeys; + +if (require.main === module) { + seedKeys().then(() => { + console.log('Seeding complete. Exiting.'); + process.exit(0); + }); +} diff --git a/backend/scripts/testApiKey.js b/backend/scripts/testApiKey.js new file mode 100644 index 0000000..08edd58 --- /dev/null +++ b/backend/scripts/testApiKey.js @@ -0,0 +1,18 @@ +const axios = require('axios'); +const API_KEY = 'sk-cKf0TV79X6Fp3CZwKfsnHv1Rq9GOK6nFCAXyDG9CvnIFKGYiTtSdOnjyadBaYc5y'; +const baseUrl = 'https://yce-api-01.makeupar.com/s2s/v2.0'; +const initPayload = { + files: [ + { content_type: 'image/jpeg', file_name: 'test.jpg', file_size: 100000 } + ] +}; +axios.post(`${baseUrl}/file`, initPayload, { + headers: { + 'Authorization': `Bearer ${API_KEY}`, + 'Content-Type': 'application/json' + } +}).then(res => console.log('Init success:', JSON.stringify(res.data))) + .catch(err => { + console.error('Init failed:', err.response ? err.response.status : err.message); + if(err.response) console.error(JSON.stringify(err.response.data)); + }); diff --git a/backend/scripts/testApiKeyTask.js b/backend/scripts/testApiKeyTask.js new file mode 100644 index 0000000..f32a29d --- /dev/null +++ b/backend/scripts/testApiKeyTask.js @@ -0,0 +1,44 @@ +const axios = require('axios'); +const API_KEY = 'sk-cKf0TV79X6Fp3CZwKfsnHv1Rq9GOK6nFCAXyDG9CvnIFKGYiTtSdOnjyadBaYc5y'; +const baseUrl = 'https://yce-api-01.makeupar.com/s2s/v2.0'; + +async function test() { + try { + const initPayload = { + files: [ + { content_type: 'image/jpeg', file_name: 'test.jpg', file_size: 100000 } + ] + }; + + console.log('Init...'); + const res = await axios.post(`${baseUrl}/file`, initPayload, { + headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' } + }); + + const fileId = res.data.data.files[0].file_id; + console.log('File ID:', fileId); + + console.log('Creating task...'); + const taskPayload = { + src_file_id: fileId, + dst_actions: [ + "wrinkle", "pore", "texture", "acne", "moisture", "eye_bag", + "firmness", "age_spot", "radiance", "redness", "oiliness" + ], + miniserver_args: { + enable_mask_overlay: false + }, + format: "json" + }; + + const taskRes = await axios.post(`${baseUrl}/task/skin-analysis`, taskPayload, { + headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' } + }); + + console.log('Task success:', taskRes.data); + } catch (err) { + console.error('Failed:', err.response ? err.response.status : err.message); + if(err.response) console.error(JSON.stringify(err.response.data, null, 2)); + } +} +test(); diff --git a/exec.json b/exec.json new file mode 100644 index 0000000..bf2647c --- /dev/null +++ b/exec.json @@ -0,0 +1,3 @@ +{ + "command": "uptime" +} diff --git a/frontend/src/AnalysisResultPage.jsx b/frontend/src/AnalysisResultPage.jsx index 28af8f5..184b7ff 100644 --- a/frontend/src/AnalysisResultPage.jsx +++ b/frontend/src/AnalysisResultPage.jsx @@ -1,1039 +1,1039 @@ -// src/pages/AnalysisResultPage.jsx -import React, { useState, useEffect, useRef } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { loadFromDB, saveToDB } from './db'; -import jsPDF from 'jspdf'; -import html2canvas from 'html2canvas'; -import API_BASE_URL from './config'; - -const AnalysisResultPage = () => { - const navigate = useNavigate(); - - const errorDescriptions = { - 'error_below_min_image_size': 'Input image resolution is too small', - 'error_exceed_max_image_size': 'Input image resolution is too large', - 'error_src_skin_too_small': 'The skin area in the uploaded image is too small. The width of the skin needs to be greater than 60% of the width of the image.', - 'error_src_skin_out_of_bound': 'The skin area in the uploaded image is out of bound', - 'error_lighting_dark': 'The lighting in the uploaded image is too dark' - }; - - const [analysisData, setAnalysisData] = useState(null); - const [isLoading, setIsLoading] = useState(true); - const [error, setError] = useState(null); - const [selectedMetric, setSelectedMetric] = useState(null); - const [activeMask, setActiveMask] = useState(null); - const [showSignupModal, setShowSignupModal] = useState(false); - const [showHelpModal, setShowHelpModal] = useState(false); - const [isVerified, setIsVerified] = useState(false); - - // Form State - const [formData, setFormData] = useState({ name: '', phone: '' }); - const [formErrors, setFormErrors] = useState({ name: '', phone: '' }); - - // Report Ref - const reportRef = useRef(null); - - // OTP State - const [showOtpModal, setShowOtpModal] = useState(false); - const [otp, setOtp] = useState(new Array(6).fill('')); - const [otpError, setOtpError] = useState(''); - const [isVerifying, setIsVerifying] = useState(false); - const [isSendingReport, setIsSendingReport] = useState(false); - const [isSubmittingSignup, setIsSubmittingSignup] = useState(false); - const [toast, setToast] = useState({ show: false, message: '' }); - - // WhatsApp API configuration has been moved to backend - - // Track the generated OTP for verification (frontend-only simulation) - const [generatedOtp, setGeneratedOtp] = useState(''); - - // Validation Regex - const nameRegex = /^[a-zA-Z\s]*$/; - const phoneRegex = /^\d{0,10}$/; - - // Ref for PDF capture - const pdfRef = useRef(null); - - useEffect(() => { - const loadAnalysisData = async () => { - try { - const urlParams = new URLSearchParams(window.location.search); - const phone = urlParams.get('phone'); - const reportId = urlParams.get('report'); - - if (phone && reportId) { - // We are coming from a verification link - try { - const res = await fetch(`${API_BASE_URL}/api/reports/${reportId}`); - if (res.ok) { - const savedReport = await res.json(); - setAnalysisData(savedReport.data); - setFormData(prev => ({ ...prev, phone: phone, name: savedReport.userName || '' })); - // Skip OTP when clicking the direct report link or from admin panel - setIsVerified(true); - setIsLoading(false); - return; - } - } catch (e) { - console.error("Failed to load report", e); - } - } - - const storedData = await loadFromDB('analysisData'); - if (!storedData) { - throw new Error('No analysis data found. Please start a new analysis.'); - } - setAnalysisData(storedData); - setIsLoading(false); - } catch (err) { - setError(err.message); - setIsLoading(false); - } - }; - loadAnalysisData(); - }, []); - - const handleNewAnalysis = async () => { - await saveToDB('analysisData', null); - navigate('/'); - }; - - const getScoreColor = (score) => { - if (!score && score !== 0) return 'bg-gray-600'; - if (score >= 70) return 'bg-emerald-500'; - if (score >= 40) return 'bg-yellow-500'; - return 'bg-limelite-red'; - }; - - const getMetricDisplayName = (metricKey) => { - const displayNames = { - wrinkle: 'Wrinkles', - radiance: 'Radiance', - firmness: 'Firmness', - oiliness: 'Oiliness', - redness: 'Redness', - dark_circle_v2: 'Dark Circles', - pore: 'Pores', - eye_bag: 'Eye Bags', - texture: 'Texture', - age_spot: 'Age Spots', - droopy_lower_eyelid: 'Droopy Lower Eyelid', - moisture: 'Moisture', - droopy_upper_eyelid: 'Droopy Upper Eyelid', - acne: 'Acne' - }; - return displayNames[metricKey] || metricKey.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()); - }; - - const handleMetricClick = (metric) => { - if (metric.output_mask_name) { - const maskData = analysisData?.maskImages?.[metric.output_mask_name]; - if (maskData) { - setActiveMask(maskData); - setSelectedMetric(metric.key); - } else { - setActiveMask(null); - setSelectedMetric(null); - } - } else { - setActiveMask(null); - setSelectedMetric(null); - } - }; - - const handleClearMask = () => { - setActiveMask(null); - setSelectedMetric(null); - }; - - const handleNameChange = (e) => { - const val = e.target.value; - if (nameRegex.test(val)) { - setFormData(prev => ({ ...prev, name: val })); - if (formErrors.name) setFormErrors(prev => ({ ...prev, name: '' })); - } - }; - - const handlePhoneChange = (e) => { - const val = e.target.value; - if (phoneRegex.test(val)) { - setFormData(prev => ({ ...prev, phone: val })); - if (formErrors.phone) setFormErrors(prev => ({ ...prev, phone: '' })); - } - }; - - // OTP Handlers - const handleOtpChange = (element, index) => { - if (isNaN(element.value)) return false; - - setOtp([...otp.map((d, idx) => (idx === index ? element.value : d))]); - - // Focus next input - if (element.nextSibling && element.value !== "") { - element.nextSibling.focus(); - } - }; - - const sendWhatsappOtp = async (phone) => { - // Generate a unique ID for this specific analysis report - const reportId = Math.random().toString(36).substring(7); - const currentUrl = window.location.origin + window.location.pathname; - const verificationLink = `${currentUrl}?phone=${phone}&report=${reportId}`; - - let otpToUse = ''; - let isExisting = false; - - try { - // 1. Create/Update User & Get OTP from Backend - const userRes = await fetch(`${API_BASE_URL}/api/users`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ name: formData.name, phone: phone }) - }); - const userResText = await userRes.text(); - let userData; - try { - userData = JSON.parse(userResText); - } catch (e) { - console.error('User API returned non-JSON:', userResText); - throw new Error('Could not connect to user API properly. Please try again.'); - } - - if (userData.success) { - otpToUse = userData.user.otp; - isExisting = userData.user.isExisting || false; - setGeneratedOtp(otpToUse); - } else if (userData.message && userData.message.includes('already registered')) { - // If backend says already registered, we treat as existing user - isExisting = true; - console.log("User already registered, proceeding as existing user"); - } else { - const errorMsg = userData.message || 'Failed to register user'; - throw new Error(errorMsg); - } - - // 2. Generate PDF and Save to Backend - let generatedPdfLink = verificationLink; - if (reportRef.current) { - const reportElement = reportRef.current; - reportElement.style.display = 'block'; - - try { - const canvas = await html2canvas(reportElement, { - scale: 2, - useCORS: true, - allowTaint: true, - backgroundColor: '#ffffff' - }); - const imgData = canvas.toDataURL('image/png'); - const pdf = new jsPDF('p', 'mm', 'a4'); - const pdfWidth = pdf.internal.pageSize.getWidth(); - const pdfHeight = (canvas.height * pdfWidth) / canvas.width; - pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight); - const pdfBlob = pdf.output('blob'); - - const fd = new FormData(); - fd.append('pdf', pdfBlob, `Limelite_Report_${phone}.pdf`); - fd.append('phone', phone); - fd.append('userName', formData.name); - - const saveRes = await fetch(`${API_BASE_URL}/api/reports/save-pdf`, { - method: 'POST', - body: fd - }); - const saveData = await saveRes.json(); - - if (saveData.success) { - generatedPdfLink = `${API_BASE_URL}${saveData.link}`; - } - } catch(err) { - console.error("Failed to generate/upload PDF during save:", err); - } finally { - reportElement.style.display = 'none'; - } - } - - verificationLink = generatedPdfLink; - - console.log(`Sending WhatsApp message request to backend for ${phone}`); - - const response = await fetch(`${API_BASE_URL}/api/whatsapp/send-otp`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - phone: phone, - name: formData.name, - otpToUse: otpToUse, - verificationLink: verificationLink, - isExisting: isExisting - }) - }); - - if (!response.ok) { - const waErrText = await response.text(); - let errorData; - try { - errorData = JSON.parse(waErrText); - } catch (e) { - errorData = { message: waErrText.substring(0, 100) }; - } - console.error('Backend WhatsApp API Error:', errorData); - throw new Error(errorData.message || 'Failed to send WhatsApp message'); - } - - console.log('WhatsApp message sent successfully via backend'); - return { ...(userData.user || {}), isExisting: isExisting }; - } catch (err) { - console.error('Error in sendWhatsappOtp:', err); - throw err; - } - }; - - const verifyWhatsappOtp = async (enteredOtp) => { - try { - const res = await fetch(`${API_BASE_URL}/api/verify-otp`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ phone: formData.phone, otp: enteredOtp }) - }); - const data = await res.json(); - return data.success; - } catch (e) { - console.error("OTP verification error", e); - return false; - } - }; - - const sendReportToWhatsapp = async () => { - setIsSendingReport(true); - try { - // Sending a follow-up message with the overall score via backend - const response = await fetch(`${API_BASE_URL}/api/whatsapp/send-report`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - phone: formData.phone, - name: formData.name, - overallScore: overallScore, - origin: window.location.origin - }) - }); - - if (!response.ok) throw new Error('Failed to send report'); - - alert("Report details sent to your WhatsApp!"); - } catch (err) { - console.error('Error sending report:', err); - alert("Failed to send report. Please try again."); - } finally { - setIsSendingReport(false); - } - }; - - const handleSignupSubmit = async () => { - // const db = JSON.parse(localStorage.getItem('limelite_users') || '{}'); - // const existingUser = db[formData.phone]; - const existingUser = false; // logic moved to backend, or we can check via api but it's fine - - - let errors = {}; - if (!formData.name.trim()) errors.name = 'Name is required'; - if (formData.phone.length !== 10) errors.phone = 'Number must be exactly 10 digits'; - - // We allow both new and existing users to proceed - // If they are existing, the backend call in sendWhatsappOtp will handle it - - if (Object.keys(errors).length > 0) { - setFormErrors(errors); - return; - } - - setIsSubmittingSignup(true); - try { - const user = await sendWhatsappOtp(formData.phone); - setShowSignupModal(false); - - if (user && user.isExisting) { - setIsVerified(true); - setToast({ show: true, message: "You're already an user, welcome back!" }); - setTimeout(() => setToast({ show: false, message: '' }), 4000); - } else { - setShowOtpModal(true); - setOtp(new Array(6).fill('')); - } - } catch (err) { - setFormErrors({ phone: err.message || 'Failed to send message. Please try again.' }); - } finally { - setIsSubmittingSignup(false); - } - }; - - const handleVerifyOtp = async () => { - const enteredOtp = otp.join(''); - if (enteredOtp.length !== 6) { - setOtpError('Please enter a valid 6-digit OTP'); - return; - } - - setIsVerifying(true); - setOtpError(''); - - try { - const isValid = await verifyWhatsappOtp(enteredOtp); - if (isValid) { - alert("OTP Verified Successfully!"); - setShowOtpModal(false); - setIsVerified(true); - } else { - setOtpError('Invalid OTP. Please try again.'); - } - } catch (error) { - setOtpError('Verification failed. Please try again.'); - } finally { - setIsVerifying(false); - } - }; - - const getScoreValue = (data, key) => { - if (!data || typeof data !== 'object') return null; - if (data[key] && typeof data[key] === 'object') return data[key].ui_score || data[key].score || data[key].raw_score || null; - if (data[key] !== undefined && data[key] !== null) return data[key]; - return null; - }; - - const hasDetailedData = (data, key) => { - return data && data[key] && typeof data[key] === 'object' && data[key].ui_score !== undefined; - }; - - // --- START OF MODIFICATION --- - /** - * Adjusts the score by -5 and ensures it's not negative. - * @param {number|string} score The original score. - * @returns {number|null} The adjusted score or null. - */ - const getAdjustedScore = (score) => { - const numScore = Number(score); - if (isNaN(numScore) || score === null || score === undefined) return null; - // Apply -5 adjustment and ensure the score is not negative. - return Math.max(0, numScore - 5); - }; - // --- END OF MODIFICATION --- - - const getDisplayMetrics = (scoreData) => { - if (!scoreData) return []; - return Object.keys(scoreData) - .filter(key => !['all', 'skin_age', 'takeaways', 'resize', 'image', 'url', 'resize_image', 'image_size'].includes(key)) - .map(key => { - const rawScore = hasDetailedData(scoreData, key) ? scoreData[key].ui_score : getScoreValue(scoreData, key); - // --- START OF MODIFICATION --- - const adjustedUiScore = getAdjustedScore(rawScore); - // --- END OF MODIFICATION --- - return { - key, - name: getMetricDisplayName(key), - // Use the adjusted score for display - ui_score: adjustedUiScore, - raw_score: hasDetailedData(scoreData, key) ? scoreData[key].raw_score : null, - output_mask_name: hasDetailedData(scoreData, key) ? scoreData[key].output_mask_name : null, - hasDetails: hasDetailedData(scoreData, key) - }; - }); - }; - - const renderUserImage = () => { - const originalImage = analysisData?.originalImage; - if (!originalImage) return null; - - return ( -
Analyzing skin profile...
-{errorDescriptions[error] || error}
- -No analysis data available.
- -- Sign up to access overall analysis report -
-{formErrors.name}
} -{formErrors.phone}
} -- Please enter the OTP sent to you on whatsapp. -
- -{otpError}
} - - - -- To access previous reports, please contact us at hello@limelite.com -
-- If you experience any technical issues, please contact us at support@example.com -
-Name
-{formData.name || 'Anonymous'}
-Contact Number
-+91 {formData.phone || 'N/A'}
-Analysis Date
-- {(() => { - const d = new Date(); - const day = d.getDate(); - const suffix = (day > 3 && day < 21) || day % 10 > 3 ? 'th' : ['th', 'st', 'nd', 'rd'][day % 10]; - return `${day}${suffix} ${d.toLocaleString('en-GB', { month: 'long' })} ${d.getFullYear()}`; - })()} -
-Skin Health
-Advanced Hydration: Apply hyaluronic acid serum daily to stabilize moisture levels.
-Dermal Protection: Broad-spectrum physical sunshade is mandatory for UV protection.
-Clinical Intervention: Visit your specialist for focused treatment on top priority zones.
-- * This diagnostic data is interpreted by Limelite AI Face Vision. For detailed medical prescriptions, please book a 1-on-1 therapist consultation. -
-LIMELITE CLINICAL SYSTEMS
-support@limelite.com | limelite.com
-Analyzing skin profile...
+{errorDescriptions[error] || error}
+ +No analysis data available.
+ ++ Sign up to access overall analysis report +
+{formErrors.name}
} +{formErrors.phone}
} ++ Please enter the OTP sent to you on whatsapp. +
+ +{otpError}
} + + + ++ To access previous reports, please contact us at hello@limelite.com +
++ If you experience any technical issues, please contact us at support@example.com +
+Name
+{formData.name || 'Anonymous'}
+Contact Number
++91 {formData.phone || 'N/A'}
+Analysis Date
++ {(() => { + const d = new Date(); + const day = d.getDate(); + const suffix = (day > 3 && day < 21) || day % 10 > 3 ? 'th' : ['th', 'st', 'nd', 'rd'][day % 10]; + return `${day}${suffix} ${d.toLocaleString('en-GB', { month: 'long' })} ${d.getFullYear()}`; + })()} +
+Skin Health
+Advanced Hydration: Apply hyaluronic acid serum daily to stabilize moisture levels.
+Dermal Protection: Broad-spectrum physical sunshade is mandatory for UV protection.
+Clinical Intervention: Visit your specialist for focused treatment on top priority zones.
++ * This diagnostic data is interpreted by Limelite AI Face Vision. For detailed medical prescriptions, please book a 1-on-1 therapist consultation. +
+LIMELITE CLINICAL SYSTEMS
+support@limelite.com | limelite.com
+| S.No | -Name | -Mobile Number | -Report | -
|---|---|---|---|
| {(currentPage - 1) * ITEMS_PER_PAGE + index + 1} | -{report.name} | -{report.phone} | -- - {report.link ? report.link.substring(report.link.indexOf('result')) : '-'} - - | -
WhatsApp Notifications
-Send automatic alerts for new analysis signups
-Auto-Archive Reports
-Automatically archive reports older than 30 days
-- To access previous reports, please contact us at hello@limelite.com -
-- If you experience any technical issues, please contact us at support@example.com -
-| S.No | +Name | +Mobile Number | +Report | +
|---|---|---|---|
| {(currentPage - 1) * ITEMS_PER_PAGE + index + 1} | +{report.name} | +{report.phone} | ++ {report.link ? ( + + View Report + + ) : '-'} + | +
WhatsApp Notifications
+Send automatic alerts for new analysis signups
+Auto-Archive Reports
+Automatically archive reports older than 30 days
++ To access previous reports, please contact us at hello@limelite.com +
++ If you experience any technical issues, please contact us at support@example.com +
+