I Built a Calendar App Kids Control – Even Parents Can't Access It Developer Mihir Shaikh launched Kid Compass, a role-based family planner where children control their own schedules and chores while parents can only view and suggest, never edit or override entries. The app, built with Next.js 15, Clerk, and PostgreSQL on Vercel, serves as a testing target for PerfAI Security's broken access control review, enforcing strict authorization boundaries such as sibling isolation and field-level ownership. A calendar and chore planner kids run themselves — parents watch, suggest, and cheer from the sidelines. Never edit, never override. Kid Compass is a role-based family planner. Kids plan, log, and check off their own day — activities, chores, to-dos. Parents get full visibility and a way to encourage from the sidelines comments, rewards , but never a way to edit a child's own entries. Underneath the product, Kid Compass is also an authorization-testing app: every access-control boundary described below is a deliberate design decision, documented inline in src/lib/auth.ts /mihirshaikbugs/kid-compass/blob/main/src/lib/auth.ts with the reasoning behind it. Roles & Permissions roles--permissions Tech Stack tech-stack Live App & Documentation live-app--documentation Security & PerfAI Testing security--perfai-testing Authorization Model authorization-model Getting Started getting-started Deployment deployment Project Notes project-notes Kid Compass has four roles, scoped per family: | Role | Can do | |---|---| Family Admin | Everything a Guardian can, plus: manage membership, create invites, revoke guardian grants, toggle a child's "maturity mode" | Guardian | See every child's schedule/chores/tasks in the family; leave suggestions; assign chores or drop them in the shared pool; set rewards | Secondary Guardian | See only what an explicit, revocable grant allows — one child, optionally one entry kind, optionally a bounded time window | Child | Create/edit/delete their own schedule blocks and tasks; mark entries private if maturity mode is on ; claim pool chores; mark their own tasks complete | A parent can always see what's planned. Only the child who owns an entry can ever check it off, edit it, or mark it done. Once maturity mode is on for a child, private entries are unreadable by anyone else — including a Family Admin. | Layer | Choice | |---|---| | Framework | Next.js 15 App Router | | Language | TypeScript | | UI | React, Tailwind CSS, Radix-based shadcn/ui | | Auth | Clerk | | Database | PostgreSQL Neon | | ORM | Prisma | | Validation | Zod | | Hosting | Vercel | | Built with | | | Resource | URL | |---|---| | Live app | | https://kid-compass-teal.vercel.app/demo https://kid-compass-teal.vercel.app/demo https://kid-compass-teal.vercel.app/docs.html https://kid-compass-teal.vercel.app/docs.html https://kid-compass-teal.vercel.app/openapi.json https://kid-compass-teal.vercel.app/openapi.json https://kid-compass-teal.vercel.app/openapi.yaml https://kid-compass-teal.vercel.app/openapi.yaml The /demo route renders one seeded family's real data with no account required — including a private entry, shown correctly redacted, to demonstrate the core privacy guarantee live. Kid Compass was purpose-built as a testing target for PerfAI Security's Broken Access Control review. The boundaries below are specifically the kind of thing a BOLA/IDOR-focused review is meant to probe: Same-tier sibling isolation — two children in one family hold the identical role CHILD and must be fully isolated from each other, despite sharing every other membership property. Field-level ownership on a single row — a chore's title / notes / status belong to the child; its rewardNote belongs to the guardian who assigned it. Two legitimate owners, two different fields, one database row. Privacy that ignores a later setting change — a private entry's visibility is baked in at creation time from the child's maturity-mode flag at that moment . Toggling the flag off later never retroactively exposes something written while it was on. Grant-scoped access with no membership shortcut — a secondary guardian's access comes entirely from an explicit, revocable grant row, never inferred from family membership alone. Ownership validation on every mutating request — task completion, block edits, and chore claims all re-verify the caller's relationship to the resource server-side, never trusting client-supplied IDs. Review questions this app is designed to be tested against: - Can one child access another child's private schedule? - Can a guardian modify data they should only be able to view? - Can a secondary guardian access data outside their granted scope? - Are private calendar entries actually protected at the API layer, not just hidden in the UI? - Are ownership checks enforced on every request, not just the ones the UI exercises? The full authorization model is documented inline in src/lib/auth.ts /mihirshaikbugs/kid-compass/blob/main/src/lib/auth.ts , and every endpoint's access rules are spelled out in the API documentation https://kid-compass-teal.vercel.app/docs.html . Two layers: Site-level Role USER / ADMIN — moderation only ban a user . Never grants access to any family's data. Per-family FamilyRole FAMILY ADMIN / GUARDIAN / SECONDARY GUARDIAN / CHILD — governs everything else. Full reasoning for every check lives in src/lib/auth.ts /mihirshaikbugs/kid-compass/blob/main/src/lib/auth.ts and the model comments in . /mihirshaikbugs/kid-compass/blob/main/prisma/schema.prisma prisma/schema.prisma npm install npm run db:push sync the schema to your local Postgres npm run db:seed 3 fictional families with kids/chores/activities npm run dev Requires a local Postgres database and a .env with DATABASE URL / DIRECT URL pointing at it see .env.example . Clerk runs in keyless dev mode locally — no API keys needed to start; visiting the app for the first time auto-provisions temporary dev keys. To promote a signed-up user to site-level ADMIN moderation only — never grants access to family data : npm run make-admin --