chore(deno): migrate toolchain from Node 24 + pnpm to Deno 2.9.7 + TypeScript 7.0.2 (W1.5)

- root deno.json workspace (nodeModulesDir auto), npm versions registered once in imports, deno.lock;
  remove pnpm-lock/pnpm-workspace/root package.json; members keep minimal package.json (name/type/exports)
- tasks: dev, typecheck (tsc 7.0.2 per member + deno check), lint/fmt (biome, useImportExtensions),
  test (vitest via deno), check:tokens, build (web + deno compile), ci, db:migrate/reset, gen:types
- tsconfig base moved to config/ (no root tsconfig.json); deno types -> types/deno.d.ts; web drops baseUrl
- server: Deno.serve entry with graceful shutdown, --role migrate|preflight|probe, WEB_ROOT static SPA hosting;
  drop @hono/node-server, tsx, esbuild build.mjs
- logger: redact child() bindings and serialize err by message/stack; sync stdout destination; tests
- relative imports get explicit extensions (sites/mp-sync paths left for follow-up)
- crash-recovery tests spawn `deno run -A`; tasks tests use unique per-file schemas
- single-container Dockerfile + entrypoint (migrate -> preflight -> api+worker watchdog), docker-compose.yml
- docs: README, runbook, ADR-001 superseded, plan §1 validation row

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
rootandClaude Fable 5.1 committed 2026-09-27 18:53:06 +08:00
1 parent d9f2af2f3c
commit 304feea141
226 files changed
+6601 -8620

No files matched your search

@@ -1,7 +1,7 @@
import { KeyRound } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import { Button } from "~/components/ui/button";
import { Button } from "~/components/ui/button.tsx";
import {
Dialog,
DialogContent,
@@ -10,9 +10,9 @@ import {
DialogHeader,
DialogTitle,
DialogTrigger,
} from "~/components/ui/dialog";
import { Input } from "~/components/ui/input";
import { clearAuth, getToken, setToken } from "~/lib/api";
} from "~/components/ui/dialog.tsx";
import { Input } from "~/components/ui/input.tsx";
import { clearAuth, getToken, setToken } from "~/lib/api.ts";
/** 设置本机使用的 API Key(存 localStorage,首版单管理员) */
export function ApiKeyDialog() {
@@ -1,7 +1,7 @@
import type { LucideIcon } from "lucide-react";
import { Inbox } from "lucide-react";
import type { ReactNode } from "react";
import { cn } from "~/lib/utils";
import { cn } from "~/lib/utils.ts";
/** 空态:图标 + 标题 + 说明 + 可选操作。用于"尚无数据"与"功能建设中"占位 */
export function EmptyState({
+1 -1
View File
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { findNavItem, NAV_ITEMS } from "./nav";
import { findNavItem, NAV_ITEMS } from "./nav.ts";
describe("控制台导航", () => {
it("12 个工作区,路径唯一", () => {
@@ -1,5 +1,5 @@
import type { ReactNode } from "react";
import { cn } from "~/lib/utils";
import { cn } from "~/lib/utils.ts";
/** 控制台页面标题:标题 + 一句说明 + 右侧操作区 */
export function PageHeader({
@@ -1,5 +1,5 @@
import type { ReactNode } from "react";
import { cn } from "~/lib/utils";
import { cn } from "~/lib/utils.ts";
export type StatusTone = "success" | "warning" | "destructive" | "neutral";
@@ -1,8 +1,8 @@
import { Construction } from "lucide-react";
import { useLocation } from "react-router";
import { EmptyState } from "./empty-state";
import { findNavItem } from "./nav";
import { PageHeader } from "./page-header";
import { EmptyState } from "./empty-state.tsx";
import { findNavItem } from "./nav.ts";
import { PageHeader } from "./page-header.tsx";
/** 工作区占位页:标题与说明取自导航表,正文为"建设中"空态 */
export function WorkspacePlaceholder({ milestone = "W3" }: { milestone?: string }) {