Slefhostet und postgres

This commit is contained in:
2026-04-02 11:39:57 +02:00
parent b1c99893a6
commit 08483c7075
215 changed files with 4584 additions and 5190 deletions

View File

@@ -26,7 +26,7 @@ loadEnvFiles([
path.join(__dirname, '.env.local'),
]);
const { closeDatabase, getDefaultDbPath, openDatabase, get, run } = require('./lib/sqlite');
const { closeDatabase, getDefaultDbPath, openDatabase, get } = require('./lib/postgres');
const { ensureAuthSchema, signUp: authSignUp, login: authLogin, issueToken, verifyJwt } = require('./lib/auth');
const {
PlantImportValidationError,
@@ -392,18 +392,31 @@ app.get('/', (_request, response) => {
});
});
app.get('/health', (_request, response) => {
const stripeSecret = (process.env.STRIPE_SECRET_KEY || '').trim();
response.status(200).json({
ok: true,
uptimeSec: Math.round(process.uptime()),
timestamp: new Date().toISOString(),
openAiConfigured: isOpenAiConfigured(),
dbReady: Boolean(db),
dbPath: getDefaultDbPath(),
stripeConfigured: Boolean(stripeSecret),
stripeMode: getStripeSecretMode(),
stripePublishableMode: getStripePublishableMode(),
const getDatabaseHealthTarget = () => {
const raw = getDefaultDbPath();
if (!raw) return '';
try {
const parsed = new URL(raw);
const databaseName = parsed.pathname.replace(/^\//, '');
return `${parsed.protocol}//${parsed.hostname}${parsed.port ? `:${parsed.port}` : ''}/${databaseName}`;
} catch {
return 'configured';
}
};
app.get('/health', (_request, response) => {
const stripeSecret = (process.env.STRIPE_SECRET_KEY || '').trim();
response.status(200).json({
ok: true,
uptimeSec: Math.round(process.uptime()),
timestamp: new Date().toISOString(),
openAiConfigured: isOpenAiConfigured(),
dbReady: Boolean(db),
dbPath: getDatabaseHealthTarget(),
stripeConfigured: Boolean(stripeSecret),
stripeMode: getStripeSecretMode(),
stripePublishableMode: getStripePublishableMode(),
scanModel: getScanModel(),
healthModel: getHealthModel(),
});
@@ -500,12 +513,12 @@ app.post('/api/payment-sheet', async (request, response) => {
app.get('/v1/billing/summary', async (request, response) => {
try {
const userId = ensureRequestAuth(request);
if (userId !== 'guest') {
const userExists = await get(db, 'SELECT id FROM auth_users WHERE id = ?', [userId]);
if (!userExists) {
return response.status(401).json({ code: 'UNAUTHORIZED', message: 'User not found.' });
}
const userId = ensureRequestAuth(request);
if (userId !== 'guest') {
const userExists = await get(db, 'SELECT id FROM auth_users WHERE id = $1', [userId]);
if (!userExists) {
return response.status(401).json({ code: 'UNAUTHORIZED', message: 'User not found.' });
}
}
const summary = await getBillingSummary(db, userId);
response.status(200).json(summary);
@@ -522,10 +535,11 @@ app.post('/v1/billing/sync-revenuecat', async (request, response) => {
return response.status(400).json({ code: 'BAD_REQUEST', message: 'Guest users cannot sync RevenueCat state.' });
}
const customerInfo = request.body?.customerInfo;
const source = typeof request.body?.source === 'string' ? request.body.source : undefined;
if (!customerInfo || typeof customerInfo !== 'object' || !customerInfo.entitlements) {
return response.status(400).json({ code: 'BAD_REQUEST', message: 'customerInfo is required.' });
}
const payload = await syncRevenueCatCustomerInfo(db, userId, customerInfo);
const payload = await syncRevenueCatCustomerInfo(db, userId, customerInfo, { source });
response.status(200).json(payload);
} catch (error) {
const payload = toApiErrorPayload(error);