Migrate Synapsis to embedded Turso
CI / smoke (push) Has been cancelled

This commit is contained in:
2026-07-14 15:50:12 -07:00
parent b4a9d82d05
commit 60f7dba46c
184 changed files with 8375 additions and 53945 deletions
+12 -19
View File
@@ -1,26 +1,19 @@
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
import * as schema from './schema';
import { mkdirSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { drizzle } from 'drizzle-orm/tursodatabase/database';
import { relations } from './relations';
// Best Practice for VPS/Self-Hosting:
// We use 'pg' (node-postgres) which connects via standard TCP.
// This works for local Postgres, Docker, VPS, and managed clouds (AWS RDS, Neon, etc.).
const configuredPath = process.env.DATABASE_PATH || './data/synapsis.db';
const databasePath = configuredPath === ':memory:' ? configuredPath : resolve(configuredPath);
const connectionString = process.env.DATABASE_URL || 'postgres://placeholder:placeholder@localhost:5432/placeholder';
if (databasePath !== ':memory:') {
mkdirSync(dirname(databasePath), { recursive: true });
}
// Create a connection pool
const pool = new Pool({
connectionString,
max: 20, // Adjust based on your server capacity
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});
export const db = drizzle(databasePath, { relations });
// Create the Drizzle client
export const db = drizzle(pool, { schema });
// Helper to check if DB is configured
export const isDbAvailable = () => !!process.env.DATABASE_URL;
// Embedded Turso is always available; DATABASE_PATH only changes its location.
export const isDbAvailable = () => true;
// Export schema for use elsewhere
export * from './schema';
+177
View File
@@ -0,0 +1,177 @@
import { defineRelations } from 'drizzle-orm';
import * as schema from './schema';
export const relations = defineRelations(schema, (r) => ({
users: {
node: r.one.nodes({ from: r.users.nodeId, to: r.nodes.id }),
botOwner: r.one.users({
from: r.users.botOwnerId,
to: r.users.id,
alias: 'ownedBots',
}),
ownedBotUsers: r.many.users({
from: r.users.id,
to: r.users.botOwnerId,
alias: 'ownedBots',
}),
posts: r.many.posts({ from: r.users.id, to: r.posts.userId }),
followersRelation: r.many.follows({
from: r.users.id,
to: r.follows.followingId,
alias: 'following',
}),
followingRelation: r.many.follows({
from: r.users.id,
to: r.follows.followerId,
alias: 'follower',
}),
},
posts: {
author: r.one.users({ from: r.posts.userId, to: r.users.id, optional: false }),
bot: r.one.bots({ from: r.posts.botId, to: r.bots.id }),
removedByUser: r.one.users({ from: r.posts.removedBy, to: r.users.id }),
replyTo: r.one.posts({
from: r.posts.replyToId,
to: r.posts.id,
alias: 'replies',
}),
replies: r.many.posts({
from: r.posts.id,
to: r.posts.replyToId,
alias: 'replies',
}),
repostOf: r.one.posts({
from: r.posts.repostOfId,
to: r.posts.id,
alias: 'reposts',
}),
reposts: r.many.posts({
from: r.posts.id,
to: r.posts.repostOfId,
alias: 'reposts',
}),
likes: r.many.likes({ from: r.posts.id, to: r.likes.postId }),
media: r.many.media({ from: r.posts.id, to: r.media.postId }),
},
media: {
user: r.one.users({ from: r.media.userId, to: r.users.id, optional: false }),
post: r.one.posts({ from: r.media.postId, to: r.posts.id }),
},
follows: {
follower: r.one.users({
from: r.follows.followerId,
to: r.users.id,
alias: 'follower',
optional: false,
}),
following: r.one.users({
from: r.follows.followingId,
to: r.users.id,
alias: 'following',
optional: false,
}),
},
likes: {
user: r.one.users({ from: r.likes.userId, to: r.users.id, optional: false }),
post: r.one.posts({ from: r.likes.postId, to: r.posts.id, optional: false }),
},
notifications: {
recipient: r.one.users({
from: r.notifications.userId,
to: r.users.id,
alias: 'recipient',
optional: false,
}),
actor: r.one.users({
from: r.notifications.actorId,
to: r.users.id,
alias: 'actor',
optional: false,
}),
post: r.one.posts({ from: r.notifications.postId, to: r.posts.id }),
},
sessions: {
user: r.one.users({ from: r.sessions.userId, to: r.users.id, optional: false }),
},
blocks: {
user: r.one.users({ from: r.blocks.userId, to: r.users.id, optional: false }),
blockedUser: r.one.users({ from: r.blocks.blockedUserId, to: r.users.id, optional: false }),
},
mutes: {
user: r.one.users({ from: r.mutes.userId, to: r.users.id, optional: false }),
mutedUser: r.one.users({ from: r.mutes.mutedUserId, to: r.users.id, optional: false }),
},
mutedNodes: {
user: r.one.users({ from: r.mutedNodes.userId, to: r.users.id, optional: false }),
},
reports: {
reporter: r.one.users({ from: r.reports.reporterId, to: r.users.id }),
resolver: r.one.users({ from: r.reports.resolvedBy, to: r.users.id }),
},
bots: {
user: r.one.users({
from: r.bots.userId,
to: r.users.id,
alias: 'botUser',
optional: false,
}),
owner: r.one.users({
from: r.bots.ownerId,
to: r.users.id,
alias: 'botOwner',
optional: false,
}),
contentSources: r.many.botContentSources({ from: r.bots.id, to: r.botContentSources.botId }),
mentions: r.many.botMentions({ from: r.bots.id, to: r.botMentions.botId }),
activityLogs: r.many.botActivityLogs({ from: r.bots.id, to: r.botActivityLogs.botId }),
rateLimits: r.many.botRateLimits({ from: r.bots.id, to: r.botRateLimits.botId }),
},
botContentSources: {
bot: r.one.bots({ from: r.botContentSources.botId, to: r.bots.id, optional: false }),
contentItems: r.many.botContentItems({
from: r.botContentSources.id,
to: r.botContentItems.sourceId,
}),
},
botContentItems: {
source: r.one.botContentSources({
from: r.botContentItems.sourceId,
to: r.botContentSources.id,
optional: false,
}),
post: r.one.posts({ from: r.botContentItems.postId, to: r.posts.id }),
},
botMentions: {
bot: r.one.bots({ from: r.botMentions.botId, to: r.bots.id, optional: false }),
post: r.one.posts({ from: r.botMentions.postId, to: r.posts.id, optional: false }),
author: r.one.users({ from: r.botMentions.authorId, to: r.users.id, optional: false }),
responsePost: r.one.posts({
from: r.botMentions.responsePostId,
to: r.posts.id,
}),
},
botActivityLogs: {
bot: r.one.bots({ from: r.botActivityLogs.botId, to: r.bots.id, optional: false }),
},
botRateLimits: {
bot: r.one.bots({ from: r.botRateLimits.botId, to: r.bots.id, optional: false }),
},
chatConversations: {
participant1: r.one.users({
from: r.chatConversations.participant1Id,
to: r.users.id,
optional: false,
}),
messages: r.many.chatMessages({
from: r.chatConversations.id,
to: r.chatMessages.conversationId,
}),
},
chatMessages: {
conversation: r.one.chatConversations({
from: r.chatMessages.conversationId,
to: r.chatConversations.id,
optional: false,
}),
},
}));
+210 -416
View File
File diff suppressed because it is too large Load Diff