refactor: rename planta → plants, clean up codebase

- Rename planta module to plants everywhere (routes, modules, API,
  branding, i18n, docker, docs, shared packages)
- Fix package name collisions: @mana/credits-service, @mana/subscriptions-service
  (unblocks turbo)
- Extract layout composables: use-ai-tier-items, use-sync-status-items,
  RouteTierGate (layout 1345→1015 lines)
- Create shared DB pool for apps/api (lib/db.ts), migrate 5 modules
- Add automations module queries.ts with useAllAutomations/useEnabledAutomations
- Remove debug console.log statements from production code
- Rename storage display name: Ablage → Speicher

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-12 18:59:44 +02:00
parent c6c19dbc77
commit a91a6076cc
110 changed files with 831 additions and 707 deletions

View file

@ -14,16 +14,12 @@ import { Hono } from 'hono';
import { Readability } from '@mozilla/readability';
import { JSDOM } from 'jsdom';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { sql } from 'drizzle-orm';
import { getConnection } from '../../lib/db';
// ─── DB Connection (reads from news.curated_articles) ──────
const DATABASE_URL =
process.env.DATABASE_URL ?? 'postgresql://mana:devpassword@localhost:5432/mana_platform';
const connection = postgres(DATABASE_URL, { max: 10 });
const db = drizzle(connection);
const db = drizzle(getConnection());
// ─── Extract Service (Readability fallback for ad-hoc URLs) ─

View file

@ -1,5 +1,5 @@
/**
* Planta module Photo upload + AI plant identification.
* Plants module Photo upload + AI plant identification.
*
* CRUD for plants, photos, watering is handled by mana-sync. This
* module owns the server-only operations: photo upload to mana-media
@ -61,7 +61,7 @@ routes.post('/photos/upload', async (c) => {
try {
const { uploadImageToMedia } = await import('../../lib/media');
const buffer = await file.arrayBuffer();
const result = await uploadImageToMedia(buffer, file.name, { app: 'planta', userId });
const result = await uploadImageToMedia(buffer, file.name, { app: 'plants', userId });
return c.json(
{
@ -73,7 +73,7 @@ routes.post('/photos/upload', async (c) => {
201
);
} catch (err) {
logger.error('planta.upload_failed', {
logger.error('plants.upload_failed', {
error: err instanceof Error ? err.message : String(err),
});
return c.json({ error: 'Upload failed' }, 500);
@ -107,11 +107,11 @@ routes.post('/analysis/identify', async (c) => {
});
return c.json(envelope(object));
} catch (err) {
logger.error('planta.analysis_failed', {
logger.error('plants.analysis_failed', {
error: err instanceof Error ? err.message : String(err),
});
return c.json({ error: 'Analysis failed' }, 500);
}
});
export { routes as plantaRoutes };
export { routes as plantsRoutes };

View file

@ -12,7 +12,7 @@ import { HTTPException } from 'hono/http-exception';
import { authMiddleware } from '@mana/shared-hono/auth';
import type { AuthVariables } from '@mana/shared-hono';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { getConnection } from '../../lib/db';
import {
decks,
slides,
@ -25,11 +25,7 @@ import {
// ─── DB Connection ─────────────────────────────────────────
const DATABASE_URL =
process.env.DATABASE_URL ?? 'postgresql://mana:devpassword@localhost:5432/mana_platform';
const connection = postgres(DATABASE_URL, { max: 5, idle_timeout: 20 });
const db = drizzle(connection, {
const db = drizzle(getConnection(), {
schema: {
decks,
slides,

View file

@ -13,11 +13,8 @@
*/
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { pgSchema, uuid, text, timestamp, integer, jsonb } from 'drizzle-orm/pg-core';
const DATABASE_URL =
process.env.DATABASE_URL ?? 'postgresql://mana:devpassword@localhost:5432/mana_platform';
import { getConnection } from '../../lib/db';
export const researchSchema = pgSchema('research');
@ -58,8 +55,7 @@ export const sources = researchSchema.table('sources', {
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
});
const connection = postgres(DATABASE_URL, { max: 5, idle_timeout: 20 });
export const db = drizzle(connection, { schema: { researchResults, sources } });
export const db = drizzle(getConnection(), { schema: { researchResults, sources } });
export type ResearchResult = typeof researchResults.$inferSelect;
export type Source = typeof sources.$inferSelect;

View file

@ -17,8 +17,8 @@ import { rrulestr } from 'rrule';
import { z } from 'zod';
import { eq, and, asc, sql } from 'drizzle-orm';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { serviceAuthMiddleware, type AuthVariables } from '@mana/shared-hono';
import { getConnection } from '../../lib/db';
import {
pgSchema,
uuid,
@ -33,9 +33,6 @@ import {
// ─── DB Schema (minimal, server-only) ──────────────────────
const DATABASE_URL =
process.env.DATABASE_URL ?? 'postgresql://mana:devpassword@localhost:5432/mana_platform';
const todoSchema = pgSchema('todo');
const tasks = todoSchema.table('tasks', {
@ -88,8 +85,7 @@ const reminders = todoSchema.table(
})
);
const connection = postgres(DATABASE_URL, { max: 5, idle_timeout: 20 });
const db = drizzle(connection, { schema: { tasks, projects, reminders } });
const db = drizzle(getConnection(), { schema: { tasks, projects, reminders } });
// ─── Routes ────────────────────────────────────────────────

View file

@ -10,7 +10,7 @@ import { Hono } from 'hono';
import { logger, type AuthVariables } from '@mana/shared-hono';
import { eq, and } from 'drizzle-orm';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { getConnection } from '../../lib/db';
import {
pgSchema,
uuid,
@ -23,8 +23,6 @@ import {
// ─── DB Schema ──────────────────────────────────────────────
const DATABASE_URL =
process.env.DATABASE_URL ?? 'postgresql://mana:devpassword@localhost:5432/mana_platform';
const LLM_URL = process.env.MANA_LLM_URL || 'http://localhost:3025';
const tracesSchema = pgSchema('traces');
@ -116,8 +114,7 @@ const guidePois = tracesSchema.table('guide_pois', {
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
});
const connection = postgres(DATABASE_URL, { max: 5, idle_timeout: 20 });
const db = drizzle(connection, { schema: { locations, cities, pois, guides, guidePois } });
const db = drizzle(getConnection(), { schema: { locations, cities, pois, guides, guidePois } });
// ─── Routes ─────────────────────────────────────────────────