refactor: Restructure monorepo to apps/server/ and apps/web/ layout

Move src/ → apps/server/ and packages/web/ → apps/web/ to adopt
standard monorepo conventions (apps/ for runnable apps, packages/
for reusable libraries). Update all config files, shared package
imports, test fixtures, and documentation to reflect new paths.

Key fixes:
- Update workspace config to ["apps/*", "packages/*"]
- Update tsconfig.json rootDir/include for apps/server/
- Add apps/web/** to vitest exclude list
- Update drizzle.config.ts schema path
- Fix ensure-schema.ts migration path detection (3 levels up in dev,
  2 levels up in dist)
- Fix tests/integration/cli-server.test.ts import paths
- Update packages/shared imports to apps/server/ paths
- Update all docs/ files with new paths
This commit is contained in:
Lukas May
2026-03-03 11:22:53 +01:00
parent 8c38d958ce
commit 34578d39c6
535 changed files with 75452 additions and 687 deletions

View File

@@ -0,0 +1,119 @@
import { useEffect, useState } from "react";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { toast } from "sonner";
import { trpc } from "@/lib/trpc";
interface RegisterProjectDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
}
export function RegisterProjectDialog({
open,
onOpenChange,
}: RegisterProjectDialogProps) {
const [name, setName] = useState("");
const [url, setUrl] = useState("");
const [defaultBranch, setDefaultBranch] = useState("main");
const [error, setError] = useState<string | null>(null);
const registerMutation = trpc.registerProject.useMutation({
onSuccess: () => {
onOpenChange(false);
toast.success("Project registered");
},
onError: (err) => {
setError(err.message);
},
});
useEffect(() => {
if (open) {
setName("");
setUrl("");
setDefaultBranch("main");
setError(null);
}
}, [open]);
function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setError(null);
registerMutation.mutate({
name: name.trim(),
url: url.trim(),
defaultBranch: defaultBranch.trim() || undefined,
});
}
const canSubmit =
name.trim().length > 0 &&
url.trim().length > 0 &&
!registerMutation.isPending;
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent>
<DialogHeader>
<DialogTitle>Register Project</DialogTitle>
<DialogDescription>
Register a git repository as a project.
</DialogDescription>
</DialogHeader>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="project-name">Name</Label>
<Input
id="project-name"
placeholder="e.g. my-app"
value={name}
onChange={(e) => setName(e.target.value)}
autoFocus
/>
</div>
<div className="space-y-2">
<Label htmlFor="project-url">Repository URL</Label>
<Input
id="project-url"
placeholder="e.g. https://github.com/org/repo.git"
value={url}
onChange={(e) => setUrl(e.target.value)}
/>
</div>
<div className="space-y-2">
<Label htmlFor="default-branch">Default Branch</Label>
<Input
id="default-branch"
placeholder="main"
value={defaultBranch}
onChange={(e) => setDefaultBranch(e.target.value)}
/>
</div>
{error && <p className="text-sm text-destructive">{error}</p>}
<DialogFooter>
<Button
type="button"
variant="outline"
onClick={() => onOpenChange(false)}
>
Cancel
</Button>
<Button type="submit" disabled={!canSubmit}>
{registerMutation.isPending ? "Registering..." : "Register"}
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
);
}