Initial commit: PRD, build tooling, and design mockups
Foodster is a self-hosted dinner log and meal suggester for one household. Stage 1 (eating history) is in development; stage 2 (the suggester) follows once there is enough history to weight against. Replace the PRD's original stack (Nuxt, Postgres, Drizzle, Pico CSS) with Go 1.27, net/http, templ, Datastar and SQLite — one static binary, no Node.js in the build. Sections 3, 4, 5, 9, 10 and 11 are rewritten to match. Record the decisions made while reviewing mockups: - the UI is written in Finnish; PRD, code and comments stay English - access is one shared password over HTTP Basic rather than open on the LAN - images are CalVer vYYYYMMDD-N, built with Podman, run under Docker Compose - registry coordinates live in .env, so no infrastructure detail is committed and the MIT publication option stays open mockups/ holds standalone HTML design studies. log-fi.html is the current one; the others are superseded exploration kept for reference.
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
# Foodster
|
||||
|
||||
A self-hosted dinner log and meal suggester for a single household. Record
|
||||
what the family actually ate, and — later — let the app propose seven dinners
|
||||
drawn from that history.
|
||||
|
||||
The interface is in Finnish. The code, comments and documentation are in
|
||||
English.
|
||||
|
||||
See [PRD.md](PRD.md) for the full specification.
|
||||
|
||||
## Status
|
||||
|
||||
**Stage 1 — eating history: in development.** The meal catalog and the daily
|
||||
log come first, because the suggester is worthless until there are a few
|
||||
weeks of real history to weight against.
|
||||
|
||||
Stage 2 — the seven-meal suggester — starts once that history exists.
|
||||
|
||||
## Stack
|
||||
|
||||
One static Go binary. No Node.js, no bundler, no separate database server.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Language | Go 1.27 |
|
||||
| HTTP | stdlib `net/http` + `http.ServeMux` |
|
||||
| Views | [templ](https://templ.guide), server-rendered |
|
||||
| Interactivity | [Datastar](https://data-star.dev) — signals and DOM patching in one ~11 kB script |
|
||||
| Styling | hand-written CSS, `light-dark()` for themes |
|
||||
| Database | SQLite via `modernc.org/sqlite` (pure Go) |
|
||||
| Auth | HTTP Basic, one shared household password |
|
||||
| Runtime image | `FROM scratch` |
|
||||
|
||||
## Quick start
|
||||
|
||||
```sh
|
||||
cp .env.example .env # then edit it
|
||||
make run # http://localhost:8080
|
||||
```
|
||||
|
||||
`make` on its own lists every target:
|
||||
|
||||
```
|
||||
make fix gofmt, templ fmt, go mod tidy
|
||||
make lint go vet, gofmt check, golangci-lint when installed
|
||||
make test go test ./...
|
||||
make build ./foodster
|
||||
make image build and tag vYYYYMMDD-N (creates a git tag)
|
||||
make push push the newest tag and :latest
|
||||
make release image + push
|
||||
make up/down/logs compose
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Everything is environment variables. `.env` is gitignored; start from
|
||||
`.env.example`.
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
|---|---|---|
|
||||
| `FOODSTER_PASSWORD` | *required* | Shared password. The app will not start without it. |
|
||||
| `FOODSTER_DB` | `/data/foodster.db` | SQLite file path. |
|
||||
| `TZ` | `Europe/Helsinki` | Used for every calendar-day calculation. |
|
||||
| `FOODSTER_REPO` | *required to build* | Image repository, no tag. |
|
||||
| `FOODSTER_TAG` | `latest` | Tag to run under compose. |
|
||||
| `FOODSTER_PORT` | `8080` | Host port to publish. |
|
||||
|
||||
Set `TZ` in development too. Under UTC the date rolls over three hours late,
|
||||
which is exactly when dinner gets logged.
|
||||
|
||||
## Deployment
|
||||
|
||||
Images are built with Podman and run under Docker Compose on a LAN server.
|
||||
They are OCI images, so either engine works.
|
||||
|
||||
```sh
|
||||
make release # build, tag, push
|
||||
# on the server:
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
Versions are CalVer — `vYYYYMMDD-N`, where `N` is the Nth build that day. The
|
||||
running version is served at `GET /healthz`, which is the one route outside
|
||||
authentication.
|
||||
|
||||
There is no database container. SQLite lives on a named volume, so a backup
|
||||
is a file copy.
|
||||
|
||||
## Security
|
||||
|
||||
Access is a single shared password over HTTP Basic — no accounts, no
|
||||
sessions. Credentials are compared in constant time, but Basic auth sends
|
||||
them in cleartext, so this belongs on a private LAN. Put TLS in front of it
|
||||
before exposing it anywhere else.
|
||||
|
||||
## Mockups
|
||||
|
||||
`mockups/` holds standalone HTML design studies. Open them directly in a
|
||||
browser; they are references, not part of the build.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE).
|
||||
Reference in New Issue
Block a user