feat: add bot and api services with config, logger and database packages

- Add bot service with telegram integration and webhook/polling modes
- Add api service with hono, swagger and zod-openapi
- Create config package for environment variable management
- Create logger package for colored console logging
- Create database package with prisma integration
- Remove next.js web and docs apps
- Update turbo.json for new services
- Add dockerfiles and gitea workflows for deployment
This commit is contained in:
Yuu Ottosoka
2025-07-08 19:46:08 +03:00
parent 393c175460
commit 71365836d3
85 changed files with 5635 additions and 4333 deletions

View File

@@ -0,0 +1,23 @@
{
"name": "@repo/config",
"version": "0.0.0",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": "./src/index.ts"
},
"scripts": {
"dev": "tsc --watch",
"build": "tsc",
"clean": "rm -rf dist",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"znv": "^0.5.0",
"zod": "^3.25.76"
},
"devDependencies": {
"@repo/typescript-config": "*",
"typescript": "^5.0.0"
}
}

View File

@@ -0,0 +1,43 @@
import { parseEnv } from 'znv';
import { z } from 'zod';
import type { ConfigSchema, ConfigOptions, InferConfig } from './types';
export const createConfig = <T extends ConfigSchema>(
options: ConfigOptions<T>,
): InferConfig<T> => {
const { schema, env = process.env, prefix = '' } = options;
// Add prefix to schema keys if provided
const prefixedSchema = prefix
? Object.entries(schema).reduce(
(acc, [key, zodSchema]) => {
acc[`${prefix}${key}`] = zodSchema;
return acc;
},
{} as Record<string, z.ZodTypeAny>
)
: schema;
try {
const parsed = parseEnv(env, prefixedSchema);
// Remove prefix from result keys if it was added
if (prefix) {
const result = {} as Record<string, unknown>;
Object.entries(parsed).forEach(([key, value]) => {
const originalKey = key.startsWith(prefix)
? key.slice(prefix.length)
: key;
result[originalKey] = value;
});
return result as InferConfig<T>;
}
return parsed as InferConfig<T>;
} catch (error) {
if (error instanceof Error) {
throw new Error(`Configuration validation failed: ${error.message}`);
}
throw error;
}
};

View File

@@ -0,0 +1,2 @@
export * from './create-config';
export * from './types';

View File

@@ -0,0 +1,18 @@
import { z } from 'zod';
export type ConfigSchema = Record<string, z.ZodTypeAny>;
export interface ConfigOptions<T extends ConfigSchema> {
schema: T;
env?: Record<string, string | undefined>;
prefix?: string;
}
export type InferConfig<T extends ConfigSchema> = {
readonly [K in keyof T]: z.infer<T[K]>;
};
export interface ConfigResult<T extends ConfigSchema> {
config: InferConfig<T>;
errors: string[];
}

View File

@@ -0,0 +1,9 @@
{
"extends": "@repo/typescript-config/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
},
"include": ["src/**/*"],
"exclude": ["dist", "node_modules"]
}