@zumito-team/analytics-module 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +237 -0
  2. package/commands/AnalyticsConfig.d.ts +12 -0
  3. package/commands/AnalyticsConfig.js +93 -0
  4. package/commands/AnalyticsConfig.ts +118 -0
  5. package/commands/Stats.d.ts +11 -0
  6. package/commands/Stats.js +52 -0
  7. package/commands/Stats.ts +66 -0
  8. package/config.d.ts +11 -0
  9. package/config.js +13 -0
  10. package/config.ts +14 -0
  11. package/events/discord/GuildMemberAdd.d.ts +7 -0
  12. package/events/discord/GuildMemberAdd.js +24 -0
  13. package/events/discord/GuildMemberAdd.ts +23 -0
  14. package/events/discord/GuildMemberRemove.d.ts +7 -0
  15. package/events/discord/GuildMemberRemove.js +24 -0
  16. package/events/discord/GuildMemberRemove.ts +23 -0
  17. package/events/discord/MessageCreate.d.ts +7 -0
  18. package/events/discord/MessageCreate.js +18 -0
  19. package/events/discord/MessageCreate.ts +16 -0
  20. package/events/discord/VoiceStateUpdate.d.ts +7 -0
  21. package/events/discord/VoiceStateUpdate.js +29 -0
  22. package/events/discord/VoiceStateUpdate.ts +31 -0
  23. package/events/framework/CommandExecuted.d.ts +7 -0
  24. package/events/framework/CommandExecuted.js +17 -0
  25. package/events/framework/CommandExecuted.ts +16 -0
  26. package/index.d.ts +15 -0
  27. package/index.js +61 -0
  28. package/index.ts +69 -0
  29. package/models/CommandDailyStats.d.ts +9 -0
  30. package/models/CommandDailyStats.js +34 -0
  31. package/models/CommandDailyStats.ts +25 -0
  32. package/models/GuildAnalyticsConfig.d.ts +12 -0
  33. package/models/GuildAnalyticsConfig.js +43 -0
  34. package/models/GuildAnalyticsConfig.ts +34 -0
  35. package/models/GuildDailyStats.d.ts +11 -0
  36. package/models/GuildDailyStats.js +40 -0
  37. package/models/GuildDailyStats.ts +31 -0
  38. package/models/VoiceChannelDailyStats.d.ts +8 -0
  39. package/models/VoiceChannelDailyStats.js +31 -0
  40. package/models/VoiceChannelDailyStats.ts +22 -0
  41. package/package.json +21 -0
  42. package/routes/AdminAnalytics.d.ts +11 -0
  43. package/routes/AdminAnalytics.js +55 -0
  44. package/routes/AdminAnalytics.ts +69 -0
  45. package/routes/UserPanelAnalytics.d.ts +11 -0
  46. package/routes/UserPanelAnalytics.js +81 -0
  47. package/routes/UserPanelAnalytics.ts +101 -0
  48. package/services/AnalyticsCollector.d.ts +62 -0
  49. package/services/AnalyticsCollector.js +470 -0
  50. package/services/AnalyticsCollector.ts +537 -0
  51. package/translations/en.json +63 -0
  52. package/translations/es.json +63 -0
  53. package/tsconfig.json +18 -0
  54. package/views/admin-analytics.ejs +170 -0
  55. package/views/user-analytics.ejs +209 -0
@@ -0,0 +1,23 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ import { ServiceContainer } from 'zumito-framework';
3
+ import { AnalyticsCollector } from '../../services/AnalyticsCollector.js';
4
+
5
+ export class GuildMemberAdd extends FrameworkEvent {
6
+ once = false;
7
+ source = 'discord';
8
+
9
+ private collector = ServiceContainer.getService(AnalyticsCollector) as AnalyticsCollector;
10
+
11
+ async execute({ guildmember }: any): Promise<void> {
12
+ if (!guildmember?.guild?.id) return;
13
+ const guildId = guildmember.guild.id;
14
+ await this.collector.recordMemberJoin(guildId);
15
+
16
+ try {
17
+ const memberCount = guildmember.guild.memberCount;
18
+ if (memberCount) {
19
+ await this.collector.recordMemberCount(guildId, memberCount);
20
+ }
21
+ } catch (_) { /* ignore */ }
22
+ }
23
+ }
@@ -0,0 +1,7 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ export declare class GuildMemberRemove extends FrameworkEvent {
3
+ once: boolean;
4
+ source: string;
5
+ private collector;
6
+ execute({ guildmember }: any): Promise<void>;
7
+ }
@@ -0,0 +1,24 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ import { ServiceContainer } from 'zumito-framework';
3
+ import { AnalyticsCollector } from '../../services/AnalyticsCollector.js';
4
+ export class GuildMemberRemove extends FrameworkEvent {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.once = false;
8
+ this.source = 'discord';
9
+ this.collector = ServiceContainer.getService(AnalyticsCollector);
10
+ }
11
+ async execute({ guildmember }) {
12
+ if (!guildmember?.guild?.id)
13
+ return;
14
+ const guildId = guildmember.guild.id;
15
+ await this.collector.recordMemberLeave(guildId);
16
+ try {
17
+ const memberCount = guildmember.guild.memberCount;
18
+ if (memberCount) {
19
+ await this.collector.recordMemberCount(guildId, memberCount);
20
+ }
21
+ }
22
+ catch (_) { /* ignore */ }
23
+ }
24
+ }
@@ -0,0 +1,23 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ import { ServiceContainer } from 'zumito-framework';
3
+ import { AnalyticsCollector } from '../../services/AnalyticsCollector.js';
4
+
5
+ export class GuildMemberRemove extends FrameworkEvent {
6
+ once = false;
7
+ source = 'discord';
8
+
9
+ private collector = ServiceContainer.getService(AnalyticsCollector) as AnalyticsCollector;
10
+
11
+ async execute({ guildmember }: any): Promise<void> {
12
+ if (!guildmember?.guild?.id) return;
13
+ const guildId = guildmember.guild.id;
14
+ await this.collector.recordMemberLeave(guildId);
15
+
16
+ try {
17
+ const memberCount = guildmember.guild.memberCount;
18
+ if (memberCount) {
19
+ await this.collector.recordMemberCount(guildId, memberCount);
20
+ }
21
+ } catch (_) { /* ignore */ }
22
+ }
23
+ }
@@ -0,0 +1,7 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ export declare class MessageCreate extends FrameworkEvent {
3
+ once: boolean;
4
+ source: string;
5
+ private collector;
6
+ execute({ message }: any): Promise<void>;
7
+ }
@@ -0,0 +1,18 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ import { ServiceContainer } from 'zumito-framework';
3
+ import { AnalyticsCollector } from '../../services/AnalyticsCollector.js';
4
+ export class MessageCreate extends FrameworkEvent {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.once = false;
8
+ this.source = 'discord';
9
+ this.collector = ServiceContainer.getService(AnalyticsCollector);
10
+ }
11
+ async execute({ message }) {
12
+ if (!message.guildId)
13
+ return;
14
+ if (message.author?.bot)
15
+ return;
16
+ await this.collector.recordMessage(message.guildId);
17
+ }
18
+ }
@@ -0,0 +1,16 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ import { ServiceContainer } from 'zumito-framework';
3
+ import { AnalyticsCollector } from '../../services/AnalyticsCollector.js';
4
+
5
+ export class MessageCreate extends FrameworkEvent {
6
+ once = false;
7
+ source = 'discord';
8
+
9
+ private collector = ServiceContainer.getService(AnalyticsCollector) as AnalyticsCollector;
10
+
11
+ async execute({ message }: any): Promise<void> {
12
+ if (!message.guildId) return;
13
+ if (message.author?.bot) return;
14
+ await this.collector.recordMessage(message.guildId);
15
+ }
16
+ }
@@ -0,0 +1,7 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ export declare class VoiceStateUpdate extends FrameworkEvent {
3
+ once: boolean;
4
+ source: string;
5
+ private collector;
6
+ execute({ oldState, newState }: any): Promise<void>;
7
+ }
@@ -0,0 +1,29 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ import { ServiceContainer } from 'zumito-framework';
3
+ import { AnalyticsCollector } from '../../services/AnalyticsCollector.js';
4
+ export class VoiceStateUpdate extends FrameworkEvent {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.once = false;
8
+ this.source = 'discord';
9
+ this.collector = ServiceContainer.getService(AnalyticsCollector);
10
+ }
11
+ async execute({ oldState, newState }) {
12
+ const guildId = newState?.guild?.id || oldState?.guild?.id;
13
+ if (!guildId)
14
+ return;
15
+ const userId = newState?.id || oldState?.id;
16
+ if (!userId)
17
+ return;
18
+ const oldChannelId = oldState?.channelId || null;
19
+ const newChannelId = newState?.channelId || null;
20
+ if (oldChannelId === newChannelId)
21
+ return;
22
+ if (oldChannelId) {
23
+ await this.collector.recordVoiceLeave(guildId, oldChannelId, userId);
24
+ }
25
+ if (newChannelId) {
26
+ await this.collector.recordVoiceJoin(guildId, newChannelId, userId);
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,31 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ import { ServiceContainer } from 'zumito-framework';
3
+ import { AnalyticsCollector } from '../../services/AnalyticsCollector.js';
4
+
5
+ export class VoiceStateUpdate extends FrameworkEvent {
6
+ once = false;
7
+ source = 'discord';
8
+
9
+ private collector = ServiceContainer.getService(AnalyticsCollector) as AnalyticsCollector;
10
+
11
+ async execute({ oldState, newState }: any): Promise<void> {
12
+ const guildId = newState?.guild?.id || oldState?.guild?.id;
13
+ if (!guildId) return;
14
+
15
+ const userId = newState?.id || oldState?.id;
16
+ if (!userId) return;
17
+
18
+ const oldChannelId = oldState?.channelId || null;
19
+ const newChannelId = newState?.channelId || null;
20
+
21
+ if (oldChannelId === newChannelId) return;
22
+
23
+ if (oldChannelId) {
24
+ await this.collector.recordVoiceLeave(guildId, oldChannelId, userId);
25
+ }
26
+
27
+ if (newChannelId) {
28
+ await this.collector.recordVoiceJoin(guildId, newChannelId, userId);
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,7 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ export declare class CommandExecuted extends FrameworkEvent {
3
+ once: boolean;
4
+ source: string;
5
+ private collector;
6
+ execute(args: any): Promise<void>;
7
+ }
@@ -0,0 +1,17 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ import { ServiceContainer } from 'zumito-framework';
3
+ import { AnalyticsCollector } from '../../services/AnalyticsCollector.js';
4
+ export class CommandExecuted extends FrameworkEvent {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.once = false;
8
+ this.source = 'framework';
9
+ this.collector = ServiceContainer.getService(AnalyticsCollector);
10
+ }
11
+ async execute(args) {
12
+ const payload = args.object || args;
13
+ if (!payload.guildId)
14
+ return;
15
+ await this.collector.recordCommand(payload);
16
+ }
17
+ }
@@ -0,0 +1,16 @@
1
+ import { FrameworkEvent } from 'zumito-framework';
2
+ import { ServiceContainer } from 'zumito-framework';
3
+ import { AnalyticsCollector } from '../../services/AnalyticsCollector.js';
4
+
5
+ export class CommandExecuted extends FrameworkEvent {
6
+ once = false;
7
+ source = 'framework';
8
+
9
+ private collector = ServiceContainer.getService(AnalyticsCollector) as AnalyticsCollector;
10
+
11
+ async execute(args: any): Promise<void> {
12
+ const payload = args.object || args;
13
+ if (!payload.guildId) return;
14
+ await this.collector.recordCommand(payload);
15
+ }
16
+ }
package/index.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { Module } from 'zumito-framework';
2
+ export declare class AnalyticsModule extends Module {
3
+ static dependencies: readonly [];
4
+ static optionalDependencies: readonly ["admin-module", "user-panel-module"];
5
+ constructor(modulePath?: string);
6
+ initialize(): Promise<void>;
7
+ onAllReady(): Promise<void>;
8
+ }
9
+ export { AnalyticsCollector } from './services/AnalyticsCollector.js';
10
+ export type { CommandExecutedPayload } from './services/AnalyticsCollector.js';
11
+ export { AnalyticsModuleConfig } from './config.js';
12
+ export { GuildDailyStats } from './models/GuildDailyStats.js';
13
+ export { CommandDailyStats } from './models/CommandDailyStats.js';
14
+ export { VoiceChannelDailyStats } from './models/VoiceChannelDailyStats.js';
15
+ export { GuildAnalyticsConfig } from './models/GuildAnalyticsConfig.js';
package/index.js ADDED
@@ -0,0 +1,61 @@
1
+ import { Module, ServiceContainer } from 'zumito-framework';
2
+ import { AnalyticsCollector } from './services/AnalyticsCollector.js';
3
+ export class AnalyticsModule extends Module {
4
+ constructor(modulePath = import.meta.url) {
5
+ super(modulePath);
6
+ ServiceContainer.addService(AnalyticsCollector, [], true);
7
+ }
8
+ async initialize() {
9
+ await super.initialize();
10
+ try {
11
+ const { NavigationService } = await import('@zumito-team/admin-module/services/NavigationService.js');
12
+ const nav = ServiceContainer.getService(NavigationService);
13
+ nav.registerItem({
14
+ id: 'analytics',
15
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-discord-white/60 group-hover:text-white" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3v18h18"/><path d="M7 16l4-8 4 5 4-3"/></svg>`,
16
+ label: 'Analiticas',
17
+ url: '/admin/analytics',
18
+ order: 8,
19
+ category: 'modules',
20
+ sidebar: {
21
+ showDropdown: false,
22
+ sections: [
23
+ {
24
+ label: 'Analiticas',
25
+ items: [
26
+ { label: 'Dashboard', url: '/admin/analytics' },
27
+ ],
28
+ },
29
+ ],
30
+ },
31
+ });
32
+ }
33
+ catch (e) {
34
+ console.warn('[AnalyticsModule] Admin panel not available, skipping admin integration');
35
+ }
36
+ try {
37
+ const { UserPanelNavigationService } = await import('@zumito-team/user-panel-module/services/UserPanelNavigationService');
38
+ const nav = ServiceContainer.getService(UserPanelNavigationService);
39
+ nav.registerSubItems('dashboard', 'general', [
40
+ { id: 'analytics', label: 'analytics.sidebarTitle', url: '/panel/:guildId/analytics' },
41
+ ]);
42
+ }
43
+ catch (e) {
44
+ console.warn('[AnalyticsModule] User panel not available, skipping user panel integration');
45
+ }
46
+ const collector = ServiceContainer.getService(AnalyticsCollector);
47
+ collector.startCleanupScheduler();
48
+ }
49
+ async onAllReady() {
50
+ const collector = ServiceContainer.getService(AnalyticsCollector);
51
+ collector.clearVoiceSessions();
52
+ }
53
+ }
54
+ AnalyticsModule.dependencies = [];
55
+ AnalyticsModule.optionalDependencies = ['admin-module', 'user-panel-module'];
56
+ export { AnalyticsCollector } from './services/AnalyticsCollector.js';
57
+ export { AnalyticsModuleConfig } from './config.js';
58
+ export { GuildDailyStats } from './models/GuildDailyStats.js';
59
+ export { CommandDailyStats } from './models/CommandDailyStats.js';
60
+ export { VoiceChannelDailyStats } from './models/VoiceChannelDailyStats.js';
61
+ export { GuildAnalyticsConfig } from './models/GuildAnalyticsConfig.js';
package/index.ts ADDED
@@ -0,0 +1,69 @@
1
+ import { Module, ServiceContainer } from 'zumito-framework';
2
+ import { AnalyticsCollector } from './services/AnalyticsCollector.js';
3
+ import { AnalyticsModuleConfig } from './config.js';
4
+
5
+ export class AnalyticsModule extends Module {
6
+ static dependencies = [] as const;
7
+ static optionalDependencies = ['admin-module', 'user-panel-module'] as const;
8
+
9
+ constructor(modulePath: string = import.meta.url) {
10
+ super(modulePath);
11
+ ServiceContainer.addService(AnalyticsCollector, [], true);
12
+ }
13
+
14
+ async initialize(): Promise<void> {
15
+ await super.initialize();
16
+
17
+ try {
18
+ const { NavigationService } = await import('@zumito-team/admin-module/services/NavigationService.js');
19
+ const nav = ServiceContainer.getService(NavigationService);
20
+ nav.registerItem({
21
+ id: 'analytics',
22
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-discord-white/60 group-hover:text-white" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3v18h18"/><path d="M7 16l4-8 4 5 4-3"/></svg>`,
23
+ label: 'Analiticas',
24
+ url: '/admin/analytics',
25
+ order: 8,
26
+ category: 'modules',
27
+ sidebar: {
28
+ showDropdown: false,
29
+ sections: [
30
+ {
31
+ label: 'Analiticas',
32
+ items: [
33
+ { label: 'Dashboard', url: '/admin/analytics' },
34
+ ],
35
+ },
36
+ ],
37
+ },
38
+ });
39
+ } catch (e) {
40
+ console.warn('[AnalyticsModule] Admin panel not available, skipping admin integration');
41
+ }
42
+
43
+ try {
44
+ const { UserPanelNavigationService } = await import('@zumito-team/user-panel-module/services/UserPanelNavigationService');
45
+ const nav = ServiceContainer.getService(UserPanelNavigationService);
46
+ nav.registerSubItems('dashboard', 'general', [
47
+ { id: 'analytics', label: 'analytics.sidebarTitle', url: '/panel/:guildId/analytics' },
48
+ ]);
49
+ } catch (e) {
50
+ console.warn('[AnalyticsModule] User panel not available, skipping user panel integration');
51
+ }
52
+
53
+ const collector = ServiceContainer.getService(AnalyticsCollector) as AnalyticsCollector;
54
+ collector.startCleanupScheduler();
55
+ }
56
+
57
+ async onAllReady(): Promise<void> {
58
+ const collector = ServiceContainer.getService(AnalyticsCollector) as AnalyticsCollector;
59
+ collector.clearVoiceSessions();
60
+ }
61
+ }
62
+
63
+ export { AnalyticsCollector } from './services/AnalyticsCollector.js';
64
+ export type { CommandExecutedPayload } from './services/AnalyticsCollector.js';
65
+ export { AnalyticsModuleConfig } from './config.js';
66
+ export { GuildDailyStats } from './models/GuildDailyStats.js';
67
+ export { CommandDailyStats } from './models/CommandDailyStats.js';
68
+ export { VoiceChannelDailyStats } from './models/VoiceChannelDailyStats.js';
69
+ export { GuildAnalyticsConfig } from './models/GuildAnalyticsConfig.js';
@@ -0,0 +1,9 @@
1
+ export declare class CommandDailyStats {
2
+ id: string;
3
+ guild_id: string;
4
+ command_name: string;
5
+ date: string;
6
+ usage_count: number;
7
+ total_execution_time_ms: number;
8
+ error_count: number;
9
+ }
@@ -0,0 +1,34 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Collection, Field } from 'zumito-framework';
8
+ let CommandDailyStats = class CommandDailyStats {
9
+ };
10
+ __decorate([
11
+ Field({ type: 'string', primary: true, unique: true })
12
+ ], CommandDailyStats.prototype, "id", void 0);
13
+ __decorate([
14
+ Field({ type: 'string' })
15
+ ], CommandDailyStats.prototype, "guild_id", void 0);
16
+ __decorate([
17
+ Field({ type: 'string' })
18
+ ], CommandDailyStats.prototype, "command_name", void 0);
19
+ __decorate([
20
+ Field({ type: 'string' })
21
+ ], CommandDailyStats.prototype, "date", void 0);
22
+ __decorate([
23
+ Field({ type: 'number', default: 0 })
24
+ ], CommandDailyStats.prototype, "usage_count", void 0);
25
+ __decorate([
26
+ Field({ type: 'number', default: 0 })
27
+ ], CommandDailyStats.prototype, "total_execution_time_ms", void 0);
28
+ __decorate([
29
+ Field({ type: 'number', default: 0 })
30
+ ], CommandDailyStats.prototype, "error_count", void 0);
31
+ CommandDailyStats = __decorate([
32
+ Collection({ name: 'analytics_command_daily_stats' })
33
+ ], CommandDailyStats);
34
+ export { CommandDailyStats };
@@ -0,0 +1,25 @@
1
+ import { Collection, Field } from 'zumito-framework';
2
+
3
+ @Collection({ name: 'analytics_command_daily_stats' })
4
+ export class CommandDailyStats {
5
+ @Field({ type: 'string', primary: true, unique: true })
6
+ id!: string;
7
+
8
+ @Field({ type: 'string' })
9
+ guild_id!: string;
10
+
11
+ @Field({ type: 'string' })
12
+ command_name!: string;
13
+
14
+ @Field({ type: 'string' })
15
+ date!: string;
16
+
17
+ @Field({ type: 'number', default: 0 })
18
+ usage_count!: number;
19
+
20
+ @Field({ type: 'number', default: 0 })
21
+ total_execution_time_ms!: number;
22
+
23
+ @Field({ type: 'number', default: 0 })
24
+ error_count!: number;
25
+ }
@@ -0,0 +1,12 @@
1
+ export declare class GuildAnalyticsConfig {
2
+ guild_id: string;
3
+ enabled: boolean;
4
+ track_messages: boolean;
5
+ track_voice: boolean;
6
+ track_members: boolean;
7
+ track_commands: boolean;
8
+ track_command_performance: boolean;
9
+ track_per_channel_voice: boolean;
10
+ retention_days: number;
11
+ public_stats_page: boolean;
12
+ }
@@ -0,0 +1,43 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Collection, Field } from 'zumito-framework';
8
+ let GuildAnalyticsConfig = class GuildAnalyticsConfig {
9
+ };
10
+ __decorate([
11
+ Field({ type: 'string', primary: true, unique: true })
12
+ ], GuildAnalyticsConfig.prototype, "guild_id", void 0);
13
+ __decorate([
14
+ Field({ type: 'boolean', default: true })
15
+ ], GuildAnalyticsConfig.prototype, "enabled", void 0);
16
+ __decorate([
17
+ Field({ type: 'boolean', default: true })
18
+ ], GuildAnalyticsConfig.prototype, "track_messages", void 0);
19
+ __decorate([
20
+ Field({ type: 'boolean', default: true })
21
+ ], GuildAnalyticsConfig.prototype, "track_voice", void 0);
22
+ __decorate([
23
+ Field({ type: 'boolean', default: true })
24
+ ], GuildAnalyticsConfig.prototype, "track_members", void 0);
25
+ __decorate([
26
+ Field({ type: 'boolean', default: true })
27
+ ], GuildAnalyticsConfig.prototype, "track_commands", void 0);
28
+ __decorate([
29
+ Field({ type: 'boolean', default: false })
30
+ ], GuildAnalyticsConfig.prototype, "track_command_performance", void 0);
31
+ __decorate([
32
+ Field({ type: 'boolean', default: false })
33
+ ], GuildAnalyticsConfig.prototype, "track_per_channel_voice", void 0);
34
+ __decorate([
35
+ Field({ type: 'number' })
36
+ ], GuildAnalyticsConfig.prototype, "retention_days", void 0);
37
+ __decorate([
38
+ Field({ type: 'boolean', default: false })
39
+ ], GuildAnalyticsConfig.prototype, "public_stats_page", void 0);
40
+ GuildAnalyticsConfig = __decorate([
41
+ Collection({ name: 'analytics_guild_config' })
42
+ ], GuildAnalyticsConfig);
43
+ export { GuildAnalyticsConfig };
@@ -0,0 +1,34 @@
1
+ import { Collection, Field } from 'zumito-framework';
2
+
3
+ @Collection({ name: 'analytics_guild_config' })
4
+ export class GuildAnalyticsConfig {
5
+ @Field({ type: 'string', primary: true, unique: true })
6
+ guild_id!: string;
7
+
8
+ @Field({ type: 'boolean', default: true })
9
+ enabled!: boolean;
10
+
11
+ @Field({ type: 'boolean', default: true })
12
+ track_messages!: boolean;
13
+
14
+ @Field({ type: 'boolean', default: true })
15
+ track_voice!: boolean;
16
+
17
+ @Field({ type: 'boolean', default: true })
18
+ track_members!: boolean;
19
+
20
+ @Field({ type: 'boolean', default: true })
21
+ track_commands!: boolean;
22
+
23
+ @Field({ type: 'boolean', default: false })
24
+ track_command_performance!: boolean;
25
+
26
+ @Field({ type: 'boolean', default: false })
27
+ track_per_channel_voice!: boolean;
28
+
29
+ @Field({ type: 'number' })
30
+ retention_days!: number;
31
+
32
+ @Field({ type: 'boolean', default: false })
33
+ public_stats_page!: boolean;
34
+ }
@@ -0,0 +1,11 @@
1
+ export declare class GuildDailyStats {
2
+ id: string;
3
+ guild_id: string;
4
+ date: string;
5
+ message_count: number;
6
+ join_count: number;
7
+ leave_count: number;
8
+ voice_minutes: number;
9
+ command_count: number;
10
+ member_count: number;
11
+ }
@@ -0,0 +1,40 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Collection, Field } from 'zumito-framework';
8
+ let GuildDailyStats = class GuildDailyStats {
9
+ };
10
+ __decorate([
11
+ Field({ type: 'string', primary: true, unique: true })
12
+ ], GuildDailyStats.prototype, "id", void 0);
13
+ __decorate([
14
+ Field({ type: 'string' })
15
+ ], GuildDailyStats.prototype, "guild_id", void 0);
16
+ __decorate([
17
+ Field({ type: 'string' })
18
+ ], GuildDailyStats.prototype, "date", void 0);
19
+ __decorate([
20
+ Field({ type: 'number', default: 0 })
21
+ ], GuildDailyStats.prototype, "message_count", void 0);
22
+ __decorate([
23
+ Field({ type: 'number', default: 0 })
24
+ ], GuildDailyStats.prototype, "join_count", void 0);
25
+ __decorate([
26
+ Field({ type: 'number', default: 0 })
27
+ ], GuildDailyStats.prototype, "leave_count", void 0);
28
+ __decorate([
29
+ Field({ type: 'number', default: 0 })
30
+ ], GuildDailyStats.prototype, "voice_minutes", void 0);
31
+ __decorate([
32
+ Field({ type: 'number', default: 0 })
33
+ ], GuildDailyStats.prototype, "command_count", void 0);
34
+ __decorate([
35
+ Field({ type: 'number', default: 0 })
36
+ ], GuildDailyStats.prototype, "member_count", void 0);
37
+ GuildDailyStats = __decorate([
38
+ Collection({ name: 'analytics_guild_daily_stats' })
39
+ ], GuildDailyStats);
40
+ export { GuildDailyStats };
@@ -0,0 +1,31 @@
1
+ import { Collection, Field } from 'zumito-framework';
2
+
3
+ @Collection({ name: 'analytics_guild_daily_stats' })
4
+ export class GuildDailyStats {
5
+ @Field({ type: 'string', primary: true, unique: true })
6
+ id!: string;
7
+
8
+ @Field({ type: 'string' })
9
+ guild_id!: string;
10
+
11
+ @Field({ type: 'string' })
12
+ date!: string;
13
+
14
+ @Field({ type: 'number', default: 0 })
15
+ message_count!: number;
16
+
17
+ @Field({ type: 'number', default: 0 })
18
+ join_count!: number;
19
+
20
+ @Field({ type: 'number', default: 0 })
21
+ leave_count!: number;
22
+
23
+ @Field({ type: 'number', default: 0 })
24
+ voice_minutes!: number;
25
+
26
+ @Field({ type: 'number', default: 0 })
27
+ command_count!: number;
28
+
29
+ @Field({ type: 'number', default: 0 })
30
+ member_count!: number;
31
+ }
@@ -0,0 +1,8 @@
1
+ export declare class VoiceChannelDailyStats {
2
+ id: string;
3
+ guild_id: string;
4
+ channel_id: string;
5
+ date: string;
6
+ total_minutes: number;
7
+ unique_users: number;
8
+ }