Any artifact can now be made publicly viewable via a share link, no login required - opt-in per artifact, toggled from the feed UI next to Keep. - Artifact.share_token: nullable, unique, high-entropy (secrets.token_urlsafe(32)). NULL = not shared; SQL treats each NULL as distinct so uniqueness still holds for the many not-shared rows. - New public route GET /s/<token> (shared_artifact_view), completely unauthenticated, serving the same rendered/raw content as the owner route via a shared serve_artifact_file() helper. - toggle_artifact_share: generates/clears the token: mirrors toggle_artifact_keep's pattern. - Fixed a real gap this surfaced: embedded images in a shared artifact's content would otherwise break for an anonymous visitor, since asset_view was owner-only. It now also allows access when the asset's parent artifact is currently shared - unattached (orphaned) assets stay private regardless. - serialize_artifact now reports is_shared/share_url so the API reflects sharing status (read-only for now; toggling stays UI-only). - Feed UI: Share button (mirrors Keep's toggle interaction), a copyable share-link box that appears when shared, and a "shared" badge on the artifact row - distinct blue accent from Keep's green so both can be visible on the same row without confusion. Verified live end-to-end (toggle on/off, public access, fake-token 404, old-link-dies-on-unshare, embedded-asset access before/after sharing) before writing the 12 automated tests in tests/views/test_sharing.py. Also fixed two unrelated stale spots noticed in docs/api.md while adding the Sharing section: the example response was missing is_kept/size_bytes, and the raw-content table didn't list json/csv (added earlier this session but never documented there). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
6 KiB
CLAUDE.md
Project
Daybook is a self-hosted, multi-user Django + Django REST Framework web app where AI agents, scripts, or people publish artifacts and each logged-in user browses their own time-ordered, label-filterable feed.
The core product principle is: agents publish content, not files. The server owns IDs, styling, storage layout, dates, and normalization into browser-native HTML, image, or PDF outputs.
Current MVP Decisions
- Each user has a personal ingest API token (DRF
Tokenmodel), viewable/regenerable from Settings → Account. - Require
sourcein every artifact payload — a free-text label identifying what posted it (agent-profile, script, or person name). Ownership of the resulting artifact comes from whichever user's token authenticated the POST, not from thesourcevalue itself. sourceandtagstogether form one unified label system: every artifact shows all its labels next to the title, and a singlelabelfilter/query param matches against either.- Require login (Django session auth) for the whole app, including the feed and API reads. Ingest (POST/PATCH) stays per-user bearer-token authenticated, since agents don't have browser sessions.
- Exception to the above: an artifact can be explicitly opted into public sharing (per-artifact, owner-toggled from the feed UI) via a high-entropy
share_token, served unauthenticated atGET /s/{share_token}. Not exposed via the ingest API yet — UI-only. Turning sharing off immediately invalidates the old link. Images embedded in a shared artifact are also served unauthenticated while it's shared, so inline content doesn't break for a link recipient. - User accounts can be created from Settings → Users (superuser-only in-app page) or via Django admin. Regular users are not staff and cannot access
/admin/. Creating a user via Settings → Users also issues their API token immediately, shown once. TagColor(label color overrides) stays global/shared across all users.- Use random 8-character artifact IDs.
- Start as a plain Django project; add Docker after core ingest and viewer work.
- Preserve original markdown as
.mdalongside rendered.html.
Architecture Notes
- Planning source:
planning/daybook_planning.md. - Django project:
daybook_project/. - Main app:
artifacts/. - Theme CSS:
static/themes/. - Feed template:
templates/artifacts/feed.html. - Settings templates:
templates/artifacts/settings_*.html. - Stored artifact files live under
artifacts_store/{source}/{YYYY-MM-DD}/.
Implementation Guidelines
- Prefer small, direct changes over broad abstractions.
- Keep ingest normalization server-side.
- The viewer should only need to render HTML, image, or PDF.
- Do not make agents responsible for styling, filenames, or storage paths.
- Preserve existing planning decisions unless the user explicitly changes them.
- Avoid adding backwards-compatibility code before anything has shipped.
Development And Deployment Workflow
- Develop and test locally in this workspace by default.
- Use the local Django commands for normal iteration:
python manage.py check,python manage.py migrate, andpython manage.py runserver. - Run the local development server on
127.0.0.1:8001. Port8000may be reserved or blocked on this workstation. - Always use this same fixed port for the dev server. Never start a second instance on a different port; if
8001is already serving, reuse it rather than starting another. - All artifact-posting tools (
skills/daybook-posting/scripts/daybook_post.py,scripts/seed_demo_artifacts.py, and any future posting skill) must defaultDAYBOOK_URLtohttp://127.0.0.1:8001to match. - A regular (non-superuser) user
test/ passwordtestpwdmust always exist in the local dev database — it's the permanent account a sibling project (AGENT_DAYBOOK__LLM_TEST) uses for API testing. If the localdb.sqlite3is ever reset, recreate this exact user (e.g. via Settings → Users) before assuming that project is broken. - Do not deploy to the Proxmox NUC during routine code iteration.
- Treat the NUC container as the local live/staging target. Deploy there only at explicit stable checkpoints, such as an end-of-day build.
- Before any NUC deployment, preserve
/opt/daybook/deploy/.envand/opt/daybook/deploy/data. - After any NUC deployment or configuration change, run the documented health checks and update the NUC ops knowledge base plus
planning/daybook-container-handoff.mdif takeover facts changed.
Repository Notes
_archive_/exists for retired or moved project docs and experiments that should not drive current implementation decisions.- Current deployment/takeover details live in
planning/daybook-container-handoff.md; canonical NUC infrastructure details live in the NUC ops repo.
Commands
- Install dependencies:
pip install -r requirements.txt - Run migrations:
python manage.py migrate - Start dev server:
python manage.py runserver 127.0.0.1:8001 - Local app URL:
http://127.0.0.1:8001/ - Local API health check:
http://127.0.0.1:8001/api/capabilities - Django checks:
python manage.py check
API Defaults
- MVP ingest endpoint:
POST /api/artifacts - MVP list endpoint:
GET /api/artifacts?label=&day=&kind=&q= - Artifact view:
GET /a/{id} - Auth: personal per-user token from Settings → Account,
Authorization: Bearer <token>. Get one by creating a superuser (python manage.py createsuperuser), logging in, and visiting Settings → Account.
Claude Code / OpenCode
This project uses CLAUDE.md for project instructions, compatible with both Claude Code and OpenCode. OpenCode is configured to load this file via a local, untracked opencode.json (it contains machine-specific MCP config, so it is not committed — recreate it locally with {"$schema": "https://opencode.ai/config.json", "instructions": ["CLAUDE.md"], "permission": "allow"} plus whatever MCP servers you want). After changing opencode.json, .opencode/, or this file, restart your AI coding assistant so the updated instructions are loaded.