DiTo97 / DiTo97/GPTZero-V

services and packages split

Open
#19 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
5
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Here is the unified **Work Plan** for the engineering team. This document covers the architectural migration, configuration changes, automation scripts, and deployment strategy required to transition the `toolkit` workspace into a polyglot monorepo.

---

# Work Plan: Polyglot Monorepo Migration

## 1. Executive Summary

We are transitioning the `toolkit` workspace from a Python-only environment to a Polyglot Monorepo (Python + TypeScript). This enables the development of a React-based frontend (`toolkit-web`) that consumes the Python backend via an **automatically generated, type-safe TypeScript SDK**.

## 2. Target Repository Structure

The file system will be reorganized to distinguish between runnable services, shared packages, and deployment configuration.

```text
toolkit/ (Root)
├── pyproject.toml # Root uv workspace config
├── package.json # NEW: Root Node workspace config
├── uv.lock
├── scripts/
│ └── export_openapi.py # NEW: Extracts OpenAPI JSON from FastAPI
├── deployment/ # NEW: Container orchestration
│ ├── docker-compose.yml
│ ├── Dockerfile.server
│ └── Dockerfile.web
├── services/ # RENAMED (was 'apps')
│ ├── toolkit-server/ # (Python) FastAPI Backend (was 'toolkit-api')
│ └── toolkit-web/ # (React) Frontend (was 'toolkit-service')
└── packages/
├── toolkit-core/ # (Python) Shared Core Logic
├── toolkit-client-py/ # (Python) API Client
└── toolkit-client-ts/ # (TS) NEW: Generated API Client

```

---

## 3. Structural & Configuration Changes

### A. Root Configuration

**File:** `pyproject.toml` (Update)
Update members to reflect the rename to `services` and exclude Node directories.

```toml
[tool.uv]
members = [
"services/toolkit-server",
"packages/toolkit-core",
"packages/toolkit-client-py"
]
exclude = [
"**/node_modules",
"**/dist",
"services/toolkit-web",
"packages/toolkit-client-ts"
]

```

**File:** `package.json` (Create)
Initialize the Node.js workspace root.

```json
{
"name": "toolkit-monorepo",
"private": true,
"workspaces": [
"services/toolkit-web",
"packages/toolkit-client-ts"
],
"scripts": {
"generate-client": "openapi --input ./openapi.json --output ./packages/toolkit-client-ts/src/generated --client axios"
},
"devDependencies": {
"openapi-typescript-codegen": "^0.25.0"
}
}

```

### B. Package Setup

**Package:** `packages/toolkit-client-ts`
Create this folder. It will house the auto-generated code.

* **File:** `package.json`
```json
{
"name": "@toolkit/client",
"version": "0.0.1",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": "./src/index.ts"
}
}

```

**Service:** `services/toolkit-web`

* Add dependency: `"@toolkit/client": "*"`

---

## 4. Automation & Code Generation

### A. OpenAPI Export Script

**File:** `scripts/export_openapi.py`
Used to extract the JSON spec without running the server.

```python
import json
import argparse
# Adjust import to match your actual server structure
from toolkit_server.main import app

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--output", default="openapi.json")
args = parser.parse_args()

print("Extracting OpenAPI schema...")
with open(args.output, "w") as f:
json.dump(app.openapi(), f, indent=2)
print(f"✅ Exported to {args.output}")

```

### B. CI/CD Pipeline (GitHub Actions)

**File:** `.github/workflows/generate-client.yml`
Automatically regenerates the TS client when the backend changes.

```yaml
name: Generate Client SDKs
on:
push:
branches: ["main"]
paths: ["services/toolkit-server/**", "packages/toolkit-core/**"]
permissions:
contents: write
jobs:
generate-sdk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with: { python-version: '3.11' }

- name: Install Backend Deps
run: pip install uv && uv sync

- name: Export OpenAPI JSON
run: |
export PYTHONPATH=$PYTHONPATH:$(pwd)/services/toolkit-server/src:$(pwd)/packages/toolkit-core/src
uv run python scripts/export_openapi.py

- name: Set up Node
uses: actions/setup-node@v4
with: { node-version: '20' }

- name: Install Generator
run: npm install

- name: Generate TypeScript Client
run: npm run generate-client

- name: Commit & Push changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore(sdk): auto-generate typescript client [skip ci]"
file_pattern: 'packages/toolkit-client-ts/**'

```

---

## 5. Deployment Architecture

### A. Backend Container

**File:** `deployment/Dockerfile.server`

```dockerfile
FROM python:3.11-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
WORKDIR /app

# Configs
COPY pyproject.toml uv.lock ./
COPY services/toolkit-server/pyproject.toml services/toolkit-server/
COPY packages/toolkit-core/pyproject.toml packages/toolkit-core/
COPY packages/toolkit-client-py/pyproject.toml packages/toolkit-client-py/

RUN uv sync --frozen

# Source
COPY services/toolkit-server/src services/toolkit-server/src
COPY packages/toolkit-core/src packages/toolkit-core/src
COPY packages/toolkit-client-py/src packages/toolkit-client-py/src

ENV PYTHONPATH=/app/services/toolkit-server/src:/app/packages/toolkit-core/src
CMD ["uv", "run", "uvicorn", "toolkit_server.main:app", "--host", "0.0.0.0", "--port", "8000"]

```

### B. Web Container

**File:** `deployment/Dockerfile.web`

```dockerfile
FROM node:20-slim as builder
WORKDIR /app
COPY package.json package-lock.json ./
COPY services/toolkit-web/package.json services/toolkit-web/
COPY packages/toolkit-client-ts/package.json packages/toolkit-client-ts/
RUN npm install

COPY services/toolkit-web services/toolkit-web
COPY packages/toolkit-client-ts packages/toolkit-client-ts

RUN npm run build --workspace=services/toolkit-web

FROM nginx:alpine
COPY --from=builder /app/services/toolkit-web/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

```

### C. Orchestration

**File:** `deployment/docker-compose.yml`

```yaml
services:
server:
build:
context: ..
dockerfile: deployment/Dockerfile.server
ports: ["8000:8000"]
volumes:
- ../services/toolkit-server/src:/app/services/toolkit-server/src
- ../packages/toolkit-core/src:/app/packages/toolkit-core/src

web:
build:
context: ..
dockerfile: deployment/Dockerfile.web
ports: ["3000:80"]
depends_on:
- server

```

---

## 6. Definition of Done

1. Repo restructured with `services/`, `packages/`, and `deployment/`.
2. `uv` workspace syncs correctly without errors.
3. `npm install` at root installs deps for web and ts-client.
4. Running `python scripts/export_openapi.py` generates a valid JSON.
5. Running `npm run generate-client` populates `packages/toolkit-client-ts`.
6. The React app can import `import { X } from '@toolkit/client'` and IntelliSense works.
7. `docker-compose up --build` launches both services successfully.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the target repository structure, then inspect pyproject.toml, the planned package.json files, scripts/export_openapi.py, and the existing services/apps layout. Run the listed workspace, client-generation, export, and docker-compose commands as they become available; done means the services/packages/deployment split works, the OpenAPI client is generated, and both containers launch successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, docker-compose, fastapi, github-actions, nginx, node.js, python, react, typescript
Domain
api, backend, build-system, ci-cd, devops, frontend, full-stack, infrastructure
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.