fac-shared-db 1.0.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 (54) hide show
  1. package/README.md +66 -0
  2. package/build/connection.d.ts +9 -0
  3. package/build/connection.js +13 -0
  4. package/build/index.d.ts +2 -0
  5. package/build/index.js +2 -0
  6. package/build/models/AcaoMarcada.d.ts +38 -0
  7. package/build/models/AcaoMarcada.js +18 -0
  8. package/build/models/AcoesConfig.d.ts +32 -0
  9. package/build/models/AcoesConfig.js +33 -0
  10. package/build/models/Advertencia.d.ts +44 -0
  11. package/build/models/Advertencia.js +20 -0
  12. package/build/models/AntiGrabberConfig.d.ts +24 -0
  13. package/build/models/AntiGrabberConfig.js +9 -0
  14. package/build/models/BindsRoupaConfig.d.ts +29 -0
  15. package/build/models/BindsRoupaConfig.js +21 -0
  16. package/build/models/Blacklist.d.ts +16 -0
  17. package/build/models/Blacklist.js +10 -0
  18. package/build/models/BotConfig.d.ts +72 -0
  19. package/build/models/BotConfig.js +66 -0
  20. package/build/models/Caixa2Item.d.ts +14 -0
  21. package/build/models/Caixa2Item.js +8 -0
  22. package/build/models/CanalConfig.d.ts +19 -0
  23. package/build/models/CanalConfig.js +9 -0
  24. package/build/models/CargoConfig.d.ts +18 -0
  25. package/build/models/CargoConfig.js +12 -0
  26. package/build/models/CraftConfig.d.ts +41 -0
  27. package/build/models/CraftConfig.js +31 -0
  28. package/build/models/Farm.d.ts +23 -0
  29. package/build/models/Farm.js +19 -0
  30. package/build/models/FarmValidacaoState.d.ts +48 -0
  31. package/build/models/FarmValidacaoState.js +31 -0
  32. package/build/models/FeatureTogglesConfig.d.ts +17 -0
  33. package/build/models/FeatureTogglesConfig.js +6 -0
  34. package/build/models/History.d.ts +14 -0
  35. package/build/models/History.js +7 -0
  36. package/build/models/KeyValue.d.ts +13 -0
  37. package/build/models/KeyValue.js +6 -0
  38. package/build/models/MembroCadastro.d.ts +16 -0
  39. package/build/models/MembroCadastro.js +9 -0
  40. package/build/models/MensagemRecrutamento.d.ts +15 -0
  41. package/build/models/MensagemRecrutamento.js +9 -0
  42. package/build/models/MensagemRotacao.d.ts +18 -0
  43. package/build/models/MensagemRotacao.js +11 -0
  44. package/build/models/RegistroOlheiro.d.ts +33 -0
  45. package/build/models/RegistroOlheiro.js +19 -0
  46. package/build/models/UpRegistro.d.ts +20 -0
  47. package/build/models/UpRegistro.js +10 -0
  48. package/build/models/Venda.d.ts +21 -0
  49. package/build/models/Venda.js +13 -0
  50. package/build/models/VendaConfig.d.ts +23 -0
  51. package/build/models/VendaConfig.js +13 -0
  52. package/build/models/index.d.ts +46 -0
  53. package/build/models/index.js +23 -0
  54. package/package.json +28 -0
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # fac-shared-db
2
+
3
+ Schemas Mongoose e helper de conexão compartilhados entre os bots do ecossistema (atualmente: `real-street-rp`, `marcar-acao-gta-rp`, `logs-exporter-gta-rp`, `pedir-rec-discord`). Todos os bots conectam direto no mesmo MongoDB Atlas — este pacote existe para que o formato de cada collection seja definido em um único lugar, em vez de duplicado/hand-rolled em cada bot.
4
+
5
+ ## Uso
6
+
7
+ ```ts
8
+ import { connectDatabase, AcaoMarcadaModel } from "fac-shared-db";
9
+
10
+ await connectDatabase(process.env.MONGO_URI!, "real-street-rp");
11
+
12
+ const acoes = await AcaoMarcadaModel.find({ resultado: "pendente" });
13
+ ```
14
+
15
+ `connectDatabase(uri, dbName?)` não conhece cluster, host ou `appName` de nenhum bot — cada bot monta sua própria connection string a partir das próprias env vars e decide como reagir a falha de conexão (retry, log, `process.exit`, etc). Isso mantém o pacote agnóstico em relação a qual bot o está consumindo.
16
+
17
+ ## Instalação
18
+
19
+ Distribuído como dependência git (sem publicação no npm):
20
+
21
+ ```json
22
+ "dependencies": {
23
+ "fac-shared-db": "git+https://github.com/Weslley08/fac-shared-db.git"
24
+ }
25
+ ```
26
+
27
+ O script `prepare` compila o TypeScript automaticamente após `npm install`.
28
+
29
+ ## Collections
30
+
31
+ | Model | Collection (Mongo) | Propósito |
32
+ |---|---|---|
33
+ | `AcaoMarcadaModel` | `acaomarcadas` | Ação escalada no canal de escalação (participantes, escalados, resultado) |
34
+ | `AcoesConfigModel` | `acoesconfigs` | Singleton: ações disponíveis + calendário semanal |
35
+ | `AdvertenciaModel` | `advertencias` | Advertências aplicadas a membros (nível, tipo, vencimento) |
36
+ | `AntiGrabberConfigModel` | `antigrabberconfigs` | Singleton: config do anti-spam de anexos |
37
+ | `BindsRoupaConfigModel` | `bindsroupaconfigs` | Singleton: grupos de binds de roupa por cargo |
38
+ | `BlacklistModel` | `blacklist` (override explícito) | Banimento de jogadores, com TTL automático |
39
+ | `BotConfigModel` | `botconfigs` | Singleton: configuração geral do bot |
40
+ | `Caixa2ItemModel` | `caixa2itens` (override explícito) | Itens do baú com limites de advertência |
41
+ | `CanalConfigModel` | `canalconfigs` | Associação de canais lógicos → IDs Discord |
42
+ | `CargoConfigModel` | `cargoconfigs` | Hierarquia/config de cargos |
43
+ | `CraftConfigModel` | `craftconfigs` | Singleton: receitas de craft de munição |
44
+ | `FarmModel` | `farms` | Registro de farm por membro |
45
+ | `FarmValidacaoStateModel` | `farmvalidacaostates` | Estado persistido da validação de farm (TTL 10min) |
46
+ | `FeatureTogglesConfigModel` | `featuretogglesconfigs` | Singleton: feature flags via DB |
47
+ | `MembroCadastroModel` | `membrocadastros` | Cadastro de membro (nome/ID in-game) |
48
+ | `MensagemRecrutamentoModel` | `mensagemrecrutamentos` | Singleton (`_id: "RECRUTAMENTO"`): texto de recrutamento vigente |
49
+ | `MensagemRotacaoModel` | `mensagemrotacaos` | Mensagens que rotacionam em canais |
50
+ | `RegistroOlheiroModel` | `registroolheiros` | Registro de olheiro/recrutamento |
51
+ | `UpRegistroModel` | `upregistros` | Registro de promoção (UP) de membro |
52
+ | `VendaModel` | `vendas` | Registro de venda de munição |
53
+ | `VendaConfigModel` | `vendaconfigs` | Singleton: preços e comissão de venda |
54
+ | `KeyValueModel` | `keyvalues` | Storage genérico key-value |
55
+ | `HistoryModel` | `histories` | Histórico append-only genérico |
56
+
57
+ Nomes de collection sem "override explícito" são o default do Mongoose (pluralização automática do nome do model) — não dependem de nenhuma string hardcoded neste pacote.
58
+
59
+ ## Quem lê/escreve o quê hoje
60
+
61
+ - **real-street-rp**: dono de todas as collections acima (cria/atualiza a maioria via painel admin e fluxos internos).
62
+ - **marcar-acao-gta-rp**: escreve em `acaomarcadas` (cria novas ações quando confirmadas via DM).
63
+ - **pedir-rec-discord**: lê `mensagemrecrutamentos` (texto de recrutamento vigente, em vez de hardcoded).
64
+ - **logs-exporter-gta-rp**: escreve em `blacklist` (upsert a partir do parsing de logs) e lê `caixa2itens` (limites de itens monitorados).
65
+
66
+ Ao adicionar uma collection nova usada por mais de um bot, ela nasce neste pacote — não em um dos bots individualmente.
@@ -0,0 +1,9 @@
1
+ import mongoose from "mongoose";
2
+ /**
3
+ * Conecta ao MongoDB via Mongoose a partir de uma connection string já montada
4
+ * pelo bot consumidor. Este pacote não conhece cluster, host ou appName de
5
+ * nenhum bot específico — cada bot monta sua própria URI a partir das próprias
6
+ * env vars e decide como lidar com falha de conexão (retry, log, exit, etc).
7
+ */
8
+ export declare function connectDatabase(uri: string, dbName?: string): Promise<typeof mongoose>;
9
+ export { mongoose };
@@ -0,0 +1,13 @@
1
+ import mongoose from "mongoose";
2
+ /**
3
+ * Conecta ao MongoDB via Mongoose a partir de uma connection string já montada
4
+ * pelo bot consumidor. Este pacote não conhece cluster, host ou appName de
5
+ * nenhum bot específico — cada bot monta sua própria URI a partir das próprias
6
+ * env vars e decide como lidar com falha de conexão (retry, log, exit, etc).
7
+ */
8
+ export async function connectDatabase(uri, dbName) {
9
+ if (mongoose.connection.readyState === 1)
10
+ return mongoose;
11
+ return mongoose.connect(uri, dbName ? { dbName } : undefined);
12
+ }
13
+ export { mongoose };
@@ -0,0 +1,2 @@
1
+ export * from "./connection.js";
2
+ export * from "./models/index.js";
package/build/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./connection.js";
2
+ export * from "./models/index.js";
@@ -0,0 +1,38 @@
1
+ import mongoose, { type Document } from "mongoose";
2
+ /**
3
+ * Registro de uma ação marcada no sistema de ações.
4
+ * Cada documento = 1 ação criada no canal de escalação.
5
+ */
6
+ export interface IAcaoMarcada extends Document {
7
+ /** Data da ação (dd/mm/yyyy) */
8
+ data: string;
9
+ /** Hora da ação (hh:mm) */
10
+ hora: string;
11
+ /** Máximo de membros permitidos */
12
+ maxMembros: number;
13
+ /** Discord IDs dos interessados (quem clicou em participar) */
14
+ participantes: string[];
15
+ /** Discord IDs dos escalados (selecionados pelo líder tático) */
16
+ escalados: string[];
17
+ /** Discord ID de quem criou a ação */
18
+ criadoPor: string;
19
+ /** Resultado da ação */
20
+ resultado: "ganhou" | "perdeu" | "pendente";
21
+ /** ID da mensagem no canal de escalação */
22
+ mensagemId: string;
23
+ /** Nome/descrição da ação */
24
+ nome: string;
25
+ /** Data de criação */
26
+ criadoEm: Date;
27
+ /** Data de finalização (quando resultado foi definido) */
28
+ finalizadoEm?: Date;
29
+ /** Data/hora da ação como Date (para queries eficientes no MongoDB) */
30
+ dataHoraAcao: Date;
31
+ }
32
+ export declare const AcaoMarcadaModel: mongoose.Model<IAcaoMarcada, {}, {}, {}, mongoose.Document<unknown, {}, IAcaoMarcada, {}, mongoose.DefaultSchemaOptions> & IAcaoMarcada & Required<{
33
+ _id: mongoose.Types.ObjectId;
34
+ }> & {
35
+ __v: number;
36
+ } & {
37
+ id: string;
38
+ }, any, IAcaoMarcada>;
@@ -0,0 +1,18 @@
1
+ import mongoose, { Schema } from "mongoose";
2
+ const AcaoMarcadaSchema = new Schema({
3
+ data: { type: String, required: true },
4
+ hora: { type: String, required: true },
5
+ maxMembros: { type: Number, required: true },
6
+ participantes: { type: [String], default: [] },
7
+ escalados: { type: [String], default: [] },
8
+ criadoPor: { type: String, required: true, index: true },
9
+ resultado: { type: String, default: "pendente", enum: ["ganhou", "perdeu", "pendente"], index: true },
10
+ nome: { type: String, required: true },
11
+ mensagemId: { type: String, required: true, unique: true },
12
+ criadoEm: { type: Date, default: Date.now },
13
+ finalizadoEm: { type: Date },
14
+ dataHoraAcao: { type: Date, required: true, index: true },
15
+ });
16
+ // Índice para relatórios por período
17
+ AcaoMarcadaSchema.index({ criadoEm: -1 });
18
+ export const AcaoMarcadaModel = mongoose.model("AcaoMarcada", AcaoMarcadaSchema);
@@ -0,0 +1,32 @@
1
+ import mongoose, { type Document } from "mongoose";
2
+ /**
3
+ * Configuração de Ações e Calendário Semanal.
4
+ * Extraído de BotConfig — uso Singleton via configId fixo ("main").
5
+ */
6
+ export interface IAcoesConfig extends Document {
7
+ configId: string;
8
+ /** Lista de ações disponíveis para marcação */
9
+ acoesDisponiveis: {
10
+ chave: string;
11
+ nome: string;
12
+ maxParticipantes: number;
13
+ }[];
14
+ /** ID do bot externo de marcar ação (DM) */
15
+ marcarAcaoBotUserId: string;
16
+ /** Calendário semanal de ações (dia 0=domingo .. 6=sábado) */
17
+ calendarioSemanal: {
18
+ dia: number;
19
+ acaoChave: string;
20
+ hora: string;
21
+ escalados: number;
22
+ }[];
23
+ /** Data (YYYY-MM-DD) do último envio automático do calendário */
24
+ calendarioUltimoEnvio: string;
25
+ }
26
+ export declare const AcoesConfigModel: mongoose.Model<IAcoesConfig, {}, {}, {}, mongoose.Document<unknown, {}, IAcoesConfig, {}, mongoose.DefaultSchemaOptions> & IAcoesConfig & Required<{
27
+ _id: mongoose.Types.ObjectId;
28
+ }> & {
29
+ __v: number;
30
+ } & {
31
+ id: string;
32
+ }, any, IAcoesConfig>;
@@ -0,0 +1,33 @@
1
+ import mongoose, { Schema } from "mongoose";
2
+ const AcoesConfigSchema = new Schema({
3
+ configId: { type: String, default: "main", unique: true },
4
+ acoesDisponiveis: {
5
+ type: [{
6
+ chave: { type: String, required: true },
7
+ nome: { type: String, required: true },
8
+ maxParticipantes: { type: Number, required: true },
9
+ }],
10
+ default: [
11
+ { chave: "niobio", nome: "Nióbio", maxParticipantes: 15 },
12
+ { chave: "paleto", nome: "Paleto", maxParticipantes: 6 },
13
+ { chave: "jojo", nome: "Jojo", maxParticipantes: 8 },
14
+ { chave: "bc", nome: "BC", maxParticipantes: 12 },
15
+ { chave: "flecca_life", nome: "Flecca Life", maxParticipantes: 8 },
16
+ { chave: "flecca_praia", nome: "Flecca Praia", maxParticipantes: 8 },
17
+ { chave: "flecca_chaves", nome: "Flecca Chaves", maxParticipantes: 8 },
18
+ { chave: "madereira", nome: "Madereira", maxParticipantes: 10 },
19
+ ],
20
+ },
21
+ marcarAcaoBotUserId: { type: String, default: "1479954523886718997" },
22
+ calendarioSemanal: {
23
+ type: [{
24
+ dia: { type: Number, required: true },
25
+ acaoChave: { type: String, required: true },
26
+ hora: { type: String, required: true },
27
+ escalados: { type: Number, required: true },
28
+ }],
29
+ default: [],
30
+ },
31
+ calendarioUltimoEnvio: { type: String, default: "" },
32
+ });
33
+ export const AcoesConfigModel = mongoose.model("AcoesConfig", AcoesConfigSchema);
@@ -0,0 +1,44 @@
1
+ import mongoose, { type Document } from "mongoose";
2
+ /**
3
+ * Registro de advertência aplicada a um membro.
4
+ * Cada documento = 1 advertência.
5
+ */
6
+ /** Tipo/categoria da advertência */
7
+ export type TipoAdvertencia = "caixa2" | "farm" | "outros";
8
+ export interface IAdvertencia extends Document {
9
+ /** Discord ID do membro advertido */
10
+ membroId: string;
11
+ /** Nome in-game no momento da ADV */
12
+ nomeInGame: string;
13
+ /** ID in-game no momento da ADV */
14
+ idInGame: string;
15
+ /** Nível da ADV (1, 2 ou 3) */
16
+ nivel: 1 | 2 | 3;
17
+ /** Tipo/categoria da advertência */
18
+ tipo: TipoAdvertencia;
19
+ /** Motivo da advertência */
20
+ motivo: string;
21
+ /** Link de evidência (opcional) */
22
+ evidencia?: string;
23
+ /** Discord ID de quem aplicou */
24
+ aplicadoPor: string;
25
+ /** Se a ADV ainda está ativa ou foi removida */
26
+ ativa: boolean;
27
+ /** Data de aplicação */
28
+ criadoEm: Date;
29
+ /** Data de expiração automática (ADVs antigas podem não ter) */
30
+ expiraEm?: Date;
31
+ /** Data em que expirou de fato (se expirou) */
32
+ expiradaEm?: Date;
33
+ /** Data de remoção (se removida manualmente) */
34
+ removidoEm?: Date;
35
+ /** Quem removeu (se removida manualmente) */
36
+ removidoPor?: string;
37
+ }
38
+ export declare const AdvertenciaModel: mongoose.Model<IAdvertencia, {}, {}, {}, mongoose.Document<unknown, {}, IAdvertencia, {}, mongoose.DefaultSchemaOptions> & IAdvertencia & Required<{
39
+ _id: mongoose.Types.ObjectId;
40
+ }> & {
41
+ __v: number;
42
+ } & {
43
+ id: string;
44
+ }, any, IAdvertencia>;
@@ -0,0 +1,20 @@
1
+ import mongoose, { Schema } from "mongoose";
2
+ const AdvertenciaSchema = new Schema({
3
+ membroId: { type: String, required: true, index: true },
4
+ nomeInGame: { type: String, required: true },
5
+ idInGame: { type: String, required: true },
6
+ nivel: { type: Number, required: true, enum: [1, 2, 3] },
7
+ tipo: { type: String, required: true, enum: ["caixa2", "farm", "outros"], default: "outros" },
8
+ motivo: { type: String, required: true },
9
+ evidencia: { type: String },
10
+ aplicadoPor: { type: String, required: true },
11
+ ativa: { type: Boolean, default: true, index: true },
12
+ criadoEm: { type: Date, default: Date.now },
13
+ expiraEm: { type: Date, index: true },
14
+ expiradaEm: { type: Date },
15
+ removidoEm: { type: Date },
16
+ removidoPor: { type: String },
17
+ });
18
+ // Índice composto para buscar ADVs ativas de um membro rapidamente
19
+ AdvertenciaSchema.index({ membroId: 1, ativa: 1 });
20
+ export const AdvertenciaModel = mongoose.model("Advertencia", AdvertenciaSchema);
@@ -0,0 +1,24 @@
1
+ import mongoose, { type Document } from "mongoose";
2
+ /**
3
+ * Configurações do sistema Anti-Grabber.
4
+ * Coleção própria — segregada do BotConfig.
5
+ * Uso Singleton via configId fixo ("main").
6
+ */
7
+ export interface IAntiGrabberConfig extends Document {
8
+ configId: string;
9
+ /** IDs de canais ignorados (anexos não disparam a detecção) */
10
+ canaisIgnorados: string[];
11
+ /** Janela de tempo (segundos) para agrupar mensagens do mesmo usuário */
12
+ janelaSegundos: number;
13
+ /** Mínimo de canais distintos com anexo na janela para acionar a detecção */
14
+ minCanais: number;
15
+ /** Duração do timeout aplicado ao membro (horas) */
16
+ timeoutHoras: number;
17
+ }
18
+ export declare const AntiGrabberConfigModel: mongoose.Model<IAntiGrabberConfig, {}, {}, {}, mongoose.Document<unknown, {}, IAntiGrabberConfig, {}, mongoose.DefaultSchemaOptions> & IAntiGrabberConfig & Required<{
19
+ _id: mongoose.Types.ObjectId;
20
+ }> & {
21
+ __v: number;
22
+ } & {
23
+ id: string;
24
+ }, any, IAntiGrabberConfig>;
@@ -0,0 +1,9 @@
1
+ import mongoose, { Schema } from "mongoose";
2
+ const AntiGrabberConfigSchema = new Schema({
3
+ configId: { type: String, default: "main", unique: true },
4
+ canaisIgnorados: { type: [String], default: [] },
5
+ janelaSegundos: { type: Number, default: 8 },
6
+ minCanais: { type: Number, default: 3 },
7
+ timeoutHoras: { type: Number, default: 24 },
8
+ });
9
+ export const AntiGrabberConfigModel = mongoose.model("AntiGrabberConfig", AntiGrabberConfigSchema);
@@ -0,0 +1,29 @@
1
+ import mongoose, { type Document } from "mongoose";
2
+ /**
3
+ * Configuração de Binds de Roupa.
4
+ * Extraído de BotConfig — uso Singleton via configId fixo ("main").
5
+ */
6
+ export interface IBindsRoupaConfig extends Document {
7
+ configId: string;
8
+ /** Grupos de cargos (100% configuráveis via painel admin), cada um com presets de roupa masculino/feminino */
9
+ bindsRoupaGrupos: {
10
+ id: string;
11
+ label: string;
12
+ cargoKeys: string[];
13
+ masculino: {
14
+ imagemUrl: string;
15
+ bindTexto: string;
16
+ };
17
+ feminino: {
18
+ imagemUrl: string;
19
+ bindTexto: string;
20
+ };
21
+ }[];
22
+ }
23
+ export declare const BindsRoupaConfigModel: mongoose.Model<IBindsRoupaConfig, {}, {}, {}, mongoose.Document<unknown, {}, IBindsRoupaConfig, {}, mongoose.DefaultSchemaOptions> & IBindsRoupaConfig & Required<{
24
+ _id: mongoose.Types.ObjectId;
25
+ }> & {
26
+ __v: number;
27
+ } & {
28
+ id: string;
29
+ }, any, IBindsRoupaConfig>;
@@ -0,0 +1,21 @@
1
+ import mongoose, { Schema } from "mongoose";
2
+ const BindsRoupaConfigSchema = new Schema({
3
+ configId: { type: String, default: "main", unique: true },
4
+ bindsRoupaGrupos: {
5
+ type: [{
6
+ id: { type: String, required: true },
7
+ label: { type: String, required: true },
8
+ cargoKeys: { type: [String], default: [] },
9
+ masculino: {
10
+ imagemUrl: { type: String, default: "" },
11
+ bindTexto: { type: String, default: "" },
12
+ },
13
+ feminino: {
14
+ imagemUrl: { type: String, default: "" },
15
+ bindTexto: { type: String, default: "" },
16
+ },
17
+ }],
18
+ default: [],
19
+ },
20
+ });
21
+ export const BindsRoupaConfigModel = mongoose.model("BindsRoupaConfig", BindsRoupaConfigSchema);
@@ -0,0 +1,16 @@
1
+ import mongoose, { type Document } from "mongoose";
2
+ export interface IBlacklist extends Document {
3
+ playerId: string;
4
+ organizacao?: string;
5
+ cargo?: string;
6
+ vencimento: Date;
7
+ criadoEm: Date;
8
+ atualizadoEm: Date;
9
+ }
10
+ export declare const BlacklistModel: mongoose.Model<IBlacklist, {}, {}, {}, mongoose.Document<unknown, {}, IBlacklist, {}, mongoose.DefaultSchemaOptions> & IBlacklist & Required<{
11
+ _id: mongoose.Types.ObjectId;
12
+ }> & {
13
+ __v: number;
14
+ } & {
15
+ id: string;
16
+ }, any, IBlacklist>;
@@ -0,0 +1,10 @@
1
+ import mongoose, { Schema } from "mongoose";
2
+ const BlacklistSchema = new Schema({
3
+ playerId: { type: String, required: true, unique: true },
4
+ organizacao: { type: String },
5
+ cargo: { type: String },
6
+ vencimento: { type: Date, required: true, index: { expireAfterSeconds: 0 } },
7
+ criadoEm: { type: Date, default: Date.now },
8
+ atualizadoEm: { type: Date, default: Date.now },
9
+ });
10
+ export const BlacklistModel = mongoose.model("Blacklist", BlacklistSchema, "blacklist");
@@ -0,0 +1,72 @@
1
+ import mongoose, { type Document } from "mongoose";
2
+ /**
3
+ * Configurações dinâmicas do bot (salvas no MongoDB).
4
+ * Apenas UM documento deve existir — uso Singleton via configId fixo.
5
+ */
6
+ export interface CargoHierarchyConfigEntry {
7
+ key: string;
8
+ /** ID do cargo no Discord (quando sincronizado do servidor) */
9
+ discordRoleId?: string;
10
+ nome: string;
11
+ sigla: string;
12
+ ordem: number;
13
+ /** Tags de permissão/grupo ativas para este cargo */
14
+ tags: string[];
15
+ }
16
+ export interface IBotConfig extends Document {
17
+ configId: string;
18
+ /** Overrides dos IDs de cargos usados pelo sistema (chave lógica → roleId Discord) */
19
+ cargoIds: Map<string, string>;
20
+ farmDiasVencimento: number;
21
+ rebaixamentoDiasRecrutador: number;
22
+ rebaixamentoDiasMembro: number;
23
+ farmDiaVencimentoGerencia: number;
24
+ recrutamentoValorPorAprovacao: number;
25
+ mensagensAutoTimestamps: Map<string, Date>;
26
+ /** Horário (HH:mm) em que mensagens automáticas são enviadas */
27
+ mensagensAutoHorarioEnvio: string;
28
+ /** Requisitos de itens por tipo de farm (parametrizável via painel admin) */
29
+ farmRequisitos: {
30
+ tipo: string;
31
+ label: string;
32
+ itens: {
33
+ nomes: string[];
34
+ quantidade: number;
35
+ acao: string;
36
+ }[];
37
+ }[];
38
+ /** Data da última execução da limpeza de blacklist */
39
+ ultimaLimpezaBlacklist: Date | null;
40
+ /** Intervalo (em horas) entre execuções da limpeza de blacklist */
41
+ limpezaBlacklistIntervaloHoras: number;
42
+ /** Dias até uma advertência (ADV) expirar automaticamente */
43
+ advDiasExpiracao: number;
44
+ /** IDs de canais onde links são permitidos (todos os outros bloqueiam) */
45
+ antiLinkCanaisPermitidos: string[];
46
+ /** Domínios liberados globalmente no anti-link (independente de canal) */
47
+ antiLinkDominiosPermitidos: string[];
48
+ /** Data da última execução da verificação de caixa2 líder */
49
+ ultimaExecucaoCaixa2Lider: Date | null;
50
+ /** Proporção mínima (0-1) que o líder deve manter no caixa2 */
51
+ caixa2LiderProporcaoMinima: number;
52
+ /** Membros com cargos fixos especiais (discordId → array de cargo keys). Configurável via painel admin. */
53
+ cargosEspeciais: Map<string, string[]>;
54
+ canaisIds: Map<string, string>;
55
+ /** Dias de retenção de logs do bot no MongoDB */
56
+ logTtlDias: number;
57
+ /** Última vez que o bot estava online (atualizado periodicamente) */
58
+ lastOnlineAt: Date | null;
59
+ /** Metas semanais de recs+ups por cargo de gerência, com redução de farm */
60
+ metasRecrutamento: {
61
+ cargoKey: string;
62
+ metaSemanal: number;
63
+ reducaoFarmPercent: number;
64
+ }[];
65
+ }
66
+ export declare const BotConfigModel: mongoose.Model<IBotConfig, {}, {}, {}, mongoose.Document<unknown, {}, IBotConfig, {}, mongoose.DefaultSchemaOptions> & IBotConfig & Required<{
67
+ _id: mongoose.Types.ObjectId;
68
+ }> & {
69
+ __v: number;
70
+ } & {
71
+ id: string;
72
+ }, any, IBotConfig>;
@@ -0,0 +1,66 @@
1
+ import mongoose, { Schema } from "mongoose";
2
+ const BotConfigSchema = new Schema({
3
+ configId: { type: String, default: "main", unique: true },
4
+ // Cargos
5
+ cargoIds: { type: Map, of: String, default: new Map() },
6
+ // Farm
7
+ farmDiasVencimento: { type: Number, default: 7 },
8
+ // Rebaixamento
9
+ rebaixamentoDiasRecrutador: { type: Number, default: 14 },
10
+ rebaixamentoDiasMembro: { type: Number, default: 1 },
11
+ // Gerência
12
+ farmDiaVencimentoGerencia: { type: Number, default: 1 }, // 1 = segunda-feira
13
+ // Recrutamento
14
+ recrutamentoValorPorAprovacao: { type: Number, default: 150_000 },
15
+ // Mensagens automáticas
16
+ mensagensAutoTimestamps: { type: Map, of: Date, default: new Map() },
17
+ mensagensAutoHorarioEnvio: { type: String, default: "17:00" },
18
+ // Validação de Farm
19
+ farmRequisitos: {
20
+ type: [{
21
+ tipo: { type: String, required: true },
22
+ label: { type: String, required: true },
23
+ itens: {
24
+ type: [{
25
+ nomes: { type: [String], required: true },
26
+ quantidade: { type: Number, required: true },
27
+ acao: { type: String, required: true },
28
+ }],
29
+ default: [],
30
+ },
31
+ }],
32
+ default: [],
33
+ },
34
+ // Blacklist
35
+ ultimaLimpezaBlacklist: { type: Date, default: null },
36
+ limpezaBlacklistIntervaloHoras: { type: Number, default: 12 },
37
+ advDiasExpiracao: { type: Number, default: 30 },
38
+ // Anti-Link — Canais (IDs)
39
+ antiLinkCanaisPermitidos: { type: [String], default: [] },
40
+ antiLinkDominiosPermitidos: { type: [String], default: ["medal.tv"] },
41
+ // Caixa2 Líder
42
+ ultimaExecucaoCaixa2Lider: { type: Date, default: null },
43
+ caixa2LiderProporcaoMinima: { type: Number, default: 0.3 },
44
+ // Cargos Especiais
45
+ cargosEspeciais: { type: Map, of: [String], default: new Map() },
46
+ // Canais
47
+ canaisIds: { type: Map, of: String, default: new Map() },
48
+ // Retenção de Dados
49
+ logTtlDias: { type: Number, default: 30 },
50
+ // Metas de Recrutamento
51
+ metasRecrutamento: {
52
+ type: [{
53
+ cargoKey: { type: String, required: true },
54
+ metaSemanal: { type: Number, required: true },
55
+ reducaoFarmPercent: { type: Number, required: true },
56
+ }],
57
+ default: [
58
+ { cargoKey: "GERENTE_RECRUTADOR", metaSemanal: 5, reducaoFarmPercent: 0.30 },
59
+ { cargoKey: "GERENTE_PRODUÇÃO", metaSemanal: 7, reducaoFarmPercent: 0.40 },
60
+ { cargoKey: "GERENTE_GERAL", metaSemanal: 10, reducaoFarmPercent: 0.50 },
61
+ ],
62
+ },
63
+ // Heartbeat
64
+ lastOnlineAt: { type: Date, default: null },
65
+ });
66
+ export const BotConfigModel = mongoose.model("BotConfig", BotConfigSchema);
@@ -0,0 +1,14 @@
1
+ import mongoose, { type Document } from "mongoose";
2
+ export interface ICaixa2Item extends Document {
3
+ nome: string;
4
+ emoji: string;
5
+ minAdv: number;
6
+ maxAdv: number;
7
+ }
8
+ export declare const Caixa2ItemModel: mongoose.Model<ICaixa2Item, {}, {}, {}, mongoose.Document<unknown, {}, ICaixa2Item, {}, mongoose.DefaultSchemaOptions> & ICaixa2Item & Required<{
9
+ _id: mongoose.Types.ObjectId;
10
+ }> & {
11
+ __v: number;
12
+ } & {
13
+ id: string;
14
+ }, any, ICaixa2Item>;
@@ -0,0 +1,8 @@
1
+ import mongoose, { Schema } from "mongoose";
2
+ const Caixa2ItemSchema = new Schema({
3
+ nome: { type: String, required: true, unique: true },
4
+ emoji: { type: String, required: true },
5
+ minAdv: { type: Number, required: true },
6
+ maxAdv: { type: Number, required: true },
7
+ }, { collection: "caixa2itens" });
8
+ export const Caixa2ItemModel = mongoose.model("Caixa2Item", Caixa2ItemSchema);
@@ -0,0 +1,19 @@
1
+ export interface ICanalConfig {
2
+ /** Chave lógica usada como _id (ex: "CANAL_ENTREGA_FARM") */
3
+ _id: string;
4
+ /** ID do canal Discord (snowflake). Vazio = não configurado */
5
+ channelId: string;
6
+ /** Label para exibição no painel admin */
7
+ label: string;
8
+ /** Descrição da funcionalidade do canal */
9
+ descricao: string;
10
+ /** Nome exato do canal no Discord para auto-detect */
11
+ discordName: string;
12
+ }
13
+ export declare const CanalConfigModel: import("mongoose").Model<ICanalConfig, {}, {}, {}, import("mongoose").Document<unknown, {}, ICanalConfig, {}, import("mongoose").DefaultSchemaOptions> & ICanalConfig & Required<{
14
+ _id: string;
15
+ }> & {
16
+ __v: number;
17
+ } & {
18
+ id: string;
19
+ }, any, ICanalConfig>;
@@ -0,0 +1,9 @@
1
+ import { Schema, model } from "mongoose";
2
+ const CanalConfigSchema = new Schema({
3
+ _id: { type: String },
4
+ channelId: { type: String, default: "" },
5
+ label: { type: String, required: true },
6
+ descricao: { type: String, required: true },
7
+ discordName: { type: String, default: "" },
8
+ }, { timestamps: false, versionKey: false });
9
+ export const CanalConfigModel = model("CanalConfig", CanalConfigSchema);
@@ -0,0 +1,18 @@
1
+ import mongoose, { type Document } from "mongoose";
2
+ export interface ICargoConfig extends Document {
3
+ key: string;
4
+ /** ID do cargo no Discord (quando sincronizado do servidor) */
5
+ discordRoleId: string;
6
+ nome: string;
7
+ sigla: string;
8
+ ordem: number;
9
+ /** Tags de permissão/grupo ativas para este cargo */
10
+ tags: string[];
11
+ }
12
+ export declare const CargoConfigModel: mongoose.Model<ICargoConfig, {}, {}, {}, mongoose.Document<unknown, {}, ICargoConfig, {}, mongoose.DefaultSchemaOptions> & ICargoConfig & Required<{
13
+ _id: mongoose.Types.ObjectId;
14
+ }> & {
15
+ __v: number;
16
+ } & {
17
+ id: string;
18
+ }, any, ICargoConfig>;
@@ -0,0 +1,12 @@
1
+ import mongoose, { Schema } from "mongoose";
2
+ const CargoConfigSchema = new Schema({
3
+ key: { type: String, required: true, unique: true },
4
+ discordRoleId: { type: String, default: "" },
5
+ nome: { type: String, required: true },
6
+ sigla: { type: String, default: "" },
7
+ ordem: { type: Number, required: true },
8
+ tags: { type: [String], default: [] },
9
+ }, { timestamps: true, strict: false });
10
+ CargoConfigSchema.index({ discordRoleId: 1 });
11
+ CargoConfigSchema.index({ ordem: 1 });
12
+ export const CargoConfigModel = mongoose.model("CargoConfig", CargoConfigSchema);