feat: private notes frontend (Quick-Jot toggle + lock icon + API key) #29
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-docs-app!29
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "26-feat-private-notes-frontend-quick-jot-to"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds private note support across the pal-e-app frontend: API key authentication for server-side requests, a private/public toggle in Quick-Jot, and lock icons on private notes in list and search views.
Changes
src/lib/api.ts: PassX-PaleDocs-TokenAPI key header inapiFetch()for authenticated server-side requests; addis_publicfield toNote,SearchResult, andCreateNotePayloadinterfaces; addUpdateNotePayloadinterface andupdateNote()functionsrc/lib/components/QuickJot.svelte: Add private note checkbox toggle with lock icon SVG; wireis_public: falseinto create payload when checked; reset toggle on form clearsrc/routes/notes/+page.svelte: Show subtle gray lock icon next to title for notes whereis_public === falsein both search-filtered and grouped-by-type viewssrc/routes/search/+page.svelte: Show lock icon on private notes in search resultsTest Plan
npm run buildpasses with zero errorsnpm run checkpasses with zero errors (only pre-existing autofocus warning)is_public: falseis sent in POST payloadis_public === falsePAL_E_DOCS_API_KEYenv var is setReview Checklist
Related
plan-pal-e-docs-- Phase F6 private notes frontend supportReview: APPROVED
Reviewed the diff (4 files, +72/-4 lines). No issues found.
Verified:
apiFetch()correctly builds headers object and conditionally addsX-PaleDocs-Tokenfromenv.PAL_E_DOCS_API_KEY(already imported at line 1) -- no secrets hardcodedis_public?: booleanis correctly optional onNote,SearchResult,CreateNotePayloadinterfacesUpdateNotePayload+updateNote()added cleanly (bonus from linter, consistent with existing patterns)isPrivatestate initialized tofalse, reset inresetForm(), correctly setspayload.is_public = falseonly when checked=== falsecheck across all 3 locations, correctly ignoringundefined(public notes that omit the field)npm run build-- zero errorsnpm run check-- zero errors (1 pre-existing autofocus warning)PR #29 Review
BLOCKERS
1.
/api/notes/+server.tsproxy does not forwardis_public-- private toggle is silently brokenThe QuickJot modal correctly sends
is_public: falsein its POST payload to/api/notes. However, the server-side proxy atsrc/routes/api/notes/+server.ts(lines 26-45) explicitly whitelists only these fields:title,slug,html_content,project_slug,note_type,status,tags. It never extracts or forwardsis_publicfrom the request body.This means the private toggle checkbox will appear to work in the UI, but every note created will be public regardless. The
is_publicfield is silently dropped at the proxy layer.Fix: Add
is_publicforwarding in+server.ts:2.
PAL_E_DOCS_API_KEYnot provisioned in deployment -- API key header will never be sentThe diff adds
env.PAL_E_DOCS_API_KEYtoapiFetch(), but:k8s/deployment.yamldoes not define this env vark8s/pal-e-auth-secrets.enc.yamldoes not contain itpal-e-deploymentsoverlays do not contain it.env.exampledoes not document itThe
if (apiKey)guard means this fails silently (no crash), but the entire API key feature is inert until the secret is provisioned. If the pal-e-docs API actually requires this header for private note operations, creating private notes will fail with a 401/403 from the upstream API.This needs either:
(a) The API key added to the SOPS secret and deployment, or
(b) An explicit note in the PR/test plan that API key provisioning is a separate follow-up issue, with a reference to that issue.
NITS
1. Lock icon SVG duplicated 4 times
The same lock SVG path (
M12 2C9.24 2 7 4.24 7 7v3H6...) is copy-pasted in:QuickJot.svelte(1x)notes/+page.svelte(2x -- search results + grouped view)search/+page.svelte(1x)Consider extracting a
<LockIcon />component (e.g.,src/lib/components/LockIcon.svelte) to avoid drift if the icon styling changes later.2.
apiFetchheader spread order could lose API keyIn
apiFetch, the pattern{ headers, ...init }means if any caller ever passesinit.headers, it will overwrite the entire headers object, silently dropping the API key and Content-Type. Currently no callers do this, so it is not an active bug. But a safer pattern would be to merge headers:3.
UpdateNotePayloadandupdateNote()are added but unusedThe diff adds an
UpdateNotePayloadinterface andupdateNote()function toapi.ts, but nothing in this PR calls them. No proxy route exists for PUT/api/notes/[slug]. This is likely prep for a future PR (PR #30 "note editing"), which is fine, but it means they are dead code in this PR's scope. If intentional, a brief comment in the PR body would clarify.4.
.env.exampleshould documentPAL_E_DOCS_API_KEYEven if the actual value is in SOPS,
.env.exampleshould list the variable so developers know it exists for local dev.5. Missing
ml-1spacing on first lock icon in search-filtered notes viewIn
notes/+page.svelte, the lock icon in the search-filtered list (line ~100 in the diff) lacks theml-1class that the grouped-by-type view's lock icon has. Minor visual inconsistency.SOP COMPLIANCE
26-feat-private-notes-frontend-quick-jot-toreferences issue #26)plan-pal-e-docs -- Phase F6)Closes #26in PR body.envfiles or credentials in diffupdateNote()is out of scope for this issue (prep for #27) -- minor scope creep but non-blockingSecurity assessment: The API key is properly confined to server-side code.
$env/dynamic/privateis imported only insrc/lib/api.ts. All.sveltefiles import onlytypefrom$lib/api(verified:BlockRenderer.svelte,QuickJot.svelte,NoteLayout.svelte,boards/[slug]/+page.svelteall useimport type). The key cannot leak to the client bundle. This is correct.VERDICT: NOT APPROVED
The proxy not forwarding
is_public(blocker #1) means the core feature -- creating private notes -- does not work end-to-end. This must be fixed before merge. The API key provisioning (blocker #2) should at minimum be acknowledged with a follow-up issue reference.