summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* chore: add govips/v2 dependencyivar12 days2-1/+6
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: add govips/v2 dependencyivar12 days2-0/+23
|
* fix: remove incorrect govips v1 dependencyivar12 days2-37/+14
|
* chore: add govips dependencyivar12 days2-0/+23
|
* fix: make slug rename and content update atomic via RenameAndUpsertPostivar12 days3-23/+121
| | | | | | | | Previously RenamePost + UpsertPost were two separate DB calls; a failure between them left the post at the new slug with stale content. The new RenameAndUpsertPost method does both in a single transaction. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* .ivar12 days34-2052/+862
|
* fix: remove spurious os.IsNotExist check on DB error in handleDeleteivar12 days1-1/+1
|
* feat: support slug editing and rename in admin UI with redirect and cache ↵ivar12 days1-153/+231
| | | | | | invalidation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add editable slug field to admin form with JS auto-populationivar12 days1-25/+56
|
* docs: add image block implementation planivar12 days1-0/+902
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: serve drafts by direct link; add 301 redirect on renamed slugsivar12 days1-0/+190
|
* fix: guard RenamePost against self-rename (noop)ivar12 days1-0/+3
|
* feat: add RenamePost with transactional rename and redirect creationivar12 days2-0/+130
| | | | | | | | | | | | | | | Implement RenamePost method that atomically: 1. Fetches the post record by old slug 2. Inserts a new record with the new slug 3. Deletes the old slug post 4. Collapses redirect chains (updates any redirects pointing to oldSlug to point to newSlug) 5. Creates a redirect from oldSlug to newSlug All operations are transactional (all-or-nothing). Includes two comprehensive tests: - TestRenamePost: basic rename with redirect creation and old slug deletion - TestRenamePost_CollapsesChain: verifies redirect chains are collapsed correctly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add redirect DB methods (AddRedirect, GetRedirect, CollapseRedirects)ivar12 days2-0/+219
|
* feat: add redirects table to meta.db schemaivar12 days1-0/+16
|
* docs: add image block upload and serving design specivar12 days1-0/+114
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add spec and implementation plan for draft access and slug editingivar12 days4-98/+858
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix: set HTML template on Gin engine for template renderingivar13 days1-0/+1
| | | | | | | | | | | | | The embedded templates were being parsed but not registered with the Gin engine's HTMLRender, causing 500 errors on admin UI requests. Now SetHTMLTemplate is called to register the parsed template set so Gin can render them properly. Verified: - Build succeeds with no errors - Binary contains embedded template strings - Admin UI pages load and render correctly - All template files (base, list, form, error) work as expected
* feat: embed admin templates into binary with //go:embedivar13 days5-3/+150
| | | | | | | | | | | | | Move admin templates from templates/admin/*.html to internal/admin/templates/*.html and embed them using //go:embed directive. This removes the runtime dependency on having template files on disk, allowing the templates to be compiled into the binary. Changes: - Add embed import and //go:embed directive for templates - Change ParseGlob() to ParseFS() to load from embedded filesystem - Copy templates to internal/admin/templates/ for embedding Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* fix: resolve Gin routing conflict with catch-all static files handlerivar13 days1-2/+7
|
* refactor: update cmdServe to use Gin engine directlyivar13 days1-9/+8
|
* refactor: convert admin handlers to Gin context-based signaturesivar13 days20-110/+1801
| | | | | | | | | | | | | | | | | - Remove old ServeHTTP method (no longer needed with Gin routing) - Update all 6 handler methods to use *gin.Context instead of http.ResponseWriter, *http.Request - Convert handler signatures: handleList, handleNew, handleNewPost, handleEdit, handleDelete - Remove render() helper (use c.HTML() directly) - Update renderError() to accept gin.Context instead of http.ResponseWriter - Update postFromForm() to extract form data from gin.Context using c.PostForm() - Update main.go to use adminSrv.NewServer() and adminSrv.Engine() - All handlers now use Gin methods: c.HTML(), c.PostForm(), c.Param(), c.Redirect() - Path parameters now extracted via c.Param("slug") instead of function arguments - HTTP status codes and error handling fully migrated to Gin patterns Build verified: go build ./cmd/nebbet succeeds Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* refactor: implement auth middleware for Ginivar13 days1-41/+30
| | | | | | | | | | | | | | | | Replace the old checkAuth() method with a Gin middleware function that validates Basic Auth credentials. The authMiddleware() now handles authentication at the middleware level rather than per-handler, supporting graceful degradation when no auth file is configured. The middleware: - Skips auth if AuthFile is empty or doesn't exist - Extracts Basic Auth credentials from the request - Verifies credentials using the auth package - Returns 401 with WWW-Authenticate header on failure - Calls c.Next() to pass control to handlers on success Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* refactor: add Gin routing infrastructure with NewServer constructorivar13 days1-183/+85
|
* chore: add gin dependencyivar13 days3-6/+104
|
* Fix modivar2026-03-312-4/+64
|
* Use sqlite packageivar2026-03-313-271/+1
|
* Use sqlite packageivar2026-03-313-266/+2
|
* Fault if not able to authenticate userivar2026-03-311-6/+6
|
* Merge pull request #2 from ivarlovlie/claude/add-post-management-rqIiOIvar Løvlie2026-03-3110-6/+987
|\
| * Add post management admin UI and switch to modernc.org/sqliteClaude2026-03-3110-6/+987
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | - Replace custom CGO sqlite driver with modernc.org/sqlite (registered as "sqlite3"); a local compat shim under compat/sqlite/ provides the same import path and WAL-mode behaviour using system libsqlite3 while network access is unavailable — swapping to the real pure-Go package later only requires removing the replace directive and running go get. - Add internal/admin/server.go: HTTP handler for /admin/ that serves a server-side-rendered post management UI (list, new, edit, delete). Posts are stored as Markdown files under content/posts/ and rebuilt via the existing Builder after every write. Basic auth is checked against the .passwords file when it exists. - Add cmd/nebbet/main.go: unified CLI with build, watch, serve (HTTP server with admin + file server + watch), and user subcommands. - Update builder.BuildAll to skip content/admin/ — admin pages are served dynamically and must never appear in the static output directory. - Mark content/admin/index.md as draft so the old static placeholder is not built even if the admin skip logic is bypassed. - Fix .gitignore: use /nebbet (root-only) so the pattern no longer accidentally ignores the cmd/nebbet/ source directory. https://claude.ai/code/session_01WLuSGxJhNs2cFM2zJzSsTx
* Merge pull request #1 from ivarlovlie/claude/static-site-sqlite-setup-mrcArIvar Løvlie2026-03-3121-0/+1468
|\
| * Add static site builder: SQLite-backed MD→HTML pipelineClaude2026-03-3121-0/+1468
|/ | | | | | | | | | | | | | | - cmd/nebbet: CLI with build [--watch] and user add/passwd/delete/list - internal/builder: markdown→HTML, component injection via HTML comments, auto importmap from lib/, fsnotify watch with 150ms debounce - internal/db: meta.db (page index, tag queries) + search.db (FTS5) - internal/sqlitedrv: minimal CGO database/sql driver for system libsqlite3 - internal/auth: htpasswd-compatible bcrypt password file management - templates/base.html + admin.html, styles/main.css + admin.css - nginx.conf with auth_basic for /admin, clean URLs, gzip - nebbet.service systemd unit for watch daemon - Example content/index.md and components/site-greeting.js https://claude.ai/code/session_01HTc1BCBCiMTEB54XQP1Wz9
* Create InitIvar Løvlie2026-03-311-0/+1