{ "version": 1, "description": "Pingora shadow gateway routes that must stay aligned with the current Genarrative Nginx production/development templates before any public cutover.", "routes": [ { "id": "acme_challenge", "samplePath": "/.well-known/acme-challenge/token", "expect": { "kind": "static", "root": "acme", "mode": "exact" }, "nginx": { "production": [ "location /.well-known/acme-challenge/", "root /var/www/html;" ] }, "docs": ["`/.well-known/acme-challenge/*`"] }, { "id": "shadow_probe", "samplePath": "/__genarrative_pingora/healthz", "expect": { "kind": "shadow_probe" }, "docs": ["`/__genarrative_pingora/healthz`"] }, { "id": "admin_redirect", "samplePath": "/admin", "expect": { "kind": "redirect_permanent", "location": "/admin/" }, "nginx": { "production": ["location = /admin", "return 301 /admin/;"], "development": ["location = /admin", "return 301 /admin/;"] }, "docs": ["`/admin`", "301 到 `/admin/`"] }, { "id": "admin_api_proxy", "samplePath": "/admin/api/users", "expect": { "kind": "proxy", "target": "api", "bodyLimit": null, "protectionClass": "admin_api" }, "nginx": { "production": [ "location ^~ /admin/api/", "proxy_pass http://genarrative_api/admin/api/;", "limit_conn genarrative_api_conn 64;", "limit_req zone=genarrative_admin_rps burst=16 nodelay;" ], "development": [ "location ^~ /admin/api/", "proxy_pass http://genarrative_api/admin/api/;", "limit_conn genarrative_api_conn 64;", "limit_req zone=genarrative_admin_rps burst=16 nodelay;" ] }, "docs": ["`/admin/api/*`"] }, { "id": "admin_assets", "samplePath": "/admin/assets/index.js", "expect": { "kind": "static", "root": "web", "mode": "exact" }, "nginx": { "production": ["location ^~ /admin/assets/", "try_files $uri =404;"], "development": ["location ^~ /admin/assets/", "try_files $uri =404;"] }, "docs": ["`/admin/assets/*`"] }, { "id": "admin_spa_fallback", "samplePath": "/admin/settings", "expect": { "kind": "static", "root": "web", "mode": "spa_fallback" }, "nginx": { "production": [ "location ^~ /admin/", "try_files $uri $uri/ /admin/index.html;" ], "development": [ "location ^~ /admin/", "try_files $uri $uri/ /admin/index.html;" ] }, "docs": ["`/admin/*`"] }, { "id": "web_assets", "samplePath": "/assets/app.js", "expect": { "kind": "static", "root": "web", "mode": "exact" }, "nginx": { "production": ["location ^~ /assets/", "try_files $uri =404;"], "development": ["location ^~ /assets/", "try_files $uri =404;"] }, "docs": ["`/assets/*`"] }, { "id": "generic_api_proxy", "samplePath": "/api/assets/history", "expect": { "kind": "proxy", "target": "api", "bodyLimit": "default", "protectionClass": "api" }, "nginx": { "production": [ "location ~ ^/api(?:/|$)", "client_max_body_size 64m;", "limit_conn genarrative_api_conn 64;", "limit_req zone=genarrative_api_rps burst=64 nodelay;", "add_header X-Accel-Buffering no always;" ], "development": [ "location ~ ^/api(?:/|$)", "client_max_body_size 64m;", "limit_conn genarrative_api_conn 64;", "limit_req zone=genarrative_api_rps burst=64 nodelay;", "add_header X-Accel-Buffering no always;" ] }, "docs": ["`/api`、`/api/*`"] }, { "id": "spacetime_subscribe", "samplePath": "/v1/database/genarrative/subscribe", "expect": { "kind": "proxy", "target": "spacetime", "bodyLimit": null, "protectionClass": "spacetime" }, "nginx": { "production": [ "location ~ ^/v1/database/[^/]+/subscribe$", "proxy_pass http://127.0.0.1:3101;", "proxy_set_header Upgrade $http_upgrade;", "proxy_set_header Connection \"Upgrade\";", "proxy_read_timeout 3600s;" ], "development": [ "location ~ ^/v1/database/[^/]+/subscribe$", "proxy_pass http://127.0.0.1:3101;", "proxy_set_header Upgrade $http_upgrade;", "proxy_set_header Connection \"Upgrade\";", "proxy_read_timeout 3600s;" ] }, "docs": ["`/v1/database/{db}/subscribe`"] }, { "id": "spacetime_identity", "samplePath": "/v1/identity", "expect": { "kind": "proxy", "target": "spacetime", "bodyLimit": null, "protectionClass": "spacetime" }, "nginx": { "production": [ "location ^~ /v1/identity", "proxy_pass http://127.0.0.1:3101;", "proxy_set_header Upgrade $http_upgrade;", "proxy_set_header Connection \"Upgrade\";" ], "development": [ "location ^~ /v1/identity", "proxy_pass http://127.0.0.1:3101;", "proxy_set_header Upgrade $http_upgrade;", "proxy_set_header Connection \"Upgrade\";" ] }, "docs": ["`/v1/identity*`"] }, { "id": "v1_forbidden", "samplePath": "/v1/ping", "expect": { "kind": "not_found" }, "nginx": { "production": ["location ^~ /v1/", "return 404;"], "development": ["location ^~ /v1/", "return 404;"] }, "docs": ["`/v1/*`"] }, { "id": "healthz_forbidden", "samplePath": "/healthz", "expect": { "kind": "not_found" }, "nginx": { "production": [ "location ~ ^/(generated-|healthz|readyz)", "return 404;" ], "development": [ "location ~ ^/(generated-|healthz|readyz)", "return 404;" ] }, "docs": ["`/healthz*`"] }, { "id": "readyz_forbidden", "samplePath": "/readyz", "expect": { "kind": "not_found" }, "nginx": { "production": [ "location ~ ^/(generated-|healthz|readyz)", "return 404;" ], "development": [ "location ~ ^/(generated-|healthz|readyz)", "return 404;" ] }, "docs": ["`/readyz*`"] }, { "id": "generated_assets_forbidden", "samplePath": "/generated-puzzle-assets/foo.webp", "expect": { "kind": "not_found" }, "nginx": { "production": [ "location ~ ^/(generated-|healthz|readyz)", "return 404;" ], "development": [ "location ~ ^/(generated-|healthz|readyz)", "return 404;" ] }, "docs": ["`/generated-*`"] }, { "id": "web_spa_fallback", "samplePath": "/project", "expect": { "kind": "static", "root": "web", "mode": "spa_fallback" }, "nginx": { "production": [ "# BEGIN GENARRATIVE MAIN SPA ROUTES", "try_files $uri /index.html =404;" ], "development": [ "# BEGIN GENARRATIVE MAIN SPA ROUTES", "try_files $uri /index.html =404;" ] }, "docs": ["主站 SPA allowlist", "失败回退 `/index.html`"] }, { "id": "profile_spa_fallback", "samplePath": "/profile", "expect": { "kind": "static", "root": "web", "mode": "spa_fallback" }, "nginx": { "production": [ "# BEGIN GENARRATIVE MAIN SPA ROUTES", "try_files $uri /index.html =404;" ], "development": [ "# BEGIN GENARRATIVE MAIN SPA ROUTES", "try_files $uri /index.html =404;" ] }, "docs": ["主站 SPA allowlist", "失败回退 `/index.html`"] }, { "id": "web_spa_case_trailing_slash", "samplePath": "/PROJECT/", "expect": { "kind": "static", "root": "web", "mode": "spa_fallback" }, "nginx": { "production": ["location ~*", "try_files $uri /index.html =404;"], "development": ["location ~*", "try_files $uri /index.html =404;"] }, "docs": ["大小写不敏感", "一个尾部斜杠"] }, { "id": "web_unknown_path_exact", "samplePath": "/some/spa/path", "expect": { "kind": "static", "root": "web", "mode": "exact" }, "nginx": { "production": ["location /", "try_files $uri $uri/ =404;"], "development": ["location /", "try_files $uri $uri/ =404;"] }, "docs": ["其它 Web 路径", "缺失时返回真实 404"] }, { "id": "creation_unknown_path_exact", "samplePath": "/creation/not-exist", "expect": { "kind": "static", "root": "web", "mode": "exact" }, "nginx": { "production": ["try_files $uri $uri/ =404;"], "development": ["try_files $uri $uri/ =404;"] }, "docs": ["`/creation/not-exist`"] }, { "id": "runtime_unknown_path_exact", "samplePath": "/runtime/not-exist", "expect": { "kind": "static", "root": "web", "mode": "exact" }, "nginx": { "production": ["try_files $uri $uri/ =404;"], "development": ["try_files $uri $uri/ =404;"] }, "docs": ["`/runtime/not-exist`"] }, { "id": "puzzle_unknown_path_exact", "samplePath": "/puzzle/not-exist", "expect": { "kind": "static", "root": "web", "mode": "exact" }, "nginx": { "production": ["try_files $uri $uri/ =404;"], "development": ["try_files $uri $uri/ =404;"] }, "docs": ["`/puzzle/not-exist`"] } ] }