diff --git a/frontend/middleware.ts b/frontend/middleware.ts index 042ee29c..7677f31b 100644 --- a/frontend/middleware.ts +++ b/frontend/middleware.ts @@ -52,6 +52,7 @@ function isPublicApi(pathname: string) { pathname === "/api/auth/me" || pathname === "/api/analytics/events" || pathname === "/api/cities" || + pathname === "/api/scan/terminal" || pathname === "/api/vitals" || /^\/api\/city\/[^/]+$/i.test(pathname) || /^\/api\/city\/[^/]+\/summary$/i.test(pathname) || diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 6addbdb5..c9540b90 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -32,6 +32,7 @@ "@types/three": "^0.183.1", "@types/trusted-types": "^2.0.7", "autoprefixer": "^10.4.20", + "playwright": "^1.59.1", "postcss": "^8.5.3", "tailwindcss": "^3.4.17", "typescript": "^5.8.3" @@ -2052,48 +2053,6 @@ } } }, - "node_modules/@solana/kit": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@solana/kit/-/kit-5.5.1.tgz", - "integrity": "sha512-irKUGiV2yRoyf+4eGQ/ZeCRxa43yjFEL1DUI5B0DkcfZw3cr0VJtVJnrG8OtVF01vT0OUfYOcUn6zJW5TROHvQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "@solana/accounts": "5.5.1", - "@solana/addresses": "5.5.1", - "@solana/codecs": "5.5.1", - "@solana/errors": "5.5.1", - "@solana/functional": "5.5.1", - "@solana/instruction-plans": "5.5.1", - "@solana/instructions": "5.5.1", - "@solana/keys": "5.5.1", - "@solana/offchain-messages": "5.5.1", - "@solana/plugin-core": "5.5.1", - "@solana/programs": "5.5.1", - "@solana/rpc": "5.5.1", - "@solana/rpc-api": "5.5.1", - "@solana/rpc-parsed-types": "5.5.1", - "@solana/rpc-spec-types": "5.5.1", - "@solana/rpc-subscriptions": "5.5.1", - "@solana/rpc-types": "5.5.1", - "@solana/signers": "5.5.1", - "@solana/sysvars": "5.5.1", - "@solana/transaction-confirmation": "5.5.1", - "@solana/transaction-messages": "5.5.1", - "@solana/transactions": "5.5.1" - }, - "engines": { - "node": ">=20.18.0" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@solana/nominal-types": { "version": "5.5.1", "resolved": "https://registry.npmmirror.com/@solana/nominal-types/-/nominal-types-5.5.1.tgz", @@ -2845,6 +2804,7 @@ "version": "2.99.1", "resolved": "https://registry.npmmirror.com/@supabase/supabase-js/-/supabase-js-2.99.1.tgz", "integrity": "sha512-5MRoYD9ffXq8F6a036dm65YoSHisC3by/d22mauKE99Vrwf792KxYIIr/iqCX7E4hkuugbPZ5EGYHTB7MKy6Vg==", + "peer": true, "dependencies": { "@supabase/auth-js": "2.99.1", "@supabase/functions-js": "2.99.1", @@ -2917,6 +2877,7 @@ "resolved": "https://registry.npmmirror.com/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "devOptional": true, + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -3134,21 +3095,6 @@ "ws": "^7.5.1" } }, - "node_modules/@walletconnect/jsonrpc-ws-connection/node_modules/utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmmirror.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, "node_modules/@walletconnect/jsonrpc-ws-connection/node_modules/ws": { "version": "7.5.10", "resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.10.tgz", @@ -3577,18 +3523,6 @@ "postcss": "^8.1.0" } }, - "node_modules/axios": { - "version": "1.14.0", - "resolved": "https://registry.npmmirror.com/axios/-/axios-1.14.0.tgz", - "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", - "proxy-from-env": "^2.1.0" - } - }, "node_modules/axios-retry": { "version": "4.5.0", "resolved": "https://registry.npmmirror.com/axios-retry/-/axios-retry-4.5.0.tgz", @@ -3732,6 +3666,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -4697,21 +4632,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "optional": true }, - "node_modules/jayson/node_modules/utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmmirror.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, "node_modules/jayson/node_modules/ws": { "version": "7.5.10", "resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.10.tgz", @@ -4738,6 +4658,7 @@ "resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.21.7.tgz", "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, + "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -4765,7 +4686,8 @@ "node_modules/leaflet": { "version": "1.9.4", "resolved": "https://registry.npmmirror.com/leaflet/-/leaflet-1.9.4.tgz", - "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==" + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "peer": true }, "node_modules/lilconfig": { "version": "3.1.3", @@ -5272,6 +5194,53 @@ "node": ">= 6" } }, + "node_modules/playwright": { + "version": "1.59.1", + "resolved": "https://registry.npmmirror.com/playwright/-/playwright-1.59.1.tgz", + "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.59.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.59.1", + "resolved": "https://registry.npmmirror.com/playwright-core/-/playwright-core-1.59.1.tgz", + "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/pngjs": { "version": "5.0.0", "resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz", @@ -5299,6 +5268,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -5527,6 +5497,7 @@ "version": "19.2.4", "resolved": "https://registry.npmmirror.com/react/-/react-19.2.4.tgz", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -5535,6 +5506,7 @@ "version": "19.2.4", "resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -6037,6 +6009,7 @@ "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, + "peer": true, "engines": { "node": ">=12" }, @@ -6077,6 +6050,7 @@ "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6469,6 +6443,7 @@ "version": "8.19.0", "resolved": "https://registry.npmmirror.com/ws/-/ws-8.19.0.tgz", "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -6523,16 +6498,6 @@ "node": ">=6" } }, - "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmmirror.com/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "optional": true, - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/zustand": { "version": "5.0.3", "resolved": "https://registry.npmmirror.com/zustand/-/zustand-5.0.3.tgz", @@ -7803,8 +7768,7 @@ "requires": {} }, "@solana/instruction-plans": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@solana/instruction-plans/-/instruction-plans-5.5.1.tgz", + "version": "https://registry.npmmirror.com/@solana/instruction-plans/-/instruction-plans-5.5.1.tgz", "integrity": "sha512-7z3CB7YMcFKuVvgcnNY8bY6IsZ8LG61Iytbz7HpNVGX2u1RthOs1tRW8luTzSG1MPL0Ox7afyAVMYeFqSPHnaQ==", "optional": true, "requires": { @@ -7839,36 +7803,6 @@ "@solana/nominal-types": "5.5.1" } }, - "@solana/kit": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@solana/kit/-/kit-5.5.1.tgz", - "integrity": "sha512-irKUGiV2yRoyf+4eGQ/ZeCRxa43yjFEL1DUI5B0DkcfZw3cr0VJtVJnrG8OtVF01vT0OUfYOcUn6zJW5TROHvQ==", - "optional": true, - "requires": { - "@solana/accounts": "5.5.1", - "@solana/addresses": "5.5.1", - "@solana/codecs": "5.5.1", - "@solana/errors": "5.5.1", - "@solana/functional": "5.5.1", - "@solana/instruction-plans": "5.5.1", - "@solana/instructions": "5.5.1", - "@solana/keys": "5.5.1", - "@solana/offchain-messages": "5.5.1", - "@solana/plugin-core": "5.5.1", - "@solana/programs": "5.5.1", - "@solana/rpc": "5.5.1", - "@solana/rpc-api": "5.5.1", - "@solana/rpc-parsed-types": "5.5.1", - "@solana/rpc-spec-types": "5.5.1", - "@solana/rpc-subscriptions": "5.5.1", - "@solana/rpc-types": "5.5.1", - "@solana/signers": "5.5.1", - "@solana/sysvars": "5.5.1", - "@solana/transaction-confirmation": "5.5.1", - "@solana/transaction-messages": "5.5.1", - "@solana/transactions": "5.5.1" - } - }, "@solana/nominal-types": { "version": "5.5.1", "resolved": "https://registry.npmmirror.com/@solana/nominal-types/-/nominal-types-5.5.1.tgz", @@ -7906,15 +7840,13 @@ } }, "@solana/plugin-core": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@solana/plugin-core/-/plugin-core-5.5.1.tgz", + "version": "https://registry.npmmirror.com/@solana/plugin-core/-/plugin-core-5.5.1.tgz", "integrity": "sha512-VUZl30lDQFJeiSyNfzU1EjYt2QZvoBFKEwjn1lilUJw7KgqD5z7mbV7diJhT+dLFs36i0OsjXvq5kSygn8YJ3A==", "optional": true, "requires": {} }, "@solana/programs": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@solana/programs/-/programs-5.5.1.tgz", + "version": "https://registry.npmmirror.com/@solana/programs/-/programs-5.5.1.tgz", "integrity": "sha512-7U9kn0Jsx1NuBLn5HRTFYh78MV4XN145Yc3WP/q5BlqAVNlMoU9coG5IUTJIG847TUqC1lRto3Dnpwm6T4YRpA==", "optional": true, "requires": { @@ -8096,8 +8028,7 @@ } }, "@solana/signers": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@solana/signers/-/signers-5.5.1.tgz", + "version": "https://registry.npmmirror.com/@solana/signers/-/signers-5.5.1.tgz", "integrity": "sha512-FY0IVaBT2kCAze55vEieR6hag4coqcuJ31Aw3hqRH7mv6sV8oqwuJmUrx+uFwOp1gwd5OEAzlv6N4hOOple4sQ==", "optional": true, "requires": { @@ -8122,8 +8053,7 @@ } }, "@solana/sysvars": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@solana/sysvars/-/sysvars-5.5.1.tgz", + "version": "https://registry.npmmirror.com/@solana/sysvars/-/sysvars-5.5.1.tgz", "integrity": "sha512-k3Quq87Mm+geGUu1GWv6knPk0ALsfY6EKSJGw9xUJDHzY/RkYSBnh0RiOrUhtFm2TDNjOailg8/m0VHmi3reFA==", "optional": true, "requires": { @@ -8134,8 +8064,7 @@ } }, "@solana/transaction-confirmation": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@solana/transaction-confirmation/-/transaction-confirmation-5.5.1.tgz", + "version": "https://registry.npmmirror.com/@solana/transaction-confirmation/-/transaction-confirmation-5.5.1.tgz", "integrity": "sha512-j4mKlYPHEyu+OD7MBt3jRoX4ScFgkhZC6H65on4Fux6LMScgivPJlwnKoZMnsgxFgWds0pl+BYzSiALDsXlYtw==", "optional": true, "requires": { @@ -8323,6 +8252,7 @@ "version": "2.99.1", "resolved": "https://registry.npmmirror.com/@supabase/supabase-js/-/supabase-js-2.99.1.tgz", "integrity": "sha512-5MRoYD9ffXq8F6a036dm65YoSHisC3by/d22mauKE99Vrwf792KxYIIr/iqCX7E4hkuugbPZ5EGYHTB7MKy6Vg==", + "peer": true, "requires": { "@supabase/auth-js": "2.99.1", "@supabase/functions-js": "2.99.1", @@ -8392,6 +8322,7 @@ "resolved": "https://registry.npmmirror.com/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "devOptional": true, + "peer": true, "requires": { "csstype": "^3.2.2" } @@ -8604,16 +8535,6 @@ "ws": "^7.5.1" }, "dependencies": { - "utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmmirror.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "optional": true, - "peer": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, "ws": { "version": "7.5.10", "resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.10.tgz", @@ -8929,17 +8850,6 @@ "postcss-value-parser": "^4.2.0" } }, - "axios": { - "version": "1.14.0", - "resolved": "https://registry.npmmirror.com/axios/-/axios-1.14.0.tgz", - "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==", - "optional": true, - "requires": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", - "proxy-from-env": "^2.1.0" - } - }, "axios-retry": { "version": "4.5.0", "resolved": "https://registry.npmmirror.com/axios-retry/-/axios-retry-4.5.0.tgz", @@ -9032,6 +8942,7 @@ "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.1.tgz", "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, + "peer": true, "requires": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -9456,14 +9367,12 @@ } }, "follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz", + "version": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz", "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "optional": true }, "form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz", + "version": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz", "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "optional": true, "requires": { @@ -9720,16 +9629,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "optional": true }, - "utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmmirror.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "optional": true, - "peer": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, "ws": { "version": "7.5.10", "resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.10.tgz", @@ -9743,7 +9642,8 @@ "version": "1.21.7", "resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.21.7.tgz", "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "dev": true + "dev": true, + "peer": true }, "jose": { "version": "6.2.1", @@ -9765,7 +9665,8 @@ "leaflet": { "version": "1.9.4", "resolved": "https://registry.npmmirror.com/leaflet/-/leaflet-1.9.4.tgz", - "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==" + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "peer": true }, "lilconfig": { "version": "3.1.3", @@ -10110,6 +10011,31 @@ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true }, + "playwright": { + "version": "1.59.1", + "resolved": "https://registry.npmmirror.com/playwright/-/playwright-1.59.1.tgz", + "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==", + "dev": true, + "requires": { + "fsevents": "2.3.2", + "playwright-core": "1.59.1" + }, + "dependencies": { + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + } + } + }, + "playwright-core": { + "version": "1.59.1", + "resolved": "https://registry.npmmirror.com/playwright-core/-/playwright-core-1.59.1.tgz", + "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==", + "dev": true + }, "pngjs": { "version": "5.0.0", "resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz", @@ -10120,6 +10046,7 @@ "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.8.tgz", "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, + "peer": true, "requires": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -10197,8 +10124,7 @@ "integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==" }, "proxy-from-env": { - "version": "2.1.0", - "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "version": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-2.1.0.tgz", "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "optional": true }, @@ -10232,12 +10158,14 @@ "react": { "version": "19.2.4", "resolved": "https://registry.npmmirror.com/react/-/react-19.2.4.tgz", - "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==" + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "peer": true }, "react-dom": { "version": "19.2.4", "resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "peer": true, "requires": { "scheduler": "^0.27.0" } @@ -10580,7 +10508,8 @@ "version": "4.0.3", "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true + "dev": true, + "peer": true } } }, @@ -10613,7 +10542,8 @@ "version": "5.9.3", "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "devOptional": true + "devOptional": true, + "peer": true }, "ufo": { "version": "1.6.3", @@ -10797,6 +10727,7 @@ "version": "8.19.0", "resolved": "https://registry.npmmirror.com/ws/-/ws-8.19.0.tgz", "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "peer": true, "requires": {} }, "y18n": { @@ -10831,12 +10762,6 @@ "decamelize": "^1.2.0" } }, - "zod": { - "version": "3.25.76", - "resolved": "https://registry.npmmirror.com/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "optional": true - }, "zustand": { "version": "5.0.3", "resolved": "https://registry.npmmirror.com/zustand/-/zustand-5.0.3.tgz", diff --git a/frontend/package.json b/frontend/package.json index 16ad593d..a92b2e40 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -33,6 +33,7 @@ "@types/three": "^0.183.1", "@types/trusted-types": "^2.0.7", "autoprefixer": "^10.4.20", + "playwright": "^1.59.1", "postcss": "^8.5.3", "tailwindcss": "^3.4.17", "typescript": "^5.8.3" diff --git a/playwright-home-check.png b/playwright-home-check.png new file mode 100644 index 00000000..e22cfa55 Binary files /dev/null and b/playwright-home-check.png differ