Personal expense tracking application for managing daily finances
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A modern, full-stack expense tracking application built with Next.js 15, tRPC, and PostgreSQL. Track your expenses, manage shared costs with friends, and gain insights into your spending patterns with beautiful analytics.檢視完整 README ↗A modern, full-stack expense tracking application built with Next.js 15, tRPC, and PostgreSQL. Track your expenses, manage shared costs with friends, and gain insights into your spending patterns with beautiful analytics.
Before you begin, ensure you have the following installed:
git clone https://github.com/jainhardik120/expense-tracker.git
cd expense-tracker
pnpm install
# or
npm install
# or
yarn install
Create a .env file in the root directory:
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/expense_tracker"
# App URL (optional)
NEXT_PUBLIC_BASE_URL="http://localhost:3000"
# Skip environment validation during build (optional)
SKIP_ENV_VALIDATION=false
Generate and run database migrations:
# Generate migration files
pnpm db:generate
# Apply migrations to database
pnpm db:migrate
pnpm dev
Open http://localhost:3000 in your browser to see the application.
The application uses a multi-tenant architecture where all data is scoped by userId. Key entities include:
src/
├── app/ # Next.js App Router
│ ├── (auth)/ # Authentication routes (login/register)
│ ├── (main)/ # Protected app routes
│ │ ├── sessions/ # Expense tracking sessions
│ │ ├── statements/ # Transaction management
│ │ └── aggregated/ # Analytics and summaries
│ └── api/ # API routes
├── components/ # Reusable React components
│ ├── ui/ # shadcn/ui components
│ └── data-table/ # Table components with filtering
├── server/ # Backend logic
│ ├── routers/ # tRPC routers
│ └── helpers/ # Helper functions
├── db/ # Database configuration
│ └── schema.ts # Drizzle schema definitions
├── lib/ # Utility functions and configurations
└── hooks/ # Custom React hooks
# Development
pnpm dev # Start development server with Turbopack
pnpm build # Build for production
pnpm start # Start production server
# Database
pnpm db:generate # Generate migration files
pnpm db:migrate # Run database migrations
# Code Quality
pnpm lint # Run ESLint
pnpm lint:fix # Fix ESLint errors
pnpm typecheck # Run TypeScript type checking
pnpm format # Format code with Prettier
# Analysis
pnpm duplicate:check # Check for code duplication
pnpm update:check # Check for dependency updates
The local database stack runs separately from Next.js:
# From the repository root, after local credentials have been provisioned
docker compose -f docker-compose.local.yml up -d --wait
# Run the app using web/.env.local
cd web
pnpm dev
PostgreSQL is available at 127.0.0.1:5432, with database and application
username expense_tracker. pgAdmin is at http://localhost:5050, with login
[email protected]; its registered server connects to postgres:5432
inside Docker. The generated passwords are in .local-db/app-password and
.local-db/pgadmin-password. .local-db/postgres-password is the separate
PostgreSQL administrator password. These files are private local configuration
and must remain ignored by Git.
For the initial setup, provision those three files with separate random
passwords and .local-db/servers.json with the pgAdmin server registration
before starting Compose. The .local-db/ directory should have mode 0700;
the two container-mounted password files and server registration must be
readable by the containers. Keep the application password file at mode 0600.
Set DATABASE_URL in web/.env.local to use the local application credentials.
An existing remote database can be copied using PostgreSQL 18 pg_dump and
pg_restore, preserving application schemas, data, sequences, and Drizzle's
migration history while omitting remote ownership and grants.
The initial switch preserves the previous environment in
web/.env.remote.local. Next.js does not automatically load that backup.
Restore it to web/.env.local and restart Next.js to reconnect to the remote
database. The clone is independent; local changes do not sync back to remote.
# Stop the containers while preserving their database volumes
docker compose -f docker-compose.local.yml down
The named volumes persist across restarts. down --volumes deletes local data.
The local PostgreSQL image includes Debian's tzdata-legacy package so browser
timezone names such as Asia/Calcutta work in dashboard aggregation queries.
The database works without network access once images are downloaded; features
that call external services, including email, GitHub sign-in, AI, and market
data, still require connectivity.
For local SQL tracing, start this repository's Jaeger service:
docker compose --env-file .env.observability.local -f docker-compose.observability.yml up -d
The ignored .env.observability.local selects the already downloaded Jaeger
image. Without that file, omit --env-file to use the default Jaeger 2 image.
web/.env.local exports traces to http://127.0.0.1:4318 using
OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf, and
OTEL_TRACES_SAMPLER=always_on. Open http://localhost:16686, select service
expense-tracker, and expand drizzle.select spans to inspect SQL and timings.
The app sends traces directly to Jaeger; an additional collector is unnecessary
for this setup. Traces are held in memory and disappear when Jaeger restarts.
Build and run with Docker:
# Build the Docker image
docker build -t expense-tracker .
# Run the container
docker run -p 3000:3000 \
-e DATABASE_URL="your_database_url" \
expense-tracker
The application can be deployed to any platform that supports Node.js and Docker:
Ensure you:
The Android GitHub Actions workflow at .github/workflows/main.yml now publishes the release .aab to the Google Play internal track as part of the master release pipeline. A separate release trigger remains as a fallback for manually published GitHub releases.
Before that release job can succeed:
Users and permissions and grant it access to com.jainhardik120.expensetracker.PLAYSTORE_SERVICE_ACCOUNT_JSON.Contributions are welcome! Please follow these steps:
git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)pnpm lint and pnpm typecheck before committingThis project is licensed under the MIT License - see the LICENSE file for details.
For questions or feedback, please open an issue on GitHub.
Built with ❤️ using Next.js 15