chore: remove all NestJS backend references, replace with Hono/Bun

- Delete nestjs-backend.md guideline (replaced by hono-server.md)
- Delete Dockerfile.nestjs-base and Dockerfile.nestjs templates
- Delete stale BACKEND_ARCHITECTURE.md doc (NestJS-era, obsolete)
- Update CLAUDE.md, GUIDELINES.md, authentication.md to Hono/Bun first
- Update all app CLAUDE.md files: backend/ → server/, NestJS → Hono+Bun
- Update all app package.json files: @*/backend → @*/server
- Update docs: LOCAL_DEVELOPMENT, PORT_SCHEMA, ENVIRONMENT_VARIABLES,
  DATABASE_MIGRATIONS, MAC_MINI_SERVER, PROJECT_OVERVIEW
- Update scripts: generate-env.mjs, setup-databases.sh, build-app.sh
- Update CI/CD: cd-macmini.yml backend → server paths
- Update Astro docs site: @chat/backend → @chat/server

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-31 16:52:25 +02:00
parent 708299b35e
commit ab387b9b3d
43 changed files with 598 additions and 2398 deletions

View file

@ -70,9 +70,9 @@ const APP_CONFIGS = [
},
},
// Chat Backend
// Chat Server (Hono/Bun)
{
path: 'apps/chat/apps/backend/.env',
path: 'apps/chat/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.CHAT_BACKEND_PORT || '3002',
@ -130,9 +130,9 @@ const APP_CONFIGS = [
},
},
// Manadeck Backend
// Manadeck Server (Hono/Bun)
{
path: 'apps/manadeck/apps/backend/.env',
path: 'apps/manadeck/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.MANADECK_BACKEND_PORT || '3004',
@ -154,9 +154,9 @@ const APP_CONFIGS = [
},
},
// Picture Backend (NestJS)
// Picture Server (Hono/Bun)
{
path: 'apps/picture/apps/backend/.env',
path: 'apps/picture/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.PICTURE_BACKEND_PORT || '3006',
@ -204,9 +204,9 @@ const APP_CONFIGS = [
},
},
// Nutriphi Backend (NestJS)
// Nutriphi Server (Hono/Bun)
{
path: 'apps/nutriphi/apps/backend/.env',
path: 'apps/nutriphi/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.NUTRIPHI_BACKEND_PORT || '3002',
@ -282,9 +282,9 @@ const APP_CONFIGS = [
},
},
// Mana Games Backend (NestJS)
// Arcade Backend (NestJS)
{
path: 'games/mana-games/apps/backend/.env',
path: 'games/arcade/apps/backend/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.MANA_GAMES_BACKEND_PORT || '3011',
@ -304,17 +304,17 @@ const APP_CONFIGS = [
},
},
// Mana Games Web (Astro)
// Arcade Web (Astro)
{
path: 'games/mana-games/apps/web/.env',
path: 'games/arcade/apps/web/.env',
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.MANA_GAMES_BACKEND_PORT || '3011'}`,
},
},
// Context Backend (NestJS)
// Context Server (Hono/Bun)
{
path: 'apps/context/apps/backend/.env',
path: 'apps/context/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.CONTEXT_BACKEND_PORT || '3020',
@ -338,9 +338,9 @@ const APP_CONFIGS = [
},
},
// Calendar Backend (NestJS)
// Calendar Server (Hono/Bun)
{
path: 'apps/calendar/apps/backend/.env',
path: 'apps/calendar/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.CALENDAR_BACKEND_PORT || '3014',
@ -379,9 +379,9 @@ const APP_CONFIGS = [
},
},
// Contacts Backend (NestJS)
// Contacts Server (Hono/Bun)
{
path: 'apps/contacts/apps/backend/.env',
path: 'apps/contacts/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.CONTACTS_BACKEND_PORT || '3015',
@ -422,9 +422,9 @@ const APP_CONFIGS = [
},
},
// Storage Backend (NestJS)
// Storage Server (Hono/Bun)
{
path: 'apps/storage/apps/backend/.env',
path: 'apps/storage/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.STORAGE_BACKEND_PORT || '3016',
@ -467,9 +467,9 @@ const APP_CONFIGS = [
},
},
// Todo Backend (NestJS)
// Todo Server (Hono/Bun)
{
path: 'apps/todo/apps/backend/.env',
path: 'apps/todo/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.TODO_BACKEND_PORT || '3018',
@ -492,9 +492,9 @@ const APP_CONFIGS = [
},
},
// Moodlit Backend (NestJS)
// Moodlit Server (Hono/Bun)
{
path: 'apps/moodlit/apps/backend/.env',
path: 'apps/moodlit/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.MOODLIT_BACKEND_PORT || '3012',
@ -524,37 +524,7 @@ const APP_CONFIGS = [
},
},
// Finance Backend (NestJS)
{
path: 'apps/finance/apps/backend/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.FINANCE_BACKEND_PORT || '3019',
DATABASE_URL: (env) => env.FINANCE_DATABASE_URL,
MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
DEV_BYPASS_AUTH: () => 'true',
DEV_USER_ID: (env) => env.DEV_USER_ID || '00000000-0000-0000-0000-000000000000',
CORS_ORIGINS: (env) => env.CORS_ORIGINS,
},
},
// Finance Mobile (Expo)
{
path: 'apps/finance/apps/mobile/.env',
vars: {
EXPO_PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.FINANCE_BACKEND_PORT || '3019'}`,
EXPO_PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
},
},
// Finance Web (SvelteKit)
{
path: 'apps/finance/apps/web/.env',
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.FINANCE_BACKEND_PORT || '3019'}`,
PUBLIC_MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
},
},
// Finance: REMOVED
// Worldream Web (SvelteKit)
{
@ -576,29 +546,11 @@ const APP_CONFIGS = [
},
},
// TechBase Backend (NestJS)
{
path: 'apps/techbase/apps/backend/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.TECHBASE_BACKEND_PORT || '3021',
DATABASE_URL: (env) => env.TECHBASE_DATABASE_URL,
MANA_CORE_AUTH_URL: (env) => env.MANA_CORE_AUTH_URL,
CORS_ORIGINS: () => 'http://localhost:4321,http://localhost:5173',
},
},
// TechBase: REMOVED
// TechBase Web (Astro)
// Traces Server (Hono/Bun)
{
path: 'apps/techbase/apps/web/.env',
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.TECHBASE_BACKEND_PORT || '3021'}`,
},
},
// Traces Backend (NestJS)
{
path: 'apps/traces/apps/backend/.env',
path: 'apps/traces/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.TRACES_BACKEND_PORT || '3026',
@ -657,9 +609,9 @@ const APP_CONFIGS = [
},
},
// Mukke Backend (NestJS)
// Mukke Server (Hono/Bun)
{
path: 'apps/mukke/apps/backend/.env',
path: 'apps/mukke/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.MUKKE_BACKEND_PORT || '3010',

View file

@ -111,11 +111,6 @@ build_base_images() {
$DOCKER build -f "$PROJECT_ROOT/docker/Dockerfile.sveltekit-base" -t sveltekit-base:local "$PROJECT_ROOT"
echo "sveltekit-base:local built."
echo ""
echo "=== Building nestjs-base image ==="
$DOCKER build -f "$PROJECT_ROOT/docker/Dockerfile.nestjs-base" -t nestjs-base:local "$PROJECT_ROOT"
echo "nestjs-base:local built."
echo ""
}
build_services() {

View file

@ -66,13 +66,8 @@ ALL_DATABASES=(
"manadeck"
"storage"
"presi"
"mail"
"moodlit"
"finance"
"inventory"
"techbase"
"voxel_lava"
"figgos"
"planta"
"nutriphi"
"photos"
@ -108,7 +103,7 @@ setup_service() {
;;
chat)
create_db_if_not_exists "chat"
push_schema "@chat/backend" "chat"
push_schema "@chat/server" "chat"
;;
zitare)
create_db_if_not_exists "zitare"
@ -116,11 +111,11 @@ setup_service() {
;;
contacts)
create_db_if_not_exists "contacts"
push_schema "@contacts/backend" "contacts"
# Schema managed by mana-sync (local-first)
;;
calendar)
create_db_if_not_exists "calendar"
push_schema "@calendar/backend" "calendar"
# Schema managed by mana-sync (local-first)
;;
clock)
create_db_if_not_exists "clock"
@ -128,47 +123,31 @@ setup_service() {
;;
todo)
create_db_if_not_exists "todo"
push_schema "@todo/backend" "todo"
push_schema "@todo/server" "todo"
;;
manadeck)
create_db_if_not_exists "manadeck"
push_schema "@manadeck/backend" "manadeck"
;;
mail)
create_db_if_not_exists "mail"
push_schema "@mail/backend" "mail"
# Schema managed by mana-sync (local-first)
;;
moodlit)
create_db_if_not_exists "moodlit"
push_schema "@moodlit/backend" "moodlit"
push_schema "@moodlit/server" "moodlit"
;;
picture)
create_db_if_not_exists "picture"
push_schema "@picture/backend" "picture"
# Schema managed by mana-sync (local-first)
;;
photos)
create_db_if_not_exists "photos"
# Schema managed by mana-sync (backend removed)
;;
finance)
create_db_if_not_exists "finance"
push_schema "@finance/backend" "finance"
;;
voxel-lava)
create_db_if_not_exists "voxel_lava"
push_schema "@voxel-lava/backend" "voxel-lava"
;;
figgos)
create_db_if_not_exists "figgos"
push_schema "@figgos/backend" "figgos"
;;
planta)
create_db_if_not_exists "planta"
push_schema "@planta/backend" "planta"
push_schema "@planta/server" "planta"
;;
nutriphi)
create_db_if_not_exists "nutriphi"
push_schema "@nutriphi/backend" "nutriphi"
# Schema managed by mana-sync (local-first)
;;
presi)
create_db_if_not_exists "presi"
@ -176,7 +155,7 @@ setup_service() {
;;
storage)
create_db_if_not_exists "storage"
push_schema "@storage/backend" "storage"
# Schema managed by mana-sync (local-first)
;;
projectdoc)
create_db_if_not_exists "projectdoc"
@ -196,7 +175,7 @@ setup_service() {
;;
questions)
create_db_if_not_exists "questions"
push_schema "@questions/backend" "questions"
# Schema managed by mana-sync (local-first)
;;
skilltree)
create_db_if_not_exists "skilltree"
@ -204,15 +183,15 @@ setup_service() {
;;
mukke)
create_db_if_not_exists "mukke"
push_schema "@mukke/backend" "mukke"
push_schema "@mukke/server" "mukke"
;;
traces)
create_db_if_not_exists "traces"
push_schema "@traces/backend" "traces"
push_schema "@traces/server" "traces"
;;
context)
create_db_if_not_exists "context"
push_schema "@context/backend" "context"
push_schema "@context/server" "context"
;;
citycorners)
create_db_if_not_exists "citycorners"
@ -224,7 +203,7 @@ setup_service() {
;;
*)
echo -e "${RED}Unknown service: $service${NC}"
echo "Available services: auth, chat, zitare, contacts, calendar, clock, todo, manadeck, mail, moodlit, picture, photos, finance, voxel-lava, figgos, planta, nutriphi, presi, storage, projectdoc, zitare_bot, todo_bot, nutriphi_bot, questions, skilltree, mukke, traces, context, citycorners, uload"
echo "Available services: auth, chat, zitare, contacts, calendar, clock, todo, manadeck, moodlit, picture, photos, planta, nutriphi, presi, storage, projectdoc, zitare_bot, todo_bot, nutriphi_bot, questions, skilltree, mukke, traces, context, citycorners, uload"
exit 1
;;
esac
@ -248,7 +227,7 @@ echo -e "\n${GREEN}Step 2: Pushing schemas${NC}"
echo "--------------------------------------"
# Push schemas for all known services
for service in auth chat zitare contacts calendar clock todo manadeck picture photos mail moodlit finance voxel-lava figgos planta nutriphi presi storage questions skilltree mukke traces context citycorners; do
for service in auth chat zitare contacts calendar clock todo manadeck picture photos moodlit planta nutriphi presi storage questions skilltree mukke traces context citycorners; do
setup_service "$service" 2>/dev/null || true
done

View file

@ -90,12 +90,6 @@ function getWorkspaceDeps(pkgJsonPath) {
return deps;
}
// Check if a Dockerfile uses nestjs-base:local as its base image
function usesNestjsBase(dockerfilePath) {
const content = readFileSync(dockerfilePath, 'utf8');
return content.includes('FROM nestjs-base:local');
}
// Check if a Dockerfile is a non-monorepo build (standalone, no workspace COPY needed)
function isStandaloneBuild(dockerfilePath) {
const content = readFileSync(dockerfilePath, 'utf8');
@ -133,22 +127,6 @@ function getDockerfileCopyPaths(dockerfilePath) {
return { copyPaths, hasPatchesCopy };
}
// Get packages pre-built in nestjs-base image
function getNestjsBasePackages() {
const baseDockerfile = join(ROOT, 'docker', 'Dockerfile.nestjs-base');
if (!existsSync(baseDockerfile)) return new Set();
const content = readFileSync(baseDockerfile, 'utf8');
const paths = new Set();
for (const line of content.split('\n')) {
const trimmed = line.trim();
const copyMatch = trimmed.match(/^COPY\s+(packages\/\S+)/);
if (copyMatch) {
paths.add(copyMatch[1]);
}
}
return paths;
}
// Extract @scope/package imports from a source file
function extractImports(filePath) {
if (!existsSync(filePath)) return [];
@ -173,13 +151,7 @@ function extractImports(filePath) {
// Validate a single Dockerfile and return result
function validateDockerfile(dockerfilePath, pkgJsonPath, relPath, packageMap, opts = {}) {
const {
isNestjsBase = false,
nestjsBasePackagePaths = new Set(),
checkImports = false,
appDir = null,
checkPatches = false,
} = opts;
const { checkImports = false, appDir = null, checkPatches = false } = opts;
if (!existsSync(pkgJsonPath)) {
return {
@ -203,14 +175,6 @@ function validateDockerfile(dockerfilePath, pkgJsonPath, relPath, packageMap, op
continue;
}
// For nestjs-base backends, packages/* are pre-built in the base image
if (isNestjsBase && dirPath.startsWith('packages/')) {
const isCoveredByBase = [...nestjsBasePackagePaths].some(
(bp) => bp === dirPath || dirPath.startsWith(bp + '/') || bp.startsWith(dirPath)
);
if (isCoveredByBase) continue;
}
// Check if any COPY path matches or is a parent directory of this package
const found = [...copyPaths].some(
(cp) => cp === dirPath || dirPath.startsWith(cp + '/') || cp.startsWith(dirPath)
@ -221,7 +185,7 @@ function validateDockerfile(dockerfilePath, pkgJsonPath, relPath, packageMap, op
}
// Check patches (only for web apps that need them)
if (checkPatches && !isNestjsBase && !hasPatchesCopy) {
if (checkPatches && !hasPatchesCopy) {
errors.push('MISSING: patches/ directory → add: COPY patches/ ./patches/');
}
@ -281,7 +245,6 @@ function main() {
const servicesDir = join(ROOT, 'services');
let hasErrors = false;
const results = [];
const nestjsBasePackagePaths = getNestjsBasePackages();
// Find all app directories
const appDirs = readdirSync(appsDir, { withFileTypes: true })
@ -317,12 +280,8 @@ function main() {
const pkgJsonPath = join(appsDir, appName, 'apps', 'backend', 'package.json');
const relPath = `apps/${appName}/apps/backend/Dockerfile`;
const isNestjsBase = usesNestjsBase(dockerfilePath);
const result = validateDockerfile(dockerfilePath, pkgJsonPath, relPath, packageMap, {
isNestjsBase,
nestjsBasePackagePaths,
});
const result = validateDockerfile(dockerfilePath, pkgJsonPath, relPath, packageMap);
if (result.errors.length > 0) hasErrors = true;
results.push(result);
printResult(result);