Sitra AchraProject Wiki
Development

Development portal architecture

The confirmed content, persistence, performance, and GitHub boundaries for the working development portal.

Current decision

The development portal is a server-rendered Next.js application backed by PostgreSQL. The database is the working source of truth for live edits. GitHub stores reviewed Markdown exports and application source, but a page save does not wait for a branch, commit, merge, build, or deployment.

This separates the two workflows that the static-site architecture had coupled:

  • Develop an idea: open an editor from the page payload, save one local database transaction, and continue working.
  • Publish a repository snapshot: export changed pages to Markdown in a background GitHub workflow with an explicit review boundary.

The second workflow is not part of the first portal slice. Until export is implemented, repository Markdown seeds the database but database edits do not flow back automatically.

Content model

Each page has a stable database identity, route slug, title, description, lifecycle status, category, Markdown body, source path, revision number, and editor identity. Every successful save writes an immutable revision record in the same transaction as the current page update. The client sends the revision it opened; a stale revision is rejected rather than silently overwriting another editor.

Categories are first-class records rather than directory side effects. Editors can create root categories and subcategories, move pages by dragging them or changing the category in the editor, and delete categories only after their pages and child categories have been moved. Page deletion removes its revision and link records transactionally.

The page editor is embedded in the article instead of opening a separate source window. Tiptap provides graphical formatting while its Markdown extension preserves the repository-facing storage format. KaTeX renders inline and block LaTeX formulas in both editing and reading views.

Explicit Markdown links and [[wiki links]] form a page-link table. Article pages show outgoing links, backlinks, and same-category neighbors. This provides useful related-topic navigation without waiting for semantic search.

The repository documents are converted into a deterministic seed during the application build. First start imports missing documents and never overwrites a page already present in PostgreSQL.

Product surfaces

The portal landing page routes to three separate products:

  • Wiki: page discovery, related topics, taxonomy management, and authoring. This is the only surface with the documentation sidebar.
  • References: image upload or URL capture, source and credit metadata, tags, filters, downloads, and a near-full-screen carousel.
  • Apps: interactive presentations and focused development tools, beginning with the planetary ocean-power ring simulation.

Uploaded references live under the portal upload directory and their searchable metadata lives in PostgreSQL. Remote image URLs can also be registered without copying the source file. Reference backups therefore require both the PostgreSQL archive and the upload archive already produced by the host backup timer.

Performance boundary

Search and editor controls must open without a network request. The rendered shell includes the page index for local search, and an article includes the complete editable content and current revision. Only save, full-text search beyond the local index, and navigation require a server request.

On the initial LXC deployment, measured loopback responses were approximately 15 ms for search, 32 ms for a transactional save, and 112 ms for a warm article render. These are verification measurements rather than long-term service-level objectives. The interaction budget remains: controls appear in the next rendered frame, ordinary database operations complete well below 250 ms on the local host, and no GitHub operation blocks editing.

Runtime and identity

The application runs as the unprivileged portal account. Next.js and PostgreSQL communicate over a local Unix socket, and nginx proxies only from loopback. The application health endpoint includes a database query so a process that cannot reach its content store is not considered healthy.

Cloudflare Tunnel and Access are the public ingress and identity boundary at https://developer.sitraachra.com. Anonymous editing is disabled. The application validates Access assertions at the origin instead of trusting a forwarded email header by itself. See Development portal hosting for the host and recovery boundary.

Consequences

  • Editing no longer creates or reconciles a Git branch.
  • docs.sitraachra.com is a deprecated compatibility hostname rather than a second editing surface.
  • GitHub downtime or rate limiting does not interrupt idea development.
  • Database backups and tested restores are required because Git is no longer the transactional store.
  • GitHub export, review, conflict presentation, and webhook ingestion remain explicit application features rather than persistence primitives.
  • Semantic search can be added later without changing the page or revision model.
04-production/portal-architecture.md