Self-hosting! (#49)

* added self-hosting
This commit is contained in:
Carl-Gerhard Lindesvärd
2024-08-28 09:28:44 +02:00
committed by GitHub
parent f0b7526847
commit df05e2dab3
70 changed files with 2310 additions and 272 deletions

View File

@@ -1,6 +1,17 @@
CREATE DATABASE IF NOT EXISTS openpanel;
CREATE TABLE openpanel.events_v2 (
CREATE TABLE IF NOT EXISTS openpanel.self_hosting
(
created_at Date,
domain String,
count UInt64
)
ENGINE = MergeTree()
ORDER BY (domain, created_at)
PARTITION BY toYYYYMM(created_at);
CREATE TABLE IF NOT EXISTS openpanel.events_v2 (
`id` UUID DEFAULT generateUUIDv4(),
`name` String,
`sdk_name` String,
@@ -80,7 +91,7 @@ SELECT
uniqState(profile_id) as profile_id,
project_id
FROM
events
events_v2
GROUP BY
date,
project_id;

View File

@@ -5,6 +5,7 @@ export const TABLE_NAMES = {
events: 'events_v2',
profiles: 'profiles',
alias: 'profile_aliases',
self_hosting: 'self_hosting',
};
export const originalCh = createClient({

View File

@@ -1,3 +1,5 @@
import { generateSalt } from '@openpanel/common';
import { db } from '../prisma-client';
export async function getCurrentSalt() {
@@ -27,7 +29,7 @@ export async function getSalts() {
}
if (!prev) {
throw new Error('No previous salt found');
throw new Error('No salt found');
}
return {
@@ -35,3 +37,44 @@ export async function getSalts() {
previous: prev.salt,
};
}
export async function createInitialSalts() {
const MAX_RETRIES = 5;
const BASE_DELAY = 1000; // 1 second
const createSaltsWithRetry = async (retryCount = 0): Promise<void> => {
try {
await getSalts();
} catch (error) {
if (error instanceof Error && error.message === 'No salt found') {
console.log('Creating salts for the first time');
await db.salt.create({
data: {
salt: generateSalt(),
createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 24),
},
});
await db.salt.create({
data: {
salt: generateSalt(),
},
});
} else {
console.log('Error getting salts', error);
if (retryCount < MAX_RETRIES) {
const delay = BASE_DELAY * Math.pow(2, retryCount);
console.log(
`Retrying in ${delay}ms... (Attempt ${retryCount + 1}/${MAX_RETRIES})`
);
await new Promise((resolve) => setTimeout(resolve, delay));
return createSaltsWithRetry(retryCount + 1);
} else {
throw new Error(
`Failed to create salts after ${MAX_RETRIES} attempts`
);
}
}
}
};
await createSaltsWithRetry();
}

View File

@@ -56,10 +56,15 @@ export type CronQueuePayloadFlushProfiles = {
type: 'flushProfiles';
payload: undefined;
};
export type CronQueuePayloadPing = {
type: 'ping';
payload: undefined;
};
export type CronQueuePayload =
| CronQueuePayloadSalt
| CronQueuePayloadFlushEvents
| CronQueuePayloadFlushProfiles;
| CronQueuePayloadFlushProfiles
| CronQueuePayloadPing;
export const eventsQueue = new Queue<EventsQueuePayload>('events', {
connection: getRedisQueue(),

View File

@@ -1,7 +1,7 @@
const api = {
logo: 'https://cdn-icons-png.flaticon.com/512/10169/10169724.png',
name: 'Rest API',
href: 'https://docs.openpanel.dev/docs/api',
href: 'https://docs.openpanel.dev/docs/sdks/api',
} as const;
export const frameworks = {
@@ -9,32 +9,32 @@ export const frameworks = {
{
logo: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/61/HTML5_logo_and_wordmark.svg/240px-HTML5_logo_and_wordmark.svg.png',
name: 'HTML / Script',
href: 'https://docs.openpanel.dev/docs/script',
href: 'https://docs.openpanel.dev/docs/sdks/script',
},
{
logo: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/2300px-React-icon.svg.png',
name: 'React',
href: 'https://docs.openpanel.dev/docs/react',
href: 'https://docs.openpanel.dev/docs/sdks/react',
},
{
logo: 'https://static-00.iconduck.com/assets.00/nextjs-icon-512x512-y563b8iq.png',
name: 'Next.js',
href: 'https://docs.openpanel.dev/docs/nextjs',
href: 'https://docs.openpanel.dev/docs/sdks/nextjs',
},
{
logo: 'https://www.datocms-assets.com/205/1642515307-square-logo.svg',
name: 'Remix',
href: 'https://docs.openpanel.dev/docs/remix',
href: 'https://docs.openpanel.dev/docs/sdks/remix',
},
{
logo: 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/95/Vue.js_Logo_2.svg/1024px-Vue.js_Logo_2.svg.png',
name: 'Vue',
href: 'https://docs.openpanel.dev/docs/vue',
href: 'https://docs.openpanel.dev/docs/sdks/vue',
},
{
logo: 'https://astro.build/assets/press/astro-icon-dark.png',
name: 'Astro',
href: 'https://docs.openpanel.dev/docs/astro',
href: 'https://docs.openpanel.dev/docs/sdks/astro',
},
api,
],
@@ -42,7 +42,7 @@ export const frameworks = {
{
logo: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/2300px-React-icon.svg.png',
name: 'React-Native',
href: 'https://docs.openpanel.dev/docs/react-native',
href: 'https://docs.openpanel.dev/docs/sdks/react-native',
},
api,
],
@@ -50,12 +50,12 @@ export const frameworks = {
{
logo: 'https://static-00.iconduck.com/assets.00/node-js-icon-454x512-nztofx17.png',
name: 'Node',
href: 'https://docs.openpanel.dev/docs/node',
href: 'https://docs.openpanel.dev/docs/sdks/node',
},
{
logo: 'https://expressjs.com/images/favicon.png',
name: 'Express',
href: 'https://docs.openpanel.dev/docs/express',
href: 'https://docs.openpanel.dev/docs/sdks/express',
},
{
logo: 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Laravel.svg/1969px-Laravel.svg.png',