feat(subscriptions): added polar as payment provider for subscriptions

* feature(dashboard): add polar / subscription

* wip(payments): manage subscription

* wip(payments): add free product, faq and some other improvements

* fix(root): change node to bundler in tsconfig

* wip(payments): display current subscription

* feat(dashboard): schedule project for deletion

* wip(payments): support custom products/subscriptions

* wip(payments): fix polar scripts

* wip(payments): add json package to dockerfiles
This commit is contained in:
Carl-Gerhard Lindesvärd
2025-02-26 11:24:00 +01:00
committed by GitHub
parent 86bf9dd064
commit 168ebc3430
105 changed files with 3395 additions and 463 deletions

View File

@@ -1,6 +1,6 @@
import { type Redis, getRedisCache, runEvery } from '@openpanel/redis';
import { type Redis, getRedisCache } from '@openpanel/redis';
import { getSafeJson } from '@openpanel/common';
import { getSafeJson } from '@openpanel/json';
import { TABLE_NAMES, ch } from '../clickhouse/client';
import type { IClickhouseBotEvent } from '../services/event.service';
import { BaseBuffer } from './base-buffer';

View File

@@ -1,8 +1,9 @@
import { getSafeJson, setSuperJson } from '@openpanel/common';
import { getSafeJson, setSuperJson } from '@openpanel/json';
import {
type Redis,
getRedisCache,
getRedisPub,
publishEvent,
runEvery,
} from '@openpanel/redis';
import { ch } from '../clickhouse/client';
@@ -260,29 +261,12 @@ return "OK"
if (!_multi) {
await multi.exec();
}
await this.publishEvent('event:received', event);
await publishEvent('events', 'received', transformEvent(event), multi);
} catch (error) {
this.logger.error('Failed to add event to Redis buffer', { error });
}
}
private async publishEvent(
channel: string,
event: IClickhouseEvent,
multi?: ReturnType<Redis['multi']>,
) {
try {
await (multi || getRedisPub()).publish(
channel,
setSuperJson(
transformEvent(event) as unknown as Record<string, unknown>,
),
);
} catch (error) {
this.logger.warn('Failed to publish event', { error });
}
}
private async getEligableSessions({ minEventsInSession = 2 }) {
const sessionsSorted = await getRedisCache().eval(
this.processSessionsScript,
@@ -429,7 +413,7 @@ return "OK"
// (E) Publish "saved" events.
const pubMulti = getRedisPub().multi();
for (const event of eventsToClickhouse) {
await this.publishEvent('event:saved', event, pubMulti);
await publishEvent('events', 'saved', transformEvent(event), pubMulti);
}
await pubMulti.exec();

View File

@@ -1,6 +1,6 @@
import { deepMergeObjects } from '@openpanel/common';
import { getSafeJson } from '@openpanel/json';
import type { ILogger } from '@openpanel/logger';
// import { getSafeJson } from '@openpanel/json';
import { type Redis, getRedisCache } from '@openpanel/redis';
import shallowEqual from 'fast-deep-equal';
import { omit } from 'ramda';
@@ -8,15 +8,6 @@ import { TABLE_NAMES, ch, chQuery } from '../clickhouse/client';
import type { IClickhouseProfile } from '../services/profile.service';
import { BaseBuffer } from './base-buffer';
// TODO: Use @openpanel/json when polar is merged
function getSafeJson<T>(str: string): T | null {
try {
return JSON.parse(str);
} catch (e) {
return null;
}
}
export class ProfileBuffer extends BaseBuffer {
private batchSize = process.env.PROFILE_BUFFER_BATCH_SIZE
? Number.parseInt(process.env.PROFILE_BUFFER_BATCH_SIZE, 10)