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.