# ArchNest — Project Guide for Kiro > Steering file for AI sessions working on this repo. Covers architecture > decisions, workflow rules, and patterns to follow. Read alongside > `design-rules.md` (visual conventions) which is injected separately. --- ## Quick Context ArchNest is a **self-hosted ops dashboard** — live infrastructure monitoring, SSH terminal/tunnels/files, Docker container management, remote desktop, and bookmarks. Deployed at `archnest.snsnetlabs.com` via Docker Compose on `racknerd1`. Private Forgejo repo (never public). ## Tech Stack (exact versions matter) | Layer | Tech | |-------|------| | Frontend | React 19, Vite 8, TypeScript 6, Tailwind CSS v4, React Router 7 | | Charts | Recharts 3 | | Icons | Lucide React (verify exports exist at runtime, not just TS types) | | Terminal | xterm.js 6 (`@xterm/xterm` + `@xterm/addon-fit`) | | Backend | Fastify 5, TypeScript 5.7, ESM (`tsx` dev, `tsc -b` build) | | DB | better-sqlite3 (SQLite) | | Auth | `@fastify/jwt` + bcryptjs + server-tracked sessions | | Validation | zod | | SSH | ssh2 library | | AWS | `@aws-sdk/client-ec2`, `@aws-sdk/client-sts` | | Deploy | Docker Compose (Alpine images), GitHub Actions → racknerd1 | ## Git Workflow - **Remote**: `origin` → private Forgejo instance (SSH via ProxyJump) - **Never commit on `main`**. Always create `kiro/` branches. - **Commit style**: imperative title + body explaining why, with trailers: ``` Co-authored-by: Samuel James Co-authored-by: Kiro ``` - **Before committing**: `npm run build` (frontend) + `cd backend && npx tsc --noEmit` (backend) - **Stage specific files** — never `git add -A` blindly - **PR flow**: `git push -u origin ` → `gh pr create` → squash-merge ## Code Patterns to Follow ### Frontend - One page component per route in `src/pages/` - All backend calls go through `src/lib/api.ts` (typed `apiFetch` wrapper) - No global state library — plain React state + localStorage for prefs - Auth via `src/lib/AuthContext.tsx` (JWT in localStorage) - New pages need: route in `App.tsx`, entry in `api.ts`, sidebar link ### Backend - One route file per feature in `backend/src/routes/` - Integration adapters in `backend/src/integrations/` (must implement `testConnection()`) - SSH-based features use `backend/src/ssh/connect.ts` shared transport - Request validation with zod schemas - Audit logging via `logEvent()` from `db/index.ts` - Secrets encrypted at rest (AES-256-GCM via `db/crypto.ts`) - Never expose secret values to frontend — only `secretKeys: string[]` ### Adding a New Integration 1. Create adapter in `backend/src/integrations/.ts` 2. Register in `backend/src/integrations/registry.ts` 3. Add type to `IntegrationType` union 4. Add route if needed in `backend/src/routes/` 5. Add `api.ts` functions + TS interfaces on frontend 6. Add card in Settings integrations section ## Policies - **Zero mock data** — every number comes from a live API/SSH/DB call - **Design-first for big features** — write a `docs/.md` before coding - **No footer** on any page - **Primary target**: 1920px+ viewport, should feel spacious - **Mesh gate** defaults OFF — never lock the live instance - **OpenSSL legacy provider** in backend Dockerfile — don't remove (needed for old PEM keys) ## Environment - Required env vars: `ARCHNEST_SECRET_KEY`, `ARCHNEST_JWT_SECRET` - Optional: `ARCHNEST_DB_PATH`, `PORT`, `ARCHNEST_GUAC_CRYPT_KEY`, `ARCHNEST_CORS_ORIGIN`, `ARCHNEST_AGENT_TOKEN`, `ARCHNEST_AGENT_STALE_MS` - Frontend dev proxies `/api` → `http://localhost:4000` ## Key Files to Read First 1. `README.md` — architecture overview 2. `HANDOFF.md` — current state + standing rules 3. `design-decisions.md` — visual conventions + per-page implementation notes 4. `ROADMAP.md` — deferred/tiered work 5. `docs/` — subsystem design documents ## SSH Config (for reference) - `ssh forgejo` → Git operations (User: forgejo, via ProxyJump linode) - `ssh forgejo-admin` → root shell on Forgejo host (for admin tasks) - `ssh linode` → jump host at 172.238.163.85