Ledgerly
2025-08-01 — present
Family/organization shared finance management app — Next.js 16 fullstack, Supabase PostgreSQL, 3-tier RBAC (OWNER/ADMIN/MEMBER), NestJS Cron recurring transaction automation, 99.45% line coverage unit tests + 300+ E2E integration tests
System Architecture
Problem Solving
Data security risk in shared finance app without role-based permission separation
Designed 3-tier RBAC, 3-layer Guard chain (SupabaseAuthGuard → MembershipGuard → SuperAdminGuard) for dual auth+authz
Independent per-org data management + granular role-based access control
Vercel Hobby Cron limit (1x/day) preventing recurring transaction automation
Separated NestJS backend via Docker on Mac mini, @nestjs/schedule daily 15:00 KST execution
Daily recurring transaction automation, platform limitation bypassed
Auth state mismatch between server and client components in SSR
Cookie-based session restoration + auth context propagation pattern with Next.js 16 + Supabase Auth SSR
Seamless auth state sync across server and client components
Manual testing unable to cover defect risk from complex RBAC + async logic
Vitest unit + Playwright E2E organized by role scenarios (Admin/Member), full-stack integration env with real BE + local Supabase
99.45% line coverage, automated role-based scenario verification system
Project Description
A shared finance management application for families and organizations to collaboratively track income and expenses. The Next.js 16 App Router frontend provides transaction, category, and budget CRUD with a Recharts-based financial analytics dashboard, handling authentication and authorization through Supabase Auth with Row Level Security. Implements a 3-tier RBAC system (OWNER/ADMIN/MEMBER) for granular organizational permissions, manages server state with TanStack Query v5, and validates form inputs with Zod 4. Recurring transaction automation runs on a separate NestJS backend deployed via Docker on a Mac mini to bypass Vercel Cron limitations, executing daily at midnight (KST) via @nestjs/schedule. Built 397 Vitest unit tests (99.45% line coverage) and 300+ Playwright E2E tests organized by role-based scenarios (Admin/Member), with a full-stack integration test environment connecting to a real backend and local Supabase.
Highlights
- 397 Vitest unit tests with 99.45% line coverage
- 300+ Playwright E2E tests, role-based scenarios
- 3-tier RBAC (OWNER/ADMIN/MEMBER) + Supabase RLS
- NestJS Cron recurring transaction auto (Docker)
- Full-stack integration test env (FE+BE+Supabase)
Performance Metrics
| Performance Metrics | Before | After |
|---|---|---|
| Vitest unit tests | - | 397건 (BE 25 + FE 31 suites) (99.45% 커버리지) |
| Playwright E2E | - | 300건+ (24 specs · 5 projects) (역할별 시나리오) |
Tech Decisions
- ▶ NestJS Docker separation: bypasses Vercel Hobby Cron limit (1/day), ensures daily 15:00 KST recurring transaction execution on Mac mini
- ▶ Supabase Auth + app-level RBAC: 3-tier guard chain — SupabaseAuthGuard (JWT) → MembershipGuard (role) → SuperAdminGuard (admin-only)
- ▶ Prisma + Supabase PG: leverages Prisma's type safety and migration tooling, routes through Supabase connection pooler for serverless connection management
Lessons Learned
- • Learned SSR authentication state management and RLS-based data access control by combining Next.js 16 App Router with Supabase Auth, understanding auth context propagation patterns between server and client components
- • Experienced permission separation and data isolation strategies in organizational multi-tenancy by designing a 3-tier RBAC system (OWNER/ADMIN/MEMBER)
- • Learned practical criteria for microservice separation and shared DB schema management by operating a separate NestJS backend via Docker to bypass Vercel Cron limitations
- • Internalized test pyramid strategy by building 397 Vitest unit tests (99.45% coverage) and 300+ Playwright E2E tests with role-based scenarios, establishing a full-stack integration test environment with real backend and local Supabase