Files

admin.arikigame

Custom Git Studio + Team Portal for Tinqs. Next.js is the only UI. Gitea runs headless as the git + API engine (clone/push/SSH/LFS/Actions/Issues/PRs). No Gitea web UI is exposed to the browser.

Architecture

HTTP API: Classical Next.js App Router only — all endpoints under src/app/api/ (route.ts handlers). No parallel Express/Fastify layer. See docs/API-ARCHITECTURE.md.

Browser (Tailscale mesh — WireGuard encrypted)
  → Next.js :8088 (this app) — identity via tailscale serve headers OR whois proxy
    → Gitea REST API v1 (headless, https://git.arikigame.com)
    → PostgreSQL :5432 (users, audit log, portal — optional in dev)

git clone / push / LFS
  → git.arikigame.com → Gitea :443 HTTPS (wire protocol; SSH :22)

No Caddy required. Tailscale is the VPN; optional tailscale serve adds HTTPS + identity headers on the MagicDNS URL, or set TAILSCALE_WHOIS_PROXY_URL so the app resolves tailnet client IPs with tailscale whois --json (see docs/TAILSCALE-PRODUCTION.md).

Gitea is headless. It stores repos, handles git protocol, runs Actions, tracks issues/PRs. This app is the sole web interface — all reads/writes go through src/lib/gitea.ts on the server, never through Gitea's HTML UI.

People auth: On the tailnet, Tailscale identity headers are enough. The login email (tailscale-user-login) is normalized to lowercase and stored as users.email — that is the canonical account key (same as your @tinqs.com identity). Existing rows in Postgres match by email; gitea_username is filled from the local part on first insert if empty. Optional portal secondary passwords live in users.password_hash only when PORTAL_SECONDARY_REQUIRED is on — they are a second factor after Tailscale, not a replacement. Optional tailscale-machine-name can be forwarded by your proxy for audit (client MagicDNS hostname).

Git: Clone/push uses git.arikigame.com only.

Quick start (local dev — npm only)

No Docker required for development. Postgres is optional (the app degrades gracefully without it — user persistence is skipped but repo browsing works).

# 1. Copy env
cp .env.example .env.local
# Edit: set GITEA_URL and GITEA_SERVICE_TOKEN (ask ops for the token)

# 2. Run
npm install
npm run dev
# → http://localhost:3000

With Postgres (for user/org/audit features):

docker compose up postgres -d
npm run dev

Where it runs

Context How
Production AWS Lightsail — Tailscale + Docker (docker compose up) or npm start; see docs/TAILSCALE-PRODUCTION.md
Local dev npm run dev — no Docker, no Tailscale
Isleborn (game dev) Does not run here. Unity uses git remotegit.arikigame.com

Tech stack

  • Next.js 16 (App Router, RSC, Server Actions)
  • TypeScript (strict)
  • Tailwind CSS (dark mode, Ariki design tokens)
  • PostgreSQL 17 (raw pg driver, no ORM — optional in dev)
  • TanStack Query (client-side cache)
  • Gitea 1.25.5 (headless git backend via REST API v1)
  • Tailscale (auth: Serve identity headers and/or whois proxy — no separate reverse proxy required)

API

REST endpoints under /api/v1/ for MCP tools, scripts, and future agents:

Endpoint Description
GET /api/v1/repos List repos (sort, order, limit, page)
GET /api/v1/repos/:owner/:repo Repo detail
GET /api/v1/repos/:owner/:repo/contents/*path File tree or file content
GET /api/v1/repos/:owner/:repo/raw/*path Raw file content
GET /api/v1/repos/:owner/:repo/commits Commit history
GET /api/v1/repos/:owner/:repo/branches Branch list
GET /api/v1/repos/:owner/:repo/tags Tag list
GET /api/v1/repos/:owner/:repo/actions CI/CD runs
GET /api/v1/orgs Organizations
GET /api/v1/me Current user identity
GET /api/health Health check

Infrastructure (optional TS_API_KEY, GITHUB_TOKEN in env — see .env.example):

Endpoint Description
GET /api/v1/infra/overview Dashboard aggregates (machines, services, tokens, agents)
GET /api/v1/infra/tokens Token metadata inventory (POST/PATCH/DELETE: admin)
GET /api/v1/infra/tokens/expiring?days=30 Tokens expiring soon
GET /api/v1/infra/services Service registry (POST/PATCH/DELETE: admin)
POST /api/v1/infra/services/:id/health Run HTTP health check (admin)
GET /api/v1/infra/tailscale/devices Live tailnet devices
GET /api/v1/infra/tailscale/dns Split DNS config
GET /api/v1/infra/github/repos?org=tinqs-ltd GitHub org repos
GET /api/v1/infra/agents Repo agent config scan (cached 5 min)

UI: /infra (admin-only). Apply DB migration db/migrations/003_infra.sql on existing Postgres; optional seed db/seed-infra.sql.

Auth: Tailscale identity headers on the tailnet, or ALLOW_DEV_AUTH for local dev.

Tests

npm test

Vitest unit tests for lib/ functions.

Deployment

Production on AWS Lightsail (medium_3_0, 4 GB RAM):

# Docker (current)
docker compose up -d

# Or direct (npm)
npm run build && npm start

Split DNS / tailscale serve / direct 100.x access routes browsers to Next (:8088) and Git Studio at https://git.arikigame.com (Gitea on :443). Details: docs/TAILSCALE-PRODUCTION.md.