- Drop zone: drag and drop files
- Paste: Ctrl+V pastes clipboard screenshots directly
- Browse: file picker button
- Saves to platform/screenshots/ with timestamp filename
- Mounted as volume in frontend container
- Accessible from any device at dash.quadjourney.com/upload
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- "Manage folders & tags" button at bottom of sidebar
- Click to enter manage mode:
- + button appears next to Folders/Tags headers
- Inline input to type and add new folder/tag
- × delete button appears on each item
- Delete confirms before removing
- "Done" button exits manage mode
- Tags/folders created/deleted via taxonomy API
- Sidebar refreshes after changes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Tags now show regardless of item_count (were hidden when 0)
- Content padding fixed (28px, overflow-x hidden)
- Sidebar nav items use same var(--text-sm) and var(--transition) as AppShell
- Active count color matches AppShell pattern
- Hero command-actions narrower to prevent overflow
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Template restructured to match Reader pattern:
brain-layout (flex) > brain-sidebar (248px) + brain-content (flex:1)
Hero and capture bar moved inside brain-content.
Removed page/app-surface wrappers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Removed duplicate in-page sidebar from AtelierBrainPage
- AppShell sub-items now full-sized, matching main nav style
- Folders/Tags tabs as pill toggle in sidebar
- All folders shown (not just ones with items)
- All tags shown (not limited to 12)
- Brain page is now just capture + search + masonry grid
- Sidebar links use /brain?folder=X and /brain?tag=X
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Brain nav item expands when on /brain page
- Shows Folders/Tags toggle tabs
- Folder links: /brain?folder=Work etc
- Tag links: /brain?tag=dev etc
- Counts shown next to each
- Brain page reads filter from URL params
- Only shows folders with items + key defaults (Home, Work, Knowledge)
- Tags limited to 12 most-used
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend:
- New Folder/Tag/ItemTag models with proper relational tables
- Taxonomy CRUD endpoints: list, create, rename, delete, merge tags
- Sidebar endpoint with folder/tag counts
- AI classification reads live folders/tags from DB, not hardcoded
- Default folders/tags seeded on first request per user
- folder_id FK on items for relational integrity
Frontend:
- Left sidebar with Folders/Tags tabs (like Karakeep)
- Click folder/tag to filter items
- "Manage" mode: add new folders/tags, delete existing
- Counts next to each folder/tag
- "All items" option to clear filter
- Replaces the old signal-strip cards
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Settings were failing with 405 (PUT not supported in Meilisearch v1.12).
Changed to PATCH. Filterable/searchable attributes now applied.
Keyword search working: wedding, yusuf, insurance, airport all return results.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 90vw x 80vh centered modal with rounded corners and shadow
- Blurred backdrop overlay, click outside to close
- PDF viewer on left, metadata sidebar on right
- Feels like a popup, not a page takeover
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PDFs open in full-screen split layout: PDF viewer (left) + metadata sidebar (right)
- Uses native browser PDF viewer (iframe) for full rendering
- Images open in centered viewer with dark background
- Sidebar shows title, summary, tags, folder, extracted text, download button
- Mobile: stacks vertically (viewer top, sidebar bottom)
- Links and notes still use the slide-over sheet
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PDF detail sheet now shows inline rendered PDF pages
- Click to expand inline, "Full view" for overlay viewer
- Uses pdfjs-dist canvas rendering (same as trips app)
- Falls back to screenshot if no original upload found
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Polls only pending/processing items by ID every 4s instead of
reloading the entire list every 3s. Prevents screen flashing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Upload button (arrow icon) in capture bar next to text input
- Accepts: PDF, PNG, JPG, GIF, WEBP, TXT, MD, CSV
- Multiple file upload supported
- Hidden file input triggered by button click
- Upload status indicator while processing
- Files sent to /api/brain/items/upload endpoint
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PDF cards: show first page render as thumbnail with "PDF" badge
- Image cards: show the original uploaded image
- PDF detail sheet: shows screenshot + extracted text in mono font
- Image detail sheet: shows the original image
- Card content shows page count for PDFs, extracted text preview
- Links still open URL on screenshot click, PDFs/images open detail
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Link detail: shows screenshot image (clickable to open URL), URL, summary, tags
- Note detail: click note text to edit, save/cancel buttons
- Notes: AI now fixes spelling/grammar instead of rewriting
- AI returns corrected_text field for notes, worker replaces raw_content
- Removed verbose meta grid (folder/confidence/status/saved)
- Folder shown as a pill badge in meta line
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Link card screenshots now open the original URL in new tab
- Card content area opens the detail sheet
- Notes: clicking the note body in detail sheet enters edit mode
- Removed Folder/Confidence/Status/Saved meta grid from detail
- Replaced with single inline folder + date line
- Tags still clickable for filtering
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Tags are now clickable buttons on cards and detail sheet
- Active tag filter shows as a pill with clear button
- Items filtered by tag via API query param
- Auto-polling every 3s for pending/processing items
- Detail sheet shows raw_content for notes with "Note" label
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 3-column CSS masonry grid (2 on tablet, 1 on mobile)
- Link cards show screenshot thumbnails
- Note cards show content body inline
- Tags as pills, folder/date in meta footer
- Screenshot serving endpoint added to brain API
- Auto-polling for pending items (3s interval)
- Detail sheet shows raw_content for notes
- Warm frosted glass card styling matching Atelier design
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- AtelierBrainPage.svelte with full CRUD UI
- Capture bar: paste URL or type note, saves instantly
- Folder signal cards with counts
- Hybrid search (keyword + semantic)
- Item feed with metadata, tags, confidence indicators
- Detail slide-over sheet with summary, metadata, actions
- Added to AppShell nav, legacy Navbar, and layout allApps
- Route at /brain
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Gateway proxies /api/brain/* to brain-api:8200/api/* via pangolin network
- User identity injected via X-Gateway-User-Id header
- Brain app registered in gateway database (sort_order 9)
- Added to GATEWAY_KEY_SERVICES for dashboard integration
- Tested: health, config, list, create all working through gateway
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Full backend service with:
- FastAPI REST API with CRUD, search, reprocess endpoints
- PostgreSQL + pgvector for items and semantic search
- Redis + RQ for background job processing
- Meilisearch for fast keyword/filter search
- Browserless/Chrome for JS rendering and screenshots
- OpenAI structured output for AI classification
- Local file storage with S3-ready abstraction
- Gateway auth via X-Gateway-User-Id header
- Own docker-compose stack (6 containers)
Classification: fixed folders (Home/Family/Work/Travel/Knowledge/Faith/Projects)
and fixed tags (28 predefined). AI assigns exactly 1 folder, 2-3 tags, title,
summary, and confidence score per item.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dashboard surface now renders at 1280px matching the React mockup exactly.
All 9 pages verified: zero mobile overflow.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Trips TLS: Removed all ssl CERT_NONE / check_hostname=False from
5 external HTTPS call sites (OpenAI, Gemini, Google Places, Geocode).
All external calls now use default TLS verification.
2. Internal CORS: Removed permissive cors() from inventory and budget.
Both are internal services accessed only via gateway.
3. App visibility: Documented as cosmetic-only in layout.server.ts.
Nav hiding is intentional UX, not access control.
4. Disconnect safety: Added confirm() dialog before service disconnect
in Settings. Prevents accidental disconnects.
5. Inventory cleanup: Removed stale /test startup log message.
Replaced with API key status indicator.
6. Frontend deps: 4 low-severity cookie vulnerabilities in @sveltejs/kit.
Fix requires breaking downgrade to kit@0.0.30 — not safe. Documented.
- Removed fitness sub-pages from mobile More sheet (Food Library and
Quick Meals are already tabs on the fitness page)
- Added Fitness Goals section to Settings page with inline editing
- Goals show current values with Edit Goals button
- Edit mode: 2x2 grid with calorie/protein/carbs/fat inputs
- Save calls PUT /api/fitness/goals
- Works for both users independently
Multi-user:
- Madiha account with per-user nav visibility
- Dashboard greeting uses actual user display name
- Navbar and MobileTabBar accept visibleApps prop
- Madiha sees: Dashboard, Trips, Fitness, Budget, Media (no Inventory, Reader)
Goals editing:
- Goals page now has Edit Goals mode with inline number inputs
- Saves via PUT /api/fitness/goals
- Shows "No goals set" state for new users
Food library:
- Default view shows all shared foods (not just user's recent)
- Both users see the same food database
- Cleaned up duplicates: archived Eggs (kept Egg), Green Grapes (kept Grapes),
duplicate Bellwether Yogurt, Latte Macchiato (kept Madiha's Caramel Latte)
Add to meal buttons:
- "Add to breakfast/lunch/dinner/snack" now focuses the resolve input
and sets the meal type so AI logs to the correct meal
#7 Transport Security:
- Removed legacy _ssl_ctx alias from config.py
- proxy.py now uses _internal_ssl_ctx directly (explicitly scoped)
- No global TLS bypass remains
#10 Deployment Hardening:
- Inventory Dockerfile: non-root (node user), health check, production deps
- Budget Dockerfile: non-root (node user), health check, npm ci, multi-stage ready
- Frontend-v2 Dockerfile: multi-stage build, non-root (node user), health check
- Added /health endpoints to inventory and budget (before auth middleware)
- All 6 containers now run as non-root with health checks
All services verified: gateway, trips, fitness, inventory, budget, frontend
- Disable open /api/auth/register endpoint (gateway)
- Require gateway session auth on Immich and Karakeep hooks proxies
- Replace SHA-256 with bcrypt in fitness service (auth + seed)
- Remove hardcoded Telegram user IDs from fitness seed
- Add Secure flag to session cookie
- Add domain allowlist and content-type validation to image proxy
- Strengthen .gitignore (env variants, runtime data, test artifacts)