refactor(server): config system (#11081)

This commit is contained in:
forehalo
2025-03-27 12:32:28 +00:00
parent 7091111f85
commit 0ea38680fa
274 changed files with 7583 additions and 5841 deletions
@@ -0,0 +1,22 @@
import { defineModuleConfig } from '../../base';
declare global {
interface AppConfigSchema {
customerIo: {
enabled: boolean;
token: string;
};
}
}
defineModuleConfig('customerIo', {
enabled: {
desc: 'Enable customer.io integration',
default: false,
},
token: {
desc: 'Customer.io token',
default: '',
schema: { type: 'string' },
},
});
@@ -0,0 +1,10 @@
import './config';
import { Module } from '@nestjs/common';
import { CustomerIoService } from './service';
@Module({
providers: [CustomerIoService],
})
export class CustomerIoModule {}
@@ -0,0 +1,72 @@
import { Injectable } from '@nestjs/common';
import { Config, OnEvent } from '../../base';
@Injectable()
export class CustomerIoService {
#fetch: ((url: string, options?: RequestInit) => Promise<Response>) | null =
null;
constructor(private readonly config: Config) {}
@OnEvent('config.init')
setup() {
const { enabled, token } = this.config.customerIo;
if (enabled && token) {
this.#fetch = (url, options) => {
return fetch(url, {
...options,
headers: {
Authorization: `Basic ${token}`,
'Content-Type': 'application/json',
...options?.headers,
},
});
};
} else {
this.#fetch = null;
}
}
@OnEvent('config.changed')
onConfigChanged(event: Events['config.changed']) {
if (event.updates.customerIo) {
this.setup();
}
}
@OnEvent('user.created')
@OnEvent('user.updated')
async onUserUpdated(user: Events['user.updated'] | Events['user.created']) {
await this.#fetch?.(
`https://track.customer.io/api/v1/customers/${user.id}`,
{
method: 'PUT',
body: JSON.stringify({
name: user.name,
email: user.email,
created_at: Number(user.createdAt) / 1000,
}),
}
);
}
@OnEvent('user.deleted')
async onUserDeleted(user: Events['user.deleted']) {
if (user.emailVerifiedAt) {
// suppress email if email is verified
await this.#fetch?.(
`https://track.customer.io/api/v1/customers/${user.email}/suppress`,
{
method: 'POST',
}
);
}
await this.#fetch?.(
`https://track.customer.io/api/v1/customers/${user.id}`,
{
method: 'DELETE',
}
);
}
}