From a1f04c7d7a93e068edc64d0a5746f52bbb181d7f Mon Sep 17 00:00:00 2001 From: yuqei Date: Mon, 22 Jun 2026 19:51:30 +0800 Subject: [PATCH] chore: align V2 into final four-project layout --- .gitignore | 13 +- README.md | 36 +- V2-README.md | 33 +- docs/adr/0001-v2-technology-stack.md | 35 +- docs/architecture/local-development.md | 12 +- infra/docker/contract-api.Dockerfile | 17 - infra/docker/worker.Dockerfile | 14 - package-lock.json | 578 +----------------- package.json | 7 +- ...ˆ同平台V2与共享AI重构任务编排-2026-06-22.md | 77 ++- .../AI合同平台V2重构版开发方案-2026-06-22.md | 80 +-- .../V2-shared路线防跑偏核查-2026-06-22.md | 30 +- ...«¯基础工程与轻量化体验底座记录-2026-06-22.md | 6 +- ...Ž端基础工程与本地开发底座记录-2026-06-22.md | 16 +- ...V2旧shared资产盘点与迁移清单-2026-06-22.md | 36 +- ...律问答AI平台与SDK最小闭环记录-2026-06-22.md | 14 +- pyproject.toml | 16 +- sdks/typescript/.gitkeep | 1 - .../packages}/ai-openapi/README.md | 0 .../packages}/ai-openapi/openapi.yaml | 0 .../services}/ai-platform-api/.env.example | 0 .../services}/ai-platform-api/README.md | 6 +- .../services}/ai-platform-api/pyproject.toml | 0 .../src/yuqei_ai_platform_api/__init__.py | 0 .../src/yuqei_ai_platform_api/config.py | 0 .../src/yuqei_ai_platform_api/legal_qa.py | 0 .../src/yuqei_ai_platform_api/logging.py | 0 .../src/yuqei_ai_platform_api/main.py | 0 .../src/yuqei_ai_platform_api/models.py | 0 .../src/yuqei_ai_platform_api/repository.py | 0 .../src/yuqei_ai_platform_api/state.py | 0 .../ai-platform-api/tests/__init__.py | 0 .../ai-platform-api/tests/test_health.py | 0 .../ai-platform-api/tests/test_legal_qa.py | 0 .../tests/test_platform_data.py | 0 .../services}/worker/.env.example | 0 .../services}/worker/README.md | 6 +- .../services}/worker/pyproject.toml | 0 .../worker/src/yuqei_worker}/__init__.py | 0 .../worker/src/yuqei_worker/config.py | 0 .../worker/src/yuqei_worker/logging.py | 0 .../services}/worker/src/yuqei_worker/main.py | 0 .../services}/worker/tests/__init__.py | 0 .../services}/worker/tests/test_health.py | 0 .../python => yuqei-ai-sdk-python}/README.md | 0 .../pyproject.toml | 0 .../src/yuqei_sdk/__init__.py | 0 .../src/yuqei_sdk/ai_platform.py | 0 .../src/yuqei_sdk/context.py | 0 .../tests/__init__.py | 0 .../tests/test_ai_platform.py | 0 .../apps}/contract-web/.env.example | 0 .../apps}/contract-web/README.md | 0 .../apps}/contract-web/next.config.ts | 0 .../apps}/contract-web/package.json | 0 .../apps}/contract-web/src/app/admin/page.tsx | 0 .../src/app/contracts/[id]/page.tsx | 0 .../contract-web/src/app/contracts/page.tsx | 0 .../apps}/contract-web/src/app/files/page.tsx | 0 .../apps}/contract-web/src/app/globals.css | 0 .../contract-web/src/app/health/page.tsx | 0 .../apps}/contract-web/src/app/layout.tsx | 0 .../apps}/contract-web/src/app/page.tsx | 0 .../contract-web/src/app/search/page.tsx | 0 .../contract-web/src/app/workspace/page.tsx | 0 .../contract-web/src/components/app-shell.tsx | 0 .../features/system/system-health-panel.tsx | 0 .../src/features/workspace/workspace-page.tsx | 0 .../apps}/contract-web/src/lib/mock-data.ts | 0 .../apps}/contract-web/tsconfig.json | 2 +- .../packages}/contract-openapi/README.md | 0 .../packages}/contract-openapi/openapi.yaml | 0 .../packages}/design-system/README.md | 0 .../packages}/design-system/package.json | 0 .../packages}/design-system/src/index.ts | 0 .../packages}/design-system/src/tokens.ts | 0 .../packages}/design-system/src/workflow.ts | 0 .../services}/contract-api/.env.example | 0 .../services}/contract-api/README.md | 6 +- .../services}/contract-api/pyproject.toml | 0 .../src/yuqei_contract_api}/__init__.py | 0 .../src/yuqei_contract_api/config.py | 0 .../src/yuqei_contract_api/logging.py | 0 .../src/yuqei_contract_api/main.py | 0 .../services}/contract-api/tests/__init__.py | 0 .../contract-api/tests/test_health.py | 0 .../contract-api/tests/test_legal_qa_proxy.py | 0 {infra => yuqei-infra}/backup/.gitkeep | 0 {infra => yuqei-infra}/compose/.env.example | 0 .../compose/docker-compose.yml | 6 +- {infra => yuqei-infra}/deploy/.gitkeep | 0 .../docker/ai-platform-api.Dockerfile | 6 +- yuqei-infra/docker/contract-api.Dockerfile | 17 + yuqei-infra/docker/worker.Dockerfile | 14 + {infra => yuqei-infra}/nginx/.gitkeep | 0 {infra => yuqei-infra}/observability/.gitkeep | 0 96 files changed, 283 insertions(+), 801 deletions(-) delete mode 100644 infra/docker/contract-api.Dockerfile delete mode 100644 infra/docker/worker.Dockerfile delete mode 100644 sdks/typescript/.gitkeep rename {packages => yuqei-ai-platform/packages}/ai-openapi/README.md (100%) rename {packages => yuqei-ai-platform/packages}/ai-openapi/openapi.yaml (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/.env.example (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/README.md (67%) rename {services => yuqei-ai-platform/services}/ai-platform-api/pyproject.toml (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/src/yuqei_ai_platform_api/__init__.py (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/src/yuqei_ai_platform_api/config.py (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/src/yuqei_ai_platform_api/legal_qa.py (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/src/yuqei_ai_platform_api/logging.py (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/src/yuqei_ai_platform_api/main.py (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/src/yuqei_ai_platform_api/models.py (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/src/yuqei_ai_platform_api/repository.py (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/src/yuqei_ai_platform_api/state.py (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/tests/__init__.py (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/tests/test_health.py (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/tests/test_legal_qa.py (100%) rename {services => yuqei-ai-platform/services}/ai-platform-api/tests/test_platform_data.py (100%) rename {services => yuqei-ai-platform/services}/worker/.env.example (100%) rename {services => yuqei-ai-platform/services}/worker/README.md (75%) rename {services => yuqei-ai-platform/services}/worker/pyproject.toml (100%) rename {services/contract-api/src/yuqei_contract_api => yuqei-ai-platform/services/worker/src/yuqei_worker}/__init__.py (100%) rename {services => yuqei-ai-platform/services}/worker/src/yuqei_worker/config.py (100%) rename {services => yuqei-ai-platform/services}/worker/src/yuqei_worker/logging.py (100%) rename {services => yuqei-ai-platform/services}/worker/src/yuqei_worker/main.py (100%) rename {services => yuqei-ai-platform/services}/worker/tests/__init__.py (100%) rename {services => yuqei-ai-platform/services}/worker/tests/test_health.py (100%) rename {sdks/python => yuqei-ai-sdk-python}/README.md (100%) rename {sdks/python => yuqei-ai-sdk-python}/pyproject.toml (100%) rename {sdks/python => yuqei-ai-sdk-python}/src/yuqei_sdk/__init__.py (100%) rename {sdks/python => yuqei-ai-sdk-python}/src/yuqei_sdk/ai_platform.py (100%) rename {sdks/python => yuqei-ai-sdk-python}/src/yuqei_sdk/context.py (100%) rename {sdks/python => yuqei-ai-sdk-python}/tests/__init__.py (100%) rename {sdks/python => yuqei-ai-sdk-python}/tests/test_ai_platform.py (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/.env.example (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/README.md (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/next.config.ts (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/package.json (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/app/admin/page.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/app/contracts/[id]/page.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/app/contracts/page.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/app/files/page.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/app/globals.css (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/app/health/page.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/app/layout.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/app/page.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/app/search/page.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/app/workspace/page.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/components/app-shell.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/features/system/system-health-panel.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/features/workspace/workspace-page.tsx (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/src/lib/mock-data.ts (100%) rename {apps => yuqei-contract-platform/apps}/contract-web/tsconfig.json (87%) rename {packages => yuqei-contract-platform/packages}/contract-openapi/README.md (100%) rename {packages => yuqei-contract-platform/packages}/contract-openapi/openapi.yaml (100%) rename {packages => yuqei-contract-platform/packages}/design-system/README.md (100%) rename {packages => yuqei-contract-platform/packages}/design-system/package.json (100%) rename {packages => yuqei-contract-platform/packages}/design-system/src/index.ts (100%) rename {packages => yuqei-contract-platform/packages}/design-system/src/tokens.ts (100%) rename {packages => yuqei-contract-platform/packages}/design-system/src/workflow.ts (100%) rename {services => yuqei-contract-platform/services}/contract-api/.env.example (100%) rename {services => yuqei-contract-platform/services}/contract-api/README.md (66%) rename {services => yuqei-contract-platform/services}/contract-api/pyproject.toml (100%) rename {services/worker/src/yuqei_worker => yuqei-contract-platform/services/contract-api/src/yuqei_contract_api}/__init__.py (100%) rename {services => yuqei-contract-platform/services}/contract-api/src/yuqei_contract_api/config.py (100%) rename {services => yuqei-contract-platform/services}/contract-api/src/yuqei_contract_api/logging.py (100%) rename {services => yuqei-contract-platform/services}/contract-api/src/yuqei_contract_api/main.py (100%) rename {services => yuqei-contract-platform/services}/contract-api/tests/__init__.py (100%) rename {services => yuqei-contract-platform/services}/contract-api/tests/test_health.py (100%) rename {services => yuqei-contract-platform/services}/contract-api/tests/test_legal_qa_proxy.py (100%) rename {infra => yuqei-infra}/backup/.gitkeep (100%) rename {infra => yuqei-infra}/compose/.env.example (100%) rename {infra => yuqei-infra}/compose/docker-compose.yml (93%) rename {infra => yuqei-infra}/deploy/.gitkeep (100%) rename {infra => yuqei-infra}/docker/ai-platform-api.Dockerfile (53%) create mode 100644 yuqei-infra/docker/contract-api.Dockerfile create mode 100644 yuqei-infra/docker/worker.Dockerfile rename {infra => yuqei-infra}/nginx/.gitkeep (100%) rename {infra => yuqei-infra}/observability/.gitkeep (100%) diff --git a/.gitignore b/.gitignore index aeb005d4..9ecc0904 100644 --- a/.gitignore +++ b/.gitignore @@ -3,10 +3,11 @@ node_modules/ frontend/.next/ frontend/.next-dev-log/ frontend/node_modules/ -services/*/.venv/ -services/*/.pytest_cache/ -apps/*/.next/ -apps/*/node_modules/ +**/.next/ +**/.next-dev-log/ +**/node_modules/ +**/.venv/ +**/.pytest_cache/ .pytest_cache/ *.pyc __pycache__/ @@ -32,8 +33,8 @@ backend/project-docs/qa-artifacts/ output/ frontend/next-env.d.ts frontend/tsconfig.tsbuildinfo -apps/*/next-env.d.ts -apps/*/tsconfig.tsbuildinfo +**/next-env.d.ts +**/tsconfig.tsbuildinfo # Temporary directories temp-*/ diff --git a/README.md b/README.md index b5633988..2f443565 100644 --- a/README.md +++ b/README.md @@ -2,36 +2,38 @@ This repository `main` branch is now the clean V2 rebuild line. -The previous complete V1 implementation is preserved on the `V1` branch. New product, architecture, database, AI platform, frontend, backend, deployment, and QA work should be developed on `main` using the V2 workspace layout. +The previous complete V1 implementation is preserved on the `V1` branch. New product, architecture, database, AI platform, frontend, backend, deployment, and QA work should be developed on `main` using the final V2 four-project layout from day one. -## Workspace Layout +## Project Layout ```text -apps/ - contract-web/ -services/ - contract-api/ - ai-platform-api/ - worker/ -packages/ - design-system/ - contract-openapi/ - ai-openapi/ -sdks/ - python/ - typescript/ -infra/ +yuqei-contract-platform/ + apps/contract-web/ + services/contract-api/ + packages/design-system/ + packages/contract-openapi/ + +yuqei-ai-platform/ + services/ai-platform-api/ + services/worker/ + packages/ai-openapi/ + +yuqei-ai-sdk-python/ + +yuqei-infra/ docker/ compose/ nginx/ observability/ backup/ deploy/ + docs/ adr/ product/ architecture/ qa/ + project-docs/ ``` @@ -42,6 +44,8 @@ project-docs/ Do not continue adding new product features to the V1 application tree on `main`. If V1 code is needed for reference, check the `V1` branch. +Do not reintroduce the old root `apps/`、`services/`、`packages/`、`sdks/`、`infra/` layout. V2 is organized around final product boundaries: contract platform, AI platform, Python SDK, and infrastructure. + ## Starting Points - `V2-README.md` diff --git a/V2-README.md b/V2-README.md index cc42671c..c19f6425 100644 --- a/V2-README.md +++ b/V2-README.md @@ -2,31 +2,32 @@ This branch is the clean V2 rebuild line. -The previous V1 implementation is preserved on the `V1` branch. New V2 development should start from the workspace layout below instead of continuing to modify the V1 application tree. +The previous V1 implementation is preserved on the `V1` branch. New V2 development starts from the final four-project layout below instead of continuing to modify the V1 application tree. -## Target Workspace +## Target Projects ```text -apps/ - contract-web/ -services/ - contract-api/ - ai-platform-api/ - worker/ -packages/ - design-system/ - contract-openapi/ - ai-openapi/ -sdks/ - python/ - typescript/ -infra/ +yuqei-contract-platform/ + apps/contract-web/ + services/contract-api/ + packages/design-system/ + packages/contract-openapi/ + +yuqei-ai-platform/ + services/ai-platform-api/ + services/worker/ + packages/ai-openapi/ + +yuqei-ai-sdk-python/ + +yuqei-infra/ docker/ compose/ nginx/ observability/ backup/ deploy/ + docs/ adr/ product/ diff --git a/docs/adr/0001-v2-technology-stack.md b/docs/adr/0001-v2-technology-stack.md index 1464c357..34a97d9c 100644 --- a/docs/adr/0001-v2-technology-stack.md +++ b/docs/adr/0001-v2-technology-stack.md @@ -1,4 +1,4 @@ -# ADR 0001: V2 Technology Stack +# ADR 0001: V2 Technology Stack Date: 2026-06-22 @@ -21,14 +21,21 @@ The product needs: ## Decision -V2 will use a Python/TypeScript monorepo in `D:\yuqei-project\ai-contract-platform`. +V2 will use four first-class engineering roots in `D:\yuqei-project\ai-contract-platform` from day one: + +- `yuqei-contract-platform` +- `yuqei-ai-platform` +- `yuqei-ai-sdk-python` +- `yuqei-infra` + +The repository is one Git development line, but the architecture is not a temporary mixed workspace. Each root is treated as a final project boundary now. ### Frontend -- `apps/contract-web` +- `yuqei-contract-platform/apps/contract-web` - Next.js + React + TypeScript - Ant Design or a small internal design system wrapper during early MVP -- `packages/design-system` for tokens, layout primitives, workflow components, and UI conventions +- `yuqei-contract-platform/packages/design-system` for tokens, layout primitives, workflow components, and UI conventions Reason: @@ -38,7 +45,7 @@ Reason: ### Backend -- `services/contract-api` +- `yuqei-contract-platform/services/contract-api` - Python 3.12+ - FastAPI - SQLAlchemy 2.x @@ -53,7 +60,7 @@ Reason: ### AI Platform -- `services/ai-platform-api` +- `yuqei-ai-platform/services/ai-platform-api` - Python 3.12+ - FastAPI - Provider adapters behind an internal interface @@ -68,7 +75,7 @@ Reason: ### Worker -- `services/worker` +- `yuqei-ai-platform/services/worker` - Python 3.12+ - Redis queue initially - Later can evolve to Celery/RQ/Arq depending on load @@ -140,15 +147,15 @@ Reason: ### API Contracts -- `packages/contract-openapi/openapi.yaml` -- `packages/ai-openapi/openapi.yaml` +- `yuqei-contract-platform/packages/contract-openapi/openapi.yaml` +- `yuqei-ai-platform/packages/ai-openapi/openapi.yaml` - OpenAPI is the source of truth for cross-service and frontend-facing contracts. - SDKs must align with these contracts. ### SDKs -- `sdks/python` -- `sdks/typescript` +- `yuqei-ai-sdk-python` +- `yuqei-ai-sdk-typescript` only if a TypeScript SDK becomes necessary Rules: @@ -178,12 +185,12 @@ Rules: Positive: - One V2 development line. -- Fewer cross-repo version mismatches. -- Contract system and AI platform still have a clear service boundary. +- Final engineering boundaries are visible in the root directory from the beginning. +- Contract system and AI platform have a clear service boundary. - SDK generation and testing become enforceable. Tradeoffs: - Old Java shared work will be used only as reference, not as production code. - Some features already prototyped in old shared repositories must be reimplemented. -- The monorepo needs disciplined module boundaries to avoid becoming another mixed codebase. +- Root-level project boundaries must be enforced in code review to avoid recreating a mixed shared codebase. diff --git a/docs/architecture/local-development.md b/docs/architecture/local-development.md index cca82e3c..2a42dc92 100644 --- a/docs/architecture/local-development.md +++ b/docs/architecture/local-development.md @@ -1,4 +1,4 @@ -# V2 Local Development +# V2 Local Development ## Run Tests @@ -11,29 +11,29 @@ python -m pytest Contract API: ```powershell -$env:PYTHONPATH='services/contract-api/src' +$env:PYTHONPATH='yuqei-contract-platform/services/contract-api/src' python -m uvicorn yuqei_contract_api.main:app --host 0.0.0.0 --port 8100 ``` AI Platform API: ```powershell -$env:PYTHONPATH='services/ai-platform-api/src' +$env:PYTHONPATH='yuqei-ai-platform/services/ai-platform-api/src' python -m uvicorn yuqei_ai_platform_api.main:app --host 0.0.0.0 --port 8101 ``` Worker health: ```powershell -$env:PYTHONPATH='services/worker/src' +$env:PYTHONPATH='yuqei-ai-platform/services/worker/src' python -m yuqei_worker.main --health ``` ## Run Infrastructure With Docker ```powershell -Copy-Item infra/compose/.env.example infra/compose/.env -ErrorAction SilentlyContinue -docker compose --env-file infra/compose/.env -f infra/compose/docker-compose.yml up --build +Copy-Item yuqei-infra/compose/.env.example yuqei-infra/compose/.env -ErrorAction SilentlyContinue +docker compose --env-file yuqei-infra/compose/.env -f yuqei-infra/compose/docker-compose.yml up --build ``` Health checks: diff --git a/infra/docker/contract-api.Dockerfile b/infra/docker/contract-api.Dockerfile deleted file mode 100644 index 879ee936..00000000 --- a/infra/docker/contract-api.Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM python:3.12-slim - -ENV PYTHONDONTWRITEBYTECODE=1 \ - PYTHONUNBUFFERED=1 \ - PYTHONPATH=/app/services/contract-api/src - -WORKDIR /app - -COPY services/contract-api/pyproject.toml /tmp/contract-api-pyproject.toml -COPY sdks/python/pyproject.toml /tmp/yuqei-python-sdk-pyproject.toml -RUN pip install --no-cache-dir fastapi httpx pydantic pydantic-settings sqlalchemy uvicorn - -COPY services/contract-api services/contract-api -COPY sdks/python sdks/python - -EXPOSE 8100 -CMD ["python", "-m", "uvicorn", "yuqei_contract_api.main:app", "--host", "0.0.0.0", "--port", "8100"] diff --git a/infra/docker/worker.Dockerfile b/infra/docker/worker.Dockerfile deleted file mode 100644 index 4503ac32..00000000 --- a/infra/docker/worker.Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM python:3.12-slim - -ENV PYTHONDONTWRITEBYTECODE=1 \ - PYTHONUNBUFFERED=1 \ - PYTHONPATH=/app/services/worker/src - -WORKDIR /app - -COPY services/worker/pyproject.toml /tmp/worker-pyproject.toml -RUN pip install --no-cache-dir pydantic pydantic-settings - -COPY services/worker services/worker - -CMD ["python", "-m", "yuqei_worker.main", "--health"] diff --git a/package-lock.json b/package-lock.json index f70032ba..dd07aa38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,499 +1,30 @@ { - "name": "yuqei-ai-contract-platform-v2", + "name": "yuqei-platform-v2-orchestrator", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "yuqei-ai-contract-platform-v2", + "name": "yuqei-platform-v2-orchestrator", "version": "0.1.0", "workspaces": [ - "apps/*", - "packages/*", - "sdks/*" + "yuqei-contract-platform/apps/*", + "yuqei-contract-platform/packages/*" ], "devDependencies": { "playwright": "^1.61.0" } }, - "apps/contract-web": { - "name": "@yuqei/contract-web", - "version": "0.1.0", - "dependencies": { - "@yuqei/design-system": "0.1.0", - "lucide-react": "1.21.0", - "next": "16.2.9", - "react": "19.2.7", - "react-dom": "19.2.7" - }, - "devDependencies": { - "@types/node": "26.0.0", - "@types/react": "19.2.17", - "@types/react-dom": "19.2.3", - "typescript": "5.9.3" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", - "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@img/colour": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", - "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", "license": "MIT", "optional": true, "engines": { "node": ">=18" } }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", - "cpu": [ - "arm" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", - "cpu": [ - "ppc64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", - "cpu": [ - "riscv64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", - "cpu": [ - "s390x" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", - "cpu": [ - "ppc64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", - "cpu": [ - "riscv64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", - "cpu": [ - "s390x" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.7.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, "node_modules/@img/sharp-win32-x64": { "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", "cpu": [ "x64" ], @@ -511,8 +42,6 @@ }, "node_modules/@next/env": { "version": "16.2.9", - "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.9.tgz", - "integrity": "sha512-ki5VxxXfzD/9TDe13wyeTKIjQTAwBVpnr8KhRDUr8ltMUq1/NBpWNT5tiPoxiGl+PHM4X2ahSOiPk6iAimIzPg==", "license": "MIT" }, "node_modules/@next/swc-darwin-arm64": { @@ -522,7 +51,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -538,7 +66,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -554,7 +81,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -570,7 +96,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -586,7 +111,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -602,7 +126,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -618,7 +141,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "win32" @@ -629,8 +151,6 @@ }, "node_modules/@next/swc-win32-x64-msvc": { "version": "16.2.9", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.9.tgz", - "integrity": "sha512-qr2VL3Ce5QrwgO2yh1ujSBawrimjVKX8FGF/cOynmdYKJY0BdHpGVNIRK1tqONB10Vkm25Ub1BD2bkjWs4+96w==", "cpu": [ "x64" ], @@ -645,8 +165,6 @@ }, "node_modules/@swc/helpers": { "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", - "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" @@ -654,8 +172,6 @@ }, "node_modules/@types/node": { "version": "26.0.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-26.0.0.tgz", - "integrity": "sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA==", "dev": true, "license": "MIT", "dependencies": { @@ -664,8 +180,6 @@ }, "node_modules/@types/react": { "version": "19.2.17", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", - "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", "dev": true, "license": "MIT", "dependencies": { @@ -674,8 +188,6 @@ }, "node_modules/@types/react-dom": { "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -683,17 +195,15 @@ } }, "node_modules/@yuqei/contract-web": { - "resolved": "apps/contract-web", + "resolved": "yuqei-contract-platform/apps/contract-web", "link": true }, "node_modules/@yuqei/design-system": { - "resolved": "packages/design-system", + "resolved": "yuqei-contract-platform/packages/design-system", "link": true }, "node_modules/baseline-browser-mapping": { "version": "2.10.38", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.38.tgz", - "integrity": "sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.cjs" @@ -704,8 +214,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001799", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", - "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", "funding": [ { "type": "opencollective", @@ -724,46 +232,23 @@ }, "node_modules/client-only": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", "license": "MIT" }, "node_modules/csstype": { "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "dev": true, "license": "MIT" }, "node_modules/detect-libc": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "optional": true, "engines": { "node": ">=8" } }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/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/lucide-react": { "version": "1.21.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.21.0.tgz", - "integrity": "sha512-reEZMXq8Qdd5jg5XYkQ5TR1fB/GiQ7ih4vcrthYDtgjSDwh0i6/YLiGjsWsIwgN49gpAnd4J2elSNzncMEEUUQ==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -771,8 +256,6 @@ }, "node_modules/nanoid": { "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", "funding": [ { "type": "github", @@ -789,8 +272,6 @@ }, "node_modules/next": { "version": "16.2.9", - "resolved": "https://registry.npmjs.org/next/-/next-16.2.9.tgz", - "integrity": "sha512-MEOJiq/UvuezAdqVSceHbqDgZt1kDw2tpGVOlsdIoJsQdbN2JY2hpVG4xnXGkbdJUOEWhnRfiu/O4Hpc9Juwww==", "license": "MIT", "dependencies": { "@next/env": "16.2.9", @@ -842,14 +323,10 @@ }, "node_modules/picocolors": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/playwright": { "version": "1.61.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.0.tgz", - "integrity": "sha512-Z+7BeeqQPRRzklHsVFP4KTGIyMxKUmfeRA4WisM6G3/XW6nwGeX6fX9qYaDa+CiUqpOkb2f6X3nar05R3kSuJQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -867,8 +344,6 @@ }, "node_modules/playwright-core": { "version": "1.61.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.0.tgz", - "integrity": "sha512-caX7TrY3Ml6egyDX0WUcTHDxodl/b51y5wJOdCEA36QviK/s2g081hvmGs8eaE3DWb6NYZQ6BjO/QkNRPenoPA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -880,8 +355,6 @@ }, "node_modules/postcss": { "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", "funding": [ { "type": "opencollective", @@ -908,8 +381,6 @@ }, "node_modules/react": { "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", - "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -917,8 +388,6 @@ }, "node_modules/react-dom": { "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", - "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "license": "MIT", "dependencies": { "scheduler": "^0.27.0" @@ -929,14 +398,10 @@ }, "node_modules/scheduler": { "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, "node_modules/semver": { "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "optional": true, "bin": { @@ -948,8 +413,6 @@ }, "node_modules/sharp": { "version": "0.34.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", - "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", "hasInstallScript": true, "license": "Apache-2.0", "optional": true, @@ -993,8 +456,6 @@ }, "node_modules/source-map-js": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -1002,8 +463,6 @@ }, "node_modules/styled-jsx": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", - "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", "license": "MIT", "dependencies": { "client-only": "0.0.1" @@ -1025,14 +484,10 @@ }, "node_modules/tslib": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, "node_modules/typescript": { "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1045,12 +500,27 @@ }, "node_modules/undici-types": { "version": "8.3.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", - "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", "dev": true, "license": "MIT" }, - "packages/design-system": { + "yuqei-contract-platform/apps/contract-web": { + "name": "@yuqei/contract-web", + "version": "0.1.0", + "dependencies": { + "@yuqei/design-system": "0.1.0", + "lucide-react": "1.21.0", + "next": "16.2.9", + "react": "19.2.7", + "react-dom": "19.2.7" + }, + "devDependencies": { + "@types/node": "26.0.0", + "@types/react": "19.2.17", + "@types/react-dom": "19.2.3", + "typescript": "5.9.3" + } + }, + "yuqei-contract-platform/packages/design-system": { "name": "@yuqei/design-system", "version": "0.1.0" } diff --git a/package.json b/package.json index 81665f3b..07cd392b 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,11 @@ { - "name": "yuqei-ai-contract-platform-v2", + "name": "yuqei-platform-v2-orchestrator", "version": "0.1.0", "private": true, "packageManager": "npm@10.9.7", "workspaces": [ - "apps/*", - "packages/*", - "sdks/*" + "yuqei-contract-platform/apps/*", + "yuqei-contract-platform/packages/*" ], "scripts": { "test": "python -m pytest", diff --git a/project-docs/AI合同平台V2与共享AI重构任务编排-2026-06-22.md b/project-docs/AI合同平台V2与共享AI重构任务编排-2026-06-22.md index 5a209c11..94ba0b9a 100644 --- a/project-docs/AI合同平台V2与共享AI重构任务编排-2026-06-22.md +++ b/project-docs/AI合同平台V2与共享AI重构任务编排-2026-06-22.md @@ -1,4 +1,4 @@ -# AI合同平台V2与共享AI重构任务编排 +# AI合同平台V2与共享AI重构任务编排 日期:2026-06-22 @@ -8,7 +8,7 @@ 正确做法是: -> 以 `D:\yuqei-project\ai-contract-platform` 的 `main` 分支作为唯一 V2 主线,把 shared 重构吸收到 V2 workspace 中,形成“合同产品平台 + 统一 AI 中台 + OpenAPI 契约 + 正式 SDK + 统一基础设施”的一体化工程。 +> 以 `D:\yuqei-project\ai-contract-platform` 的 `main` 分支作为唯一 V2 主线,从第一天就落成 `yuqei-contract-platform`、`yuqei-ai-platform`、`yuqei-ai-sdk-python`、`yuqei-infra` 四个最终工程,形成“合同产品平台 + 统一 AI 中台 + OpenAPI 契约 + 正式 SDK + 统一基础设施”的一体化工程。 旧 shared 仓库不再继续扩展新功能,只作为历史参考、行为对照、代码迁移素材和数据导出来源。 @@ -20,30 +20,28 @@ | `D:\yuqei-project\ai-contract-platform-v1` | V1 旧系统参考目录 | 只读参考,不继续开发新功能 | | `D:\yuqei-project\shared-ai-platform` | 旧 Python shared 原型 | 不新增能力,仅参考可复用代码和数据处理经验 | | `D:\yuqei-project\shared-ai-platform-java` | 旧 Java shared 主线 | 不新增能力,仅参考模块边界和接口设计 | -| `D:\yuqei-project\shared-ai-python-sdk` | 旧 Python SDK 参考 | 参考客户端结构,V2 SDK 在 `sdks/python` 重做 | +| `D:\yuqei-project\shared-ai-python-sdk` | 旧 Python SDK 参考 | 参考客户端结构,V2 SDK 在 `yuqei-ai-sdk-python` 重做 | | `D:\yuqei-project\shared-java-libs` | Java 公共库参考 | V2 当前不采用 Java 主线时不继续扩展 | ## 3. V2 新目录承载关系 +V2 不再采用旧式 `shared-*` 多仓混合,也不采用临时混放路线。当前 `main` 从第一天就按四个最终工程组织: + ```text -apps/ - contract-web/ # 合同平台前端 +yuqei-contract-platform/ + apps/contract-web/ # 合同平台前端 + services/contract-api/ # 合同业务后端 + packages/design-system/ # 设计系统、组件规范、tokens + packages/contract-openapi/ # 合同业务 API 契约 -services/ - contract-api/ # 合同业务后端 - ai-platform-api/ # 新共享 AI 中台服务 - worker/ # 异步任务、文档解析、索引、导出 +yuqei-ai-platform/ + services/ai-platform-api/ # 新共享 AI 中台服务 + services/worker/ # 异步任务、文档解析、索引、导出 + packages/ai-openapi/ # AI 中台 API 契约 -packages/ - design-system/ # 设计系统、组件规范、tokens - contract-openapi/ # 合同业务 API 契约 - ai-openapi/ # AI 中台 API 契约 +yuqei-ai-sdk-python/ # 新正式 Python SDK -sdks/ - python/ # 新正式 Python SDK - typescript/ # 前端或 Node 服务 SDK - -infra/ +yuqei-infra/ docker/ compose/ nginx/ @@ -54,12 +52,11 @@ infra/ shared 的新形态不是一个旧式 `shared-*` 大杂烩仓库,而是: -- `services/ai-platform-api`:共享 AI 中台服务。 -- `packages/ai-openapi`:AI 中台契约真相源。 -- `sdks/python`、`sdks/typescript`:跨服务调用边界。 -- `services/worker`:AI、知识库、文档解析、导出等异步任务执行。 -- `packages/design-system`:前端体验统一,但不急于抽复杂组件库。 - +- `yuqei-ai-platform/services/ai-platform-api`:共享 AI 中台服务。 +- `yuqei-ai-platform/packages/ai-openapi`:AI 中台契约真相源。 +- `yuqei-ai-sdk-python`:跨服务调用边界。 +- `yuqei-ai-platform/services/worker`:AI、知识库、文档解析、导出等异步任务执行。 +- `yuqei-contract-platform/packages/design-system`:前端体验统一,但不急于抽复杂组件库。 ## 4. 关键原则 1. 合同业务流程不进 shared。 @@ -140,11 +137,11 @@ S6 安全、性能、部署和数据迁移 - 缓存/队列:Redis。 - 对象存储:MinIO/S3。 - 搜索:PostgreSQL FTS 起步,后续可扩展 OpenSearch/Meilisearch。 -- 初始化 monorepo 工具链。 +- 初始化四个最终工程的根目录、构建脚本和边界校验。 - 初始化 `contract-api`。 - 初始化 `ai-platform-api`。 - 初始化 `contract-web`。 -- 初始化 `packages/contract-openapi` 和 `packages/ai-openapi`。 +- 初始化 `yuqei-contract-platform/packages/contract-openapi` 和 `yuqei-ai-platform/packages/ai-openapi`。 - 初始化基础 Docker Compose。 - 建立统一配置、日志、健康检查、错误码规范。 @@ -195,15 +192,15 @@ GET /api/v1/audit/ai-runs 任务: -- 在 `packages/ai-openapi` 固化 AI 中台契约。 -- 在 `sdks/python` 实现 Python SDK: +- 在 `yuqei-ai-platform/packages/ai-openapi` 固化 AI 中台契约。 +- 在 `yuqei-ai-sdk-python` 实现 Python SDK: - 同步 client - 异步 client - SSE 事件解析 - 类型定义 - 错误映射 - 超时、重试、trace id -- 在 `sdks/typescript` 实现前端或 Node 侧基础 client。 +- 如确需前端或 Node 侧直接调用 AI 中台,另建 `yuqei-ai-sdk-typescript` 并按同样契约生成。 - 建立 SDK contract tests。 验收: @@ -329,8 +326,8 @@ docs/adr/0001-v2-technology-stack.md 输出目录: ```text -packages/ai-openapi/ -packages/contract-openapi/ +yuqei-ai-platform/packages/ai-openapi/ +yuqei-contract-platform/packages/contract-openapi/ ``` 内容: @@ -344,9 +341,9 @@ packages/contract-openapi/ 输出目录: ```text -services/contract-api/ -services/ai-platform-api/ -services/worker/ +yuqei-contract-platform/services/contract-api/ +yuqei-ai-platform/services/ai-platform-api/ +yuqei-ai-platform/services/worker/ ``` 内容: @@ -362,8 +359,8 @@ services/worker/ 输出目录: ```text -apps/contract-web/ -packages/design-system/ +yuqei-contract-platform/apps/contract-web/ +yuqei-contract-platform/packages/design-system/ ``` 内容: @@ -379,10 +376,10 @@ packages/design-system/ 输出目录: ```text -infra/compose/ -infra/docker/ -infra/nginx/ -infra/observability/ +yuqei-infra/compose/ +yuqei-infra/docker/ +yuqei-infra/nginx/ +yuqei-infra/observability/ ``` 内容: diff --git a/project-docs/AI合同平台V2重构版开发方案-2026-06-22.md b/project-docs/AI合同平台V2重构版开发方案-2026-06-22.md index d762f0b6..8fd4802b 100644 --- a/project-docs/AI合同平台V2重构版开发方案-2026-06-22.md +++ b/project-docs/AI合同平台V2重构版开发方案-2026-06-22.md @@ -69,7 +69,7 @@ V2 启动后建议: 当前定位是 Python 原型 + 文档仓。 -V2 中建议: +V2 中执行: - 保留为历史原型和迁移资料。 - 不作为生产 AI 中台主线。 @@ -91,9 +91,9 @@ V2 中建议: 当前 SDK 有保留价值,但建议重写为 V2 正式 SDK。 -V2 中建议: +V2 中执行: -- 改名为 `yuqei-ai-sdk-python` 或在新 monorepo 中放入 `sdks/python`。 +- 正式工程名为 `yuqei-ai-sdk-python`。 - SDK 由 OpenAPI 契约生成基础客户端,再手写业务友好封装。 - 合同系统只能通过 SDK 或 OpenAPI client 调用 AI 中台。 - 删除 V1 中 vendored SDK 副本。 @@ -110,31 +110,35 @@ V2 中建议: ## 4. 新仓库与模块划分 -### 4.1 推荐方案:V2 workspace monorepo +### 4.1 推荐方案:四个最终工程一次到位 -为了避免多个仓库在重构初期版本漂移,建议 V2 先采用一个 workspace monorepo: +本次重构不采用临时混放路线。V2 从第一天开始就按四个最终工程边界开发。当前 `main` 分支只是一条统一开发线,根目录直接体现最终架构边界: ```text -yuqei-platform-v2/ - apps/ - contract-web/ # 合同平台 Web 前端 - admin-web/ # 可选,若管理区需要独立部署 +ai-contract-platform/ + yuqei-contract-platform/ + apps/ + contract-web/ # 合同平台 Web 前端 + admin-web/ # 可选,若管理区需要独立部署 - services/ - contract-api/ # 合同业务后端 - ai-platform-api/ # 统一 AI 中台 - worker/ # 文档解析、索引、AI 长任务、通知任务 + services/ + contract-api/ # 合同业务后端 - packages/ - design-system/ # V2 自研设计系统 - contract-openapi/ # 合同业务 OpenAPI 契约 - ai-openapi/ # AI 中台 OpenAPI 契约 + packages/ + design-system/ # V2 自研设计系统 + contract-openapi/ # 合同业务 OpenAPI 契约 - sdks/ - python/ # yuqei-ai-sdk-python - typescript/ # 可选,前端或其他 Node 服务调用 + yuqei-ai-platform/ + services/ + ai-platform-api/ # 统一 AI 中台 + worker/ # 文档解析、索引、AI 长任务、通知任务 - infra/ + packages/ + ai-openapi/ # AI 中台 OpenAPI 契约 + + yuqei-ai-sdk-python/ # 合同系统调用 AI 中台的正式 Python SDK + + yuqei-infra/ docker/ compose/ nginx/ @@ -151,20 +155,21 @@ yuqei-platform-v2/ 说明: -- 代码在一个 workspace 中统一开发,部署时仍然是独立服务。 -- 合同系统和 AI 中台边界通过 OpenAPI 和 SDK 固化。 -- 后续团队规模扩大后,可以再按 `contract-platform`、`ai-platform`、`infra` 拆成独立仓库。 +- 四个顶层工程从现在开始就是最终边界,不再留下二次拆分的技术债。 +- 统一 Git 分支只负责降低当前协作成本,不改变工程边界。 +- 合同系统和 AI 中台通过 OpenAPI 和 SDK 固化边界,部署时仍然是独立服务。 +- 如果未来因为组织治理必须变成多个物理 Git 仓库,也只是迁移仓库存放方式,不再改变代码结构和系统边界。 -### 4.2 最终逻辑边界与未来仓库命名 +### 4.2 最终工程边界 -V2 当前采用 monorepo 是为了避免重构初期多仓库版本漂移,但产品和工程边界必须按下面四块执行。未来如果拆成独立仓库,仓库名直接采用下表,避免重新出现旧 `shared-*` 大杂烩结构。 +V2 产品和工程边界必须按下面四块执行,避免重新出现旧 `shared-*` 大杂烩结构。 -| 最终逻辑仓库/产品线 | 当前 V2 workspace 承载 | 负责内容 | 不负责内容 | +| 最终工程 | 当前代码位置 | 负责内容 | 不负责内容 | |---|---|---|---| -| `yuqei-contract-platform` | `apps/contract-web`、`services/contract-api`、`packages/contract-openapi`、合同侧 worker 任务 | 企业合同系统:前端、后端、审批、台账、合同仓库、合同房间、权限、合同审计、业务通知 | 模型 provider、Prompt 拼装、RAG 检索、知识库内部表、AI 运行审计 | -| `yuqei-ai-platform` | `services/ai-platform-api`、`packages/ai-openapi`、AI 侧 worker 任务 | 统一 AI 中台:模型网关、知识库、RAG、Prompt、法律审查、法条引用、文档智能、AI 审计、质量评测 | 合同审批流、合同台账、合同房间业务状态 | -| `yuqei-ai-sdk-python` | `sdks/python` | 合同系统调用 AI 中台的正式 Python SDK,由 OpenAPI 生成基础客户端,再手写业务友好封装 | 业务数据库访问、模型 provider 直连、旧 vendored SDK 兼容层 | -| `yuqei-infra` | `infra/*` | 部署、环境变量、监控、日志、备份、发布脚本、安全基线 | 业务功能、AI 业务能力、前端产品体验 | +| `yuqei-contract-platform` | `yuqei-contract-platform/apps/contract-web`、`yuqei-contract-platform/services/contract-api`、`yuqei-contract-platform/packages/contract-openapi`、合同侧 worker 任务 | 企业合同系统:前端、后端、审批、台账、合同仓库、合同房间、权限、合同审计、业务通知 | 模型 provider、Prompt 拼装、RAG 检索、知识库内部表、AI 运行审计 | +| `yuqei-ai-platform` | `yuqei-ai-platform/services/ai-platform-api`、`yuqei-ai-platform/packages/ai-openapi`、AI 侧 worker 任务 | 统一 AI 中台:模型网关、知识库、RAG、Prompt、法律审查、法条引用、文档智能、AI 审计、质量评测 | 合同审批流、合同台账、合同房间业务状态 | +| `yuqei-ai-sdk-python` | `yuqei-ai-sdk-python` | 合同系统调用 AI 中台的正式 Python SDK,由 OpenAPI 生成基础客户端,再手写业务友好封装 | 业务数据库访问、模型 provider 直连、旧 vendored SDK 兼容层 | +| `yuqei-infra` | `yuqei-infra/*` | 部署、环境变量、监控、日志、备份、发布脚本、安全基线 | 业务功能、AI 业务能力、前端产品体验 | 旧模块最终处理方式: @@ -172,7 +177,7 @@ V2 当前采用 monorepo 是为了避免重构初期多仓库版本漂移,但 |---|---| | `shared-ai-platform-java` | 不作为未来主线;本项目未正式上线前不需要继续做线上兼容,只冻结为旧服务行为对照和接口参考;新 AI 能力不得再写入该模块。 | | `shared-ai-platform` | 保留历史文档、原型和数据处理经验;不再承接生产功能。 | -| `shared-ai-python-sdk` | 保留 SDK 定位和测试思想;正式 SDK 在 `sdks/python` 重做,建议包名继续向 `yuqei-ai-sdk-python` 收敛。 | +| `shared-ai-python-sdk` | 保留 SDK 定位和测试思想;正式 SDK 在 `yuqei-ai-sdk-python` 重做,建议包名继续向 `yuqei-ai-sdk-python` 收敛。 | | `shared-java-libs` | 如果 V2 不采用 Java 主线,归档为参考,不再扩展。 | | `ai-contract-platform/backend/vendor/shared-ai-platform-sdk` | 最终删除;合同系统内不得再塞一份 SDK 副本。 | @@ -188,18 +193,17 @@ AI 中台必须承接模型、Prompt、知识库、RAG、引用依据、运行 关键技术原则: -- API 先行:`packages/ai-openapi` 和 `packages/contract-openapi` 是跨边界契约真相源。 +- API 先行:`yuqei-ai-platform/packages/ai-openapi` 和 `yuqei-contract-platform/packages/contract-openapi` 是跨边界契约真相源。 - 长流程可靠:合同审查、文档解析、知识库索引、批量导入等长流程后续接入 durable workflow 方案,例如 Temporal 或同类能力。 - 全链路可观测:AI 调用、RAG 命中、Prompt 版本、模型耗时、错误和费用后续纳入 OpenTelemetry 体系。 防跑偏检查清单: -- 新 AI 能力先看是否属于 `yuqei-ai-platform`,不要直接写进 `services/contract-api`。 -- `services/contract-api` 调 AI 只能使用 `yuqei_sdk` 或 OpenAPI 生成客户端。 -- 新 SDK 代码只能进入 `sdks/python` 或 `sdks/typescript`,不得恢复 `backend/vendor/shared-ai-platform-sdk`。 -- 新部署、环境变量、监控、备份、发布脚本进入 `infra`。 +- 新 AI 能力先看是否属于 `yuqei-ai-platform`,不要直接写进 `yuqei-contract-platform/services/contract-api`。 +- `yuqei-contract-platform/services/contract-api` 调 AI 只能使用 `yuqei_sdk` 或 OpenAPI 生成客户端。 +- 新 SDK 代码只能进入 `yuqei-ai-sdk-python`;如确需 TypeScript SDK,另建 `yuqei-ai-sdk-typescript`,不得恢复 `backend/vendor/shared-ai-platform-sdk`。 +- 新部署、环境变量、监控、备份、发布脚本进入 `yuqei-infra`。 - 旧 `shared-*` 仓库只能只读参考,不新增功能、不新增依赖。 - ### 4.3 为什么不继续多个 shared 仓库 旧 shared 结构的问题: diff --git a/project-docs/V2-shared路线防跑偏核查-2026-06-22.md b/project-docs/V2-shared路线防跑偏核查-2026-06-22.md index a30c9784..2a4fcf9d 100644 --- a/project-docs/V2-shared路线防跑偏核查-2026-06-22.md +++ b/project-docs/V2-shared路线防跑偏核查-2026-06-22.md @@ -1,4 +1,4 @@ -# V2 shared 路线防跑偏核查 +# V2 shared 路线防跑偏核查 日期:2026-06-22 @@ -13,14 +13,14 @@ - 正式 SDK - 统一基础设施 -本次补强了主方案中的最终逻辑命名,明确未来拆仓时对应: +本次补强了主方案中的最终工程命名,并已把当前代码目录调整为: - `yuqei-contract-platform` - `yuqei-ai-platform` - `yuqei-ai-sdk-python` - `yuqei-infra` -V2 当前保留 monorepo 只是开发阶段的工程组织方式,不代表把边界混在一起。 +V2 不再采用临时混放路线。当前根目录已经按这四个最终工程组织。 ## 2. 已核查文档 @@ -35,10 +35,10 @@ V2 当前保留 monorepo 只是开发阶段的工程组织方式,不代表把 | 目标边界 | 当前代码位置 | 当前状态 | |---|---|---| -| `yuqei-contract-platform` | `apps/contract-web`、`services/contract-api`、`packages/contract-openapi` | 已建立 V2 前端壳、合同 API、合同 OpenAPI;合同 API 通过 SDK 调 AI。 | -| `yuqei-ai-platform` | `services/ai-platform-api`、`packages/ai-openapi` | 已建立模型配置、知识文档检索、法律问答、AI run audit 的 MVP。 | -| `yuqei-ai-sdk-python` | `sdks/python` | 已有 `AiPlatformClient` 和法律问答调用闭环;后续扩展合同审查、生成、改写、履约义务提取。 | -| `yuqei-infra` | `infra/compose`、`infra/docker`、`infra/nginx`、`infra/observability`、`infra/backup`、`infra/deploy` | 已建立基础目录和本地 compose 底座;后续补 OpenTelemetry、备份、发布脚本和生产环境模板。 | +| `yuqei-contract-platform` | `yuqei-contract-platform/apps/contract-web`、`yuqei-contract-platform/services/contract-api`、`yuqei-contract-platform/packages/contract-openapi` | 已建立 V2 前端壳、合同 API、合同 OpenAPI;合同 API 通过 SDK 调 AI。 | +| `yuqei-ai-platform` | `yuqei-ai-platform/services/ai-platform-api`、`yuqei-ai-platform/packages/ai-openapi` | 已建立模型配置、知识文档检索、法律问答、AI run audit 的 MVP。 | +| `yuqei-ai-sdk-python` | `yuqei-ai-sdk-python` | 已有 `AiPlatformClient` 和法律问答调用闭环;后续扩展合同审查、生成、改写、履约义务提取。 | +| `yuqei-infra` | `yuqei-infra/compose`、`yuqei-infra/docker`、`yuqei-infra/nginx`、`yuqei-infra/observability`、`yuqei-infra/backup`、`yuqei-infra/deploy` | 已建立基础目录和本地 compose 底座;后续补 OpenTelemetry、备份、发布脚本和生产环境模板。 | ## 4. 旧 shared 处理状态 @@ -46,7 +46,7 @@ V2 当前保留 monorepo 只是开发阶段的工程组织方式,不代表把 |---|---|---| | `shared-ai-platform-java` | 不作为未来主线 | 冻结为行为对照和接口参考;不新增 V2 功能。 | | `shared-ai-platform` | 不作为生产 AI 中台 | 只保留文档、原型和数据处理经验。 | -| `shared-ai-python-sdk` | SDK 定位有价值,但实现重做 | 以 `sdks/python` 为正式 SDK 主线。 | +| `shared-ai-python-sdk` | SDK 定位有价值,但实现重做 | 以 `yuqei-ai-sdk-python` 为正式 SDK 主线。 | | `shared-java-libs` | V2 不采用 Java 主线 | 归档参考。 | | `backend/vendor/shared-ai-platform-sdk` | 不应恢复 | 合同系统不得再内置 SDK 副本。 | @@ -55,15 +55,15 @@ V2 当前保留 monorepo 只是开发阶段的工程组织方式,不代表把 - 当前 `main` 分支已经是 V2 主线。 - 当前目录没有发现 `backend/vendor/shared-ai-platform-sdk`。 - 当前代码没有发现旧 `shared-ai-platform`、`shared-ai-platform-java`、`shared-java-libs` 的生产依赖。 -- `services/contract-api` 通过 `yuqei_sdk.AiPlatformClient` 调用 AI 中台,没有直接写模型 provider 适配。 -- `services/ai-platform-api` 正在承接模型配置、知识库检索、法律问答、AI 审计能力。 -- `packages/ai-openapi` 已描述 AI 中台 API 边界。 -- `packages/contract-openapi` 已声明 Contract API 只能通过 SDK/OpenAPI client 调 AI Platform。 +- `yuqei-contract-platform/services/contract-api` 通过 `yuqei_sdk.AiPlatformClient` 调用 AI 中台,没有直接写模型 provider 适配。 +- `yuqei-ai-platform/services/ai-platform-api` 正在承接模型配置、知识库检索、法律问答、AI 审计能力。 +- `yuqei-ai-platform/packages/ai-openapi` 已描述 AI 中台 API 边界。 +- `yuqei-contract-platform/packages/contract-openapi` 已声明 Contract API 只能通过 SDK/OpenAPI client 调 AI Platform。 ## 6. 仍需注意的风险 -1. `sdks/typescript` 还没有正式实现,后续如果前端或 Node 服务要直接调用 AI 中台,需要补契约生成和封装。 -2. `services/ai-platform-api` 目前还是 MVP,知识库和审计主要是内存实现,后续必须落数据库、迁移脚本和权限。 +1. TypeScript SDK 还没有正式实现;后续如果前端或 Node 服务确实需要直接调用 AI 中台,应新建 `yuqei-ai-sdk-typescript`,不要恢复 `sdks/*` 旧式结构。 +2. `yuqei-ai-platform/services/ai-platform-api` 目前还是 MVP,知识库和审计主要是内存实现,后续必须落数据库、迁移脚本和权限。 3. OpenTelemetry、费用统计、模型耗时拆解还没有完成,不能把当前 MVP 当成最终可观测能力。 4. Temporal 或同类 durable workflow 还未接入,长流程任务需要先用清晰接口预留边界。 5. 后续开发中只要出现“为了方便在合同 API 里直接拼 Prompt 或查知识库”的需求,必须回退到 AI 中台边界重新设计。 @@ -75,7 +75,7 @@ V2 当前保留 monorepo 只是开发阶段的工程组织方式,不代表把 优先顺序: 1. AI Platform 数据持久化:provider config、prompt template、knowledge document、ai run audit。 -2. OpenAPI 生成和 SDK 契约测试,让 `sdks/python` 真正成为稳定调用边界。 +2. OpenAPI 生成和 SDK 契约测试,让 `yuqei-ai-sdk-python` 真正成为稳定调用边界。 3. 法律审查、合同生成、条款改写、履约义务提取进入 AI 中台,而不是合同 API。 4. 合同系统继续做企业合同主流程:工作台、合同房间、审批、台账、仓库、审计。 5. `infra` 补环境模板、健康检查、监控日志、备份和发布脚本。 diff --git a/project-docs/V2前端基础工程与轻量化体验底座记录-2026-06-22.md b/project-docs/V2前端基础工程与轻量化体验底座记录-2026-06-22.md index dc5594f0..6a07b9a6 100644 --- a/project-docs/V2前端基础工程与轻量化体验底座记录-2026-06-22.md +++ b/project-docs/V2前端基础工程与轻量化体验底座记录-2026-06-22.md @@ -1,4 +1,4 @@ -# V2 前端基础工程与轻量化体验底座记录 +# V2 前端基础工程与轻量化体验底座记录 日期:2026-06-22 @@ -26,7 +26,7 @@ npm run web:build ### Design System -目录:`packages/design-system` +目录:`yuqei-contract-platform/packages/design-system` 已建立: @@ -36,7 +36,7 @@ npm run web:build ### Contract Web -目录:`apps/contract-web` +目录:`yuqei-contract-platform/apps/contract-web` 已建立: diff --git a/project-docs/V2后端基础工程与本地开发底座记录-2026-06-22.md b/project-docs/V2后端基础工程与本地开发底座记录-2026-06-22.md index 0596b11b..d1e14dc4 100644 --- a/project-docs/V2后端基础工程与本地开发底座记录-2026-06-22.md +++ b/project-docs/V2后端基础工程与本地开发底座记录-2026-06-22.md @@ -1,4 +1,4 @@ -# V2 后端基础工程与本地开发底座记录 +# V2 后端基础工程与本地开发底座记录 日期:2026-06-22 @@ -10,7 +10,7 @@ ### Contract API -目录:`services/contract-api` +目录:`yuqei-contract-platform/services/contract-api` 已建立: @@ -24,7 +24,7 @@ ### AI Platform API -目录:`services/ai-platform-api` +目录:`yuqei-ai-platform/services/ai-platform-api` 已建立: @@ -38,7 +38,7 @@ ### Worker -目录:`services/worker` +目录:`yuqei-ai-platform/services/worker` 已建立: @@ -54,8 +54,8 @@ 已建立: - 根目录 `pyproject.toml`,统一 pytest 入口。 -- `infra/compose/docker-compose.yml`。 -- `infra/compose/.env.example`。 +- `yuqei-infra/compose/docker-compose.yml`。 +- `yuqei-infra/compose/.env.example`。 - 三个服务 Dockerfile。 - `docs/architecture/local-development.md`。 - V2 目录相关 `.gitignore` 规则。 @@ -101,8 +101,8 @@ git diff --check 优先顺序: -1. `apps/contract-web` 初始化 Next.js/React/TypeScript。 -2. `packages/design-system` 建立 tokens、主导航、页面壳、工作台布局规范。 +1. `yuqei-contract-platform/apps/contract-web` 初始化 Next.js/React/TypeScript。 +2. `yuqei-contract-platform/packages/design-system` 建立 tokens、主导航、页面壳、工作台布局规范。 3. 建立前端本地启动、lint、typecheck、build 命令。 4. 前端健康页对接 `contract-api` 的 `/health`。 5. 再进入 S2/S3:AI Platform MVP 和 SDK MVP。 diff --git a/project-docs/V2旧shared资产盘点与迁移清单-2026-06-22.md b/project-docs/V2旧shared资产盘点与迁移清单-2026-06-22.md index 49653b60..2693b33a 100644 --- a/project-docs/V2旧shared资产盘点与迁移清单-2026-06-22.md +++ b/project-docs/V2旧shared资产盘点与迁移清单-2026-06-22.md @@ -1,4 +1,4 @@ -# V2 旧 shared 资产盘点与迁移清单 +# V2 旧 shared 资产盘点与迁移清单 日期:2026-06-22 @@ -6,14 +6,14 @@ 旧 `shared-*` 仓库不再作为 V2 的继续开发主线。 -V2 采用当前仓库 `D:\yuqei-project\ai-contract-platform` 的 monorepo workspace,把 shared 能力重新落到: +V2 采用当前仓库 `D:\yuqei-project\ai-contract-platform` 的四个最终工程边界,把 shared 能力重新落到: -- `services/ai-platform-api` -- `packages/ai-openapi` -- `sdks/python` -- `sdks/typescript` -- `services/worker` -- `packages/design-system` +- `yuqei-ai-platform/services/ai-platform-api` +- `yuqei-ai-platform/packages/ai-openapi` +- `yuqei-ai-sdk-python` +- 如确需 TypeScript SDK,另建 `yuqei-ai-sdk-typescript` +- `yuqei-ai-platform/services/worker` +- `yuqei-contract-platform/packages/design-system` 旧 shared 仓库只作为历史参考、行为对照、迁移素材和测试样例来源。 @@ -23,7 +23,7 @@ V2 采用当前仓库 `D:\yuqei-project\ai-contract-platform` 的 monorepo works |---|---|---:|---| | `shared-ai-platform` | Python 原型平台,含知识库、会话、任务、OCR、RAG、SDK 原型和大量文档 | 有 | 参考实现和数据处理经验,不继续扩展 | | `shared-ai-platform-java` | Java 版共享 AI 平台,含 v0.2 contract、legal-review、knowledge、chat、prompt、provider-router | 有 | 参考模块边界、契约和测试,不迁移 Java 技术栈 | -| `shared-ai-python-sdk` | 形式化 Python SDK,默认 `/api/v0.2`,含 SSE、错误处理、legal-review、document extraction 测试 | 无 | 迁移 API 设计和测试思想,V2 在 `sdks/python` 重做 | +| `shared-ai-python-sdk` | 形式化 Python SDK,默认 `/api/v0.2`,含 SSE、错误处理、legal-review、document extraction 测试 | 无 | 迁移 API 设计和测试思想,V2 在 `yuqei-ai-sdk-python` 重做 | | `shared-java-libs` | Java 公共库,含 shared-ai-sdk、shared-web、shared-storage、shared-notify、shared-core | 有 | V2 不采用 Java 主线,仅参考公共能力边界 | ## 3. `shared-ai-platform` 盘点 @@ -83,7 +83,7 @@ V2 采用当前仓库 `D:\yuqei-project\ai-contract-platform` 的 monorepo works V2 处理建议: - 不在旧仓库继续提交该功能。 -- 将“可配置 OCR 引擎、OCR 质量门禁、OCR 失败结构化返回”作为 `services/worker` 的文档解析需求。 +- 将“可配置 OCR 引擎、OCR 质量门禁、OCR 失败结构化返回”作为 `yuqei-ai-platform/services/worker` 的文档解析需求。 - PaddleOCR 是否启用作为 V2 技术栈 ADR 的可选项,默认不阻塞基础工程。 ## 4. `shared-ai-platform-java` 盘点 @@ -144,7 +144,7 @@ V2 处理建议: V2 处理建议: - 不在旧 Java 仓库继续扩展。 -- 把 v0.2 contract 的思想迁移到 `packages/ai-openapi/openapi.yaml`。 +- 把 v0.2 contract 的思想迁移到 `yuqei-ai-platform/packages/ai-openapi/openapi.yaml`。 - 把 legal-review v0.2 路径设计迁移为 V2 新接口,但路径统一为 `/api/v1/legal/review`,避免继续沿用 domain-pack 历史命名。 ## 5. `shared-ai-python-sdk` 盘点 @@ -178,11 +178,11 @@ V2 处理建议: ### 5.3 V2 迁移策略 -V2 在 `sdks/python` 重新实现正式 SDK: +V2 在 `yuqei-ai-sdk-python` 重新实现正式 SDK: - 包名建议:`yuqei-ai-sdk-python`。 - Python import 建议:`yuqei_ai_sdk`。 -- 由 `packages/ai-openapi/openapi.yaml` 生成基础类型。 +- 由 `yuqei-ai-platform/packages/ai-openapi/openapi.yaml` 生成基础类型。 - 手写业务友好封装。 - 默认调用 `/api/v1`。 - 必须支持: @@ -225,7 +225,7 @@ V2 使用 Python/TypeScript 主线,因此只吸收“能力边界”和“默 对应落地: -- `services/contract-api` 和 `services/ai-platform-api` 的 middleware 必须可配置。 +- `yuqei-contract-platform/services/contract-api` 和 `yuqei-ai-platform/services/ai-platform-api` 的 middleware 必须可配置。 - 错误响应必须标准化,但不能让 SDK 与 HTTP 状态混淆。 - storage/notify 作为应用内可替换 adapter,不做跨仓库 Java shared。 @@ -270,9 +270,9 @@ V2 不再保留: ## 9. 后续执行项 1. 建立 V2 技术栈 ADR。 -2. 建立 `packages/ai-openapi/openapi.yaml`。 -3. 建立 `packages/contract-openapi/openapi.yaml`。 -4. 初始化 `services/ai-platform-api`。 -5. 初始化 `sdks/python`。 +2. 建立 `yuqei-ai-platform/packages/ai-openapi/openapi.yaml`。 +3. 建立 `yuqei-contract-platform/packages/contract-openapi/openapi.yaml`。 +4. 初始化 `yuqei-ai-platform/services/ai-platform-api`。 +5. 初始化 `yuqei-ai-sdk-python`。 6. 迁移 SSE、错误处理、RequestContext 的测试思想。 7. 初始化合同系统只通过 SDK 调用 AI 中台的边界。 diff --git a/project-docs/V2法律问答AI平台与SDK最小闭环记录-2026-06-22.md b/project-docs/V2法律问答AI平台与SDK最小闭环记录-2026-06-22.md index 9b5d5732..88e5ceed 100644 --- a/project-docs/V2法律问答AI平台与SDK最小闭环记录-2026-06-22.md +++ b/project-docs/V2法律问答AI平台与SDK最小闭环记录-2026-06-22.md @@ -1,4 +1,4 @@ -# V2 法律问答 AI 平台与 SDK 最小闭环记录 +# V2 法律问答 AI 平台与 SDK 最小闭环记录 日期:2026-06-22 @@ -6,16 +6,16 @@ 把法律问答能力放到正确的 V2 架构边界里: -- AI 能力归属 `services/ai-platform-api`。 +- AI 能力归属 `yuqei-ai-platform/services/ai-platform-api`。 - 合同系统不直接写模型 provider 或 AI 规则。 -- 合同系统通过 `sdks/python` 调用 AI Platform。 +- 合同系统通过 `yuqei-ai-sdk-python` 调用 AI Platform。 - OpenAPI 契约同步记录这个边界。 ## 2. 已完成内容 ### AI Platform -目录:`services/ai-platform-api` +目录:`yuqei-ai-platform/services/ai-platform-api` 新增: @@ -34,7 +34,7 @@ ### Python SDK -目录:`sdks/python` +目录:`yuqei-ai-sdk-python` 新增: @@ -53,7 +53,7 @@ SDK 负责: ### Contract API -目录:`services/contract-api` +目录:`yuqei-contract-platform/services/contract-api` 新增: @@ -65,7 +65,7 @@ SDK 负责: 已更新: -- `packages/contract-openapi/openapi.yaml` +- `yuqei-contract-platform/packages/contract-openapi/openapi.yaml` 新增合同系统法律问答代理契约: diff --git a/pyproject.toml b/pyproject.toml index 84359975..b9f310a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,14 @@ [tool.pytest.ini_options] testpaths = [ - "services/contract-api/tests", - "services/ai-platform-api/tests", - "services/worker/tests", - "sdks/python/tests", + "yuqei-contract-platform/services/contract-api/tests", + "yuqei-ai-platform/services/ai-platform-api/tests", + "yuqei-ai-platform/services/worker/tests", + "yuqei-ai-sdk-python/tests", ] pythonpath = [ - "services/contract-api/src", - "services/ai-platform-api/src", - "services/worker/src", - "sdks/python/src", + "yuqei-contract-platform/services/contract-api/src", + "yuqei-ai-platform/services/ai-platform-api/src", + "yuqei-ai-platform/services/worker/src", + "yuqei-ai-sdk-python/src", ] addopts = "-q --import-mode=importlib" diff --git a/sdks/typescript/.gitkeep b/sdks/typescript/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/sdks/typescript/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/ai-openapi/README.md b/yuqei-ai-platform/packages/ai-openapi/README.md similarity index 100% rename from packages/ai-openapi/README.md rename to yuqei-ai-platform/packages/ai-openapi/README.md diff --git a/packages/ai-openapi/openapi.yaml b/yuqei-ai-platform/packages/ai-openapi/openapi.yaml similarity index 100% rename from packages/ai-openapi/openapi.yaml rename to yuqei-ai-platform/packages/ai-openapi/openapi.yaml diff --git a/services/ai-platform-api/.env.example b/yuqei-ai-platform/services/ai-platform-api/.env.example similarity index 100% rename from services/ai-platform-api/.env.example rename to yuqei-ai-platform/services/ai-platform-api/.env.example diff --git a/services/ai-platform-api/README.md b/yuqei-ai-platform/services/ai-platform-api/README.md similarity index 67% rename from services/ai-platform-api/README.md rename to yuqei-ai-platform/services/ai-platform-api/README.md index bbf40669..79f811ff 100644 --- a/services/ai-platform-api/README.md +++ b/yuqei-ai-platform/services/ai-platform-api/README.md @@ -1,11 +1,11 @@ -# AI Platform API +# AI Platform API FastAPI service for V2 shared AI capabilities. ## Local Run ```powershell -cd services/ai-platform-api +cd yuqei-ai-platform/services/ai-platform-api python -m uvicorn yuqei_ai_platform_api.main:app --app-dir src --reload --port 8101 ``` @@ -19,5 +19,5 @@ Health endpoints: From repository root: ```powershell -python -m pytest services/ai-platform-api/tests +python -m pytest yuqei-ai-platform/services/ai-platform-api/tests ``` diff --git a/services/ai-platform-api/pyproject.toml b/yuqei-ai-platform/services/ai-platform-api/pyproject.toml similarity index 100% rename from services/ai-platform-api/pyproject.toml rename to yuqei-ai-platform/services/ai-platform-api/pyproject.toml diff --git a/services/ai-platform-api/src/yuqei_ai_platform_api/__init__.py b/yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/__init__.py similarity index 100% rename from services/ai-platform-api/src/yuqei_ai_platform_api/__init__.py rename to yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/__init__.py diff --git a/services/ai-platform-api/src/yuqei_ai_platform_api/config.py b/yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/config.py similarity index 100% rename from services/ai-platform-api/src/yuqei_ai_platform_api/config.py rename to yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/config.py diff --git a/services/ai-platform-api/src/yuqei_ai_platform_api/legal_qa.py b/yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/legal_qa.py similarity index 100% rename from services/ai-platform-api/src/yuqei_ai_platform_api/legal_qa.py rename to yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/legal_qa.py diff --git a/services/ai-platform-api/src/yuqei_ai_platform_api/logging.py b/yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/logging.py similarity index 100% rename from services/ai-platform-api/src/yuqei_ai_platform_api/logging.py rename to yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/logging.py diff --git a/services/ai-platform-api/src/yuqei_ai_platform_api/main.py b/yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/main.py similarity index 100% rename from services/ai-platform-api/src/yuqei_ai_platform_api/main.py rename to yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/main.py diff --git a/services/ai-platform-api/src/yuqei_ai_platform_api/models.py b/yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/models.py similarity index 100% rename from services/ai-platform-api/src/yuqei_ai_platform_api/models.py rename to yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/models.py diff --git a/services/ai-platform-api/src/yuqei_ai_platform_api/repository.py b/yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/repository.py similarity index 100% rename from services/ai-platform-api/src/yuqei_ai_platform_api/repository.py rename to yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/repository.py diff --git a/services/ai-platform-api/src/yuqei_ai_platform_api/state.py b/yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/state.py similarity index 100% rename from services/ai-platform-api/src/yuqei_ai_platform_api/state.py rename to yuqei-ai-platform/services/ai-platform-api/src/yuqei_ai_platform_api/state.py diff --git a/services/ai-platform-api/tests/__init__.py b/yuqei-ai-platform/services/ai-platform-api/tests/__init__.py similarity index 100% rename from services/ai-platform-api/tests/__init__.py rename to yuqei-ai-platform/services/ai-platform-api/tests/__init__.py diff --git a/services/ai-platform-api/tests/test_health.py b/yuqei-ai-platform/services/ai-platform-api/tests/test_health.py similarity index 100% rename from services/ai-platform-api/tests/test_health.py rename to yuqei-ai-platform/services/ai-platform-api/tests/test_health.py diff --git a/services/ai-platform-api/tests/test_legal_qa.py b/yuqei-ai-platform/services/ai-platform-api/tests/test_legal_qa.py similarity index 100% rename from services/ai-platform-api/tests/test_legal_qa.py rename to yuqei-ai-platform/services/ai-platform-api/tests/test_legal_qa.py diff --git a/services/ai-platform-api/tests/test_platform_data.py b/yuqei-ai-platform/services/ai-platform-api/tests/test_platform_data.py similarity index 100% rename from services/ai-platform-api/tests/test_platform_data.py rename to yuqei-ai-platform/services/ai-platform-api/tests/test_platform_data.py diff --git a/services/worker/.env.example b/yuqei-ai-platform/services/worker/.env.example similarity index 100% rename from services/worker/.env.example rename to yuqei-ai-platform/services/worker/.env.example diff --git a/services/worker/README.md b/yuqei-ai-platform/services/worker/README.md similarity index 75% rename from services/worker/README.md rename to yuqei-ai-platform/services/worker/README.md index 3881e37c..57cc6c9d 100644 --- a/services/worker/README.md +++ b/yuqei-ai-platform/services/worker/README.md @@ -1,4 +1,4 @@ -# Worker +# Worker Python worker process for V2 background tasks. @@ -13,7 +13,7 @@ Initial responsibilities: ## Local Health Check ```powershell -cd services/worker +cd yuqei-ai-platform/services/worker $env:PYTHONPATH='src' python -m yuqei_worker.main --health ``` @@ -23,5 +23,5 @@ python -m yuqei_worker.main --health From repository root: ```powershell -python -m pytest services/worker/tests +python -m pytest yuqei-ai-platform/services/worker/tests ``` diff --git a/services/worker/pyproject.toml b/yuqei-ai-platform/services/worker/pyproject.toml similarity index 100% rename from services/worker/pyproject.toml rename to yuqei-ai-platform/services/worker/pyproject.toml diff --git a/services/contract-api/src/yuqei_contract_api/__init__.py b/yuqei-ai-platform/services/worker/src/yuqei_worker/__init__.py similarity index 100% rename from services/contract-api/src/yuqei_contract_api/__init__.py rename to yuqei-ai-platform/services/worker/src/yuqei_worker/__init__.py diff --git a/services/worker/src/yuqei_worker/config.py b/yuqei-ai-platform/services/worker/src/yuqei_worker/config.py similarity index 100% rename from services/worker/src/yuqei_worker/config.py rename to yuqei-ai-platform/services/worker/src/yuqei_worker/config.py diff --git a/services/worker/src/yuqei_worker/logging.py b/yuqei-ai-platform/services/worker/src/yuqei_worker/logging.py similarity index 100% rename from services/worker/src/yuqei_worker/logging.py rename to yuqei-ai-platform/services/worker/src/yuqei_worker/logging.py diff --git a/services/worker/src/yuqei_worker/main.py b/yuqei-ai-platform/services/worker/src/yuqei_worker/main.py similarity index 100% rename from services/worker/src/yuqei_worker/main.py rename to yuqei-ai-platform/services/worker/src/yuqei_worker/main.py diff --git a/services/worker/tests/__init__.py b/yuqei-ai-platform/services/worker/tests/__init__.py similarity index 100% rename from services/worker/tests/__init__.py rename to yuqei-ai-platform/services/worker/tests/__init__.py diff --git a/services/worker/tests/test_health.py b/yuqei-ai-platform/services/worker/tests/test_health.py similarity index 100% rename from services/worker/tests/test_health.py rename to yuqei-ai-platform/services/worker/tests/test_health.py diff --git a/sdks/python/README.md b/yuqei-ai-sdk-python/README.md similarity index 100% rename from sdks/python/README.md rename to yuqei-ai-sdk-python/README.md diff --git a/sdks/python/pyproject.toml b/yuqei-ai-sdk-python/pyproject.toml similarity index 100% rename from sdks/python/pyproject.toml rename to yuqei-ai-sdk-python/pyproject.toml diff --git a/sdks/python/src/yuqei_sdk/__init__.py b/yuqei-ai-sdk-python/src/yuqei_sdk/__init__.py similarity index 100% rename from sdks/python/src/yuqei_sdk/__init__.py rename to yuqei-ai-sdk-python/src/yuqei_sdk/__init__.py diff --git a/sdks/python/src/yuqei_sdk/ai_platform.py b/yuqei-ai-sdk-python/src/yuqei_sdk/ai_platform.py similarity index 100% rename from sdks/python/src/yuqei_sdk/ai_platform.py rename to yuqei-ai-sdk-python/src/yuqei_sdk/ai_platform.py diff --git a/sdks/python/src/yuqei_sdk/context.py b/yuqei-ai-sdk-python/src/yuqei_sdk/context.py similarity index 100% rename from sdks/python/src/yuqei_sdk/context.py rename to yuqei-ai-sdk-python/src/yuqei_sdk/context.py diff --git a/sdks/python/tests/__init__.py b/yuqei-ai-sdk-python/tests/__init__.py similarity index 100% rename from sdks/python/tests/__init__.py rename to yuqei-ai-sdk-python/tests/__init__.py diff --git a/sdks/python/tests/test_ai_platform.py b/yuqei-ai-sdk-python/tests/test_ai_platform.py similarity index 100% rename from sdks/python/tests/test_ai_platform.py rename to yuqei-ai-sdk-python/tests/test_ai_platform.py diff --git a/apps/contract-web/.env.example b/yuqei-contract-platform/apps/contract-web/.env.example similarity index 100% rename from apps/contract-web/.env.example rename to yuqei-contract-platform/apps/contract-web/.env.example diff --git a/apps/contract-web/README.md b/yuqei-contract-platform/apps/contract-web/README.md similarity index 100% rename from apps/contract-web/README.md rename to yuqei-contract-platform/apps/contract-web/README.md diff --git a/apps/contract-web/next.config.ts b/yuqei-contract-platform/apps/contract-web/next.config.ts similarity index 100% rename from apps/contract-web/next.config.ts rename to yuqei-contract-platform/apps/contract-web/next.config.ts diff --git a/apps/contract-web/package.json b/yuqei-contract-platform/apps/contract-web/package.json similarity index 100% rename from apps/contract-web/package.json rename to yuqei-contract-platform/apps/contract-web/package.json diff --git a/apps/contract-web/src/app/admin/page.tsx b/yuqei-contract-platform/apps/contract-web/src/app/admin/page.tsx similarity index 100% rename from apps/contract-web/src/app/admin/page.tsx rename to yuqei-contract-platform/apps/contract-web/src/app/admin/page.tsx diff --git a/apps/contract-web/src/app/contracts/[id]/page.tsx b/yuqei-contract-platform/apps/contract-web/src/app/contracts/[id]/page.tsx similarity index 100% rename from apps/contract-web/src/app/contracts/[id]/page.tsx rename to yuqei-contract-platform/apps/contract-web/src/app/contracts/[id]/page.tsx diff --git a/apps/contract-web/src/app/contracts/page.tsx b/yuqei-contract-platform/apps/contract-web/src/app/contracts/page.tsx similarity index 100% rename from apps/contract-web/src/app/contracts/page.tsx rename to yuqei-contract-platform/apps/contract-web/src/app/contracts/page.tsx diff --git a/apps/contract-web/src/app/files/page.tsx b/yuqei-contract-platform/apps/contract-web/src/app/files/page.tsx similarity index 100% rename from apps/contract-web/src/app/files/page.tsx rename to yuqei-contract-platform/apps/contract-web/src/app/files/page.tsx diff --git a/apps/contract-web/src/app/globals.css b/yuqei-contract-platform/apps/contract-web/src/app/globals.css similarity index 100% rename from apps/contract-web/src/app/globals.css rename to yuqei-contract-platform/apps/contract-web/src/app/globals.css diff --git a/apps/contract-web/src/app/health/page.tsx b/yuqei-contract-platform/apps/contract-web/src/app/health/page.tsx similarity index 100% rename from apps/contract-web/src/app/health/page.tsx rename to yuqei-contract-platform/apps/contract-web/src/app/health/page.tsx diff --git a/apps/contract-web/src/app/layout.tsx b/yuqei-contract-platform/apps/contract-web/src/app/layout.tsx similarity index 100% rename from apps/contract-web/src/app/layout.tsx rename to yuqei-contract-platform/apps/contract-web/src/app/layout.tsx diff --git a/apps/contract-web/src/app/page.tsx b/yuqei-contract-platform/apps/contract-web/src/app/page.tsx similarity index 100% rename from apps/contract-web/src/app/page.tsx rename to yuqei-contract-platform/apps/contract-web/src/app/page.tsx diff --git a/apps/contract-web/src/app/search/page.tsx b/yuqei-contract-platform/apps/contract-web/src/app/search/page.tsx similarity index 100% rename from apps/contract-web/src/app/search/page.tsx rename to yuqei-contract-platform/apps/contract-web/src/app/search/page.tsx diff --git a/apps/contract-web/src/app/workspace/page.tsx b/yuqei-contract-platform/apps/contract-web/src/app/workspace/page.tsx similarity index 100% rename from apps/contract-web/src/app/workspace/page.tsx rename to yuqei-contract-platform/apps/contract-web/src/app/workspace/page.tsx diff --git a/apps/contract-web/src/components/app-shell.tsx b/yuqei-contract-platform/apps/contract-web/src/components/app-shell.tsx similarity index 100% rename from apps/contract-web/src/components/app-shell.tsx rename to yuqei-contract-platform/apps/contract-web/src/components/app-shell.tsx diff --git a/apps/contract-web/src/features/system/system-health-panel.tsx b/yuqei-contract-platform/apps/contract-web/src/features/system/system-health-panel.tsx similarity index 100% rename from apps/contract-web/src/features/system/system-health-panel.tsx rename to yuqei-contract-platform/apps/contract-web/src/features/system/system-health-panel.tsx diff --git a/apps/contract-web/src/features/workspace/workspace-page.tsx b/yuqei-contract-platform/apps/contract-web/src/features/workspace/workspace-page.tsx similarity index 100% rename from apps/contract-web/src/features/workspace/workspace-page.tsx rename to yuqei-contract-platform/apps/contract-web/src/features/workspace/workspace-page.tsx diff --git a/apps/contract-web/src/lib/mock-data.ts b/yuqei-contract-platform/apps/contract-web/src/lib/mock-data.ts similarity index 100% rename from apps/contract-web/src/lib/mock-data.ts rename to yuqei-contract-platform/apps/contract-web/src/lib/mock-data.ts diff --git a/apps/contract-web/tsconfig.json b/yuqei-contract-platform/apps/contract-web/tsconfig.json similarity index 87% rename from apps/contract-web/tsconfig.json rename to yuqei-contract-platform/apps/contract-web/tsconfig.json index 4b9fd76c..fbe69c21 100644 --- a/apps/contract-web/tsconfig.json +++ b/yuqei-contract-platform/apps/contract-web/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "baseUrl": ".", "paths": { diff --git a/packages/contract-openapi/README.md b/yuqei-contract-platform/packages/contract-openapi/README.md similarity index 100% rename from packages/contract-openapi/README.md rename to yuqei-contract-platform/packages/contract-openapi/README.md diff --git a/packages/contract-openapi/openapi.yaml b/yuqei-contract-platform/packages/contract-openapi/openapi.yaml similarity index 100% rename from packages/contract-openapi/openapi.yaml rename to yuqei-contract-platform/packages/contract-openapi/openapi.yaml diff --git a/packages/design-system/README.md b/yuqei-contract-platform/packages/design-system/README.md similarity index 100% rename from packages/design-system/README.md rename to yuqei-contract-platform/packages/design-system/README.md diff --git a/packages/design-system/package.json b/yuqei-contract-platform/packages/design-system/package.json similarity index 100% rename from packages/design-system/package.json rename to yuqei-contract-platform/packages/design-system/package.json diff --git a/packages/design-system/src/index.ts b/yuqei-contract-platform/packages/design-system/src/index.ts similarity index 100% rename from packages/design-system/src/index.ts rename to yuqei-contract-platform/packages/design-system/src/index.ts diff --git a/packages/design-system/src/tokens.ts b/yuqei-contract-platform/packages/design-system/src/tokens.ts similarity index 100% rename from packages/design-system/src/tokens.ts rename to yuqei-contract-platform/packages/design-system/src/tokens.ts diff --git a/packages/design-system/src/workflow.ts b/yuqei-contract-platform/packages/design-system/src/workflow.ts similarity index 100% rename from packages/design-system/src/workflow.ts rename to yuqei-contract-platform/packages/design-system/src/workflow.ts diff --git a/services/contract-api/.env.example b/yuqei-contract-platform/services/contract-api/.env.example similarity index 100% rename from services/contract-api/.env.example rename to yuqei-contract-platform/services/contract-api/.env.example diff --git a/services/contract-api/README.md b/yuqei-contract-platform/services/contract-api/README.md similarity index 66% rename from services/contract-api/README.md rename to yuqei-contract-platform/services/contract-api/README.md index 29e280aa..7e95891c 100644 --- a/services/contract-api/README.md +++ b/yuqei-contract-platform/services/contract-api/README.md @@ -1,11 +1,11 @@ -# Contract API +# Contract API FastAPI service for V2 contract workflows. ## Local Run ```powershell -cd services/contract-api +cd yuqei-contract-platform/services/contract-api python -m uvicorn yuqei_contract_api.main:app --app-dir src --reload --port 8100 ``` @@ -19,5 +19,5 @@ Health endpoints: From repository root: ```powershell -python -m pytest services/contract-api/tests +python -m pytest yuqei-contract-platform/services/contract-api/tests ``` diff --git a/services/contract-api/pyproject.toml b/yuqei-contract-platform/services/contract-api/pyproject.toml similarity index 100% rename from services/contract-api/pyproject.toml rename to yuqei-contract-platform/services/contract-api/pyproject.toml diff --git a/services/worker/src/yuqei_worker/__init__.py b/yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/__init__.py similarity index 100% rename from services/worker/src/yuqei_worker/__init__.py rename to yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/__init__.py diff --git a/services/contract-api/src/yuqei_contract_api/config.py b/yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/config.py similarity index 100% rename from services/contract-api/src/yuqei_contract_api/config.py rename to yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/config.py diff --git a/services/contract-api/src/yuqei_contract_api/logging.py b/yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/logging.py similarity index 100% rename from services/contract-api/src/yuqei_contract_api/logging.py rename to yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/logging.py diff --git a/services/contract-api/src/yuqei_contract_api/main.py b/yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/main.py similarity index 100% rename from services/contract-api/src/yuqei_contract_api/main.py rename to yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/main.py diff --git a/services/contract-api/tests/__init__.py b/yuqei-contract-platform/services/contract-api/tests/__init__.py similarity index 100% rename from services/contract-api/tests/__init__.py rename to yuqei-contract-platform/services/contract-api/tests/__init__.py diff --git a/services/contract-api/tests/test_health.py b/yuqei-contract-platform/services/contract-api/tests/test_health.py similarity index 100% rename from services/contract-api/tests/test_health.py rename to yuqei-contract-platform/services/contract-api/tests/test_health.py diff --git a/services/contract-api/tests/test_legal_qa_proxy.py b/yuqei-contract-platform/services/contract-api/tests/test_legal_qa_proxy.py similarity index 100% rename from services/contract-api/tests/test_legal_qa_proxy.py rename to yuqei-contract-platform/services/contract-api/tests/test_legal_qa_proxy.py diff --git a/infra/backup/.gitkeep b/yuqei-infra/backup/.gitkeep similarity index 100% rename from infra/backup/.gitkeep rename to yuqei-infra/backup/.gitkeep diff --git a/infra/compose/.env.example b/yuqei-infra/compose/.env.example similarity index 100% rename from infra/compose/.env.example rename to yuqei-infra/compose/.env.example diff --git a/infra/compose/docker-compose.yml b/yuqei-infra/compose/docker-compose.yml similarity index 93% rename from infra/compose/docker-compose.yml rename to yuqei-infra/compose/docker-compose.yml index 0bf29b42..6bbe0794 100644 --- a/infra/compose/docker-compose.yml +++ b/yuqei-infra/compose/docker-compose.yml @@ -47,7 +47,7 @@ services: contract-api: build: context: ../.. - dockerfile: infra/docker/contract-api.Dockerfile + dockerfile: yuqei-infra/docker/contract-api.Dockerfile environment: CONTRACT_API_ENVIRONMENT: local CONTRACT_API_DATABASE_URL: postgresql+psycopg://yuqei:yuqei-local@postgres:5432/yuqei_v2 @@ -64,7 +64,7 @@ services: ai-platform-api: build: context: ../.. - dockerfile: infra/docker/ai-platform-api.Dockerfile + dockerfile: yuqei-infra/docker/ai-platform-api.Dockerfile environment: AI_PLATFORM_ENVIRONMENT: local AI_PLATFORM_DATABASE_URL: postgresql+psycopg://yuqei:yuqei-local@postgres:5432/yuqei_v2 @@ -81,7 +81,7 @@ services: worker: build: context: ../.. - dockerfile: infra/docker/worker.Dockerfile + dockerfile: yuqei-infra/docker/worker.Dockerfile environment: YUQEI_WORKER_ENVIRONMENT: local YUQEI_WORKER_REDIS_URL: redis://redis:6379/2 diff --git a/infra/deploy/.gitkeep b/yuqei-infra/deploy/.gitkeep similarity index 100% rename from infra/deploy/.gitkeep rename to yuqei-infra/deploy/.gitkeep diff --git a/infra/docker/ai-platform-api.Dockerfile b/yuqei-infra/docker/ai-platform-api.Dockerfile similarity index 53% rename from infra/docker/ai-platform-api.Dockerfile rename to yuqei-infra/docker/ai-platform-api.Dockerfile index e1ae2f3d..726d045a 100644 --- a/infra/docker/ai-platform-api.Dockerfile +++ b/yuqei-infra/docker/ai-platform-api.Dockerfile @@ -2,14 +2,14 @@ FROM python:3.12-slim ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ - PYTHONPATH=/app/services/ai-platform-api/src + PYTHONPATH=/app/yuqei-ai-platform/services/ai-platform-api/src WORKDIR /app -COPY services/ai-platform-api/pyproject.toml /tmp/ai-platform-api-pyproject.toml +COPY yuqei-ai-platform/services/ai-platform-api/pyproject.toml /tmp/ai-platform-api-pyproject.toml RUN pip install --no-cache-dir fastapi pydantic pydantic-settings sqlalchemy uvicorn -COPY services/ai-platform-api services/ai-platform-api +COPY yuqei-ai-platform/services/ai-platform-api yuqei-ai-platform/services/ai-platform-api EXPOSE 8101 CMD ["python", "-m", "uvicorn", "yuqei_ai_platform_api.main:app", "--host", "0.0.0.0", "--port", "8101"] diff --git a/yuqei-infra/docker/contract-api.Dockerfile b/yuqei-infra/docker/contract-api.Dockerfile new file mode 100644 index 00000000..11758bd9 --- /dev/null +++ b/yuqei-infra/docker/contract-api.Dockerfile @@ -0,0 +1,17 @@ +FROM python:3.12-slim + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PYTHONPATH=/app/yuqei-contract-platform/services/contract-api/src:/app/yuqei-ai-sdk-python/src + +WORKDIR /app + +COPY yuqei-contract-platform/services/contract-api/pyproject.toml /tmp/contract-api-pyproject.toml +COPY yuqei-ai-sdk-python/pyproject.toml /tmp/yuqei-ai-sdk-python-pyproject.toml +RUN pip install --no-cache-dir fastapi httpx pydantic pydantic-settings sqlalchemy uvicorn + +COPY yuqei-contract-platform/services/contract-api yuqei-contract-platform/services/contract-api +COPY yuqei-ai-sdk-python yuqei-ai-sdk-python + +EXPOSE 8100 +CMD ["python", "-m", "uvicorn", "yuqei_contract_api.main:app", "--host", "0.0.0.0", "--port", "8100"] diff --git a/yuqei-infra/docker/worker.Dockerfile b/yuqei-infra/docker/worker.Dockerfile new file mode 100644 index 00000000..e867b165 --- /dev/null +++ b/yuqei-infra/docker/worker.Dockerfile @@ -0,0 +1,14 @@ +FROM python:3.12-slim + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PYTHONPATH=/app/yuqei-ai-platform/services/worker/src + +WORKDIR /app + +COPY yuqei-ai-platform/services/worker/pyproject.toml /tmp/worker-pyproject.toml +RUN pip install --no-cache-dir pydantic pydantic-settings + +COPY yuqei-ai-platform/services/worker yuqei-ai-platform/services/worker + +CMD ["python", "-m", "yuqei_worker.main", "--health"] diff --git a/infra/nginx/.gitkeep b/yuqei-infra/nginx/.gitkeep similarity index 100% rename from infra/nginx/.gitkeep rename to yuqei-infra/nginx/.gitkeep diff --git a/infra/observability/.gitkeep b/yuqei-infra/observability/.gitkeep similarity index 100% rename from infra/observability/.gitkeep rename to yuqei-infra/observability/.gitkeep