# WarpBox Development Rules

This guide exists for contributors and LLM agents doing behavior-preserving
cleanup. It complements [docs/tech.md](docs/tech.md), which maps the current
implementation.

## Cleanup Principles

- Keep systems boring and obvious.
- Prefer short files grouped by one clear responsibility.
- Prefer narrow helpers over clever abstraction.
- Keep related functions physically close.
- Split files when one file mixes multiple domains.
- Avoid huge utility drawers where unrelated helpers gather.
- Do behavior-preserving cleanup before feature work.
- Use tests before and after each cleanup slice.

Cleanup is not feature work. Do not change runtime behavior unless the task
explicitly says to fix behavior.

## File Responsibility Goals

Files should not mix:

- UI and state.
- Transport and rendering.
- Validation and routing.
- Filesystem operations and business rules.
- Admin workflows and public box workflows.

When a file is large and contains multiple concerns, prefer splitting by
responsibility. Use comment regions only when a file is cohesive and splitting
would make it harder to follow.

Previously split cleanup targets:

- `static/js/app.js` now bootstraps `static/js/upload/`.
- `static/css/upload.css` now lives under `static/css/upload/` and `static/css/components/`.
- `lib/server/handlers.go` is split by handler responsibility.
- `lib/boxstore/store.go` is split by storage responsibility.
- `lib/server/admin.go` is split by admin responsibility.
- `lib/config/config.go` is split by config responsibility.

Do not refactor multiple systems in one cleanup slice.

## Comment and JSDoc Guidance

Add comments for:

- Behavior rules that are easy to break.
- Edge cases.
- Concurrency or background worker behavior.
- Security-sensitive choices.
- Non-obvious product decisions.

Avoid comments that restate code. Prefer clear names and small functions first.
Use JSDoc only when it clarifies non-obvious inputs, outputs, or side effects.

## Go Rules

- Keep public routes stable.
- Keep environment variable names stable.
- Keep API response shapes stable.
- Keep manifest JSON field names stable.
- Keep storage directory layout stable.
- Keep handler files focused on one handler category.
- Keep route registration separate from validation and business logic.
- Return clear wrapped errors when context helps debugging.
- Avoid package moves unless the cleanup slice is specifically about package
  ownership.
- Run `gofmt`, `go vet`, and `go test` through `./check.sh`.

Server handler files:

- `pages.go`
- `downloads.go`
- `uploads.go`
- `box_auth.go`
- `validation.go`
- `retention.go`

Keep `lib/server/handlers.go` absent unless there is a deliberate reason to
reintroduce a cohesive handler file.

## JavaScript Rules

- Use vanilla JavaScript only.
- Do not add a build step.
- Keep browser scripts loaded directly by templates.
- Avoid new globals; centralize mutable upload state when splitting.
- Keep DOM queries/rendering separate from API calls and upload orchestration.
- Prefer an action map over long action `if` chains when cleaning event code.
- Share generic UI helpers through `static/js/warpbox-ui.js`.
- Preserve existing data attributes and template contracts unless explicitly
  changing behavior.

Target upload split when that cleanup slice is chosen:

- `static/js/upload/state.js`
- `static/js/upload/dom.js`
- `static/js/upload/files.js`
- `static/js/upload/api.js`
- `static/js/upload/upload-flow.js`
- `static/js/upload/options.js`
- `static/js/upload/popups.js`
- `static/js/upload/terminal.js`
- `static/js/upload/events.js`
- `static/js/app.js` as bootstrap only

## CSS Rules

- Keep shared styles in shared files.
- Keep page-specific styles page-scoped.
- Avoid duplicated popup, toast, button, and window rules.
- Use page prefixes for page styles:
  - `upload-`
  - `box-`
  - `admin-`
- Keep visual changes out of behavior-preserving cleanup unless the cleanup
  slice is CSS-only.
- Preserve template class names unless the same slice updates every use.

Target CSS split when that cleanup slice is chosen:

- `base.css`
- `window.css`
- `components/buttons.css`
- `components/popups.css`
- `components/toast.css`
- `upload/layout.css`
- `upload/queue.css`
- `upload/options.css`
- `upload/dialogs.css`
- `upload/responsive.css`
- `box.css`
- `admin.css`

## Template Rules

- Keep server-rendered HTML simple.
- Do not rename public routes during cleanup.
- Do not change form field names or data attributes unless the matching Go and
  JavaScript code changes in the same slice.
- Keep static CSS and JS loading explicit.
- Avoid hidden behavior changes through template conditionals.

Current loading model:

- Go loads templates from `templates/*.html`.
- Gin serves `/static` from `./static` with gzip middleware.
- Templates link CSS directly from `/static/css/...`.
- Templates load browser JavaScript directly from `/static/js/...`.
- There is no JavaScript or CSS build step.

## Safety Rules

- Inspect repository structure before editing.
- Identify relevant files for the current cleanup slice.
- Identify how JavaScript and CSS are loaded before frontend cleanup.
- Identify available test/check commands before editing.
- Summarize the intended change before editing.
- Make the smallest useful change.
- Do not rename public routes.
- Do not rename environment variables.
- Do not change API response shapes.
- Do not change manifest JSON field names.
- Do not change storage directory layout.
- Do not add frontend tooling during cleanup.
- Do not rewrite working code just to make it look different.
- Do not mix unrelated cleanup areas in one change.
- Do not claim tests passed unless they actually ran.

## Definition of Done

For each cleanup slice:

- Change scope matches one cleanup area.
- Behavior is unchanged unless the slice is explicitly a fix.
- Files have clearer responsibility than before.
- Comments explain only non-obvious rules or risks.
- Tests or checks were run and recorded.
- Any failed command is recorded with the exact reason.
- Next cleanup slice is clear.
