From efe4d53ee7560038581f20ce96011f72ac4ebcc9 Mon Sep 17 00:00:00 2001 From: Manash Pratim Bhuyan Date: Mon, 24 Aug 2026 14:19:41 +0530 Subject: [PATCH] fix(monorepo): modernize structure, remove shallow trpc wrapper, fix cli Eliminate shallow @arche-template/trpc package and export tRPC contract directly from @arche-template/server/trpc. Fix workspace glob 'tests/*' to 'tests' in root package.json so @arche-template/tests is included in the workspace graph. Fix CLI template path resolution in web-core.ts after bun build. Move bundled CLI dependencies (@arche-template/registry, zod) to devDependencies for npm publish readiness. Switch CLI package dry-run script from npm pack to bun pm pack. Enforce strict DATABASE_URL requirement in production for packages/store. Add sensible defaults and Vercel skipValidation to clientEnv. Consolidate turbo CI pipeline with streaming UI and root tasks. Remove dead apps/server/env.ts and empty .npmrc. Update documentation and template generators for direct tRPC exports. --- .changeset/config.json | 1 - .npmrc | 0 AGENTS.md | 3 +- apps/cli/package.json | 12 +++--- apps/cli/src/lib/generators/agent-docs.ts | 1 - apps/cli/src/lib/generators/backend.ts | 15 ++----- apps/cli/src/lib/generators/bundles.ts | 1 - apps/cli/src/lib/scaffold.ts | 7 +--- apps/cli/src/lib/web-core.ts | 7 +++- .../web/components/live/live-room-context.tsx | 6 ++- .../src/templates/fullstack/.archefiles.json | 1 - .../fullstack/apps/server/tsconfig.json | 1 - .../templates/fullstack/apps/web/package.json | 1 - .../fullstack/apps/web/trpc/client.tsx | 2 +- .../fullstack/apps/web/trpc/server.tsx | 2 +- .../fullstack/apps/worker/tsconfig.json | 5 +-- .../fullstack/packages/trpc/.gitignore | 34 ---------------- .../fullstack/packages/trpc/AGENTS.md | 26 ------------- .../fullstack/packages/trpc/README.md | 8 ---- .../fullstack/packages/trpc/package.json | 27 ------------- .../fullstack/packages/trpc/src/index.ts | 15 ------- .../fullstack/packages/trpc/tsconfig.json | 16 -------- apps/cli/tests/backend.test.ts | 16 -------- apps/server/env.ts | 25 ------------ apps/server/package.json | 1 + apps/server/src/modules/trpc/index.ts | 6 ++- apps/server/src/modules/trpc/trpc.routes.ts | 4 +- apps/server/tsconfig.json | 1 - .../web/components/live/live-room-context.tsx | 6 ++- apps/web/env.ts | 11 +++--- apps/web/package.json | 4 +- apps/web/trpc/client.tsx | 2 +- apps/web/trpc/http-server.tsx | 2 +- apps/web/trpc/server.tsx | 2 +- apps/web/tsconfig.json | 2 +- apps/worker/tsconfig.json | 1 - bun.lock | 39 ++++++++++--------- docs/README.md | 1 - docs/architecture.md | 2 +- docs/implementation-summary.md | 2 +- package.json | 12 +++--- packages/auth/package.json | 1 + packages/backend-common/src/index.ts | 19 +++++---- packages/common/src/env/client.ts | 11 +++--- packages/store/src/index.ts | 6 +++ packages/trpc/.gitignore | 34 ---------------- packages/trpc/AGENTS.md | 26 ------------- packages/trpc/README.md | 8 ---- packages/trpc/package.json | 28 ------------- packages/trpc/src/index.ts | 20 ---------- packages/trpc/tsconfig.json | 16 -------- tests/package.json | 3 +- tests/src/cli/create-kitsu-stack.test.ts | 5 +-- tests/src/integration/post-crud.test.ts | 6 +-- tests/src/toolings/server-turbo-cache.test.ts | 7 +++- .../src/toolings/sync-template-agents.test.ts | 3 +- tests/tsconfig.json | 2 +- toolings/scripts/repo-doctor.ts | 2 +- toolings/scripts/sync-template-agents.ts | 5 +-- toolings/scripts/sync-web-core.ts | 5 +-- turbo.json | 9 ++++- 61 files changed, 129 insertions(+), 417 deletions(-) delete mode 100644 .npmrc delete mode 100644 apps/cli/src/templates/fullstack/packages/trpc/.gitignore delete mode 100644 apps/cli/src/templates/fullstack/packages/trpc/AGENTS.md delete mode 100644 apps/cli/src/templates/fullstack/packages/trpc/README.md delete mode 100644 apps/cli/src/templates/fullstack/packages/trpc/package.json delete mode 100644 apps/cli/src/templates/fullstack/packages/trpc/src/index.ts delete mode 100644 apps/cli/src/templates/fullstack/packages/trpc/tsconfig.json delete mode 100644 apps/server/env.ts delete mode 100644 packages/trpc/.gitignore delete mode 100644 packages/trpc/AGENTS.md delete mode 100644 packages/trpc/README.md delete mode 100644 packages/trpc/package.json delete mode 100644 packages/trpc/src/index.ts delete mode 100644 packages/trpc/tsconfig.json diff --git a/.changeset/config.json b/.changeset/config.json index 1557c9c..0295d08 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -14,7 +14,6 @@ "@arche-template/server", "@arche-template/store", "@arche-template/tooling-scripts", - "@arche-template/trpc", "@arche-template/typescript-config", "@arche-template/ui", "@arche-template/web", diff --git a/.npmrc b/.npmrc deleted file mode 100644 index e69de29..0000000 diff --git a/AGENTS.md b/AGENTS.md index cfc6baf..2be0521 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,7 +14,7 @@ Run `bun run repo:doctor` before release or after large cleanup passes. ## Repo-specific invariants - tRPC: `apps/server/src/modules//*.trpc.ts` → `apps/server/src/modules/trpc/app.router.ts`. -- `packages/trpc` is the **client contract only** (re-exports `AppRouter` / `createCaller`). +- tRPC contract: `apps/server/src/modules/trpc` exports `AppRouter` and `createCaller` directly to web/worker. - Production default: Vercel web + Render Docker API + Neon + Upstash — [docs/production-playbook.md](docs/production-playbook.md). - Prefer correctness and robustness over short-term convenience. @@ -29,7 +29,6 @@ CI: `bun run ci:min` (full `bun run ci` on `main`/`prod`/`develop`) — [docs/ci | `apps/web` | Next.js App Router; tRPC client + `trpcCaller` for RSC | | `apps/server` | Express, Better Auth, `src/modules/*` | | `apps/worker` | Background jobs (Redis/BullMQ when enabled) | -| `packages/trpc` | Client contract only | | `packages/store` | Prisma schema and client | | `packages/auth` | Better Auth server + client | | `packages/backend-common` | `serverEnv`, Redis, BullMQ, logging, `validate-env` | diff --git a/apps/cli/package.json b/apps/cli/package.json index d14ef03..f576ec6 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -53,24 +53,24 @@ "dev": "bun run ./src/index.ts", "link": "bun run build && bun link", "unlink": "bun unlink", - "test": "bun test", + "test": "bun test tests", "lint": "oxlint", "lint:fix": "oxlint --fix", "check-types": "tsc --noEmit", - "pack:dry-run": "bun run build && npm pack --dry-run", + "pack:dry-run": "bun run build && bun pm pack --dry-run", "prepublishOnly": "bun run build" }, "dependencies": { - "@arche-template/registry": "workspace:*", "@clack/prompts": "^1.4.0", - "picocolors": "^1.1.1", - "zod": "catalog:" + "picocolors": "^1.1.1" }, "devDependencies": { + "@arche-template/registry": "workspace:*", "@arche-template/typescript-config": "workspace:*", "@types/node": "catalog:", "oxlint": "catalog:", - "typescript": "catalog:" + "typescript": "catalog:", + "zod": "catalog:" }, "engines": { "node": ">=20.0.0" diff --git a/apps/cli/src/lib/generators/agent-docs.ts b/apps/cli/src/lib/generators/agent-docs.ts index 729a139..8b0700a 100644 --- a/apps/cli/src/lib/generators/agent-docs.ts +++ b/apps/cli/src/lib/generators/agent-docs.ts @@ -22,7 +22,6 @@ function keyDirs(config: ProjectConfig): string[] { dirs.push('`apps/server` — API server') dirs.push('`packages/auth` — Better Auth configuration') dirs.push('`packages/store` — Database schema and client') - dirs.push('`packages/trpc` — tRPC routers and context') dirs.push('`packages/common` — Shared TypeScript helpers') } if (includeWorker) dirs.push('`apps/worker` — Background job processing') diff --git a/apps/cli/src/lib/generators/backend.ts b/apps/cli/src/lib/generators/backend.ts index 00b843c..1450083 100644 --- a/apps/cli/src/lib/generators/backend.ts +++ b/apps/cli/src/lib/generators/backend.ts @@ -220,12 +220,6 @@ export const protectedProcedure = t.procedure ` } -/** Keep @arche-template/trpc as a thin re-export for web clients */ -function trpcIndexFetch(): string { - return `export type { AppRouter, RouterInputs, RouterOutputs } from '@arche-template/server/trpc' -` -} - /** Server-side tRPC barrel after removing Express-only route modules (Hono fetch adapter). */ function trpcIndexFetchServer(): string { return `import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server' @@ -663,10 +657,10 @@ export async function applyBackendTransform( // 3. Patch server package.json await patchPackageJson(join(destinationDir, serverDir, 'package.json'), honoPackageJsonPatch()) - // 4. Rewrite tRPC package for fetch-based context (fullstack only) - const trpcSrcDir = join(destinationDir, 'packages', 'trpc', 'src') + // 4. Rewrite tRPC server module for fetch-based context (fullstack only) + const trpcModuleDir = join(destinationDir, serverDir, 'src/modules/trpc') try { - await stat(trpcSrcDir) + await stat(trpcModuleDir) await writeFile_( join(destinationDir, serverDir, 'src/modules/trpc/trpc.ts'), trpcContextFetch(), @@ -675,9 +669,8 @@ export async function applyBackendTransform( join(destinationDir, serverDir, 'src/modules/trpc/index.ts'), trpcIndexFetchServer(), ) - await writeFile_(join(destinationDir, 'packages/trpc/src/index.ts'), trpcIndexFetch()) } catch { - // tRPC package not present — standalone or polyglot without tRPC + // tRPC module not present — standalone or polyglot without tRPC } await patchFullstackHomepageCopy(destinationDir, config.backend) diff --git a/apps/cli/src/lib/generators/bundles.ts b/apps/cli/src/lib/generators/bundles.ts index 27de7e9..18e5019 100644 --- a/apps/cli/src/lib/generators/bundles.ts +++ b/apps/cli/src/lib/generators/bundles.ts @@ -67,7 +67,6 @@ This project was scaffolded with the **product** bundle (auth, database, API). - \`apps/web\` — Next.js frontend - \`apps/server\` — Express API + tRPC + Better Auth - \`packages/store\` — Database (Prisma/Drizzle) -- \`packages/trpc\` — API contract (re-exports server router) - \`packages/auth\` — Better Auth configuration ## Commands diff --git a/apps/cli/src/lib/scaffold.ts b/apps/cli/src/lib/scaffold.ts index a97879f..90824b1 100644 --- a/apps/cli/src/lib/scaffold.ts +++ b/apps/cli/src/lib/scaffold.ts @@ -575,7 +575,6 @@ async function pruneServiceApiFullstack(destinationDir: string): Promise { - removeWorkspacePackages(pkg.dependencies, ['auth', 'store', 'trpc', 'common', 'server']) + removeWorkspacePackages(pkg.dependencies, ['auth', 'store', 'common', 'server']) removeKeys(pkg.dependencies, [ '@arche-template/auth', '@arche-template/store', - '@arche-template/trpc', '@arche-template/common', '@arche-template/server', '@trpc/client', @@ -624,11 +622,10 @@ async function pruneServiceApiFullstack(destinationDir: string): Promise { const compilerOptions = tsconfig.compilerOptions as Record | undefined const paths = compilerOptions?.paths as Record | undefined - removeWorkspacePathAliases(paths, ['auth', 'store', 'trpc', 'common', 'server']) + removeWorkspacePathAliases(paths, ['auth', 'store', 'common', 'server']) removeKeys(paths, [ '@arche-template/store/*', '@arche-template/auth/*', - '@arche-template/trpc/*', '@arche-template/common/*', '@arche-template/server/*', ]) diff --git a/apps/cli/src/lib/web-core.ts b/apps/cli/src/lib/web-core.ts index f6747db..f957093 100644 --- a/apps/cli/src/lib/web-core.ts +++ b/apps/cli/src/lib/web-core.ts @@ -1,8 +1,11 @@ -import { readFileSync } from 'node:fs' +import { existsSync, readFileSync } from 'node:fs' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' -const WEB_CORE_DIR = join(dirname(fileURLToPath(import.meta.url)), '../templates/_web-core') +const __dir = dirname(fileURLToPath(import.meta.url)) +const WEB_CORE_DIR = existsSync(join(__dir, '../templates/_web-core')) + ? join(__dir, '../templates/_web-core') + : join(__dir, '../src/templates/_web-core') export interface WebCoreVersions { dependencies: Record diff --git a/apps/cli/src/templates/addons/live-demo/apps/web/components/live/live-room-context.tsx b/apps/cli/src/templates/addons/live-demo/apps/web/components/live/live-room-context.tsx index 6d2375d..e78e2ea 100644 --- a/apps/cli/src/templates/addons/live-demo/apps/web/components/live/live-room-context.tsx +++ b/apps/cli/src/templates/addons/live-demo/apps/web/components/live/live-room-context.tsx @@ -12,7 +12,7 @@ import { type RefObject, } from 'react' -import type { RouterOutputs } from '@arche-template/trpc' +import type { RouterOutputs } from '@arche-template/server/trpc' import { liveStreamUrl } from '@/lib/live-chat-sync' import { createLiveFeed, @@ -76,7 +76,9 @@ export function LiveRoomProvider({ children }: { children: React.ReactNode }) { }, [queryClient, trpc.chat.list, trpc.lattice.getState]) const handlersRef = useRef({ onEvent, onPollTick }) - handlersRef.current = { onEvent, onPollTick } + useEffect(() => { + handlersRef.current = { onEvent, onPollTick } + }, [onEvent, onPollTick]) useEffect(() => { const feed = createLiveFeed({ diff --git a/apps/cli/src/templates/fullstack/.archefiles.json b/apps/cli/src/templates/fullstack/.archefiles.json index 54d0d55..29e45e2 100644 --- a/apps/cli/src/templates/fullstack/.archefiles.json +++ b/apps/cli/src/templates/fullstack/.archefiles.json @@ -10,7 +10,6 @@ "packages/backend-common", "packages/common", "packages/store", - "packages/trpc", "toolings/typescript-config" ], "exclude": [".vercel", "logs"] diff --git a/apps/cli/src/templates/fullstack/apps/server/tsconfig.json b/apps/cli/src/templates/fullstack/apps/server/tsconfig.json index 914abf9..7370877 100644 --- a/apps/cli/src/templates/fullstack/apps/server/tsconfig.json +++ b/apps/cli/src/templates/fullstack/apps/server/tsconfig.json @@ -7,7 +7,6 @@ "@/*": ["./src/*"], "@arche-template/store/*": ["../../packages/store/src/*"], "@arche-template/auth/*": ["../../packages/auth/src/*"], - "@arche-template/trpc/*": ["../../packages/trpc/src/*"], "@arche-template/backend-common/*": ["../../packages/backend-common/src/*"], "@arche-template/common/*": ["../../packages/common/src/*"] } diff --git a/apps/cli/src/templates/fullstack/apps/web/package.json b/apps/cli/src/templates/fullstack/apps/web/package.json index ac3f6ca..0d17272 100644 --- a/apps/cli/src/templates/fullstack/apps/web/package.json +++ b/apps/cli/src/templates/fullstack/apps/web/package.json @@ -16,7 +16,6 @@ "@arche-template/common": "workspace:*", "@arche-template/server": "workspace:*", "@arche-template/store": "workspace:*", - "@arche-template/trpc": "workspace:*", "@tanstack/react-query": "^5.101.1", "@trpc/client": "^11.18.0", "@trpc/tanstack-react-query": "^11.18.0", diff --git a/apps/cli/src/templates/fullstack/apps/web/trpc/client.tsx b/apps/cli/src/templates/fullstack/apps/web/trpc/client.tsx index 8c7dcf9..1e3b4c4 100644 --- a/apps/cli/src/templates/fullstack/apps/web/trpc/client.tsx +++ b/apps/cli/src/templates/fullstack/apps/web/trpc/client.tsx @@ -1,5 +1,5 @@ 'use client' -import type { AppRouter } from '@arche-template/trpc' +import type { AppRouter } from '@arche-template/server/trpc' import type { QueryClient } from '@tanstack/react-query' import { QueryClientProvider } from '@tanstack/react-query' import { createTRPCClient, httpBatchLink, loggerLink } from '@trpc/client' diff --git a/apps/cli/src/templates/fullstack/apps/web/trpc/server.tsx b/apps/cli/src/templates/fullstack/apps/web/trpc/server.tsx index b5e54c0..438b104 100644 --- a/apps/cli/src/templates/fullstack/apps/web/trpc/server.tsx +++ b/apps/cli/src/templates/fullstack/apps/web/trpc/server.tsx @@ -1,5 +1,5 @@ import 'server-only' -import type { AppRouter } from '@arche-template/trpc' +import type { AppRouter } from '@arche-template/server/trpc' import { dehydrate, HydrationBoundary } from '@tanstack/react-query' import { createTRPCClient, httpLink } from '@trpc/client' import { createTRPCOptionsProxy, TRPCQueryOptions } from '@trpc/tanstack-react-query' diff --git a/apps/cli/src/templates/fullstack/apps/worker/tsconfig.json b/apps/cli/src/templates/fullstack/apps/worker/tsconfig.json index 7b9b1e6..a8d0640 100644 --- a/apps/cli/src/templates/fullstack/apps/worker/tsconfig.json +++ b/apps/cli/src/templates/fullstack/apps/worker/tsconfig.json @@ -7,9 +7,8 @@ "@/*": ["src/*"], "@arche-template/store/*": ["../../packages/store/src/*"], "@arche-template/auth/*": ["../../packages/auth/src/*"], - "@arche-template/trpc/*": ["../../packages/trpc/src/*"], - "@arche-template/backend-common/*": ["../../packages/trpc/backend-common/src/*"], - "@arche-template/common/*": ["../../packages/trpc/common/src/*"] + "@arche-template/backend-common/*": ["../../packages/backend-common/src/*"], + "@arche-template/common/*": ["../../packages/common/src/*"] }, "outDir": "dist" } diff --git a/apps/cli/src/templates/fullstack/packages/trpc/.gitignore b/apps/cli/src/templates/fullstack/packages/trpc/.gitignore deleted file mode 100644 index a14702c..0000000 --- a/apps/cli/src/templates/fullstack/packages/trpc/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -# dependencies (bun install) -node_modules - -# output -out -dist -*.tgz - -# code coverage -coverage -*.lcov - -# logs -logs -_.log -report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# caches -.eslintcache -.cache -*.tsbuildinfo - -# IntelliJ based IDEs -.idea - -# Finder (MacOS) folder config -.DS_Store diff --git a/apps/cli/src/templates/fullstack/packages/trpc/AGENTS.md b/apps/cli/src/templates/fullstack/packages/trpc/AGENTS.md deleted file mode 100644 index 9901377..0000000 --- a/apps/cli/src/templates/fullstack/packages/trpc/AGENTS.md +++ /dev/null @@ -1,26 +0,0 @@ -# tRPC Package Notes - -## Purpose - -`@arche-template/trpc` is the **client-facing API contract** for web and workers. - -Implementation lives in `apps/server/src/modules` (module-first). This package re-exports types and callers only. - -## Read First - -- `src/index.ts` — re-exports from `@arche-template/server/trpc` -- `apps/server/src/modules/trpc/app.router.ts` — router composition -- `apps/server/src/modules/trpc/trpc.ts` — context and procedures - -## Boundary - -| Layer | Location | -| --------------- | ---------------------------------------------------- | -| Business logic | `apps/server/src/modules//*.service.ts` | -| tRPC procedures | `apps/server/src/modules//*.trpc.ts` | -| App router | `apps/server/src/modules/trpc/app.router.ts` | -| Web imports | `@arche-template/trpc` (`AppRouter`, `createCaller`) | - -## Update When - -Exported types, router composition, or re-export paths change. diff --git a/apps/cli/src/templates/fullstack/packages/trpc/README.md b/apps/cli/src/templates/fullstack/packages/trpc/README.md deleted file mode 100644 index 15724e6..0000000 --- a/apps/cli/src/templates/fullstack/packages/trpc/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# tRPC Package - -Client-facing API contract for web and workers. - -- Start with [AGENTS.md](./AGENTS.md). -- Implementation: `apps/server/src/modules//*.trpc.ts` -- Composition: `apps/server/src/modules/trpc/app.router.ts` -- This package re-exports `AppRouter`, `createCaller`, and middleware from `@arche-template/server/trpc`. diff --git a/apps/cli/src/templates/fullstack/packages/trpc/package.json b/apps/cli/src/templates/fullstack/packages/trpc/package.json deleted file mode 100644 index ed252fb..0000000 --- a/apps/cli/src/templates/fullstack/packages/trpc/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "@arche-template/trpc", - "private": true, - "type": "module", - "module": "src/index.ts", - "exports": { - ".": { - "types": "./src/index.ts", - "import": "./src/index.ts" - } - }, - "scripts": { - "lint": "oxlint -c ../../.oxlintrc.json", - "lint:fix": "oxlint --fix", - "check-types": "tsc --noEmit" - }, - "dependencies": { - "@arche-template/server": "workspace:*" - }, - "devDependencies": { - "@arche-template/typescript-config": "workspace:*", - "@types/bun": "1.3.14" - }, - "peerDependencies": { - "typescript": "^6.0.3" - } -} diff --git a/apps/cli/src/templates/fullstack/packages/trpc/src/index.ts b/apps/cli/src/templates/fullstack/packages/trpc/src/index.ts deleted file mode 100644 index 7e38e05..0000000 --- a/apps/cli/src/templates/fullstack/packages/trpc/src/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @arche-template/trpc — client-facing API contract - * - * Implementation lives in apps/server/src/modules (module-first architecture). - * Server callers: import from `@arche-template/server/trpc`. - */ - -export type { AppRouter, RouterInputs, RouterOutputs } from '@arche-template/server/trpc' -export { - appRouter, - createCaller, - createTRPCContext, - createCallerFactory, - expressMiddleWare, -} from '@arche-template/server/trpc' diff --git a/apps/cli/src/templates/fullstack/packages/trpc/tsconfig.json b/apps/cli/src/templates/fullstack/packages/trpc/tsconfig.json deleted file mode 100644 index 12e9cb6..0000000 --- a/apps/cli/src/templates/fullstack/packages/trpc/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "@arche-template/typescript-config/backend.json", - "compilerOptions": { - "ignoreDeprecations": "6.0", - "types": ["bun"], - "baseUrl": ".", - "paths": { - "@/*": ["../../apps/server/src/*"], - "@arche-template/server/trpc": ["../../apps/server/src/modules/trpc/index.ts"], - "@arche-template/store/*": ["../store/src/*"], - "@arche-template/auth/*": ["../auth/src/*"], - "@arche-template/backend-common/*": ["../backend-common/src/*"] - } - }, - "exclude": ["node_modules"] -} diff --git a/apps/cli/tests/backend.test.ts b/apps/cli/tests/backend.test.ts index 56390c6..61586d8 100644 --- a/apps/cli/tests/backend.test.ts +++ b/apps/cli/tests/backend.test.ts @@ -56,7 +56,6 @@ describe('applyBackendTransform', () => { await mkdir(join(tempDir, 'apps/server/src/modules/auth'), { recursive: true }) await mkdir(join(tempDir, 'apps/server/src/modules/health'), { recursive: true }) await mkdir(join(tempDir, 'apps/server/src/modules/root'), { recursive: true }) - await mkdir(join(tempDir, 'packages/trpc/src'), { recursive: true }) // Mock Express app.ts await writeFile( @@ -96,12 +95,6 @@ describe('applyBackendTransform', () => { join(tempDir, 'apps/server/src/modules/trpc/trpc.ts'), 'import { createExpressMiddleware } from "@trpc/server/adapters/express"\n', ) - // Mock tRPC index.ts - await writeFile( - join(tempDir, 'packages/trpc/src/index.ts'), - 'export { expressMiddleWare } from "./middleware"\n', - ) - // Mock Express-only artifacts removed by hono-bun transform await writeFile( join(tempDir, 'apps/server/src/vercel-handler.ts'), 'import express from "express"\n', @@ -212,15 +205,6 @@ describe('applyBackendTransform', () => { expect(trpcTs).not.toContain('CreateExpressContextOptions') }) - it('rewrites tRPC index.ts to client contract types only', async () => { - await applyBackendTransform(tempDir, makeConfig({ backend: 'hono-bun' })) - const indexTs = await readFile(join(tempDir, 'packages/trpc/src/index.ts'), 'utf8') - expect(indexTs).toContain('AppRouter') - expect(indexTs).toContain('RouterInputs') - expect(indexTs).not.toContain('expressMiddleWare') - expect(indexTs).not.toContain('createCaller') - }) - it('app.ts mounts auth, trpc, health, and 404 routes', async () => { await applyBackendTransform(tempDir, makeConfig({ backend: 'hono-bun' })) const content = await readFile(join(tempDir, 'apps/server/src/app.ts'), 'utf8') diff --git a/apps/server/env.ts b/apps/server/env.ts deleted file mode 100644 index 97e38a9..0000000 --- a/apps/server/env.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Backend app environment (Express). - * Extends shared server env with any server-specific variables. - * - * Usage in routes: - * import { serverEnv } from '@arche-template/backend-common/env' - * const dbUrl = serverEnv.DATABASE_URL - */ - -import { serverEnv as baseEnv } from '@arche-template/backend-common/env' -import { createEnv } from '@t3-oss/env-core' -export const serverEnv = createEnv({ - extends: [baseEnv], - server: { - // Add server-specific variables here - // Example: LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'), - }, - clientPrefix: undefined, - client: {}, - runtimeEnv: process.env, - emptyStringAsUndefined: true, - skipValidation: !!process.env.CI || !!process.env.VERCEL, -}) - -export type ServerEnv = typeof serverEnv diff --git a/apps/server/package.json b/apps/server/package.json index 3720a94..d1abf89 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -9,6 +9,7 @@ "./trpc": "./src/modules/trpc/index.ts" }, "scripts": { + "test": "bun test", "check-types": "tsc --noEmit", "build": "bun build ./src/server.ts --outdir ./dist --target bun --minify --sourcemap", "build:vercel": "bun build ./src/vercel-handler.ts --outdir ./dist --target bun --minify --sourcemap", diff --git a/apps/server/src/modules/trpc/index.ts b/apps/server/src/modules/trpc/index.ts index 9ae98aa..fef2605 100644 --- a/apps/server/src/modules/trpc/index.ts +++ b/apps/server/src/modules/trpc/index.ts @@ -1,12 +1,14 @@ import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server' import { appRouter } from './app.router' import { createCallerFactory, createTRPCContext } from './trpc' -import { expressMiddleWare } from './trpc.routes' export type RouterInputs = inferRouterInputs export type RouterOutputs = inferRouterOutputs export const createCaller = createCallerFactory(appRouter) -export { appRouter, createTRPCContext, createCallerFactory, expressMiddleWare } +export { appRouter, createTRPCContext, createCallerFactory } export type { AppRouter } from './app.router' + +// Express-specific: import directly from './trpc.routes' in server code +export { expressMiddleWare } from './trpc.routes' diff --git a/apps/server/src/modules/trpc/trpc.routes.ts b/apps/server/src/modules/trpc/trpc.routes.ts index 1a92fa2..d7668a8 100644 --- a/apps/server/src/modules/trpc/trpc.routes.ts +++ b/apps/server/src/modules/trpc/trpc.routes.ts @@ -1,11 +1,11 @@ import { createExpressMiddleware } from '@trpc/server/adapters/express' -import { Router } from 'express' +import { type Router as ExpressRouter, Router } from 'express' import { env } from '../../common/env' import { logger } from '../../common/logger' import { appRouter } from './app.router' import { createTRPCContext } from './trpc' -export const trpcRoutes = Router() +export const trpcRoutes: ExpressRouter = Router() const expressMiddleWare = createExpressMiddleware({ router: appRouter, diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json index 914abf9..7370877 100644 --- a/apps/server/tsconfig.json +++ b/apps/server/tsconfig.json @@ -7,7 +7,6 @@ "@/*": ["./src/*"], "@arche-template/store/*": ["../../packages/store/src/*"], "@arche-template/auth/*": ["../../packages/auth/src/*"], - "@arche-template/trpc/*": ["../../packages/trpc/src/*"], "@arche-template/backend-common/*": ["../../packages/backend-common/src/*"], "@arche-template/common/*": ["../../packages/common/src/*"] } diff --git a/apps/web/components/live/live-room-context.tsx b/apps/web/components/live/live-room-context.tsx index 6d2375d..e78e2ea 100644 --- a/apps/web/components/live/live-room-context.tsx +++ b/apps/web/components/live/live-room-context.tsx @@ -12,7 +12,7 @@ import { type RefObject, } from 'react' -import type { RouterOutputs } from '@arche-template/trpc' +import type { RouterOutputs } from '@arche-template/server/trpc' import { liveStreamUrl } from '@/lib/live-chat-sync' import { createLiveFeed, @@ -76,7 +76,9 @@ export function LiveRoomProvider({ children }: { children: React.ReactNode }) { }, [queryClient, trpc.chat.list, trpc.lattice.getState]) const handlersRef = useRef({ onEvent, onPollTick }) - handlersRef.current = { onEvent, onPollTick } + useEffect(() => { + handlersRef.current = { onEvent, onPollTick } + }, [onEvent, onPollTick]) useEffect(() => { const feed = createLiveFeed({ diff --git a/apps/web/env.ts b/apps/web/env.ts index d8deac2..971b36f 100644 --- a/apps/web/env.ts +++ b/apps/web/env.ts @@ -47,19 +47,20 @@ export const env = createEnv({ NEXT_PUBLIC_SITE_NAME: z.string().default('Arche'), NEXT_PUBLIC_SITE_URL: z.string().url().default('http://localhost:3000'), NEXT_PUBLIC_SITE_DESCRIPTION: z.string().default(defaultSiteDescription), - NEXT_PUBLIC_APP_URL: z.string().url(), - NEXT_PUBLIC_API_URL: z.string().url(), + NEXT_PUBLIC_APP_URL: z.string().url().default('http://localhost:3000'), + NEXT_PUBLIC_API_URL: z.string().url().default('http://localhost:8080'), }, experimental__runtimeEnv: { NEXT_PUBLIC_SITE_NAME: publicSiteName, NEXT_PUBLIC_SITE_URL: publicSiteUrl, NEXT_PUBLIC_SITE_DESCRIPTION: publicSiteDescription, - NEXT_PUBLIC_APP_URL: publicAppUrl, - NEXT_PUBLIC_API_URL: sanitizePublicEnv(process.env.NEXT_PUBLIC_API_URL), + NEXT_PUBLIC_APP_URL: publicAppUrl ?? 'http://localhost:3000', + NEXT_PUBLIC_API_URL: + sanitizePublicEnv(process.env.NEXT_PUBLIC_API_URL) ?? 'http://localhost:8080', }, emptyStringAsUndefined: true, // CI/Vercel set CI=1; runtime fallbacks above must stay in sync with Zod defaults. - skipValidation: !!process.env.CI, + skipValidation: !!process.env.CI || !!process.env.VERCEL, }) export type Env = typeof env diff --git a/apps/web/package.json b/apps/web/package.json index 348530b..5901b88 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -4,6 +4,7 @@ "private": true, "type": "module", "scripts": { + "test": "bun test", "dev": "next dev --turbopack --port 3000", "build": "next build", "start": "next start", @@ -18,8 +19,8 @@ "@arche-template/auth": "workspace:*", "@arche-template/common": "workspace:*", "@arche-template/registry": "workspace:*", + "@arche-template/server": "workspace:*", "@arche-template/store": "workspace:*", - "@arche-template/trpc": "workspace:*", "@arche-template/ui": "workspace:*", "@t3-oss/env-nextjs": "catalog:", "@tanstack/react-query": "catalog:", @@ -43,6 +44,7 @@ "devDependencies": { "@arche-template/typescript-config": "workspace:*", "@tailwindcss/postcss": "catalog:", + "@types/express": "catalog:", "@types/mdx": "catalog:", "@types/node": "catalog:", "@types/react": "catalog:", diff --git a/apps/web/trpc/client.tsx b/apps/web/trpc/client.tsx index 9e7fe3b..c3b965e 100644 --- a/apps/web/trpc/client.tsx +++ b/apps/web/trpc/client.tsx @@ -1,5 +1,5 @@ 'use client' -import type { AppRouter } from '@arche-template/trpc' +import type { AppRouter } from '@arche-template/server/trpc' import type { QueryClient } from '@tanstack/react-query' import { QueryClientProvider } from '@tanstack/react-query' import { createTRPCClient, httpBatchLink, loggerLink } from '@trpc/client' diff --git a/apps/web/trpc/http-server.tsx b/apps/web/trpc/http-server.tsx index fb463f9..6c026f0 100644 --- a/apps/web/trpc/http-server.tsx +++ b/apps/web/trpc/http-server.tsx @@ -1,6 +1,6 @@ import 'server-only' -import type { AppRouter } from '@arche-template/trpc' +import type { AppRouter } from '@arche-template/server/trpc' import { dehydrate, HydrationBoundary } from '@tanstack/react-query' import { createTRPCClient, httpLink } from '@trpc/client' import { createTRPCOptionsProxy, TRPCQueryOptions } from '@trpc/tanstack-react-query' diff --git a/apps/web/trpc/server.tsx b/apps/web/trpc/server.tsx index 705be0a..e9e06e9 100644 --- a/apps/web/trpc/server.tsx +++ b/apps/web/trpc/server.tsx @@ -1,7 +1,7 @@ import 'server-only' // <-- ensure this file cannot be imported from the client import { auth } from '@arche-template/auth/server' +import { createCaller } from '@arche-template/server/trpc' import { prisma as db } from '@arche-template/store' -import { createCaller } from '@arche-template/trpc' import { headers } from 'next/headers' import { cache } from 'react' diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index b92f424..c95dc38 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -8,7 +8,7 @@ "@arche-template/ui/*": ["../../packages/ui/src/*"], "@arche-template/store/*": ["../../packages/store/src/*"], "@arche-template/auth/*": ["../../packages/auth/src/*"], - "@arche-template/trpc/*": ["../../packages/trpc/src/*"], + "@arche-template/server/trpc": ["../server/src/modules/trpc/index.ts"], "@arche-template/common/*": ["../../packages/common/src/*"] }, "plugins": [ diff --git a/apps/worker/tsconfig.json b/apps/worker/tsconfig.json index 7b9b1e6..67b0219 100644 --- a/apps/worker/tsconfig.json +++ b/apps/worker/tsconfig.json @@ -7,7 +7,6 @@ "@/*": ["src/*"], "@arche-template/store/*": ["../../packages/store/src/*"], "@arche-template/auth/*": ["../../packages/auth/src/*"], - "@arche-template/trpc/*": ["../../packages/trpc/src/*"], "@arche-template/backend-common/*": ["../../packages/trpc/backend-common/src/*"], "@arche-template/common/*": ["../../packages/trpc/common/src/*"] }, diff --git a/bun.lock b/bun.lock index 8a43264..123587a 100644 --- a/bun.lock +++ b/bun.lock @@ -22,16 +22,16 @@ "create-arche": "dist/index.js", }, "dependencies": { - "@arche-template/registry": "workspace:*", "@clack/prompts": "^1.4.0", "picocolors": "^1.1.1", - "zod": "catalog:", }, "devDependencies": { + "@arche-template/registry": "workspace:*", "@arche-template/typescript-config": "workspace:*", "@types/node": "catalog:", "oxlint": "catalog:", "typescript": "catalog:", + "zod": "catalog:", }, }, "apps/server": { @@ -71,8 +71,8 @@ "@arche-template/auth": "workspace:*", "@arche-template/common": "workspace:*", "@arche-template/registry": "workspace:*", + "@arche-template/server": "workspace:*", "@arche-template/store": "workspace:*", - "@arche-template/trpc": "workspace:*", "@arche-template/ui": "workspace:*", "@t3-oss/env-nextjs": "catalog:", "@tanstack/react-query": "catalog:", @@ -96,6 +96,7 @@ "devDependencies": { "@arche-template/typescript-config": "workspace:*", "@tailwindcss/postcss": "catalog:", + "@types/express": "catalog:", "@types/mdx": "catalog:", "@types/node": "catalog:", "@types/react": "catalog:", @@ -206,20 +207,6 @@ "typescript": "catalog:", }, }, - "packages/trpc": { - "name": "@arche-template/trpc", - "dependencies": { - "@arche-template/server": "workspace:*", - }, - "devDependencies": { - "@arche-template/typescript-config": "workspace:*", - "@types/bun": "catalog:", - "oxlint": "catalog:", - }, - "peerDependencies": { - "typescript": "catalog:", - }, - }, "packages/ui": { "name": "@arche-template/ui", "version": "0.0.0", @@ -248,6 +235,20 @@ "typescript": "catalog:", }, }, + "tests": { + "name": "@arche-template/tests", + "dependencies": { + "@arche-template/auth": "workspace:*", + "@arche-template/server": "workspace:*", + "@arche-template/store": "workspace:*", + }, + "devDependencies": { + "@types/bun": "catalog:", + }, + "peerDependencies": { + "typescript": "catalog:", + }, + }, "toolings/dev": { "name": "@arche-template/dev", "devDependencies": { @@ -358,9 +359,9 @@ "@arche-template/store": ["@arche-template/store@workspace:packages/store"], - "@arche-template/tooling-scripts": ["@arche-template/tooling-scripts@workspace:toolings/scripts"], + "@arche-template/tests": ["@arche-template/tests@workspace:tests"], - "@arche-template/trpc": ["@arche-template/trpc@workspace:packages/trpc"], + "@arche-template/tooling-scripts": ["@arche-template/tooling-scripts@workspace:toolings/scripts"], "@arche-template/typescript-config": ["@arche-template/typescript-config@workspace:toolings/typescript-config"], diff --git a/docs/README.md b/docs/README.md index 0bdfb26..b6e3dc6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -47,7 +47,6 @@ current implementation sources. - `apps/worker` - optional worker template source. - `packages/auth` - Better Auth template package. - `packages/store` - Prisma/store template package. -- `packages/trpc` - client contract template package. - `packages/backend-common` - env, logging, Redis helpers. - `packages/ui` - shared UI components. - `toolings/*` - shared config and repo scripts. diff --git a/docs/architecture.md b/docs/architecture.md index 863ae40..479425c 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -17,7 +17,7 @@ Runtime flow across workspaces. For variant families (next, backend, rust), see - `apps/web` → `@arche-template/auth`, `@arche-template/common`, `@arche-template/store`, `@arche-template/trpc`, `@arche-template/ui` - `apps/server` → `@arche-template/auth`, `@arche-template/backend-common`, `@arche-template/store`; implements tRPC - `apps/worker` → `@arche-template/backend-common`, `@arche-template/store` (jobs; needs `REDIS_URL`) -- `packages/trpc` → re-exports server router types and `createCaller` only +- `apps/server/src/modules/trpc` → exports router types and `createCaller` directly to web/worker - `packages/backend-common` → `serverEnv`, application Redis (`redis`), BullMQ connections (`ioredis`), logging, `validate-env` ## Config diff --git a/docs/implementation-summary.md b/docs/implementation-summary.md index 197761e..ebacaab 100644 --- a/docs/implementation-summary.md +++ b/docs/implementation-summary.md @@ -16,7 +16,7 @@ This is a **decision tree** for navigating production documentation. Use this to ### Building Features -- Adding a new API endpoint? → `packages/trpc/README.md` + `backend-only.md` (API section) +- Adding a new API endpoint? → `apps/server/src/modules/trpc` + `backend-only.md` (API section) - Building UI components? → `packages/ui/AGENTS.md` + `frontend-design` skill - Working with authentication? → `packages/auth/README.md` - Setting up background jobs? → `apps/worker/README.md` or `backend-only.md` (Job Processing section) diff --git a/package.json b/package.json index 47bbe10..42819ae 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "apps/*", "packages/*", "toolings/*", - "tests/*" + "tests" ], "catalog": { "@bull-board/api": "^7.1.5", @@ -84,12 +84,12 @@ "deps:audit": "bun toolings/scripts/audit-dependencies.ts", "deps:unused": "bun toolings/scripts/audit-unused-dependencies.ts", "template-deps:check": "bun toolings/scripts/audit-template-deps.ts", - "ci": "bun run format:check && bunx turbo run lint check-types && bun test && bunx turbo run build && bun run pkg:check && bun run repo:doctor:strict", - "ci:affected": "bun run format:check && bunx turbo run lint check-types --affected && bun test && bunx turbo run build --affected && bun run pkg:check && bun run repo:doctor:strict", - "ci:min": "bun run format:check && bunx turbo run lint check-types && bun test && bunx turbo run build", + "ci": "bun run format:check && turbo run lint check-types test build && bun run pkg:check && bun run repo:doctor:strict", + "ci:affected": "bun run format:check && turbo run lint check-types test build --affected && bun run pkg:check && bun run repo:doctor:strict", + "ci:min": "bun run format:check && turbo run lint check-types test build", "ci:full": "bun run ci && bun toolings/scripts/verify-generated-project.ts --combo-matrix --run=install,typecheck,lint,build", - "check:cli": "bun run format:check && bunx turbo run lint check-types --filter=@kitsunekode/arche && bun test apps/cli/tests", - "check:web": "bun run format:check && bunx turbo run lint check-types --filter=@arche-template/web && bun test apps/web", + "check:cli": "bun run format:check && turbo run lint check-types test --filter=@kitsunekode/arche", + "check:web": "bun run format:check && turbo run lint check-types test --filter=@arche-template/web", "secret-scan": "gitleaks detect --source . --redact=100 --config .gitleaks.toml", "secret-scan:staged": "gitleaks protect --staged --redact --config .gitleaks.toml", "dev": "turbo run dev", diff --git a/packages/auth/package.json b/packages/auth/package.json index b3dc633..afc067f 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -9,6 +9,7 @@ "./guest-display-name": "./src/guest-display-name.ts" }, "scripts": { + "test": "bun test", "lint": "oxlint", "lint:fix": "oxlint --fix", "check-types": "tsc --noEmit" diff --git a/packages/backend-common/src/index.ts b/packages/backend-common/src/index.ts index a73cb68..f1323e0 100644 --- a/packages/backend-common/src/index.ts +++ b/packages/backend-common/src/index.ts @@ -1,9 +1,12 @@ -// Barrel export for @arche-template/backend-common main entry. -// Most consumers should use subpath exports: -// @arche-template/backend-common/config -// @arche-template/backend-common/logger -// @arche-template/backend-common/redis -// -// This file is intentionally minimal — see subpath exports in package.json. +/** + * @arche-template/backend-common + * + * Shared backend toolkit for server, worker, and CLI. + * Prefer subpath imports for tree-shaking: + * + * import { serverEnv } from '@arche-template/backend-common/env' + * import { logger } from '@arche-template/backend-common/logger' + * import { redis } from '@arche-template/backend-common/redis' + */ -export {} +export { serverEnv } from './env' diff --git a/packages/common/src/env/client.ts b/packages/common/src/env/client.ts index f454d03..cfc08e3 100644 --- a/packages/common/src/env/client.ts +++ b/packages/common/src/env/client.ts @@ -17,16 +17,17 @@ function vercelWebOrigin(): string | undefined { export const clientEnv = createEnv({ server: {}, client: { - NEXT_PUBLIC_APP_URL: z.string().url(), - NEXT_PUBLIC_API_URL: z.string().url(), + NEXT_PUBLIC_APP_URL: z.string().url().default('http://localhost:3000'), + NEXT_PUBLIC_API_URL: z.string().url().default('http://localhost:8080'), }, clientPrefix: 'NEXT_PUBLIC_', runtimeEnvStrict: { - NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL ?? vercelWebOrigin(), - NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL, + NEXT_PUBLIC_APP_URL: + process.env.NEXT_PUBLIC_APP_URL ?? vercelWebOrigin() ?? 'http://localhost:3000', + NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:8080', }, emptyStringAsUndefined: true, - skipValidation: !!process.env.CI, + skipValidation: !!process.env.CI || !!process.env.VERCEL, }) export type ClientEnv = typeof clientEnv diff --git a/packages/store/src/index.ts b/packages/store/src/index.ts index d3a5127..0a56ff6 100644 --- a/packages/store/src/index.ts +++ b/packages/store/src/index.ts @@ -1,6 +1,12 @@ import { PrismaPg } from '@prisma/adapter-pg' import { PrismaClient } from './generated/client' +if (process.env.NODE_ENV === 'production' && !process.env.DATABASE_URL) { + throw new Error( + 'DATABASE_URL is required in production. Set it in your .env file or environment variables.', + ) +} + const connectionString = process.env.DATABASE_URL ?? 'postgresql://postgres:postgres@localhost:5432/template' const adapter = new PrismaPg({ connectionString }) diff --git a/packages/trpc/.gitignore b/packages/trpc/.gitignore deleted file mode 100644 index a14702c..0000000 --- a/packages/trpc/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -# dependencies (bun install) -node_modules - -# output -out -dist -*.tgz - -# code coverage -coverage -*.lcov - -# logs -logs -_.log -report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# caches -.eslintcache -.cache -*.tsbuildinfo - -# IntelliJ based IDEs -.idea - -# Finder (MacOS) folder config -.DS_Store diff --git a/packages/trpc/AGENTS.md b/packages/trpc/AGENTS.md deleted file mode 100644 index 9901377..0000000 --- a/packages/trpc/AGENTS.md +++ /dev/null @@ -1,26 +0,0 @@ -# tRPC Package Notes - -## Purpose - -`@arche-template/trpc` is the **client-facing API contract** for web and workers. - -Implementation lives in `apps/server/src/modules` (module-first). This package re-exports types and callers only. - -## Read First - -- `src/index.ts` — re-exports from `@arche-template/server/trpc` -- `apps/server/src/modules/trpc/app.router.ts` — router composition -- `apps/server/src/modules/trpc/trpc.ts` — context and procedures - -## Boundary - -| Layer | Location | -| --------------- | ---------------------------------------------------- | -| Business logic | `apps/server/src/modules//*.service.ts` | -| tRPC procedures | `apps/server/src/modules//*.trpc.ts` | -| App router | `apps/server/src/modules/trpc/app.router.ts` | -| Web imports | `@arche-template/trpc` (`AppRouter`, `createCaller`) | - -## Update When - -Exported types, router composition, or re-export paths change. diff --git a/packages/trpc/README.md b/packages/trpc/README.md deleted file mode 100644 index 15724e6..0000000 --- a/packages/trpc/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# tRPC Package - -Client-facing API contract for web and workers. - -- Start with [AGENTS.md](./AGENTS.md). -- Implementation: `apps/server/src/modules//*.trpc.ts` -- Composition: `apps/server/src/modules/trpc/app.router.ts` -- This package re-exports `AppRouter`, `createCaller`, and middleware from `@arche-template/server/trpc`. diff --git a/packages/trpc/package.json b/packages/trpc/package.json deleted file mode 100644 index 79885b0..0000000 --- a/packages/trpc/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "@arche-template/trpc", - "private": true, - "type": "module", - "module": "src/index.ts", - "exports": { - ".": { - "types": "./src/index.ts", - "import": "./src/index.ts" - } - }, - "scripts": { - "lint": "oxlint", - "lint:fix": "oxlint --fix", - "check-types": "tsc --noEmit" - }, - "dependencies": { - "@arche-template/server": "workspace:*" - }, - "devDependencies": { - "@arche-template/typescript-config": "workspace:*", - "@types/bun": "catalog:", - "oxlint": "catalog:" - }, - "peerDependencies": { - "typescript": "catalog:" - } -} diff --git a/packages/trpc/src/index.ts b/packages/trpc/src/index.ts deleted file mode 100644 index 21ee4a6..0000000 --- a/packages/trpc/src/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @arche-template/trpc — client-facing API contract - * - * Implementation lives in apps/server/src/modules (module-first architecture). - * This package re-exports types and server callers for web/worker consumers. - * - * Boundary: - * - HTTP mounts, REST routes: apps/server/src/modules/* - * - tRPC procedures: apps/server/src/modules//*.trpc.ts - * - App router composition: apps/server/src/modules/trpc/app.router.ts - */ - -export type { AppRouter, RouterInputs, RouterOutputs } from '@arche-template/server/trpc' -export { - appRouter, - createCaller, - createTRPCContext, - createCallerFactory, - expressMiddleWare, -} from '@arche-template/server/trpc' diff --git a/packages/trpc/tsconfig.json b/packages/trpc/tsconfig.json deleted file mode 100644 index 12e9cb6..0000000 --- a/packages/trpc/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "@arche-template/typescript-config/backend.json", - "compilerOptions": { - "ignoreDeprecations": "6.0", - "types": ["bun"], - "baseUrl": ".", - "paths": { - "@/*": ["../../apps/server/src/*"], - "@arche-template/server/trpc": ["../../apps/server/src/modules/trpc/index.ts"], - "@arche-template/store/*": ["../store/src/*"], - "@arche-template/auth/*": ["../auth/src/*"], - "@arche-template/backend-common/*": ["../backend-common/src/*"] - } - }, - "exclude": ["node_modules"] -} diff --git a/tests/package.json b/tests/package.json index c25c34f..d77741d 100644 --- a/tests/package.json +++ b/tests/package.json @@ -13,8 +13,7 @@ "dependencies": { "@arche-template/auth": "workspace:*", "@arche-template/server": "workspace:*", - "@arche-template/store": "workspace:*", - "@arche-template/trpc": "workspace:*" + "@arche-template/store": "workspace:*" }, "devDependencies": { "@types/bun": "catalog:" diff --git a/tests/src/cli/create-kitsu-stack.test.ts b/tests/src/cli/create-kitsu-stack.test.ts index 5c700ed..d98ff4f 100644 --- a/tests/src/cli/create-kitsu-stack.test.ts +++ b/tests/src/cli/create-kitsu-stack.test.ts @@ -121,7 +121,7 @@ describe('family-aware agent docs', () => { it('includes fullstack key dirs for fullstack family', () => { const agents = buildRootAgentsMd(baseConfig()) expect(agents).toContain('apps/web') - expect(agents).toContain('packages/trpc') + expect(agents).toContain('apps/server') expect(agents).toContain('packages/store') }) @@ -129,7 +129,7 @@ describe('family-aware agent docs', () => { const agents = buildRootAgentsMd(baseConfig({ family: 'next' })) expect(agents).toContain('components') expect(agents).not.toContain('apps/web') - expect(agents).not.toContain('packages/trpc') + expect(agents).not.toContain('apps/server') }) }) @@ -194,7 +194,6 @@ describe('scaffold smoke tests', () => { expect(existsSync(join(tsTurboDir, 'package.json'))).toBe(true) expect(existsSync(join(tsTurboDir, 'apps/server'))).toBe(true) expect(existsSync(join(tsTurboDir, 'apps/web'))).toBe(true) - expect(existsSync(join(tsTurboDir, 'packages/trpc'))).toBe(true) expect(existsSync(join(tsTurboDir, 'docker-compose.yml'))).toBe(true) expect(existsSync(join(tsTurboDir, 'SHOWCASE.mdx'))).toBe(true) }) diff --git a/tests/src/integration/post-crud.test.ts b/tests/src/integration/post-crud.test.ts index 4ecd3f6..70b0fc6 100644 --- a/tests/src/integration/post-crud.test.ts +++ b/tests/src/integration/post-crud.test.ts @@ -5,8 +5,8 @@ import { join } from 'node:path' const rootDir = join(import.meta.dir, '../../..') describe('post CRUD integration', () => { - it('has tRPC package with index entry', () => { - expect(existsSync(join(rootDir, 'packages/trpc/src/index.ts'))).toBe(true) + it('has tRPC module with index entry', () => { + expect(existsSync(join(rootDir, 'apps/server/src/modules/trpc/index.ts'))).toBe(true) }) it('has store package with index entry', () => { @@ -14,7 +14,7 @@ describe('post CRUD integration', () => { }) it('tRPC index exports appRouter', async () => { - const content = await Bun.file(join(rootDir, 'packages/trpc/src/index.ts')).text() + const content = await Bun.file(join(rootDir, 'apps/server/src/modules/trpc/index.ts')).text() expect(content).toMatch(/appRouter|createCaller/) }) diff --git a/tests/src/toolings/server-turbo-cache.test.ts b/tests/src/toolings/server-turbo-cache.test.ts index 70ed4b8..84af022 100644 --- a/tests/src/toolings/server-turbo-cache.test.ts +++ b/tests/src/toolings/server-turbo-cache.test.ts @@ -1,5 +1,8 @@ import { describe, expect, it } from 'bun:test' import { readFileSync } from 'node:fs' +import { join } from 'node:path' + +const repoRoot = join(import.meta.dir, '../../..') type ServerTurboTask = { inputs?: string[] @@ -11,7 +14,9 @@ type ServerTurboConfig = { describe('server Turbo cache configuration', () => { it('invalidates server bundles when JIT workspace package source changes', () => { - const config = JSON.parse(readFileSync('apps/server/turbo.json', 'utf8')) as ServerTurboConfig + const config = JSON.parse( + readFileSync(join(repoRoot, 'apps/server/turbo.json'), 'utf8'), + ) as ServerTurboConfig const buildInputs = config.tasks.build?.inputs ?? [] const vercelInputs = config.tasks['build:vercel']?.inputs ?? [] diff --git a/tests/src/toolings/sync-template-agents.test.ts b/tests/src/toolings/sync-template-agents.test.ts index 0140435..6b48613 100644 --- a/tests/src/toolings/sync-template-agents.test.ts +++ b/tests/src/toolings/sync-template-agents.test.ts @@ -8,7 +8,7 @@ import { } from '../../../toolings/scripts/sync-template-agents' describe('sync-template-agents', () => { - it('finds the eight fullstack template pairs in the real repo', async () => { + it('finds the seven fullstack template pairs in the real repo', async () => { const pairs = await collectTemplateAgentsPairs() const relatives = pairs.map((p) => p.relative).sort() expect(relatives).toEqual([ @@ -18,7 +18,6 @@ describe('sync-template-agents', () => { 'packages/backend-common/AGENTS.md', 'packages/common/AGENTS.md', 'packages/store/AGENTS.md', - 'packages/trpc/AGENTS.md', 'toolings/typescript-config/AGENTS.md', ]) }) diff --git a/tests/tsconfig.json b/tests/tsconfig.json index 9fbe5c9..1073e0f 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -25,7 +25,7 @@ "@arche-template/server": ["apps/server/src/server.ts"], "@arche-template/auth/*": ["packages/auth/src/*"], "@arche-template/auth": ["packages/auth/src/index.ts"], - "@arche-template/trpc": ["packages/trpc/src/index.ts"], + "@arche-template/server/trpc": ["apps/server/src/modules/trpc/index.ts"], "@arche-template/store": ["packages/store/src/index.ts"], "@arche-template/common": ["packages/common/src/index.ts"], "@arche-template/backend-common": ["packages/backend-common/src/index.ts"], diff --git a/toolings/scripts/repo-doctor.ts b/toolings/scripts/repo-doctor.ts index 75f80ce..69d2112 100644 --- a/toolings/scripts/repo-doctor.ts +++ b/toolings/scripts/repo-doctor.ts @@ -20,7 +20,7 @@ interface CliOptions { strict: boolean } -const ROOT = process.cwd() +const ROOT = resolve(import.meta.dir, '../..') const IGNORE_SEGMENTS = ['node_modules', '.git', '.turbo', '.next', 'dist', 'build', 'out'] const DOC_GLOBS = [ 'README.md', diff --git a/toolings/scripts/sync-template-agents.ts b/toolings/scripts/sync-template-agents.ts index 103a51d..6f841d8 100644 --- a/toolings/scripts/sync-template-agents.ts +++ b/toolings/scripts/sync-template-agents.ts @@ -1,7 +1,6 @@ -#!/usr/bin/env bun -import { join } from 'node:path' +import { join, resolve } from 'node:path' -const ROOT = process.cwd() +const ROOT = resolve(import.meta.dir, '../..') const TEMPLATE_PREFIX = join(ROOT, 'apps/cli/src/templates/fullstack') async function fileExists(path: string): Promise { diff --git a/toolings/scripts/sync-web-core.ts b/toolings/scripts/sync-web-core.ts index 08bc970..7b132ad 100644 --- a/toolings/scripts/sync-web-core.ts +++ b/toolings/scripts/sync-web-core.ts @@ -1,8 +1,7 @@ -#!/usr/bin/env bun import { existsSync, readFileSync, writeFileSync } from 'node:fs' -import { join } from 'node:path' +import { join, resolve } from 'node:path' -const ROOT = process.cwd() +const ROOT = resolve(import.meta.dir, '../..') const WEB_CORE = join(ROOT, 'apps/cli/src/templates/_web-core') const SHARED_COPY_FILES = [ diff --git a/turbo.json b/turbo.json index 41b4fb3..8d8c273 100644 --- a/turbo.json +++ b/turbo.json @@ -1,6 +1,6 @@ { "$schema": "https://v2-10-0.turborepo.dev/schema.json", - "ui": "tui", + "ui": "stream", "globalEnv": [ "NODE_ENV", "NEXT_PUBLIC_APP_URL", @@ -24,6 +24,9 @@ "GOOGLE_CLIENT_SECRET" ], "tasks": { + "test": { + "dependsOn": ["transit"] + }, "transit": { "dependsOn": ["^transit"] }, @@ -64,6 +67,10 @@ "db:seed": { "persistent": true, "cache": false + }, + "db:studio": { + "cache": false, + "persistent": true } } }