aboutsummaryrefslogtreecommitdiff
path: root/api/src/db/schema/recurring-expenses.ts
diff options
context:
space:
mode:
Diffstat (limited to 'api/src/db/schema/recurring-expenses.ts')
-rw-r--r--api/src/db/schema/recurring-expenses.ts69
1 files changed, 69 insertions, 0 deletions
diff --git a/api/src/db/schema/recurring-expenses.ts b/api/src/db/schema/recurring-expenses.ts
new file mode 100644
index 0000000..8a0a1df
--- /dev/null
+++ b/api/src/db/schema/recurring-expenses.ts
@@ -0,0 +1,69 @@
+import { sql } from 'drizzle-orm';
+import { integer, real, sqliteTable, text } from 'drizzle-orm/sqlite-core';
+import { users } from './users';
+
+/**
+ * Tabela de gastos recorrentes (despesas fixas mensais).
+ * Ex: Aluguel, Internet, Streaming, Academia.
+ * Estes gastos são deduzidos automaticamente do saldo todo mês,
+ * sem precisar recadastrar.
+ */
+export const recurringExpenses = sqliteTable('recurring_expenses', {
+ id: integer('id').primaryKey({ autoIncrement: true }),
+
+ user_id: integer('user_id')
+ .notNull()
+ .references(() => users.id, { onDelete: 'cascade' }),
+
+ /** Nome/descrição do gasto (ex: "Aluguel", "Netflix") */
+ name: text('name').notNull(),
+
+ /** Valor mensal do gasto (em R$) */
+ amount: real('amount').notNull(),
+
+ /**
+ * Categoria do gasto para organização e futuros relatórios.
+ * Ex: "moradia", "alimentação", "lazer", "saúde", "transporte", "educação", "outros"
+ */
+ category: text('category').notNull().default('outros'),
+
+ /** Tipo do lançamento: 'expense' (despesa) ou 'income' (receita) */
+ type: text('type').notNull().default('expense'),
+
+ /**
+ * Dia do mês em que a despesa costuma vencer (1-31).
+ * Opcional — usado apenas para informação ao usuário.
+ */
+ due_day: integer('due_day'),
+
+ /**
+ * Indica se o gasto está ativo.
+ * Quando false, não é deduzido do saldo (útil para pausar sem deletar).
+ * Armazenado como integer (0 = false, 1 = true) por limitação do SQLite.
+ */
+ is_active: integer('is_active', { mode: 'boolean' }).notNull().default(true),
+
+ /**
+ * Data a partir da qual este gasto passa a ser contabilizado.
+ * Formato ISO 8601 (YYYY-MM-DD).
+ */
+ starts_at: text('starts_at').notNull().default(sql`(date('now'))`),
+
+ /**
+ * Data em que este gasto deixa de ser contabilizado (opcional).
+ * Útil para despesas com prazo definido (ex: parcelamento de 12x).
+ * Formato ISO 8601 (YYYY-MM-DD).
+ */
+ ends_at: text('ends_at'),
+
+ created_at: text('created_at')
+ .notNull()
+ .default(sql`(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))`),
+
+ updated_at: text('updated_at')
+ .notNull()
+ .default(sql`(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))`),
+});
+
+export type RecurringExpense = typeof recurringExpenses.$inferSelect;
+export type NewRecurringExpense = typeof recurringExpenses.$inferInsert;