Lalabase
티켓·문서·근무시간·고객대화를 한 곳에 모아 KI로 검색, 소프트웨어 기업 고객 프로젝트용, 오픈소스로 자체 서버·독일 클라우드에 배포
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Quản lý hóa đơn phòng trọ — một codebase, một deployment, nhiều tòa nhà (định tuyến theo subdomain). Tòa nhà đầu tiên: 190 Nguyễn Trãi → https://190nt.vercel.app Toàn bộ tài liệu đặc tả nằm trong docs/: Dùng cặp key mới sb_publishable_ / sb_secret_, không dùng anon / service_role. SUPABASE_SECRET_KEY chỉ được import từ server — không bao giờ đặt sau tiền tố NEXT_PUBLIC_. Trên localhost và *.vercel.app, host không có subdomain hợp lệ nên middleware rơi về DEFAULT_BUILDING_SLUG. Thiếu biến này thì local dev và Preview sẽ chết.README 전문 보기 ↗
Quản lý hóa đơn phòng trọ — một codebase, một deployment, nhiều tòa nhà (định tuyến theo subdomain).
Tòa nhà đầu tiên: 190 Nguyễn Trãi → https://190nt.vercel.app
Toàn bộ tài liệu đặc tả nằm trong docs/:
| File | Nội dung |
|---|---|
HANDOFF-rentory.md | Nguồn sự thật nghiệp vụ — mục 4 |
CHANGELOG-nghiep-vu.md | Delta nghiệp vụ đã chốt (CR-01…CR-07) |
srs-quan-ly-phong.md | Quản lý phòng, hợp đồng, người ở |
srs-chi-so-va-lap-hoa-don.md | Màn Chỉ số + mẫu hóa đơn in |
srs-setting-toa-nha.md | Cài đặt tòa nhà |
DESIGN_SYSTEM.md | Token màu, chữ, component |
| Layer | Chọn |
|---|---|
| Framework | Next.js 15 App Router + TypeScript strict |
| UI | Tailwind CSS v4 + shadcn/ui + lucide-react |
| Data | Supabase (Postgres + Auth + RLS), @supabase/supabase-js, @supabase/ssr |
| Client state | TanStack Query v5 |
| Validation | Zod |
| Date | date-fns |
| Font | Space Grotesk (tiêu đề + số tiền), Manrope (body), subset vietnamese |
| Test | Vitest |
npm install
cp .env.example .env.local # rồi điền key thật
npm run dev
.env.local (không commit):
NEXT_PUBLIC_SUPABASE_URL=https://hmymrmnrtreblizpvwbe.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...
SUPABASE_SECRET_KEY=sb_secret_... # server-only
DEFAULT_BUILDING_SLUG=190nguyentrai
Dùng cặp key mới sb_publishable_ / sb_secret_, không dùng anon / service_role.
SUPABASE_SECRET_KEY chỉ được import từ server — không bao giờ đặt sau tiền tố NEXT_PUBLIC_.
Trên localhost và *.vercel.app, host không có subdomain hợp lệ nên middleware rơi về
DEFAULT_BUILDING_SLUG. Thiếu biến này thì local dev và Preview sẽ chết.
npm run dev # dev server
npm run build # production build
npm run test # vitest (bắt buộc xanh trước khi merge)
npm run typecheck # tsc --noEmit
npm run lint # eslint
Mọi thay đổi schema chỉ qua migration file trong supabase/migrations/, commit vào Git.
Không sửa tay trên Dashboard.
export SUPABASE_ACCESS_TOKEN=... # Personal Access Token
npx supabase link --project-ref hmymrmnrtreblizpvwbe
npx supabase db push # đẩy migration mới
npx supabase gen types typescript --project-id hmymrmnrtreblizpvwbe --schema public > src/types/database.ts
RLS: 1 admin / tòa nhà. Mọi bảng dẫn về buildings.admin_id = auth.uid() qua các
hàm is_my_building / building_of_room / building_of_invoice / building_of_receipt.
src/
app/ # App Router
login/ # S-01 đăng nhập
auth/signout/ # route đăng xuất
components/
ui/ # shadcn/ui
lib/
billing/ # ★ toàn bộ nghiệp vụ tính toán — pure function, có test
code.ts # 4.4 mã hóa đơn
periods.ts # 4.1 kỳ thu trước / thu sau
defaults.ts # HD-01/02/03 số liệu mặc định 3 loại hóa đơn
recognized.ts # TT-03/TT-06 số ghi nhận & trạng thái thu
marks.ts # HD-04/HD-08a mốc công tơ + log
occupants.ts # BR-P13…P17 người ở, người đại diện, ngưỡng hết hạn
meter.ts # BR-M01 thứ tự đọc công tơ, ngày chốt mặc định
print.ts # mục 7 SRS — model bản in hóa đơn
png.ts # xuất DOM → PNG (không dùng thư viện ngoài)
supabase/ # client (browser) · server (RLS) · admin (bypass RLS)
tenant.ts # 2.5 host → slug tòa nhà
env.ts # validate env bằng Zod
middleware.ts # subdomain + refresh session + chặn route
supabase/migrations/ # nguồn sự thật của schema
Nguyên tắc: tiền là số nguyên VND (int), không float. Kỳ là chuỗi YYYY-MM.
Toàn bộ tính toán nằm trong lib/billing/ dưới dạng pure function có unit test; UI chỉ gọi.
Mỗi function comment mã quy tắc tương ứng (// HD-02).
main → Production (Vercel project rentory, account ducpm103)Domain đang dùng: 190nt.vercel.app — domain free của account, không cần DNS.
*.vercel.app luôn rơi về DEFAULT_BUILDING_SLUG trong middleware, kể cả domain
"đẹp" như 190nt: không phân biệt được với URL preview
(rentory-a1iav6i1v-ducpm103.vercel.app), mà đoán sai thì Preview chết. Một tòa
thì fallback là đủ.
Khi thêm tòa thứ hai sẽ cần domain riêng để mỗi tòa có subdomain thật
(toa2.example.com). Lúc đó thêm domain vào project rồi trỏ DNS:
CNAME <slug> cname.vercel-dns.com
Nếu apex domain nằm ở một Vercel account khác, account này phải verify quyền sở
hữu bằng bản ghi TXT _vercel do Vercel cấp — subdomain của cùng một apex chạy
ở các account khác nhau được, nhưng cùng một hostname thì chỉ một account giữ.