libretechandClaude Opus 4.7 f9c941f723 Add tenant-scoped notes REST API
internal/httpapi/notes.go exposes:
- GET    /api/notes            list summaries {id, title, updated_at}
- GET    /api/notes/{id}       full {id, title, content, updated_at}
- PUT    /api/notes/{id}       create/update; ?base=<unix> for
                                optimistic-locking conflict detection
- DELETE /api/notes/{id}       remove; ?base=<unix> guards against
                                deleting a row modified after the
                                client last saw it

Backed by tenant.FS so all reads/writes go through the per-user
sandbox — path traversal is rejected at parse time (regex slug)
and again by os.Root inside the FS layer.

On-disk format is plain Markdown: first line `# Title`, rest is
content. grep / cat / vim still produce a usable view of raw
files. Title round-trips through composeNote/splitTitle.

Conflict semantics: when the client supplies ?base=<unix>, the
server compares against the file's mtime. If the file is newer,
respond 409 with the current note body so the client can present
a merge UI. Same logic on DELETE returns 409 alone.

cmd/librenotes/serve.go grows a tenantPool that memoises FS
handles per user id; defer-closes them on shutdown.

Tests cover: full CRUD round-trip, cross-tenant isolation,
unauthenticated 401s, invalid IDs (regex rejection), and the
conflict path with a real mtime advance.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 22:42:43 +02:00
2026-04-28 22:42:43 +02:00
2026-04-28 21:58:59 +02:00
2026-04-28 21:58:59 +02:00
2026-04-28 21:58:59 +02:00

librenotes

CI

Cloud-native, multi-tenant notes application. A fork of Notesium extended with authentication, per-user data isolation, sync, and PWA support so it can run as a hosted service at librenot.es.

Features

  • Markdown notes with bi-directional links (Zettelkasten / evergreen notes)
  • Embedded web app — no Electron, no Node runtime, single static binary
  • Multi-tenant backend with magic-link authentication (in development)
  • Offline-capable PWA with background sync (planned, Phase 4)

Build

Requires Go 1.20 or later.

go build ./cmd/librenotes

This produces a librenotes binary in the current directory. The web frontend and shell completion are embedded into the binary at compile time, so no extra files are needed at runtime.

A Makefile with build, test, run, and clean targets is provided for convenience:

make build
make test

Run

./librenotes web --notes-dir ~/notes

See ./librenotes help for the full command list.

Development setup

A Nix flake provides a reproducible development environment with Go, build tools, and the project CLIs. Use the plain dev shell for a non-sandboxed Go toolchain:

nix develop .#dev

Alternatively, build a Docker-based dev environment:

docker build -f Dockerfile.dev -t librenotes-dev .
docker run --rm -it -v "$PWD:/workspace" librenotes-dev

The repository layout follows the standard Go project structure:

cmd/librenotes/      Binary entry point
internal/notesium/   Core notes package (forked from Notesium)
internal/notesium/web/   Embedded frontend assets

The Go module path is git.librete.ch/public/librenotes.

Fork attribution

librenotes is a fork of Notesium by Alon Swartz, used and redistributed under the MIT License. See NOTICE for the upstream commit hash at fork time and instructions for tracking upstream changes.

License

MIT — see LICENSE. Copyright is shared between the original Notesium author and the librenotes contributors.

S
Description
No description provided
Readme MIT
987 KiB
2026-04-29 01:30:06 +02:00
Languages
JavaScript 51.3%
Go 33.8%
HTML 8%
Shell 2.9%
CSS 2.4%
Other 1.6%