This is a Next.js project for managing personal finances, built with TypeScript, PostgreSQL, and Drizzle ORM.
Note: This is a personal portfolio project built with modern web technologies. The code is open source under the Apache 2.0 License - you're free to use, modify, and distribute it, including for commercial purposes. See LICENSE for details.
- Frontend: Next.js 15 with App Router, TypeScript, Tailwind CSS, shadcn/ui
- Database: PostgreSQL with Drizzle ORM
- Authentication: JWT tokens with secure password hashing
- Testing: Vitest with comprehensive unit and integration tests
- Type Safety: Zod schemas for runtime validation and TypeScript inference
- Node.js 18+ and pnpm
- PostgreSQL database
- Environment variables configured (see
.env.example)
- Install dependencies:
pnpm install- Set up your environment variables:
cp .env.example .env.local
# Edit .env.local with your database credentials- Set up the database schema:
# Generate and apply database migrations
pnpm drizzle-kit generate:pg
pnpm drizzle-kit push:pg- Start the development server:
pnpm devOpen http://localhost:3000 with your browser to see the result.
This project uses Drizzle ORM for database schema management and migrations. The schema is defined in app/api/lib/schema.ts.
When you need to modify the database structure:
Edit app/api/lib/schema.ts to add/modify tables, columns, or relations:
// Example: Adding a new column
export const transactions = pgTable("transactions", {
id: serial("id").primaryKey(),
// ... existing columns
newColumn: varchar("new_column", { length: 100 }), // Add new column
});Generate SQL migration files based on your schema changes:
pnpm drizzle-kit generate:pgThis creates a new migration file in the drizzle/ directory with the SQL commands needed to update your database.
Push the schema changes to your PostgreSQL database:
pnpm drizzle-kit push:pgThis command:
- Applies the generated SQL migrations to your database
- Updates the database structure to match your schema
- Handles column additions, deletions, and modifications
If you modified data structures, update the corresponding Zod schemas in lib/schemas.ts:
// Example: Update schema validation
export const TransactionCreateSchema = z.object({
// ... existing fields
newField: z.string().optional(), // Add validation for new field
});For complex schema changes that require data transformation:
curl -X GET http://localhost:3000/api/admin/migrate-categoriescurl -X POST http://localhost:3000/api/admin/migrate-categories- Always backup your database before running migrations in production
- Test migrations locally before applying to production
- Review generated SQL in the migration files before applying
- Use transactions for complex data migrations
- Maintain backward compatibility when possible during schema changes
# Check what changes would be applied
pnpm drizzle-kit generate:pg --custom
# Push changes directly (development only)
pnpm drizzle-kit push:pg
# Open Drizzle Studio for database inspection
pnpm drizzle-kit studio
# Introspect existing database
pnpm drizzle-kit introspect:pgThe current database includes:
- users: User accounts with authentication
- categories: Transaction categories with user ownership
- defaultCategories: System-wide category templates
- bankAccounts: User bank accounts with balance tracking
- creditCards: Credit card accounts with limits
- transactions: All financial transactions with category relationships
pnpm dev- Start development serverpnpm build- Build for productionpnpm lint- Run ESLintpnpm typecheck- Run TypeScript compiler check
pnpm test- Run all testspnpm test:watch- Run tests in watch modepnpm test:coverage- Run tests with coverage
pnpm drizzle-kit generate:pg- Generate migrationspnpm drizzle-kit push:pg- Apply schema changespnpm drizzle-kit studio- Open database studio
- π° Transaction Management: Create, edit, and categorize income/expense transactions
- π¦ Multi-Account Support: Manage multiple bank accounts and credit cards
- π Category System: Organize transactions with custom categories and visual indicators
- π Secure Authentication: JWT-based authentication with password hashing
- π± Responsive Design: Mobile-first design using Tailwind CSS and shadcn/ui
- π Data Migration: Built-in utilities for migrating and transforming data
- β Type Safety: End-to-end type safety with TypeScript and Zod validation
- π§ͺ Comprehensive Testing: Unit and integration tests with high coverage
- Framework: Next.js 15 with App Router
- Styling: Tailwind CSS with shadcn/ui components (New York style, stone base color)
- State Management: TanStack Query for server state, localStorage for auth tokens
- Validation: Zod schemas as single source of truth for types and validation
- Testing: Vitest with coverage support and UI mode
- Database: PostgreSQL with Drizzle ORM
- API: Next.js API routes following RESTful patterns
- Authentication: JWT with Bearer tokens, 24h expiration
- Schema: Centralized in
app/api/lib/schema.tswith proper relations - Error Handling: Portuguese error messages with consistent format
- Type Safety: Zod schemas inferred to TypeScript types across the stack
- API Layer: Custom
fetchWithAuth()utility with automatic 401 handling - Component Structure: Feature-based organization with reusable UI components
- Data Flow: Forms β Zod validation β TanStack Query β Database via Drizzle
app/
βββ api/ # Next.js API routes
β βββ auth/ # Authentication endpoints
β βββ categories/ # Category CRUD operations
β βββ transactions/ # Transaction management
β βββ lib/ # Database schema and utilities
βββ categories/ # Category management pages
βββ transactions/ # Transaction pages
βββ components/ # Reusable UI components
βββ ui/ # shadcn/ui components
lib/
βββ schemas.ts # Zod validation schemas
βββ utils/ # Utility functions
tests/
βββ unit/ # Unit tests
βββ integration/ # Integration tests
βββ helpers/ # Test utilities
To learn more about the technologies used:
- Next.js Documentation - Next.js features and API
- Drizzle ORM - TypeScript ORM documentation
- shadcn/ui - Re-usable component library
- TanStack Query - Data fetching and state management
- Zod - TypeScript-first schema validation
Required environment variables for production:
DATABASE_URL=postgresql://username:password@host:port/database
JWT_SECRET=your-secret-key-here
NEXTAUTH_SECRET=your-nextauth-secret- Set up a PostgreSQL database
- Run migrations:
pnpm drizzle-kit push:pg - Optionally seed with default data via the migration API
The easiest way to deploy is using the Vercel Platform:
- Connect your GitHub repository
- Add environment variables
- Deploy automatically on every push to main
Check out the Next.js deployment documentation for more details.
Contributions are welcome! Please read our Contributing Guidelines before submitting a pull request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please ensure your code:
- Follows the project's coding standards
- Includes appropriate tests
- Passes all linting and type checks
- Has been tested locally
Security is a top priority for a financial application. Please review:
- Security Policy - How to report vulnerabilities
- Security Audit Report - Latest security audit findings
If you discover a security vulnerability, please follow our Security Policy for responsible disclosure.
Copyright (c) 2026 Tiago A Marek
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the LICENSE file for the specific language governing permissions and limitations under the License.
This project is open source and you are free to:
- Use it for personal or commercial purposes
- Modify and adapt the code
- Distribute original or modified versions
- Include it in proprietary software
You must:
- Include the original copyright notice and license
- State any significant changes you made
- Include a copy of the Apache 2.0 License
The software is provided "as-is" without warranties.
- Built with Next.js
- UI components from shadcn/ui
- Database ORM by Drizzle
- State management with TanStack Query
- Validation with Zod
Disclaimer: This is a personal project for educational and portfolio purposes. While security best practices have been implemented, use at your own risk for managing actual financial data. Always ensure you have proper backups and security measures in place.