Appearance
Ecosystem & Repositories
The platform is deliberately split across four private repositories, each with one job. This page is the map: what lives where, and how data moves between them.
The map
rendering diagram…
drag to pan · ctrl / ⌘ + scroll to zoom
Repository responsibilities
ediky-website — the product
The app root lives at ediky-website/ediky/ (the outer folder holds GitHub workflows and the repo README). It contains:
- the React 19 SPA (
src/) — every page, component, hook, and client library, - Cloudflare Pages Functions (
functions/) — the request/response backend: AI grading, code-run proxy, notes proxy, Codeforces proxy, - two Cloudflare Workers (
worker/,worker-reminders/) — scheduled background judging and event reminders, - the question bank content (
src/content/<section>/*.md) — the shipped output ofediky_tools, - build tooling (
tools/) —build-content.mjs,lint-content.mjs, and a mirror of the qgen pipeline, - Firestore rules (
firestore-rules/) and operational scripts (scripts/).
Full breakdown: Folder Structure.
ediky_tools — the content factory
Generation and validation pipelines that author questions outside the product repo, then validate against and write directly into the real website checkout. It holds no live content of its own; tools/site_config.py is the single place that resolves "where is the real website repo" (via a sibling checkout or EDIKY_WEBSITE_ROOT). This design exists because an earlier split — where each repo kept its own copy of content and lint rules — let 34 duplicate questions ship in one batch; the pipelines now lint against the website's actual live content, so duplicate titles/slugs are caught at authoring time. Details: Tools Overview.
Docy — lecture-notes content
Per-subject markdown for the learning workspace: cn/, os/, dbms/, oop/, dsa/, sql/, stl/, lld/, hld/, sql-practice/, plus tools/ (~750 files). Files are named by lecture index (0.md, 1.md, …) and are not bundled into the app — the website fetches them at runtime through the /get-notes Pages Function, which proxies the GitHub Contents API using a server-side token (the repo is private; the token never reaches the browser). Details: Docy.
ediky-core — this portal
A standalone VitePress site, deployed as its own Cloudflare Pages project under the Ediky Workflow name. Nothing in the app imports from it; the app links out to it (the Docs item in the user menu). It ships its own Pages Function (/api/ask-docs) for the documentation assistant, reusing the website's provider-chain module verbatim.
Cross-repo data flows
1. Question content: ediky_tools → ediky-website
rendering diagram…
drag to pan · ctrl / ⌘ + scroll to zoom
The critical property: the pipeline's duplicate checks and lint run against the website's real src/content/, not a local mirror — so what passes locally is exactly what deploys.
2. Lecture notes: Docy → browser (at runtime)
SubjectLayout asks /list-notes for a subject's file listing and /get-notes?path=<subject>/<n>.md for each body. Both Functions call the GitHub Contents API for the private Docy repo with env.GITHUB_TOKEN, add CORS, and return the markdown. Editing a note in Docy therefore updates the live site on next fetch — no website redeploy needed.
3. App → Docs: the Docs menu item
UserMenu.jsx renders a Docs entry (BookOpen icon) that opens this portal in a new tab. The URL comes from VITE_DOCS_URL with a sensible fallback, so per-environment docs (preview vs production) need no code change.
Why four repos instead of one
- Deploy isolation — content authoring churn (hundreds of markdown commits) never triggers app deploys; docs edits never touch the product pipeline; Docy edits require no deploy at all.
- Different lifecycles — the tools repo runs on a laptop with Python + compilers; the website deploys to Cloudflare; mixing their dependency worlds helps nobody.
- Honest boundaries — each repo's README/docs can assume one audience. The cost is cross-repo coordination, which
site_config.py(tools→website) and the/get-notesproxy (Docy→website) each solve explicitly rather than implicitly.