Skip to content
Projects

nakafaai/nakafa.com has 81 GitHub stars and 18 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-15 06:45 UTC. Last push 2026-11-13.

How these counts are measured

Measured star growth

in 24h
0
in 7 days
Collecting history
in 15 days
Collecting history
in 1 month
Collecting history

Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.

About

AI Native Free High-Quality Learning Platform (K-12 to University)

Learning

README.md

Original

Nakafa

DeepWiki

Nakafa is a source-available educational platform for structured learning, assessments, Quran study, and political analysis. The production site is nakafa.com.

This repository owns the React applications on TanStack Start, design system, transactional Convex backend, renderer implementations, user state, and product integrations. The separate Aksara repository owns authored content and signed publication artifacts for every content scope. packages/contents contains only live Nakafa product, formatting, and agent contracts. It is not an authored content source or publication path.

Toolchain

package.json is the toolchain source of truth:

  • Node.js 26.13.1, and the Node major that packages/backend/convex.json names for Convex "use node" actions, installed with brew install node@<major>. The local acceptance backend finds it through Homebrew, so no shell puts it first.
  • Bun 1.4.4
  • Turborepo
  • TanStack Start and React 19
  • tsrs, the Rust port of the TypeScript 7.1 compiler
  • Convex
  • Vitest
  • Biome through Ultracite

Do not add .npmrc, .node-version, .nvmrc, or another package-manager contract unless the repository gains a measured need that package.json cannot express.

Setup

git clone https://github.com/nakafaai/nakafa.com.git
cd nakafa.com
bun install --frozen-lockfile
cp apps/www/.env.example apps/www/.env.local

Fill in the application environment and use the main dev deployment selected in packages/backend/.env.local (see packages/backend/AGENTS.md). Content routes need a populated, verified Aksara signed runtime. An empty backend is not a complete content fixture.

Nakafa uses Portless HTTPS URLs for local development. Google rejects .localhost subdomains as OAuth redirect URIs, so configure the proxy with Nakafa's owned development suffix before testing Google sign-in:

bunx portless proxy start --tld local.nakafa.com

Stop an existing proxy before changing its suffix. This setting is shared by local projects. Portless listens on port 443, creates and trusts a local certificate authority, and registers local DNS entries for running apps.

Run bun run dev for hot reload. The canonical checkout serves https://nakafa.local.nakafa.com; worktrees receive their own prefix, such as https://ci.nakafa.local.nakafa.com. The web and email preview servers receive separate names. CAS runs as Cloudflare Workers, so it has no local server. Use bunx portless list to inspect active routes, bunx portless get nakafa to obtain this checkout's web URL, and bunx portless doctor to check the proxy, DNS, and certificate trust.

Set SITE_URL in apps/www/.env.local and the selected development backend to that exact web origin. Set VITE_CONVEX_URL and VITE_CONVEX_SITE_URL to the same main dev deployment. The shared deployment carries one SITE_URL, which backs auth and checkout, so a worktree on its own origin must use an isolated development deployment instead of the shared one. Google's client configuration must include the web origin under authorized JavaScript origins and <web-origin>/api/auth/callback/google under authorized redirect URIs. A worktree needs its exact callback registered separately; Google does not accept wildcard callbacks. Acceptance databases use inert authentication credentials. Real sign-in requires a development backend configured with the Google client credentials.

Ordinary bun run build and bun run start use your configured nonproduction backend. For a reproducible production-mode acceptance run, use:

bun run acceptance:prepare
bun run acceptance:build
bun run acceptance:start

Preparation creates a private native Convex database under .cache/acceptance, checks out the reviewed Aksara revision pinned in packages/backend/scripts/content/acceptance/source.json, and publishes its fixed acceptance selection through Aksara's normal signed publication protocol. It uses an ephemeral local signer and needs no production deployment or signing credentials. Aksara owns every authored source and validates complete lesson groups, exam sets, locales, and structured snapshots before activation.

The acceptance build and start commands run ordinary app commands with that isolated backend. They preserve your normal Convex selection and stop the owned backend when the operation ends. Production Convex runs functions on dedicated hosts, so the local backend runs at most one active isolate per core and the build runs below its CPU priority. Prerender bursts then queue for a core instead of spending Convex's one-second query limit waiting for one. Start also serves a stand-in for PostHog ingestion on a loopback port that preparation reserves, because the build bakes that address into the app's analytics proxy. It accepts and discards every event, so analytics never leaves the machine and the proxy logs no failures. Start serves the app on http://localhost:3000, without Portless.

Run the browser suites from the repository root in a second terminal:

bun --filter www test:browser

That runs every project at once, which suits one file or folder. A whole run selects each suite in turn with PLAYWRIGHT_SUITE: the parallel suites runtime, learner, chat, visual and browsers first, then the one-worker suites timing and browser-timing, whose specs measure latency and paint (apps/www/playwright.config.ts). A test records a trace and a video, kept when it fails, only with PLAYWRIGHT_RECORD=1, as a rerun of a failure asks.

A browser test seeds its learners, schools and rows in its own process, through the local backend's admin HTTP API (LocalConvex in packages/backend/scripts/content/acceptance/convex.ts), so a fixture costs one call and no process. A person gets the same fixtures from the command line, for example a signed-in learner's cookie for a browser of their own:

bun run --cwd packages/backend acceptance learner /tmp/learner-cookie.json

Each checkout prepares its own runtime, and its backend takes free ports. To serve a second runtime beside another one, name the app's port with ACCEPTANCE_PORT in every acceptance command and in the browser suites. Preparation records the origin and bakes it into the backend, the build bakes it into the app, and build and start refuse a port other than the recorded one:

ACCEPTANCE_PORT=3100 bun run acceptance:prepare
ACCEPTANCE_PORT=3100 bun run acceptance:build
ACCEPTANCE_PORT=3100 bun run acceptance:start
ACCEPTANCE_PORT=3100 bun --filter www test:browser

Stop acceptance services before bun run acceptance:clean removes their database, source checkout, signer, logs, and the web app's cached signed fetch responses. Cleanup verifies filesystem ownership and refuses a database whose identity changed. To refresh the fixture, clean it and repeat preparation. Update the pinned Aksara revision deliberately when the acceptance contract needs new reviewed examples.

Production deploys run from GitHub Actions only after a merge to main. The deploy workflow deploys the Convex backend with its deploy key, then runs alchemy deploy for the stage. The Alchemy stack in apps/www/alchemy.run.ts builds the web app and deploys it to Cloudflare Workers. App builds query bounded real published samples and verify the signed content with the current renderer. They do not export or import production tables or release history. Full corpus validation remains in Aksara's publication and renderer compatibility checks. See ADR 0037.

Repository layout

  • apps/www: main TanStack Start application at https://nakafa.local.nakafa.com
  • apps/mcp: Cloudflare Worker edge for the Convex MCP runtime
  • apps/api: Cloudflare Worker edge for the Convex REST runtime
  • apps/cas: CAS math engine, a Python Durable Object behind a TypeScript front at https://cas.nakafa.com
  • apps/email: email preview application at https://email.nakafa.local.nakafa.com
  • packages/backend: Confect schema, functions, workflows, native Agent capabilities, and integrations
  • packages/design-system: shared React components and renderer implementations
  • packages/contents: Nakafa product, formatting, route-context, learner, and agent contracts
  • packages/testing: shared Vitest configuration
  • packages/utilities: generic cross-domain primitives
  • repos/effect: read-only Effect source pinned to the installed version

Read the nearest AGENTS.md before working. Convex changes also require packages/backend/AGENTS.md and the generated Convex guidelines. Effect work requires reading repos/effect/.agents/AGENTS.md plus the relevant implementation, tests, type-level tests, module structure, and API design in the vendored source.

Commands

bun run dev
bun run dev:all
bun run build
bun run start
bun run test
bun run lint
bun run security:audit
bun run format
bun run boundaries
bun run effect:source:check

There is no root typecheck script. Run the typecheck owned by each changed workspace, for example:

bun --filter www typecheck
bun --filter @repo/backend typecheck
bun --filter @repo/design-system typecheck

Tests use Vitest config files owned by each workspace. Keep tests colocated as name.test.ts, import the Vitest APIs they use, and preserve the per-file coverage gate that every workspace inherits from packages/testing. Final tests only target real colocated .ts Modules. Do not commit tests for .tsx Modules, rename React tests to hide them as .test.ts, create __tests__ folders, or add duplicate test-only source Modules. Verify rendered React behavior through production Browser or E2E acceptance.

Content ownership

Do not add substitute content or duplicate Aksara-owned source to this repository. Authored educational content changes belong in nakafaai/aksara. Nakafa consumes only authenticated current Aksara contracts and signed publication artifacts.

The shared @nakafa/aksara-contracts/locale module is the only locale source of truth. English, Indonesian, and German are active. TanStack Start routing, API validation, Convex validators, AI language handling, date formatting, checkout localization, and sitemap generation derive from that contract. Do not add a second app-local locale list.

Aksara's signed page family owns public legal and company documents. Nakafa uses the same verified Page projections and artifacts for human routes, footer navigation, sitemap entries, and Markdown or LLM delivery. Do not restore local legal MDX, hard-coded legal route catalogs, or another publication path.

Renderer and component implementations remain in Nakafa. Aksara content refers to reviewed renderer contracts and never carries duplicate React or TSX implementations.

Contributing

Read AGENTS.md and .github/CONTRIBUTING.md. Submit a ready pull request from a branch, keep it current with main, resolve review conversations, and run the relevant checks on the exact head before merge.

License

Nakafa uses a source-available license model and is not open source under the Open Source Definition.

Area License or policy
Software source code Nakafa Source Available License 2.0
Educational content, articles, exercises, datasets, and media Nakafa Content License 2.0
Names, logos, domains, product names, UI identity, and brand assets Nakafa Trademark and Brand Policy 2.0

Commercial, hosted, redistribution, modification, white-label, rebrand, and AI-training uses require prior written permission from PT. Nakafa Tekno Kreatif. See the license files for the complete terms.

Reference material:

For commercial licensing inquiries: [email protected]