Skip to content
ozelokul.com ikonuClient work2026

ozelokul.com

A private-school, college and university discovery platform with a parent centre and school panels.

Web
Let’s build something like this
ozelokul.com interface 1
ozelokul.com mobile interface 1
SaaSAMG / 26
Project
ozelokul.com
Our role
Architecture · Backend · Authorisation · Admin panel
Duration
4 months

01 / Behind the product

A real need. A considered solution.

01

Challenge

Parents choosing a school face scattered information: fees, scholarship exams, open seats and campus facilities live in different places and cannot be compared. The client had a finished design running entirely on mock data, about 53 routes and 50,000 lines. The brief: build a production-grade backend underneath without touching a single pixel, and a panel that leaves no need for a developer.

02

Approach

Supabase was built under the Vite + TanStack Start interface that stayed as it was: 111 migrations, every table under row-level security, 81 provinces and 973 districts, 411 taxonomy terms, a 22-section school panel and an entitlement engine with three plans and 47 permission keys. School, college and university profiles, open seats, a scholarship exam calendar, early registration and discounts, a price index with a published methodology; a parent centre with alarms, surveys, matching, cost calculation and journey screens.

The admin panel has three layers: hand-built workflow screens, acting on behalf of any school inside its own panel, and a data browser generated from the schema, so a new column shows up on its own. 80 server mutations were put through live exploit attempts with real JWTs and the four holes found were closed.

03

Result

Public pages render server-side with data through SSR; the notification dispatcher and scheduled jobs run as Edge Functions. The school application → documents → approval → onboarding flow, moderation, a parent CRM and a data pool live in the panel. A university faculty catalogue and discovery options are the latest modules.

03 / Scope & details

The details make the experience.

  • 01

    111 migrations, every table under RLS; an entitlement engine with 3 plans and 47 permission keys

  • 02

    81 provinces, 973 districts, 411 taxonomy terms; a 22-section school panel

  • 03

    A schema-generated data browser: a new column shows up in the panel by itself

  • 04

    80 server mutations audited with live exploit attempts

  • 05

    From mock data to a real backend without touching the design

Technology

ReactTypeScriptSupabasePostgreSQLTailwind CSS

Vite / TanStack Start / Supabase / PostgreSQL

INSIDE THE PRODUCT

The engineering behind the interface.

Systems we built and concrete problems we addressed in this project.

01

Authorisation: a god in the database, a surface problem in the panel

private.has_perm() short-circuits for the platform admin up front and every policy built on can_campus lets the admin through; a write test succeeded on 9 of 10 critical tables. The problem was surface, not permission: most of 149 tables had no screen. The answer is a data browser generated from the schema.

02

An audit with live exploit attempts

80 mutation endpoints defined with createServerFn were mapped to gates and 30 were tried live with real JWTs. Four findings were exploited (an unmatched campus answering a quote request, an invite token not bound to an email, unauthenticated analytics writes, missing state-transition checks) and closed; two had no RLS counterpart either, so a second line of defence was added.

03

Reference data as seed

The go-live check counts: 81 provinces, 973 districts, 411 taxonomy terms, 22 section definitions, 3 plans, 47 permission keys and zero tables without RLS. Every field of the mock data was mapped to the schema first, then loaded as a seed migration.

Your idea could be next.

What could we build for you?

From a first release to a growing platform. Let’s plan the design, development and launch together.

Tell us about your project

From Türkiye to the US, UK, Australia and everywhere in between.