🔧 chore: create @manacore/shared-drizzle-config and migrate 16 configs

- Create factory function with dbName, schemaPath, outDir, schemaFilter options
- Migrate 12 app backends: calendar, chat, clock, contacts, nutriphi, picture,
  planta, presi, questions, skilltree, storage, todo
- Migrate 4 services: mana-core-auth, telegram-zitare-bot, telegram-todo-bot,
  telegram-nutriphi-bot
- Update consolidation docs with completed Drizzle config task

Savings: ~160 LOC (16 configs × ~10 LOC each)
This commit is contained in:
Till-JS 2026-01-29 16:54:44 +01:00
parent 188290b427
commit 6807543d60
21 changed files with 283 additions and 179 deletions

View file

@ -1,12 +1,3 @@
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
dialect: 'postgresql',
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dbCredentials: {
url: process.env.DATABASE_URL || 'postgresql://manacore:devpassword@localhost:5432/calendar',
},
verbose: true,
strict: true,
});
export default createDrizzleConfig({ dbName: 'calendar' });

View file

@ -1,12 +1,3 @@
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
dialect: 'postgresql',
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dbCredentials: {
url: process.env.DATABASE_URL || 'postgresql://chat:password@localhost:5432/chat',
},
verbose: true,
strict: true,
});
export default createDrizzleConfig({ dbName: 'chat' });

View file

@ -1,12 +1,3 @@
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
dialect: 'postgresql',
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dbCredentials: {
url: process.env.DATABASE_URL || 'postgresql://manacore:devpassword@localhost:5432/clock',
},
verbose: true,
strict: true,
});
export default createDrizzleConfig({ dbName: 'clock' });

View file

@ -1,15 +1,6 @@
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
dialect: 'postgresql',
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dbCredentials: {
url:
process.env.CONTACTS_DATABASE_URL ||
process.env.DATABASE_URL ||
'postgresql://manacore:devpassword@localhost:5432/contacts',
},
verbose: true,
strict: true,
export default createDrizzleConfig({
dbName: 'contacts',
additionalEnvVars: ['CONTACTS_DATABASE_URL'],
});

View file

@ -1,15 +1,4 @@
import { defineConfig } from 'drizzle-kit';
import * as dotenv from 'dotenv';
import 'dotenv/config';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
dotenv.config();
export default defineConfig({
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
verbose: true,
strict: true,
});
export default createDrizzleConfig({ dbName: 'nutriphi' });

View file

@ -1,13 +1,4 @@
import { defineConfig } from 'drizzle-kit';
import * as dotenv from 'dotenv';
import 'dotenv/config';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
dotenv.config();
export default defineConfig({
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL || 'postgresql://picture:password@localhost:5432/picture',
},
});
export default createDrizzleConfig({ dbName: 'picture' });

View file

@ -1,12 +1,3 @@
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
dialect: 'postgresql',
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dbCredentials: {
url: process.env.DATABASE_URL || 'postgresql://manacore:devpassword@localhost:5432/planta',
},
verbose: true,
strict: true,
});
export default createDrizzleConfig({ dbName: 'planta' });

View file

@ -1,11 +1,4 @@
import 'dotenv/config';
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
});
export default createDrizzleConfig({ dbName: 'presi' });

View file

@ -1,11 +1,8 @@
import 'dotenv/config';
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
out: './drizzle',
schema: './src/db/schema/*.ts',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
export default createDrizzleConfig({
dbName: 'questions',
schemaPath: './src/db/schema/*.ts',
outDir: './drizzle',
});

View file

@ -1,11 +1,7 @@
import 'dotenv/config';
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
schema: './src/db/schema/index.ts',
out: './drizzle',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
export default createDrizzleConfig({
dbName: 'skilltree',
outDir: './drizzle',
});

View file

@ -1,15 +1,6 @@
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
dialect: 'postgresql',
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dbCredentials: {
url:
process.env.STORAGE_DATABASE_URL ||
process.env.DATABASE_URL ||
'postgresql://manacore:devpassword@localhost:5432/storage',
},
verbose: true,
strict: true,
export default createDrizzleConfig({
dbName: 'storage',
additionalEnvVars: ['STORAGE_DATABASE_URL'],
});

View file

@ -1,13 +1,7 @@
import { defineConfig } from 'drizzle-kit';
import * as dotenv from 'dotenv';
import 'dotenv/config';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
dotenv.config();
export default defineConfig({
schema: './src/db/schema/index.ts',
out: './drizzle',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
export default createDrizzleConfig({
dbName: 'todo',
outDir: './drizzle',
});

View file

@ -15,7 +15,7 @@
| **MITTEL** | UI Component Cleanup | 400 LOC | Niedrig |
| ~~**MITTEL**~~ | ~~Vite Configs~~ | ~~300 LOC~~**~350 LOC entfernt** | ~~Niedrig~~ |
| **MITTEL** | Navigation Stores | 50 LOC | Niedrig |
| **NIEDRIG** | Drizzle Configs | 200 LOC | Niedrig |
| ~~**NIEDRIG**~~ | ~~Drizzle Configs~~ | ~~200 LOC~~**~160 LOC entfernt** | ~~Niedrig~~ |
| **NIEDRIG** | Logger Utilities | 130 LOC | Niedrig |
---
@ -343,26 +343,44 @@ export default defineConfig(mergeViteConfig(baseConfig, {
---
### 4.3 NIEDRIG: Drizzle Configs (200 LOC)
### ~~4.3 NIEDRIG: Drizzle Configs~~ ✅ ERLEDIGT (~160 LOC gespart)
**Problem:** 12 Backends haben 90% identische drizzle.config.ts.
**Status:** `@manacore/shared-drizzle-config` Package erstellt und 16 Configs migriert (29.01.2026)
**Empfehlung:** Factory-Funktion
**Erstelltes Package:** `packages/shared-drizzle-config/`
- `createDrizzleConfig()` - Factory mit dbName, schemaPath, outDir, schemaFilter, etc.
- Standardwerte: schema `./src/db/schema/index.ts`, out `./src/db/migrations`
- Fallback URL: `postgresql://manacore:devpassword@localhost:5432/{dbName}`
**Migrierte Configs (16 von 20):**
- ✅ Backends: calendar, chat, clock, contacts, nutriphi, picture, planta, presi, questions, skilltree, storage, todo
- ✅ Services: mana-core-auth, telegram-zitare-bot, telegram-todo-bot, telegram-nutriphi-bot
**Nicht migriert (Sonderfälle):**
- ⏭️ telegram-project-doc-bot (postgres:postgres Credentials)
- ⏭️ matrix-project-doc-bot (leere Fallback-URL)
- ⏭️ manadeck-database, nutriphi-database (Packages mit kompiliertem JS-Pfad)
**Vorher (10-15 LOC):**
```typescript
// Vorher (17 LOC pro Backend)
export default defineConfig({
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dialect: 'postgresql',
dbCredentials: { url: process.env.DATABASE_URL || '...' },
verbose: true,
strict: true,
});
// Nachher (5 LOC)
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default createDrizzleConfig('chat');
```
**Nachher (1-5 LOC):**
```typescript
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default createDrizzleConfig({ dbName: 'chat' });
```
**Einsparung:** 16 Configs × ~10 LOC = ~160 LOC
---
## 5. Utility Functions
@ -415,9 +433,9 @@ export default createDrizzleConfig('chat');
| Aufgabe | LOC | Aufwand |
|---------|-----|---------|
| `@manacore/shared-nestjs-setup` erstellen | 1.800 | Mittel |
| `@manacore/shared-nestjs-health` erstellen | 170 | Niedrig |
| Drizzle Config Factory erstellen | 200 | Niedrig |
| `@manacore/shared-nestjs-setup` erstellen | 1.800 | Mittel | Offen |
| `@manacore/shared-nestjs-health` erstellen | 170 | Niedrig | Offen |
| ~~Drizzle Config Factory erstellen~~ | ~~200~~**160** | ~~Niedrig~~ | ✅ Erledigt |
### Phase 4: Skeleton Refactoring (Optional, ~800 LOC)

View file

@ -0,0 +1,27 @@
{
"name": "@manacore/shared-drizzle-config",
"version": "1.0.0",
"description": "Shared Drizzle ORM configuration factory",
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"import": "./src/index.ts",
"default": "./src/index.ts"
}
},
"scripts": {
"type-check": "tsc --noEmit"
},
"dependencies": {
"drizzle-kit": "^0.30.4"
},
"devDependencies": {
"typescript": "^5.7.2"
},
"peerDependencies": {
"drizzle-kit": ">=0.20.0"
}
}

View file

@ -0,0 +1,129 @@
import { defineConfig, type Config } from 'drizzle-kit';
export interface DrizzleConfigOptions {
/**
* Database name for fallback URL when DATABASE_URL is not set
* Example: 'calendar' -> postgresql://manacore:devpassword@localhost:5432/calendar
*/
dbName: string;
/**
* Path to schema file(s)
* @default './src/db/schema/index.ts'
*/
schemaPath?: string;
/**
* Output directory for migrations
* @default './src/db/migrations'
*/
outDir?: string;
/**
* Environment variable name for database URL
* @default 'DATABASE_URL'
*/
envVar?: string;
/**
* Additional environment variable names to check (in order)
* Example: ['STORAGE_DATABASE_URL'] for storage backend
*/
additionalEnvVars?: string[];
/**
* Schema filter for multi-schema databases
* Example: ['auth', 'credits', 'public']
*/
schemaFilter?: string[];
/**
* Enable verbose output
* @default true
*/
verbose?: boolean;
/**
* Enable strict mode
* @default true
*/
strict?: boolean;
}
/**
* Default PostgreSQL connection for local development
*/
const DEFAULT_PG_HOST = 'localhost';
const DEFAULT_PG_PORT = '5432';
const DEFAULT_PG_USER = 'manacore';
const DEFAULT_PG_PASSWORD = 'devpassword';
/**
* Creates a Drizzle Kit configuration with sensible defaults
*
* @example
* // Basic usage
* export default createDrizzleConfig({ dbName: 'calendar' });
*
* @example
* // With custom paths
* export default createDrizzleConfig({
* dbName: 'calendar',
* schemaPath: './src/database/schema.ts',
* outDir: './drizzle',
* });
*
* @example
* // With schema filter (multi-schema)
* export default createDrizzleConfig({
* dbName: 'manacore',
* schemaFilter: ['auth', 'credits', 'public'],
* });
*/
export function createDrizzleConfig(options: DrizzleConfigOptions): Config {
const {
dbName,
schemaPath = './src/db/schema/index.ts',
outDir = './src/db/migrations',
envVar = 'DATABASE_URL',
additionalEnvVars = [],
schemaFilter,
verbose = true,
strict = true,
} = options;
// Build fallback URL
const fallbackUrl = `postgresql://${DEFAULT_PG_USER}:${DEFAULT_PG_PASSWORD}@${DEFAULT_PG_HOST}:${DEFAULT_PG_PORT}/${dbName}`;
// Check all env vars in order
let databaseUrl: string | undefined;
for (const envVarName of [...additionalEnvVars, envVar]) {
if (process.env[envVarName]) {
databaseUrl = process.env[envVarName];
break;
}
}
databaseUrl = databaseUrl || fallbackUrl;
const config: Config = {
dialect: 'postgresql',
schema: schemaPath,
out: outDir,
dbCredentials: {
url: databaseUrl,
},
verbose,
strict,
};
// Add schema filter if provided
if (schemaFilter && schemaFilter.length > 0) {
config.schemaFilter = schemaFilter;
}
return defineConfig(config);
}
// Re-export defineConfig for cases where more customization is needed
export { defineConfig } from 'drizzle-kit';
export type { Config } from 'drizzle-kit';

View file

@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"declaration": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
}

21
pnpm-lock.yaml generated
View file

@ -277,6 +277,9 @@ importers:
'@manacore/shared-splitscreen':
specifier: workspace:*
version: link:../../../../packages/shared-splitscreen
'@manacore/shared-stores':
specifier: workspace:*
version: link:../../../../packages/shared-stores
'@manacore/shared-subscription-ui':
specifier: workspace:*
version: link:../../../../packages/shared-subscription-ui
@ -1139,6 +1142,9 @@ importers:
'@manacore/shared-splitscreen':
specifier: workspace:*
version: link:../../../../packages/shared-splitscreen
'@manacore/shared-stores':
specifier: workspace:*
version: link:../../../../packages/shared-stores
'@manacore/shared-subscription-ui':
specifier: workspace:*
version: link:../../../../packages/shared-subscription-ui
@ -4175,6 +4181,9 @@ importers:
'@manacore/shared-splitscreen':
specifier: workspace:*
version: link:../../../../packages/shared-splitscreen
'@manacore/shared-stores':
specifier: workspace:*
version: link:../../../../packages/shared-stores
'@manacore/shared-subscription-ui':
specifier: workspace:*
version: link:../../../../packages/shared-subscription-ui
@ -4585,6 +4594,16 @@ importers:
specifier: ^5.0.0
version: 5.9.3
packages/shared-drizzle-config:
dependencies:
drizzle-kit:
specifier: ^0.30.4
version: 0.30.6
devDependencies:
typescript:
specifier: ^5.7.2
version: 5.9.3
packages/shared-errors:
devDependencies:
'@nestjs/common':
@ -4927,6 +4946,8 @@ importers:
specifier: ^5.0.0
version: 5.9.3
packages/shared-tsconfig: {}
packages/shared-types:
devDependencies:
typescript:

View file

@ -1,13 +1,6 @@
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
dialect: 'postgresql',
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dbCredentials: {
url: process.env.DATABASE_URL || 'postgresql://manacore:devpassword@localhost:5432/manacore',
},
export default createDrizzleConfig({
dbName: 'manacore',
schemaFilter: ['auth', 'credits', 'referrals', 'public'],
verbose: true,
strict: true,
});

View file

@ -1,11 +1,9 @@
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
schema: './src/database/schema.ts',
out: './drizzle',
dialect: 'postgresql',
dbCredentials: {
url:
process.env.DATABASE_URL || 'postgresql://manacore:devpassword@localhost:5432/nutriphi_bot',
},
export default createDrizzleConfig({
dbName: 'nutriphi_bot',
schemaPath: './src/database/schema.ts',
outDir: './drizzle',
verbose: false,
strict: false,
});

View file

@ -1,10 +1,9 @@
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
schema: './src/database/schema.ts',
out: './drizzle',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL || 'postgresql://manacore:devpassword@localhost:5432/todo_bot',
},
export default createDrizzleConfig({
dbName: 'todo_bot',
schemaPath: './src/database/schema.ts',
outDir: './drizzle',
verbose: false,
strict: false,
});

View file

@ -1,10 +1,9 @@
import { defineConfig } from 'drizzle-kit';
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default defineConfig({
schema: './src/database/schema.ts',
out: './drizzle',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL || 'postgresql://manacore:devpassword@localhost:5432/zitare_bot',
},
export default createDrizzleConfig({
dbName: 'zitare_bot',
schemaPath: './src/database/schema.ts',
outDir: './drizzle',
verbose: false,
strict: false,
});