new selfhosted version

This commit is contained in:
antonio
2025-11-28 14:11:51 +01:00
parent afda29997d
commit 951860f67e
1046 changed files with 72586 additions and 574750 deletions

View File

@@ -0,0 +1,26 @@
import { model, Schema, Types } from 'mongoose';
export type TPremium = {
user_id: Schema.Types.ObjectId,
premium_type: number,
customer_id: string,
subscription_id: string,
expire_at: number,
payment_failed?: boolean,
plan_cancelled?: boolean,
created_at: Date,
}
const PremiumSchema = new Schema<TPremium>({
user_id: { type: Types.ObjectId, unique: true, index: 1 },
customer_id: { type: String },
premium_type: { type: Number },
subscription_id: { type: String },
expire_at: { type: Number },
payment_failed: { type: Boolean },
plan_cancelled: { type: Boolean },
created_at: { type: Date, default: () => Date.now() }
})
export const PremiumModel = model<TPremium>('premiums', PremiumSchema);

View File

@@ -3,12 +3,14 @@ import { model, Schema, Types } from 'mongoose';
export type TRegister = {
email: string,
password: string,
code: string,
created_at: Date
}
const RegisterSchema = new Schema<TRegister>({
email: { type: String },
password: { type: String },
code: { type: String },
created_at: { type: Date, default: () => Date.now() }
});

View File

@@ -1,8 +1,8 @@
import { model, Schema, Types } from 'mongoose';
export type TProjectLimit = {
export type TUserLimit = {
_id: Schema.Types.ObjectId,
project_id: Schema.Types.ObjectId,
user_id: Schema.Types.ObjectId,
events: number,
visits: number,
ai_messages: number,
@@ -12,8 +12,8 @@ export type TProjectLimit = {
billing_start_at: Date,
}
const ProjectLimitSchema = new Schema<TProjectLimit>({
project_id: { type: Types.ObjectId, index: true, unique: true },
const UserLimitSchema = new Schema<TUserLimit>({
user_id: { type: Types.ObjectId, index: true, unique: true },
events: { type: Number, required: true, default: 0 },
visits: { type: Number, required: true, default: 0 },
ai_messages: { type: Number, required: true, default: 0 },
@@ -23,4 +23,4 @@ const ProjectLimitSchema = new Schema<TProjectLimit>({
billing_expire_at: { type: Date, required: true },
});
export const ProjectLimitModel = model<TProjectLimit>('project_limits', ProjectLimitSchema);
export const UserLimitModel = model<TUserLimit>('user_limits', UserLimitSchema);

View File

@@ -7,14 +7,6 @@ export type TUser = {
locale: string,
picture: string,
created_at: Date,
google_tokens?: {
refresh_token?: string;
expiry_date?: number;
access_token?: string;
token_type?: string;
id_token?: string;
scope?: string;
}
}
const UserSchema = new Schema<TUser>({
@@ -22,15 +14,7 @@ const UserSchema = new Schema<TUser>({
name: String,
given_name: String,
locale: String,
picture: String,
google_tokens: {
refresh_token: String,
expiry_date: Number,
access_token: String,
token_type: String,
id_token: String,
scope: String
},
picture: String,
created_at: { type: Date, default: () => Date.now() }
})

View File

@@ -0,0 +1,20 @@
import { model, Schema } from 'mongoose';
export type TAggBouncing = {
project_id: Schema.Types.ObjectId,
domain: string,
from: Date,
to: Date,
data: { _id: { date: Date }, count: number, timestamp: number }[]
}
const AggBouncingSchema = new Schema<TAggBouncing>({
project_id: { type: Schema.Types.ObjectId, index: true },
domain: { type: String, required: true },
from: { type: Date, required: true },
to: { type: Date, required: true },
data: [{ type: Schema.Types.Mixed }]
});
export const AggBouncingModel = model<TAggBouncing>('agg_bouncings', AggBouncingSchema);

View File

@@ -0,0 +1,20 @@
import { model, Schema } from 'mongoose';
export type TAggDuration = {
project_id: Schema.Types.ObjectId,
domain: string,
from: Date,
to: Date,
data: { _id: { date: Date }, count: number, timestamp: number }[]
}
const AggDurationSchema = new Schema<TAggDuration>({
project_id: { type: Schema.Types.ObjectId, index: true },
domain: { type: String, required: true },
from: { type: Date, required: true },
to: { type: Date, required: true },
data: [{ type: Schema.Types.Mixed }]
});
export const AggDurationModel = model<TAggDuration>('agg_durations', AggDurationSchema);

View File

@@ -0,0 +1,25 @@
import { model, Schema } from 'mongoose';
export type TAgg = {
project_id: Schema.Types.ObjectId,
domain: string,
data_type: string,
date: Date,
data: number
}
const AggSchema = new Schema<TAgg>({
project_id: { type: Schema.Types.ObjectId, index: true },
data_type: { type: String, index: true, required: true },
domain: { type: String, required: true },
date: { type: Date, required: true },
data: { type: Number, required: true }
});
AggSchema.index(
{ project_id: 1, date: 1, domain: 1, data_type: 1 },
{ unique: true }
);
export const AggModel = model<TAgg>('aggregations', AggSchema);

View File

@@ -0,0 +1,20 @@
import { model, Schema } from 'mongoose';
export type TAggSession = {
project_id: Schema.Types.ObjectId,
domain: string,
from: Date,
to: Date,
data: { _id: { date: Date }, count: number, timestamp: number }[]
}
const AggSessionSchema = new Schema<TAggSession>({
project_id: { type: Schema.Types.ObjectId, index: true },
domain: { type: String, required: true },
from: { type: Date, required: true },
to: { type: Date, required: true },
data: [{ type: Schema.Types.Mixed }]
});
export const AggSessionModel = model<TAggSession>('agg_sessions', AggSessionSchema);

View File

@@ -0,0 +1,20 @@
import { model, Schema } from 'mongoose';
export type TAggVisit = {
project_id: Schema.Types.ObjectId,
domain: string,
from: Date,
to: Date,
data: { _id: { date: Date }, count: number, timestamp: number }[]
}
const AggVisitSchema = new Schema<TAggVisit>({
project_id: { type: Schema.Types.ObjectId, index: true },
domain: { type: String, required: true },
from: { type: Date, required: true },
to: { type: Date, required: true },
data: [{ type: Schema.Types.Mixed }]
});
export const AggVisitModel = model<TAggVisit>('agg_visits', AggVisitSchema);

View File

@@ -0,0 +1,24 @@
import { model, Schema } from 'mongoose';
export type TAiNewChatSchema = {
_id: Schema.Types.ObjectId,
project_id: Schema.Types.ObjectId,
messages: any[],
status: string,
title: string,
deleted: boolean,
created_at: Date,
updated_at: Date
}
const AiNewChatSchema = new Schema<TAiNewChatSchema>({
project_id: { type: Schema.Types.ObjectId, index: 1 },
status: { type: String },
messages: [{ _id: false, type: Schema.Types.Mixed }],
title: { type: String, required: true },
deleted: { type: Boolean, default: false },
created_at: { type: Date, default: () => Date.now() },
updated_at: { type: Date, default: () => Date.now() },
});
export const AiNewChatModel = model<TAiNewChatSchema>('ai_new_chats', AiNewChatSchema);

View File

@@ -2,14 +2,14 @@ import { model, Schema, Types } from 'mongoose';
export type TLimitNotify = {
_id: Schema.Types.ObjectId,
project_id: Schema.Types.ObjectId,
user_id: Schema.Types.ObjectId,
limit1: boolean,
limit2: boolean,
limit3: boolean
}
const LimitNotifySchema = new Schema<TLimitNotify>({
project_id: { type: Types.ObjectId, index: 1 },
user_id: { type: Types.ObjectId, index: 1 },
limit1: { type: Boolean },
limit2: { type: Boolean },
limit3: { type: Boolean }

View File

@@ -0,0 +1,28 @@
import { model, Schema, Types } from 'mongoose';
export type TEmailNotify = {
_id: Schema.Types.ObjectId,
user_id: Schema.Types.ObjectId,
n1: boolean,
n2: boolean,
n3: boolean,
n4: boolean,
n5: boolean,
n6: boolean,
n7: boolean,
n8: boolean
}
const EmailNotifySchema = new Schema<TEmailNotify>({
user_id: { type: Types.ObjectId, index: 1 },
n1: { type: Boolean },
n2: { type: Boolean },
n3: { type: Boolean },
n4: { type: Boolean },
n5: { type: Boolean },
n6: { type: Boolean },
n7: { type: Boolean },
n8: { type: Boolean },
});
export const EmailNotifyModel = model<TEmailNotify>('email_notifies', EmailNotifySchema);

View File

@@ -15,7 +15,7 @@ const EventSchema = new Schema<TEvent>({
name: { type: String, required: true, index: 1 },
metadata: Schema.Types.Mixed,
session: { type: String, index: 1 },
flowHash: { type: String },
flowHash: { type: String, index: 1 },
website: { type: String, index: 1 },
created_at: { type: Date, default: () => Date.now(), index: true },
})

View File

@@ -8,11 +8,20 @@ export type TVisit = {
continent: string,
country: string,
region: string,
city: string,
session: string,
flowHash: string,
device: string,
utm_medium: string,
utm_source: string,
utm_term: string,
utm_campaign: string,
utm_content: string,
website: string,
page: string,
referrer: string,
@@ -28,18 +37,29 @@ const VisitSchema = new Schema<TVisit>({
continent: { type: String },
country: { type: String },
region: { type: String },
city: { type: String },
session: { type: String, index: true },
flowHash: { type: String },
session: { type: String },
flowHash: { type: String, index: true },
device: { type: String },
website: { type: String, required: true, index: true },
utm_medium: { type: String },
utm_source: { type: String },
utm_term: { type: String },
utm_campaign: { type: String },
utm_content: { type: String },
website: { type: String, required: true },
page: { type: String, required: true },
referrer: { type: String, required: true },
created_at: { type: Date, default: () => Date.now() },
})
VisitSchema.index({ project_id: 1, created_at: -1 });
VisitSchema.index({ _id: 1, project_id: 1 });
VisitSchema.index({ project_id: 1, website: 1 });
VisitSchema.index({ project_id: 1, session: 1, created_at: 1, });
export const VisitModel = model<TVisit>('visits', VisitSchema);

View File

@@ -4,22 +4,12 @@ export type TProject = {
_id: Schema.Types.ObjectId,
owner: Schema.Types.ObjectId,
name: string,
premium: boolean,
premium_type: number,
customer_id: string,
subscription_id: string,
premium_expire_at: Date,
created_at: Date
}
const ProjectSchema = new Schema<TProject>({
owner: { type: Types.ObjectId, index: 1 },
name: { type: String, required: true },
premium: { type: Boolean, default: false },
premium_type: { type: Number, default: 0 },
customer_id: { type: String, required: true },
subscription_id: { type: String, required: true },
premium_expire_at: { type: Date, required: true },
created_at: { type: Date, default: () => Date.now() },
})

View File

@@ -0,0 +1,20 @@
import { model, Schema, Types } from 'mongoose';
export type TProjectShare = {
_id: Schema.Types.ObjectId,
project_id: Schema.Types.ObjectId,
domain: string,
link: string,
password: string,
description: string
}
const ProjectShareSchema = new Schema<TProjectShare>({
project_id: { type: Types.ObjectId, index: true },
domain: { type: String, required: true },
link: { type: String, required: true },
password: { type: String },
description: { type: String }
});
export const ProjectShareModel = model<TProjectShare>('project_shares', ProjectShareSchema);

View File

@@ -0,0 +1,21 @@
import { model, Schema, Types } from 'mongoose';
export type TReportCustomization = {
_id: Schema.Types.ObjectId,
project_id: Schema.Types.ObjectId,
bg: string,
text: string,
logo: string
}
const ReportCustomizationSchema = new Schema<TReportCustomization>({
project_id: { type: Types.ObjectId, index: 1 },
bg: { type: String, required: true },
text: { type: String, required: true },
logo: { type: String, required: true },
});
export const ReportCustomizationModel = model<TReportCustomization>('repo_customizations', ReportCustomizationSchema);

View File

@@ -0,0 +1,18 @@
import { model, Schema, Types } from 'mongoose';
export type TAddressBlacklistSchema = {
_id: Schema.Types.ObjectId,
project_id: Schema.Types.ObjectId,
address: string,
description: string,
created_at: Date
}
const AddressBlacklistSchema = new Schema<TAddressBlacklistSchema>({
project_id: { type: Types.ObjectId, index: 1 },
address: { type: String, required: true },
description: { type: String },
created_at: { type: Date, default: () => Date.now() },
});
export const AddressBlacklistModel = model<TAddressBlacklistSchema>('address_blacklists', AddressBlacklistSchema);

View File

@@ -0,0 +1,16 @@
import { model, Schema, Types } from 'mongoose';
export type TBotTrafficOptionSchema = {
_id: Schema.Types.ObjectId,
project_id: Schema.Types.ObjectId,
block: boolean,
created_at: Date
}
const BotTrafficOptionSchema = new Schema<TBotTrafficOptionSchema>({
project_id: { type: Types.ObjectId, index: 1 },
block: { type: Boolean, required: true },
created_at: { type: Date, default: () => Date.now() },
});
export const BotTrafficOptionModel = model<TBotTrafficOptionSchema>('bot_traffic_options', BotTrafficOptionSchema);

View File

@@ -0,0 +1,18 @@
import { model, Schema, Types } from 'mongoose';
export type TCountryBlacklistSchema = {
_id: Schema.Types.ObjectId,
project_id: Schema.Types.ObjectId,
country: string,
description: string,
created_at: Date
}
const CountryBlacklistSchema = new Schema<TCountryBlacklistSchema>({
project_id: { type: Types.ObjectId, index: 1 },
country: { type: String, required: true },
description: { type: String },
created_at: { type: Date, default: () => Date.now() },
});
export const CountryBlacklistModel = model<TCountryBlacklistSchema>('country_blacklists', CountryBlacklistSchema);

View File

@@ -0,0 +1,16 @@
import { model, Schema, Types } from 'mongoose';
export type TDomainWhitelistSchema = {
_id: Schema.Types.ObjectId,
project_id: Schema.Types.ObjectId,
domains: string[],
created_at: Date
}
const DomainWhitelistSchema = new Schema<TDomainWhitelistSchema>({
project_id: { type: Types.ObjectId, index: 1 },
domains: [{ type: String, required: true }],
created_at: { type: Date, default: () => Date.now() },
});
export const DomainWhitelistModel = model<TDomainWhitelistSchema>('domain_whitelists', DomainWhitelistSchema);