Files
beenvoice/drizzle/0001_supreme_the_enforcers.sql
T
Claude e6b79ce2c2 Add bulk actions, multi-currency, expenses, templates, and reports
Schema (migration 0001):
- clients: add currency column (default USD)
- invoices: add currency column (default USD)
- New expenses table: amount, currency, category, billable, reimbursable,
  client/invoice/business relations, notes
- New invoice_templates table: name, type (notes|terms), content, isDefault

API:
- invoices: add bulkUpdateStatus and bulkDelete procedures (ownership-safe)
- invoices: currency field threaded through create/update schemas
- clients: currency field added to create/update schemas
- New expenses router: full CRUD with authorization
- New invoiceTemplates router: full CRUD, isDefault management per type
- Root router: wire in expenses and invoiceTemplates

Currency (src/lib/currency.ts):
- Shared formatCurrency(amount, currency) utility replacing hardcoded USD
- SUPPORTED_CURRENCIES list (17 currencies)
- Invoice form: currency selector in Config card, auto-fills from client
- Client form: currency selector in Billing Information card

Bulk actions (invoices list):
- Checkbox column with select-all support
- Selection toolbar: Mark as Sent/Paid/Draft dropdown, Delete (N) button
- DataTable: new selectionActions prop renders toolbar when rows selected

Notes templates:
- Invoice form: Notes card with textarea in Details tab
- Template dropdown button appears when templates exist
- /dashboard/invoices/templates: full CRUD page for notes and terms templates

New pages:
- /dashboard/expenses: expense list with summary cards, add/edit dialog
- /dashboard/reports: KPI cards, 12-month revenue area chart, top clients
  bar chart, status breakdown, recent activity
- Navigation: Expenses and Reports added to Main section

https://claude.ai/code/session_012sqEgNQpx676isepeoX4Mi
2026-04-05 02:34:06 +00:00

43 lines
3.1 KiB
SQL

CREATE TABLE "beenvoice_expense" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"businessId" varchar(255),
"clientId" varchar(255),
"invoiceId" varchar(255),
"date" timestamp NOT NULL,
"description" varchar(500) NOT NULL,
"amount" real NOT NULL,
"currency" varchar(3) DEFAULT 'USD' NOT NULL,
"category" varchar(100),
"billable" boolean DEFAULT false NOT NULL,
"reimbursable" boolean DEFAULT false NOT NULL,
"notes" varchar(500),
"createdById" varchar(255) NOT NULL,
"createdAt" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
"updatedAt" timestamp
);
--> statement-breakpoint
CREATE TABLE "beenvoice_invoice_template" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"name" varchar(255) NOT NULL,
"type" varchar(50) DEFAULT 'notes' NOT NULL,
"content" text NOT NULL,
"isDefault" boolean DEFAULT false NOT NULL,
"createdById" varchar(255) NOT NULL,
"createdAt" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
"updatedAt" timestamp
);
--> statement-breakpoint
ALTER TABLE "beenvoice_client" ADD COLUMN "currency" varchar(3) DEFAULT 'USD' NOT NULL;--> statement-breakpoint
ALTER TABLE "beenvoice_invoice" ADD COLUMN "currency" varchar(3) DEFAULT 'USD' NOT NULL;--> statement-breakpoint
ALTER TABLE "beenvoice_expense" ADD CONSTRAINT "beenvoice_expense_businessId_beenvoice_business_id_fk" FOREIGN KEY ("businessId") REFERENCES "public"."beenvoice_business"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "beenvoice_expense" ADD CONSTRAINT "beenvoice_expense_clientId_beenvoice_client_id_fk" FOREIGN KEY ("clientId") REFERENCES "public"."beenvoice_client"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "beenvoice_expense" ADD CONSTRAINT "beenvoice_expense_invoiceId_beenvoice_invoice_id_fk" FOREIGN KEY ("invoiceId") REFERENCES "public"."beenvoice_invoice"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "beenvoice_expense" ADD CONSTRAINT "beenvoice_expense_createdById_beenvoice_user_id_fk" FOREIGN KEY ("createdById") REFERENCES "public"."beenvoice_user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "beenvoice_invoice_template" ADD CONSTRAINT "beenvoice_invoice_template_createdById_beenvoice_user_id_fk" FOREIGN KEY ("createdById") REFERENCES "public"."beenvoice_user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "expense_created_by_idx" ON "beenvoice_expense" USING btree ("createdById");--> statement-breakpoint
CREATE INDEX "expense_client_id_idx" ON "beenvoice_expense" USING btree ("clientId");--> statement-breakpoint
CREATE INDEX "expense_invoice_id_idx" ON "beenvoice_expense" USING btree ("invoiceId");--> statement-breakpoint
CREATE INDEX "expense_date_idx" ON "beenvoice_expense" USING btree ("date");--> statement-breakpoint
CREATE INDEX "expense_billable_idx" ON "beenvoice_expense" USING btree ("billable");--> statement-breakpoint
CREATE INDEX "invoice_template_created_by_idx" ON "beenvoice_invoice_template" USING btree ("createdById");--> statement-breakpoint
CREATE INDEX "invoice_template_type_idx" ON "beenvoice_invoice_template" USING btree ("type");