Make the offline RAG chain observable without widening credential access
Some checks failed
verify / verify (push) Has been cancelled

Expose the verified synthetic retrieval path through a typed React client and a non-root Nginx edge while keeping database credentials and data-network reachability out of the browser tier. A fixed-origin gateway preserves request boundaries and now closes upstream streams even when downstream disconnects before body iteration. The deployment ADR and runbooks record the four-network topology and its accepted Web edge-egress risk.

Constraint: The previously exposed Bailian key must be revoked and no live provider credential may enter Git, images, logs, or the browser.
Rejected: Connect Web directly to the data network | expands lateral reach to PostgreSQL.
Rejected: Publish the database-aware API on the edge network | gives a credential-bearing process a public default route.
Rejected: Buffer streaming responses in either proxy | prevents incremental chat delivery in the future.
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Do not mark Stage 1 or Stage 2 complete until the rotated-key live smoke and remaining stage gates pass.
Tested: make verify; 65 backend tests; 14 frontend tests; Docker image build; container health and isolation probes; real HTTP demo/status/search/docs/OpenAPI checks.
Not-tested: Live Bailian models, real document ingestion, business chat SSE generation, and final browser screenshot automation because the browser skill runtime was unavailable.
This commit is contained in:
2026-07-12 17:38:57 +08:00
parent 2fa27ae71c
commit c3bad0f186
60 changed files with 9062 additions and 82 deletions

52
frontend/package.json Normal file
View File

@@ -0,0 +1,52 @@
{
"name": "geological-rag-frontend",
"private": true,
"version": "0.1.0",
"type": "module",
"engines": {
"node": ">=22.12.0",
"npm": ">=10.9.0"
},
"scripts": {
"dev": "vite --host 127.0.0.1",
"build": "tsc -b && vite build",
"preview": "vite preview --host 127.0.0.1",
"generate:api": "node scripts/generate-openapi.mjs",
"format": "prettier --write .",
"format:check": "prettier --check .",
"lint": "eslint . --max-warnings 0",
"typecheck": "tsc -b --pretty false",
"test": "vitest run",
"test:watch": "vitest",
"verify": "npm run format:check && npm run lint && npm run typecheck && npm run test && npm run build"
},
"dependencies": {
"@tanstack/react-query": "5.101.2",
"react": "19.2.7",
"react-dom": "19.2.7",
"react-router-dom": "7.18.1"
},
"devDependencies": {
"@eslint/js": "10.0.1",
"@testing-library/jest-dom": "6.9.1",
"@testing-library/react": "16.3.2",
"@testing-library/user-event": "14.6.1",
"@types/node": "26.1.1",
"@types/react": "19.2.17",
"@types/react-dom": "19.2.3",
"@vitejs/plugin-react": "6.0.3",
"@vitest/coverage-v8": "4.1.10",
"eslint": "10.7.0",
"eslint-config-prettier": "10.1.8",
"eslint-plugin-react-hooks": "7.1.1",
"eslint-plugin-react-refresh": "0.5.3",
"globals": "17.7.0",
"jsdom": "29.1.1",
"openapi-typescript": "7.13.0",
"prettier": "3.9.5",
"typescript": "5.9.3",
"typescript-eslint": "8.63.0",
"vite": "8.1.4",
"vitest": "4.1.10"
}
}