TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
A family scheduling platform for Israeli parents and teachers. Manage children's lessons, playdates, and personal events in one place — with Google Calendar sync and daily email digests.檢視完整 README ↗A family scheduling platform for Israeli parents and teachers. Manage children's lessons, playdates, and personal events in one place — with Google Calendar sync and daily email digests.
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, React 19) |
| Language | TypeScript 5 |
| Styling | Tailwind CSS 4, shadcn/ui, Lucide icons |
| Auth | NextAuth.js 4 (Google OAuth) |
| Database | PostgreSQL (Neon serverless) via Prisma 7 |
| Resend | |
| Calendar | Google Calendar API v3 |
| Testing | Playwright (E2E) |
| Deployment | Vercel |
git clone <repo-url>
cd otef-parents
npm install
Copy .env.example to .env.local and fill in the values:
# Database (Neon PostgreSQL)
DATABASE_URL="postgresql://[USER]:[PASSWORD]@[HOST].neon.tech/[DBNAME]?sslmode=require"
# NextAuth
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="<generate with: openssl rand -base64 32>"
# Google OAuth
GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""
# Resend (email)
RESEND_API_KEY=""
# Cron job authentication
CRON_SECRET=""
npx prisma generate
npx prisma db push
Optional — seed sample data:
npx tsx scripts/seed-groups.ts
npm run dev
Open http://localhost:3000.
src/
├── app/
│ ├── api/ # API routes (52 endpoints)
│ │ ├── auth/ # NextAuth handler
│ │ ├── children/ # Child CRUD + invite codes
│ │ ├── groups/ # Group management
│ │ ├── schools/ # School management + import
│ │ ├── playdates/ # Playdate CRUD + join
│ │ ├── schedule/ # Schedule items
│ │ ├── lessons/ # Recurring lessons
│ │ ├── events/ # Personal events
│ │ ├── calendar/ # Google Calendar sync
│ │ ├── dashboard/ # Daily feed data
│ │ ├── admin/ # Admin endpoints
│ │ ├── cron/ # Daily digest cron job
│ │ └── account/ # User account + Google disconnect
│ ├── dashboard/ # Authenticated app pages
│ │ ├── children/ # Manage children
│ │ ├── playdates/ # Browse playdates
│ │ ├── lessons/ # View lessons
│ │ ├── teacher/ # Teacher dashboard
│ │ ├── admin/ # Admin panel
│ │ ├── settings/ # User preferences
│ │ └── help/ # Help & FAQ
│ ├── login/ # Sign-in page
│ ├── privacy/ # Privacy policy
│ ├── terms/ # Terms of service
│ └── walkthrough/ # Onboarding flow
├── components/ # React components
│ ├── ui/ # shadcn/ui base components
│ ├── daily-feed.tsx # Main schedule view
│ ├── add-lesson-dialog.tsx
│ ├── add-to-calendar-button.tsx
│ ├── teacher-dashboard-tabs.tsx
│ ├── admin-panel.tsx
│ └── ...
├── lib/
│ ├── auth.ts # NextAuth config + role helpers + requireAdmin()
│ ├── google-calendar.ts # Calendar API client
│ ├── email.ts # Resend email + digest formatting
│ ├── prisma.ts # Prisma client
│ ├── import-parsers.ts # CSV/XLSX import parsing
│ ├── rate-limit.ts # In-memory rate limiter
│ ├── validation.ts # Input sanitization + validation helpers
│ └── format.ts # Date/time utilities
└── types/ # TypeScript definitions
prisma/
├── schema.prisma # Database schema (14 models)
└── migrations/ # Migration history
scripts/
├── seed-groups.ts # Seed sample groups
├── seed-mock-playdate.ts # Seed test playdates
└── migrate-default-school.ts # Default school migration
e2e/ # Playwright tests (8 specs)
Key models:
PARENT, TEACHER, ADMIN, SUPERADMINChildParent (supports co-parenting)Invite codes (ChildInvite, GroupInvite) are 6-character, single-use, 24-hour expiry.
The app uses Google OAuth for authentication and Calendar API for event sync.
Scopes requested:
| Scope | Purpose |
|---|---|
openid | Google Sign-In |
email | User identification + digest emails |
profile | Display name and avatar |
calendar.events | Sync lessons, playdates, and events to Google Calendar |
The app only creates and deletes events it owns — it never reads or modifies existing calendar data. Users can disconnect Google Calendar from Settings at any time.
Offline access is enabled so the daily digest cron can manage calendar events without the user being logged in.
| Job | Schedule | Description |
|---|---|---|
| Daily Digest | 0 6 * * * (6 AM UTC) | Sends personalized email summaries to users with digest enabled, respecting their preferred time in Israel timezone |
Configured in vercel.json and secured with CRON_SECRET.
# Run E2E tests
npx playwright test
# Run with UI
npx playwright test --ui
Tests cover: login page, auth redirects, API protection, PWA manifest, RTL layout, input validation, static assets, and accessibility.
Config: Chromium, he-IL locale, Asia/Jerusalem timezone, port 3002.
Hardened per Web Application Security for AI Agents (CandleKeep).
src/middleware.ts) protects all /dashboard/* and /api/* routes — defense-in-depth on top of per-route auth checksPARENT, TEACHER, ADMIN, SUPERADMIN) enforced via requireRole() and requireSchoolRole() helpersrequireAdmin() in lib/auth.ts — single source of truth for SUPERADMIN checksTEACHER and above — parents cannot self-elevatelib/validation.ts)sanitizeString(input, maxLength) — trims and enforces length limits on every text input across all 30+ API routesisValidEmail() — format validation on email inputsisValidUrl() — protocol validation (http/https only) on all Zoom/URL fieldslib/rate-limit.ts)In-memory per-process rate limiter on critical endpoints:
| Endpoint | Limit | Window |
|---|---|---|
| Invite code redemption | 10 requests | 60s per user |
| Admin child search | 30 requests | 60s per admin |
| Bulk import | 5 requests | 60s per user |
{ error: string } JSON with appropriate HTTP status codeshttp(s):// before storage and renderingcrypto.randomBytes(), not Math.random()Configured in next.config.ts:
Content-Security-Policy — restricts script, style, img, connect, and frame sourcesCross-Origin-Opener-Policy: same-origin-allow-popupsStrict-Transport-Security (HSTS with preload, 2-year max-age)X-Content-Type-Options: nosniffX-Frame-Options: DENYReferrer-Policy: strict-origin-when-cross-originPermissions-Policy (camera, microphone, geolocation disabled)/api/cron/daily-digest requires a Bearer token matching CRON_SECRETCRON_SECRET is not configured (prevents Bearer undefined bypass).env* files excluded in .gitignoreopenssl rand -base64 32NEXT_PUBLIC_ prefix on any secretDeployed on Vercel. The build command runs Prisma generate before Next.js build:
prisma generate && next build
he-IL) as primary languageAsia/Jerusalem)Private project.