diff options
Diffstat (limited to 'api/src/db/schema/recurring-expenses.ts')
| -rw-r--r-- | api/src/db/schema/recurring-expenses.ts | 69 |
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; |