docs: expand repository and setup guides

This commit is contained in:
Yanislav Igonin 2026-07-15 18:02:57 +04:00
parent e28cc97465
commit e3026e99f4
2 changed files with 286 additions and 35 deletions

174
AGENTS.md
View File

@ -1,28 +1,166 @@
# Repository Guidelines # AGENTS.md
## Project Structure & Module Organization Guidance for coding agents working in this repository. Keep changes focused,
preserve existing behavior unless the task explicitly changes it, and verify
all claims with fresh commands.
`main.go` wires the Fiber application, middleware, routes, database startup, and template engine. Keep HTTP handlers in `controllers/`, persistence logic and data types in `repositories/`, database setup in `db/`, and environment parsing in `config/`. Gateway integration belongs in `gateway/`; shared helpers live in `utils/` and `files/`. Server-rendered HTML is organized under `templates/{pages,components,head}`, while browser assets live in `static/`. Add ordered PostgreSQL changes to `migrations/` using the existing `<number>-<description>.sql` pattern. Load-testing scripts belong in `tests/`. ## Project Overview
## Build, Test, and Development Commands micrach is a small, server-rendered, single-board imageboard. It uses Go,
Fiber v2, Fiber HTML templates, PostgreSQL through `pgx`, and filesystem-backed
image uploads. It intentionally uses little browser-side JavaScript.
- `cp .env.example .env` creates local configuration; adjust `POSTGRES_URL` before starting. The service supports thread creation, replies, JPEG/PNG attachments,
- `go run .` starts the service and applies migrations against the configured PostgreSQL database. thumbnails, CAPTCHA, rate limiting, pagination, bump limits, `sage`, thread
- `make dev` runs the app through `nodemon` for automatic restarts. archival, and optional external gateway registration.
- `go build .` produces the local `micrach` binary.
- `GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build .` matches the CI Linux build.
- `go test ./...` runs all Go tests.
- `go vet ./...` performs standard static checks.
- `sh tests/load.sh` runs the optional Vegeta load test; review its target URL first.
## Coding Style & Naming Conventions ## Repository Map
Use `gofmt` (tabs for Go indentation) and run `go fmt ./...` before submitting. Keep package names short and lowercase. Use `PascalCase` for exported identifiers, `camelCase` for unexported identifiers, and descriptive handler names such as `CreateThread`. Keep controllers thin: validation and HTTP concerns stay in handlers, while SQL and persistence behavior stay in repositories. Follow existing kebab-case names for CSS, templates, and migration descriptions. - `main.go`: application startup, middleware, static mounts, routes, and server.
- `controllers/`: Fiber handlers, request parsing, HTTP responses, and form flow.
- `repositories/`: SQL queries, persistence types, and template view data.
- `db/`: PostgreSQL pool initialization and startup migration runner.
- `config/`: environment parsing and defaults.
- `gateway/`: optional gateway registration and authenticated ping endpoint.
- `utils/`: post validation, upload directories, and image thumbnail handling.
- `files/`: shared filesystem read helpers.
- `build/`: production CSS cache-busting rewrite.
- `templates/{pages,components,head}`: server-rendered HTML.
- `static/`: checked-in CSS, icons, and error images.
- `uploads/`: generated runtime files; ignored by Git and never commit them.
- `migrations/`: ordered PostgreSQL changes named `<number>-<description>.sql`.
- `tests/`: optional Vegeta load test, not the unit-test suite.
## Testing Guidelines ## Runtime Flow and Routes
The repository currently has no unit tests or enforced coverage threshold. Add tests beside the code as `*_test.go`, using `TestXxx` and table-driven cases where practical. Avoid shared production databases; isolate repository tests with disposable test data or a dedicated database. Run `go test ./...` and `go vet ./...` for every change. Use Vegeta only for explicit performance work. Startup loads `.env`, initializes configuration and the DB pool, applies
missing migrations, optionally seeds data, performs production CSS rewriting,
creates `uploads/`, then starts Fiber.
## Commit & Pull Request Guidelines | Method | Path | Handler / purpose |
| --- | --- | --- |
| `GET` | `/` | Render paginated thread catalog. |
| `POST` | `/` | Validate and create a thread. |
| `GET` | `/:threadID` | Render one thread and its replies. |
| `POST` | `/:threadID` | Validate and add a reply. |
| `GET` | `/captcha/:captchaID` | Render CAPTCHA PNG. |
| `GET` | `/api/ping` | Gateway health endpoint; registered only when `GATEWAY_URL` is set. |
History mixes terse imperative subjects with `feat:` and `fix:` prefixes. Prefer focused Conventional Commit subjects, for example `fix: reject oversized uploads`. Keep each commit buildable. Pull requests should explain behavior changes, configuration or migration impact, and verification commands. Link relevant issues and include screenshots for template or CSS changes. Never commit `.env`, uploads, generated load-test artifacts, or credentials. Static content is served from `/static`; generated files are served from
`/uploads`. Thread and reply creation spans PostgreSQL plus filesystem writes,
so review both paths when changing upload behavior.
## Local Setup and Commands
Create a PostgreSQL database, then:
```sh
cp .env.example .env
# Edit POSTGRES_URL and normally set IS_DB_SEEDED=false.
go run .
```
Common checks:
```sh
go fmt ./...
go test ./...
go vet ./...
go build .
GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build .
```
`make dev` requires `nodemon`. `sh tests/load.sh` requires Vegeta and targets a
historical public URL by default; change the target to a controlled environment
before use. Do not run the load test as routine verification.
The module declares Go 1.15 and CI installs Go 1.17. Avoid language or standard
library features newer than Go 1.17 unless the task also upgrades the supported
Go version and CI configuration.
## Configuration and Generated State
- `.env` is local and must never be committed.
- `POSTGRES_URL` selects the database; startup applies migrations automatically.
- `IS_DB_SEEDED=true` adds sample data on every startup, not only once.
- `ENV=production` renames CSS files and rewrites templates in place at startup.
Do not use this mode in a development checkout unless that mutation is wanted.
- `GATEWAY_URL=""` disables gateway routes and registration.
- Uploads are limited to four JPEG/PNG files, 3 MiB each. Titles allow 100
runes; post text allows 1,000 runes.
- Runtime uploads, built binaries, `.env`, and load-test artifacts are ignored
and must remain untracked.
## Architecture and Coding Conventions
- Keep handlers thin: HTTP parsing/status/rendering in `controllers/`; SQL and
persistence behavior in `repositories/`.
- Keep DB startup and migration mechanics in `db/`, environment parsing in
`config/`, gateway behavior in `gateway/`, and reusable helpers in `utils/`
or `files/`.
- Follow existing package naming: short, lowercase names. Use `PascalCase` for
exported identifiers and `camelCase` for unexported identifiers.
- Format Go with `gofmt`/`go fmt`; do not hand-format with spaces.
- Follow existing kebab-case naming for templates, CSS, and migration
descriptions. Preserve current server-rendered approach and minimal-JS goal.
- Use parameterized SQL. Keep related DB operations transactional where the
existing workflow requires atomicity.
- Avoid unrelated refactors. If a task exposes adjacent problems, report them
separately unless they block the requested work.
## Change Guide
- Route or request behavior: update `main.go` and/or `controllers/`, then cover
status codes, redirects, validation errors, and template data.
- Persistence behavior: update `repositories/`; add a migration for schema
changes rather than editing an already-applied migration.
- Schema changes: add the next numeric file in `migrations/`. Keep filename
shape exactly `<number>-<description>.sql`; the runner parses it directly.
- Page or component changes: edit `templates/` and matching `static/styles/`.
Check catalog, thread, error, empty, and pagination states as relevant.
- Upload changes: inspect controller transaction flow, `utils/`, repository file
records, original/thumbnail paths, validation limits, and cleanup behavior.
- Config changes: update `config/config.go`, `.env.example`, README config table,
and deployment environment forwarding together.
- Deployment changes: note that `Dockerfile` expects a prebuilt Linux binary and
`docker-compose.yml` assumes Swarm, Traefik, an external network, and a
persistent host upload mount.
## Testing Expectations
There are currently no checked-in Go unit tests and no coverage threshold. Add
`*_test.go` files beside changed code, use `TestXxx`, and prefer table-driven
cases when practical. Repository tests must use disposable test data or a
dedicated database, never a shared production database.
Minimum verification for code changes:
1. Run `go fmt ./...` and review the resulting diff.
2. Run `go test ./...`.
3. Run `go vet ./...`.
4. Run `go build .` (or the Linux CI build for deployment-sensitive work).
5. For templates/CSS, start the app and manually inspect affected responsive
states; include screenshots in the PR.
For documentation-only changes, inspect the rendered Markdown, verify all local
links and commands against the repository, and review `git diff --check`.
## Git, Commits, and Pull Requests
- Inspect `git status` before editing. Preserve user changes and unrelated files.
- Never commit `.env`, credentials, uploads, binaries, or generated load-test
outputs.
- Prefer focused Conventional Commit subjects, such as
`fix: reject oversized uploads` or `docs: expand setup guide`.
- Keep each commit buildable. Do not rewrite history or discard local changes
unless explicitly requested.
- PRs should describe behavior, config/migration impact, verification commands,
linked issues, and screenshots for UI changes.
## Agent Completion Checklist
- Requested scope is fully addressed; unrelated behavior is untouched.
- New behavior has tests where practical.
- Documentation and `.env.example` match config/code changes.
- No secret, upload, binary, or generated artifact is included.
- Fresh verification commands pass, and final report names commands actually run.

147
README.md
View File

@ -1,27 +1,140 @@
# micrach # micrach
Go tryout. Single board imageboard.
UPD: stopped the service from the link above, too much shit posted from TOR, don't have time to moderate :( micrach is a small, server-rendered imageboard written in Go. It provides one
board where visitors can create threads, reply with text or images, bump or
`sage` threads, and browse the thread catalog without a client-side SPA.
## Motivation The project began as a Go learning project and as an experiment in building a
Tired of a fucking SPAs, so I decided to write this simple and lightweight imageboard (microboard, actually) with as less JS as possible. lightweight imageboard with very little JavaScript. The former public instance
Also, I wanted to learn Go, so I decided to write this in Go. is offline because it required more moderation than the maintainer could
provide; the source remains available for local use and development.
Maybe I'll add an api and create a SPA with the Next.js framework in the future, but right now I'm trying to make this as simple as possible. ## Features
## Prerequisites - Server-rendered HTML using Fiber templates
1. Go 1.13+. - Thread creation, replies, catalog pagination, bump limits, and `sage`
2. PostgreSQL. - JPEG and PNG uploads with generated thumbnails
3. Create `.env` file from `.env.example`, change env vars to your needs. - Optional CAPTCHA and request rate limiting
4. Create db with the name that is specified in `.env` file in `POSTGRES_URL` env var. - Automatic PostgreSQL migrations on startup
- Automatic archival when the active-thread limit is reached
- Optional registration with an external board gateway
## Stack
- Go (the module declares Go 1.15; CI builds with Go 1.17)
- [Fiber v2](https://github.com/gofiber/fiber)
- PostgreSQL via `pgx`
- Plain HTML templates and CSS
## Run locally
### Prerequisites
- Go 1.17 or newer
- PostgreSQL
- A PostgreSQL database that the configured user can create tables in
### Setup
1. Create the database. With standard local PostgreSQL tooling:
## Run
Just run:
```sh ```sh
go run main.go createdb micrach
``` ```
**In development** I prefer to run it with [nodemon](https://github.com/remy/nodemon) for live reload. 2. Copy the example configuration:
## How it looks ```sh
![SCR-20230509-jreo](https://user-images.githubusercontent.com/15846431/237027105-481f2d55-541b-4c3b-8dd0-db464c25102f.jpeg) cp .env.example .env
```
3. Edit `.env`. At minimum, make `POSTGRES_URL` match your local database.
For normal development, set `IS_DB_SEEDED=false`; when true, sample rows are
inserted every time the application starts.
4. Start the application from the repository root:
```sh
go run .
```
5. Open [http://localhost:3000](http://localhost:3000), or the port configured
by `PORT`.
Startup connects to PostgreSQL, applies missing files from `migrations/`, and
creates the ignored local `uploads/` directory. Uploaded originals and
thumbnails are stored on disk, so keep that directory persistent when running
the service in a container.
## Configuration
`.env` is loaded automatically and is ignored by Git.
| Variable | Default in code | Purpose |
| --- | --- | --- |
| `ENV` | `release` | Runtime mode. `production` enables CSS filename rewriting at startup. |
| `PORT` | `3000` | HTTP listen port. |
| `POSTGRES_URL` | `postgresql://localhost/micrach` | PostgreSQL connection URL. |
| `IS_DB_SEEDED` | `false` | Insert sample posts at startup. Avoid enabling repeatedly. |
| `IS_RATE_LIMITER_ENABLED` | `true` | Enable Fiber request limiting. |
| `THREADS_MAX_COUNT` | `50` | Maximum active threads before old threads are archived. |
| `THREAD_BUMP_LIMIT` | `500` | Reply count after which a thread no longer bumps. |
| `IS_CAPTCHA_ACTIVE` | `true` | Require CAPTCHA for new threads and replies. |
| `GATEWAY_URL` | empty | External gateway base URL. Empty disables gateway integration. |
| `GATEWAY_API_KEY` | empty | Shared key used for gateway registration and `/api/ping`. |
| `GATEWAY_BOARD_ID` | empty | Board identifier sent to the gateway. |
| `GATEWAY_BOARD_URL` | empty | Parsed from the environment but not currently used by the gateway client. |
| `GATEWAY_BOARD_DESCRIPTION` | empty | Board description sent to the gateway. |
See [.env.example](.env.example) for a complete example.
## Development commands
```sh
# Run with automatic restart; requires nodemon.
make dev
# Format, test, vet, and build.
go fmt ./...
go test ./...
go vet ./...
go build .
# Reproduce the Linux CI build.
GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build .
```
`tests/load.sh` is an optional Vegeta load test. Its checked-in target is a
historical public URL, so change it to an environment you own before running
the script. Generated load-test files are ignored by Git.
## Containers and deployment
The `Dockerfile` packages a prebuilt `micrach` binary together with templates,
static assets, and migrations. Build the Linux binary before building the
image. The checked-in `docker-compose.yml` is production-oriented: it expects
Docker Swarm, an existing `web` overlay network, Traefik, a published image,
and host-mounted upload storage. It is not a standalone local PostgreSQL setup.
## Project layout
```text
controllers/ HTTP handlers and request validation flow
repositories/ PostgreSQL queries and view data types
db/ connection pool and migration runner
config/ environment parsing
gateway/ optional external gateway integration
templates/ server-rendered pages, components, and head fragments
static/ CSS, icons, and error images
uploads/ runtime uploads (created locally, ignored by Git)
migrations/ ordered PostgreSQL schema changes
tests/ optional load-test scripts
```
## Screenshot
![micrach catalog](https://user-images.githubusercontent.com/15846431/237027105-481f2d55-541b-4c3b-8dd0-db464c25102f.jpeg)
## License
[MIT](LICENSE)