# Hono JSX + Bun + SQLite (Server-Rendered Internal Tools) — AI Agent Guidelines & Architecture Rules

> Rules for internal tools rendered on the server with Hono JSX on Bun: forms over fetch, htmx where needed, an OAuth allow-list, Drizzle over SQLite or a read replica, and cron in the same process.
> Technologies: Hono, Bun, SQLite, Drizzle, HTMX, TypeScript

---

## AGENTS.md
```markdown
# Project Architecture & Guidelines (Hono JSX Internal Tool)

## 1. System Architecture
- **Runtime**: Bun, one process serving HTML and running scheduled jobs.
- **Framework**: Hono v4 with its built-in JSX renderer (`hono/jsx`). Pages are rendered on the server; there is no client build.
- **Interactivity**: Plain HTML forms that POST and redirect. htmx for the few places that need partial updates (inline edit, live filters).
- **Data**: Drizzle ORM over SQLite (`bun:sqlite`) for the tool's own tables. Product data is read from a read replica, and writes to the product go through the product's API.
- **Auth**: Google Workspace or GitHub OAuth with an allow-list of emails or a team; no passwords stored.
- **Hosting**: A small VPS or container behind the company VPN or an identity-aware proxy.

## 2. File Layout
- `src/index.ts`: The Hono app, middleware order (logger → auth → routes), and `export default { port, fetch }`.
- `src/auth.ts`: OAuth callback and the allow-list middleware, in one file.
- `src/pages/<screen>.tsx`: One file per screen: the GET handler renders, the POST handler validates, writes and redirects.
- `src/components/Layout.tsx`: The one page shell (nav, flash messages, CSS link).
- `src/db/schema.ts`, `src/db/client.ts`, `drizzle/`: Schema, connection and generated migrations.
- `src/jobs/<name>.ts`: Scheduled work, registered in `src/index.ts` with an in-process scheduler (e.g. `croner`) or exposed as a cron route the host calls.

## 3. Request Rules
- Validate every form with `@hono/zod-validator` (`zValidator('form', schema)`). On failure, re-render the same page with errors and the submitted values.
- Successful POSTs redirect (303) to a GET; never render a page from a POST.
- htmx endpoints return HTML fragments from the same components the full page uses, so markup is never duplicated.
- Escape by default: render user data through JSX, never by string concatenation.

## 4. Auth & Safety
- Every route except `/login` and the OAuth callback sits behind the allow-list middleware.
- Record who did what: an `audit_log` table written by the same transaction as the change.
- Destructive actions require a POST with a CSRF token (`hono/csrf`) and a confirmation step.

## 5. Coding Standards
- Strict TypeScript, zero `any`. Row types come from `typeof table.$inferSelect`.
- No React, no bundler, no client state. If a screen seems to need them, it is probably two screens.
- Jobs are plain async functions that can be run from a test or a one-off script.

## 6. Testing Conventions
- `bun test` with `app.request()` against an in-memory SQLite database: assert status codes, redirects and key text in the HTML.
- Test the allow-list explicitly: a non-listed email gets 403 on every route.
- Call job functions directly in tests; do not wait on the scheduler.

## 7. Git Workflow & PR Conventions
- Conventional Commits scoped to the screen or job: `feat(refunds): bulk approve screen`.
- A schema change ships with its Drizzle migration.
- Changes to the allow-list or auth are reviewed by a second person, even on a small team.
```

---

## CLAUDE.md
```markdown
# CLAUDE.md — Hono JSX Internal Tool Commands & Conventions

> Claude Code also reads `AGENTS.md` when no `CLAUDE.md` is present — keep this file for Claude-specific directives.

## Common Commands
- `bun run dev` - Start with watch mode (`bun --watch src/index.ts`)
- `bun test` - Run route and job tests
- `bunx drizzle-kit generate` / `bunx drizzle-kit migrate` - Create and apply migrations

## Code Style Guidelines
- New screen = one file in `src/pages/` with its GET and POST handlers.
- Forms and redirects first; reach for htmx only when a full reload hurts.
- Never write to the product database directly; call the product API.
```

---

## .cursor/rules/stack.mdc
```markdown
---
description: Hono JSX server-rendered internal tool on Bun
globs: ["src/**/*.ts", "src/**/*.tsx"]
alwaysApply: true
---

# Hono JSX Internal Tool

- Bun + Hono v4 with `hono/jsx`; server-rendered pages, no client build.
- Forms POST, validate with `zValidator('form', …)`, then 303 redirect; htmx only for partial updates.
- OAuth allow-list middleware on every route; CSRF on mutations; audit log for changes.
- Drizzle over SQLite for the tool's tables; product data read-only from a replica.
- Jobs are plain functions in `src/jobs/`, scheduled in the same process.
```

---

## Architecture Overview & Best Practices
## Architecture Overview

Guidelines for **internal tools** built as **server-rendered HTML** with **Hono JSX** on **Bun**: forms instead of fetch calls, **htmx** where a reload hurts, **Drizzle over SQLite** for the tool's own data, and scheduled jobs in the same process.

### Key Advantages

- **One file per screen**: the GET renders, the POST validates and redirects, so an agent can add a screen and a table in one change.
- **Nothing on the client**: no bundler, no state library, no API layer between the form and the database.
- **Safe by default**: an OAuth allow-list, CSRF on mutations and an audit log are part of the template, not an afterthought.