āĻĸāĻžāĻāĻž āĻŦāĻŋāĻļā§āĻŦāĻŦāĻŋāĻĻā§āϝāĻžāϞāϝāĻŧ ¡ āĻĒā§āϰāĻžāĻŖāĻŋāĻŦāĻŋāĻĻā§āϝāĻž āĻŦāĻŋāĻāĻžāĻ āĻāĻžāĻĻā§āĻāϰ
āĻĸāĻžāĻāĻž āĻŦāĻŋāĻļā§āĻŦāĻŦāĻŋāĻĻā§āϝāĻžāϞāϝāĻŧā§āϰ āĻĒā§āϰāĻžāĻŖāĻŋāĻŦāĻŋāĻĻā§āϝāĻž āĻŦāĻŋāĻāĻžāĻā§āϰ āύā§āϝāĻžāĻāĻžāϰāĻžāϞ āĻšāĻŋāϏā§āĻāϰāĻŋ āĻāĻžāĻĻā§āĻāϰā§āϰ āĻāύā§āϝ āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ-āĻā§āϝāĻžāĻāĻžāϞāĻāĻŋāĻ āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻ ā§āϝāĻžāĻĒ â āĻā§āϝāĻžāĻā§āϏā§āύāĻŽāĻŋ-āϏāĻā§āϤāύ āϰā§āĻāϰā§āĻĄ, āĻĒā§āϰāĻŋāύā§āĻ-āĻā§āϰā§āĻĄ QR āϞā§āĻŦā§āϞ āĻāϰ āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ-āĻ āύāϞāĻŋ āĻ ā§āϝāĻžāĻā§āϏā§āϏāĨ¤
- āϞāĻžāĻāĻ (āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ)
- ⧍ā§Ļ⧍ā§Ŧ
- āĻĒāĻžāĻŦāϞāĻŋāĻ āĻā§āϝāĻžāϞāĻžāϰāĻŋ āϤā§āϰāĻŋāϤā§

āϏāĻāĻā§āϝāĻžāϝāĻŧ
- āĻā§āϝāĻžāĻā§āϏā§āύāĻŽāĻŋ āĻĢāĻŋāϞā§āĻĄ
- 9
- āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻŽāĻĄāĻŋāĻāϞ
- 7
- āϰā§āϞ
- 3
- āϞā§āĻŦā§āϞ āĻĒā§āϰāĻŋāύā§āĻ
- QR
01āϏāĻŽāϏā§āϝāĻž
āĻĸāĻžāĻāĻž āĻŦāĻŋāĻļā§āĻŦāĻŦāĻŋāĻĻā§āϝāĻžāϞāϝāĻŧā§āϰ āĻĒā§āϰāĻžāĻŖāĻŋāĻŦāĻŋāĻĻā§āϝāĻž āĻŦāĻŋāĻāĻžāĻ āĻāĻāĻāĻŋ āύā§āϝāĻžāĻāĻžāϰāĻžāϞ āĻšāĻŋāϏā§āĻāϰāĻŋ āĻāĻžāĻĻā§āĻāϰ āĻĒāϰāĻŋāĻāĻžāϞāύāĻž āĻāϰ⧠â āϝā§āĻāĻžāύ⧠āĻĢāĻžāĻāϞāĻžāĻŽ āĻĨā§āĻā§ āϏā§āĻĒāĻŋāϏāĻŋāϏ āĻĒāϰā§āϝāύā§āϤ āĻĒā§āϰ⧠āĻā§āϝāĻžāĻā§āϏā§āύāĻŽāĻŋ, āĻāĻžāϞā§āĻāĻļāύ āϤāĻžāϰāĻŋāĻ, āϏā§āĻĨāĻžāύ, āĻāĻžāϞā§āĻā§āĻāϰ, āĻā§āϝāĻžāĻŦāĻŋāύā§āĻ, āĻļā§āϞāĻĢ āĻāϰ āĻŦāĻžāĻā§āϏāϏāĻš āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āϏāĻāϰāĻā§āώāĻŋāϤ āĻšāϝāĻŧāĨ¤ āϰā§āĻāϰā§āĻĄāĻā§āϞ⧠āĻāĻžāĻāĻā§, āϏā§āĻĒā§āϰā§āĻĄāĻļāĻŋāĻā§ āĻāϰ āĻŦāĻŋāĻā§āĻāĻŋāύā§āύ āĻĢāϰā§āĻŽā§ āĻāĻĄāĻŧāĻŋāϝāĻŧā§ āĻāĻŋāϞāĨ¤ āĻā§āύ⧠āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āϤāĻžāϰ āĻĢāĻŋāĻāĻŋāĻā§āϝāĻžāϞ āϏā§āĻā§āϰā§āĻā§āϰ āϏāĻā§āĻā§ āϝā§āĻā§āϤ āĻāĻŋāϞ āύāĻž, āĻĒā§āϰāĻŋāύā§āĻāϝā§āĻā§āϝ āϞā§āĻŦā§āϞ āϤā§āϰāĻŋ āĻšāϤ āύāĻž, āĻāϰ āĻā§āϝāĻžāĻŦāĻŋāύā§āĻ-āĻĒāϰāĻŋāĻŦāϰā§āϤāύā§āϰ āĻā§āύ⧠āĻ āĻĄāĻŋāĻ āĻā§āϰā§āĻāϞ āĻāĻŋāϞ āύāĻžāĨ¤ āĻŦāĻŋāĻāĻžāĻā§āϰ āĻĻāϰāĻāĻžāϰ āĻāĻŋāϞ āĻāĻāĻāĻŋ āĻāĻāĻ āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻ ā§āϝāĻžāĻĒ āϝāĻž āϏāĻŽā§āĻĒā§āϰā§āĻŖ āĻā§āϝāĻžāĻā§āϏā§āύāĻŽāĻŋ āϧāϰā§, QR āĻā§āĻĄāϏāĻš āĻĒā§āϰāĻŋāύā§āĻ-āϰā§āĻĄāĻŋ āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āϞā§āĻŦā§āϞ āϤā§āϰāĻŋ āĻāϰ⧠āĻāĻŦāĻ āĻā§āĻŦāϞ āĻŦāĻŋāĻāĻžāĻ-āĻ āύā§āĻŽā§āĻĻāĻŋāϤ āϏā§āĻāĻžāĻĢāϰāĻžāĻ āĻ ā§āϝāĻžāĻā§āϏā§āϏ āĻāϰāϤ⧠āĻĒāĻžāϰ⧠â āĻĒāϰāĻŦāϰā§āϤ⧠āĻĒāϰā§āϝāĻžāϝāĻŧā§ āĻāĻāĻāĻŋ āĻĒāĻžāĻŦāϞāĻŋāĻ āĻā§āϝāĻžāϞāĻžāϰāĻŋ āϝā§āĻā§āϤ āĻšāĻāϝāĻŧāĻžāϰ āĻĒāϰāĻŋāĻāϞā§āĻĒāύāĻžāϏāĻšāĨ¤
02āϝāĻž āϤā§āϰāĻŋ āĻāϰā§āĻāĻŋ
- 01
āĻāĻāĻāĻŋ āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āϰā§āĻāϰā§āĻĄ â āϏāĻŽā§āĻĒā§āϰā§āĻŖ āϞāĻŋāύāĻŋāϝāĻŧāĻžāύ āĻā§āϝāĻžāĻā§āϏā§āύāĻŽāĻŋ (āĻĢāĻžāĻāϞāĻžāĻŽ, āĻā§āϞāĻžāϏ, āĻ āϰā§āĻĄāĻžāϰ, āĻĢā§āϝāĻžāĻŽāĻŋāϞāĻŋ, āĻā§āύāĻžāϏ, āϏā§āĻĒāĻŋāϏāĻŋāϏ, āϏāĻžāϝāĻŧā§āύā§āĻāĻŋāĻĢāĻŋāĻ āύāĻžāĻŽ, āĻāĻŽāύ āύāĻžāĻŽ, āϞā§āĻāĻžāϞ āύāĻžāĻŽ) āϏāĻš āĻāĻžāϞā§āĻāĻļāύ āϤāĻžāϰāĻŋāĻ, āϏā§āĻĨāĻžāύ, āĻāĻžāϞā§āĻā§āĻāϰ āĻāϰ āĻāύā§āĻā§āϰāĻŋ āϤāĻžāϰāĻŋāĻ â Drizzle āĻĻāĻŋāϝāĻŧā§ Postgres-āĻ āĻŽāĻĄā§āϞ āĻāϰāĻžāĨ¤
- 02
āĻĒā§āϰāϤāĻŋāĻāĻŋ āϰā§āĻāϰā§āĻĄā§ āĻĢāĻŋāĻāĻŋāĻā§āϝāĻžāϞ-āϏā§āĻā§āϰā§āĻ āĻŽā§āϝāĻžāĻĒ â cabinetNo, shelfNo, boxNo āĻāĻŦāĻ āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āĻāĻžāĻāĻĒ / āĻĒā§āϰāĻŋāĻāĻžāϰā§āĻā§āĻļāύ āĻāĻžāĻāĻĒ â āϝāĻžāϤ⧠āĻĄā§āĻāĻžāĻŦā§āϏā§āϰ āĻāĻāĻāĻŋ āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āϏāĻŦāϏāĻŽāϝāĻŧ āĻāĻžāĻĻā§āĻāϰā§āϰ āĻāĻāĻāĻŋ āĻĢāĻŋāĻāĻŋāĻā§āϝāĻžāϞ āĻ āĻŦāϏā§āĻĨāĻžāύā§āϰ āϏāĻā§āĻā§ āϝā§āĻā§āϤ āĻĨāĻžāĻā§āĨ¤
- 03
`(print)/specimens/[id]/print`-āĻ āĻĒā§āϰāĻŋāύā§āĻ-āĻā§āϰā§āĻĄ āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āϞā§āĻŦā§āϞ â āĻāĻ āĻžāϞ⧠āϞā§āĻŦā§āϞ āĻāĻžāĻāĻā§āϰ āĻāύā§āϝ āϞā§āĻāĻāĻ, react-qr-code āĻĻāĻŋāϝāĻŧā§ āĻāύāĻā§āĻĄā§āĻĄ QR āϝāĻžāϤ⧠āĻĢā§āύ āϏā§āĻā§āϝāĻžāύ⧠āϏāϰāĻžāϏāϰāĻŋ āϞāĻžāĻāĻ āϰā§āĻāϰā§āĻĄ āĻā§āϞā§āĨ¤
- 04
āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ-āĻ āύāϞāĻŋ āĻāĻāĻāĻžāϰ āϤā§āϰāĻŋ â āϤāĻŋāύāĻāĻŋ āϰā§āϞ (admin, staff, viewer), āĻā§āύ⧠āĻĒāĻžāĻŦāϞāĻŋāĻ āϏāĻžāĻāύāĻāĻĒ āύā§āĻ, āĻā§āύ⧠āϏā§āϞāĻĢ-āĻāύāĻāĻžāĻāĻ āύā§āĻāĨ¤ Better Auth āϏā§āĻļāύ āϏāĻžāĻŽāϞāĻžāϝāĻŧ; āĻāĻāĻāĻŋ āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏāĻŋāĻĄ āϏā§āĻā§āϰāĻŋāĻĒā§āĻ āĻĒā§āϰāĻĨāĻŽ āĻ ā§āϝāĻžāĻāĻžāĻāύā§āĻ āϤā§āϰāĻŋ āĻāϰā§āĨ¤
- 05
āĻāĻŋāĻāĻŋāĻāϰ-āĻā§āϝāĻžāϞāĻžāϰāĻŋ āĻĒāϰā§āϝāĻžāϝāĻŧā§āϰ āĻāύā§āϝ āĻĒā§āϰāϏā§āϤā§āϤ āĻāĻāĻāĻŋ āĻĒāĻžāĻŦāϞāĻŋāĻ `/public/specimens/[id]` āϰā§āĻ, āϝāĻžāϤ⧠āĻāĻāĻ āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āϰā§āĻāϰā§āĻĄ āϏā§āĻāĻžāĻĢ āĻā§āϝāĻžāĻāĻžāϞāĻ āĻāϰ āĻāĻŦāĻŋāώā§āϝāϤ āĻĒāĻžāĻŦāϞāĻŋāĻ āĻāĻžāĻĻā§āĻāϰ āĻā§āϝāĻžāϞāĻžāϰāĻŋ â āĻĻā§āĻā§āĻā§āĻ āĻĒāĻžāĻāϝāĻŧāĻžāϰ āĻāϰā§āĨ¤
- 06
Next.js āĻĒāĻžāĻŦāϞāĻŋāĻ āĻĄāĻŋāϰā§āĻā§āĻāϰāĻŋāϤ⧠Docker āĻāϞāĻŋāĻāĻŽ āĻŦāĻžāĻāύā§āĻĄāϏāĻš āĻĄāĻŋāϏā§āĻ-āĻŽāĻžāĻāύā§āĻā§āĻĄ āĻāĻŽā§āĻ āĻāĻĒāϞā§āĻĄ, āϝāĻžāϤ⧠āĻāύā§āĻā§āĻāύāĻžāϰ āϰāĻŋāĻŦāĻŋāϞā§āĻĄā§ S3 āύāĻŋāϰā§āĻāϰāϤāĻž āĻāĻžāĻĄāĻŧāĻžāĻ āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āĻĢāĻā§āĻā§āϰāĻžāĻĢ āĻāĻŋāĻā§ āĻĨāĻžāĻā§āĨ¤
- 07
āĻāĻāĻāĻŋ āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻŦā§āϝāĻžāĻāĻāĻĒ āĻāύā§āĻĄāĻĒāϝāĻŧā§āύā§āĻ, āϝāĻž āϞāĻžāĻāĻ Postgres āĻĄāĻžāĻŽā§āĻĒ āĻāϰ āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻāĻĒāϞā§āĻĄ āĻāϰāĻž āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āĻāĻŽā§āĻ āĻāĻāϏāĻā§āĻā§ āĻĄāĻžāĻāύāϞā§āĻĄāϝā§āĻā§āϝ āĻāϰā§āĻāĻžāĻāĻā§ āϏā§āĻā§āϰāĻŋāĻŽ āĻāϰ⧠â āϏāĻŋāĻā§āĻāϞ-VPS āĻĄāĻŋāĻĒā§āϞāϝāĻŧāĻŽā§āύā§āĻā§āϰ āĻāύā§āϝ āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻžāϰ āĻŦā§āĻŽāĻžāĨ¤
03āϏā§āĻā§āϝāĻžāĻ
āĻĒāĻžāĻŦāϞāĻŋāĻ + āĻāĻŋāĻāĻŋāĻāϰ (āĻĢā§āĻ ā§¨)
- Next.js 16
- React 19
- Tailwind 4
- Base UI
- shadcn/ui
- react-qr-code
- recharts
- Public gallery
āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻ ā§āϝāĻžāĻĒ
- Better Auth
- 3-role RBAC
- Admin-only invites
- react-hook-form
- Zod
- Print-grade labels
- Cabinet/shelf/box
- Backup + restore
āĻĄā§āĻāĻž + āĻ āĻŦāĻāĻžāĻ āĻžāĻŽā§
- Drizzle ORM
- PostgreSQL
- Postgres-js
- Server actions
- Disk-mounted uploads
- CSV/Excel export
- Docker Compose
- GitHub Actions CI
04āϏā§āĻā§āϰāĻŋāύāĻļāĻ
05āĻāĻ āĻŋāύ āĻ āĻāĻļ
āĻŽā§āϞ āĻŽāĻĄā§āϞāĻŋāĻ āϏāĻŋāĻĻā§āϧāĻžāύā§āϤ āĻāĻŋāϞ āĻāĻāĻž āϝ⧠â āĻāĻāĻāĻŋ āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āϰā§āĻāϰā§āĻĄ āĻļā§āϧ⧠āĻāĻāĻāĻŋ āϏāĻžāϰāĻŋ āύāϝāĻŧ; āĻāĻāĻž āĻāĻāĻāĻŋ āϏāĻžāϰāĻŋ + āĻāĻāĻāĻŋ āĻĢāĻŋāĻāĻŋāĻā§āϝāĻžāϞ āĻ āĻŦāϏā§āĻĨāĻžāύ + āĻāĻāĻāĻŋ āĻĒā§āϰāĻŋāύā§āĻāϝā§āĻā§āϝ āĻāϰā§āĻāĻŋāĻĢā§āϝāĻžāĻā§āĻāĨ¤ āĻā§āϝāĻžāĻŦāĻŋāύā§āĻ, āĻļā§āϞāĻĢ āĻāϰ āĻŦāĻžāĻā§āϏāĻā§ āĻĄā§āĻāĻžāĻŦā§āϏ āĻĨā§āĻā§ āĻāĻžāĻĒāĻžāύ⧠āĻāĻ āĻžāϞ⧠āϞā§āĻŦā§āϞ āĻšāϝāĻŧā§ āĻāĻŦāĻžāϰ QR āϏā§āĻā§āϝāĻžāύā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻā§āϰ⧠āĻāϏāϤ⧠āĻšāĻŦā§ â āϝāĻžāϤ⧠āĻāĻžāĻĻā§āĻāϰ āϏā§āĻāĻžāĻĢ āĻāĻāĻāĻŋ āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āϤā§āϞ⧠āϞā§āĻŦā§āϞ āϏā§āĻā§āϝāĻžāύ āĻāϰ⧠āύāĻŋāĻā§āϰ āĻĢā§āύ⧠āϞāĻžāĻāĻ āϰā§āĻāϰā§āĻĄ āĻĻā§āĻāϤ⧠āĻĒāĻžāύāĨ¤ āĻ āϰā§āĻĨāĻžā§ QR-āĻā§ āĻāĻāĻāĻŋ āϏā§āĻĨāĻŋāϤāĻŋāĻļā§āϞ, āĻĒāĻžāĻŦāϞāĻŋāĻ URL āĻāύāĻā§āĻĄ āĻāϰāϤ⧠āĻšāĻŦā§, āϝā§āĻāĻžāύ⧠āĻā§āϝāĻžāĻāĻžāϞāĻ āĻĨāĻžāĻāĻŦā§ āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ-āĻ āύāϞāĻŋ â āĻāĻāĻ āĻĄā§āĻāĻžāĻŦā§āϏ āϏāĻžāϰāĻŋāĻā§ āĻāĻŋāϰ⧠āĻĻā§āĻā§ āϰā§āĻ (`/public/specimens/[id]` āĻāϰ `/(admin)/specimens/[id]`)āĨ¤
āĻĻā§āĻŦāĻŋāϤā§āϝāĻŧ āϏāĻŋāĻĻā§āϧāĻžāύā§āϤ āĻāĻŋāϞ āĻāĻŋāĻāĻŋāĻāϰ āĻā§āϝāĻžāϞāĻžāϰāĻŋāĻā§ āĻĻā§āĻŦāĻŋāϤā§āϝāĻŧ āĻĒāϰā§āϝāĻžāϝāĻŧā§āϰ āĻāύā§āϝ āϏāĻā§āϤāύāĻāĻžāĻŦā§ āϰā§āĻā§ āĻĻā§āĻāϝāĻŧāĻžāĨ¤ āĻŽāĻāĻāĻĒā§ āĻā§āĻŽāĻŋāĻĢāĻŋāĻā§āĻļāύ, XP āĻŦāĻžāϰ āĻāϰ "discover" āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ āĻāĻŋāϞ, āĻāĻŋāύā§āϤ⧠āĻŦāĻŋāĻāĻžāĻā§āϰ āĻāĻā§ āĻĻāϰāĻāĻžāϰ āĻāĻŋāϞ āĻāĻāĻāĻŋ āĻāĻžāĻ āĻāϰāĻž āĻā§āϝāĻžāĻāĻžāϞāĻāĨ¤ āϤāĻžāĻ āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āϞāĻžāĻāϏ āĻļāĻŋāĻĒ āĻāϰā§āĻāĻŋ â āĻ āĻĨ, āϏā§āĻĒā§āϏāĻŋāĻŽā§āύ CRUD, āĻāĻāĻāĻžāϰ, āϰāĻŋāĻĒā§āϰā§āĻ, āϏā§āĻāĻŋāĻāϏ, āĻŦā§āϝāĻžāĻāĻāĻĒ â Drizzle āĻāϰ Better Auth āϏāĻš āĻāĻāĻāĻŋ āĻāĻāĻ Next.js 16 āĻ ā§āϝāĻžāĻĒā§, āĻāĻŦāĻ āĻĒāĻžāĻŦāϞāĻŋāĻ āϰā§āĻ āϏāĻŋāĻāύā§āĻāĻžāϰ āĻāĻŽāύāĻāĻžāĻŦā§ āϤā§āϰāĻŋ āϝ⧠āĻā§āϝāĻžāϞāĻžāϰāĻŋ āĻĄā§āĻāĻž āĻŽāĻĄā§āϞ āύāĻž āĻā§āĻāϝāĻŧā§āĻ āĻŦāϏ⧠āϝāĻžāϝāĻŧāĨ¤ āĻĒā§āϰāĻĨāĻŽ āϏā§āϞāĻžāĻāϏ⧠āĻāĻŽ-āĻ āĻŦā§āĻļāĻŋ; āĻĒāĻžāĻŦāϞāĻŋāĻ āĻĻā§āĻāĻžāϰ āĻāĻā§ āĻā§āϝāĻžāĻāĻžāϞāĻāĻā§ āĻŦāĻŋāĻļā§āĻŦāϏā§āϤ āĻšāϤ⧠āĻšāĻŦā§āĨ¤
āĻāĻŦāĻžāϰ āĻāĻĒāύāĻžāϰ āĻĒāĻžāϞāĻž
āĻāĻĒāύāĻžāϰ āĻ āĻĒāĻžāϰā§āĻļāύā§āϰ āĻāύā§āϝ āĻāϰāĻāĻŽ āϤā§āϰāĻŋ āĻāϰāϤ⧠āĻāĻžāύ?
āĻāĻŽāϰāĻž āĻŦāĻāϰ⧠āĻ āϞā§āĻĒ āĻāĻŋāĻā§ āĻāĻžāϏā§āĻāĻŽ āĻĒā§āϰāĻāϞā§āĻĒ āĻā§āϰāĻšāĻŖ āĻāϰāĻŋāĨ¤ āĻāĻāĻž āĻāĻĒāύāĻžāϰ āϏāĻŽāϏā§āϝāĻžāϰ āĻāĻžāĻāĻžāĻāĻžāĻāĻŋ āĻŽāύ⧠āĻšāϞ⧠āĻāĻžāύāĻžāύāĨ¤