# CURRENT AI WORKING SESSION — HANDOVER **Active AI:** Gemini (Antigravity) **Last Updated:** 2026-04-12 **Current Version:** v1.3.5 (pending bump to v1.3.6) **Branch:** dev --- ## STATUS: 🟢 STABLE — FOLDER STRUCTURE SEPARATION COMPLETE Runtime data (`data/`, `logs/`) is now properly excluded from Git with init-on-first-run support for both local/systemd and Docker deployment modes. --- ## WHAT WAS DONE THIS SESSION ### Folder Structure Separation (data/logs init refactor) - **`data/.gitkeep`** — Added to track the `data/` directory in Git without committing runtime data - **`logs/.gitkeep`** — Added to track the `logs/` directory in Git without committing log files - **`scripts/init_data.sh`** (NEW) — Shared first-run init script: creates `data/` + `logs/` dirs, copies `ldap_config.json.example` → `data/ldap_config.json` if missing - **`backend/entrypoint.sh`** (NEW) — Docker entrypoint: runs `init_data.sh` then starts uvicorn via `exec` - **`backend/Dockerfile`** — Changed `CMD` → `ENTRYPOINT`, added `COPY scripts/`, made scripts executable - **`docker-compose.yml`** — Added `./scripts:/app/scripts:ro` volume to backend service - **`start_server.sh`** — Added call to `scripts/init_data.sh` after env vars, before uvicorn - **`.gitignore`** — Changed `data/` → `data/*` with `!/data/.gitkeep` exception; same for `logs/` - **Git index cleaned** — `data/inventory.db` and `data/ldap_config.json` removed from tracking via `git rm --cached` - **Layout**: Moved all controls OUT of the camera viewport overlay. Camera feed is now 100% unobstructed. - **Automated OCR**: Removed manual "OCR SCAN" button. OCR now runs automatically on a 4-second cycle. - **Visual Countdown**: Added a countdown display (4, 3, 2, 1, Scan) with a progress bar so the user can see the next scan timing. - **Scan-line animation**: Now only active when `isStarted && !isSelecting && !paused`. - **Typography**: Removed all `uppercase` and `tracking-widest` styles per `AI_RULES.md` Section 3. - **Silent failures**: Auto-OCR no longer shows toast errors if no text is found (silently retries on next cycle). ### 2. Item Type Datalist (`AIOnboarding.tsx`, `page.tsx`, `inventory/page.tsx`) - Added a searchable `` to the Item Type field across all relevant forms. - Dynamically populated with existing unique types from the DB, while still allowing manual free-text input. ### 3. `save-version` Automation Command - Created `scripts/save_version.py` — increments patch version in `VERSION.json`, commits all changes, creates a snapshot branch `v.X.Y.Z`, and generates the production ZIP via `./export_prod.sh`. - Registered as an official AI Command Shortcut in `AI_RULES.md` Section 6. --- ## WHAT THE NEXT AI MUST DO 1. Run `save-version` to finalize version `1.3.6` if not already done. 2. Monitor TypeScript warnings as the `Item` interface in `frontend/lib/db.ts` may be missing fields. 3. If the Item Type datalist grows too large, consider a dedicated "Category/Type Management" settings page. 4. Periodically review `dev_docs/SECURITY_REPORT.md`. --- ## SYSTEM STATE **Active database:** `/data/inventory.db` **LDAP config:** `backend/config/ldap_config.json` ```json {"ldap_enabled": true, "server_uri": "ldap://192.168.84.107:3890", "base_dn": "dc=example,dc=com", "user_template": "cn={username},ou=people,dc=example,dc=com", "groups_dn": "ou=groups", "use_tls": false, "role_mappings": [{"group": "inventory_admins", "role": "admin"}, {"group": "inventory_users", "role": "user"}]} ``` **How to start:** ```bash ./start_server.sh ``` - Frontend: `https://:3003` - Backend: `http://localhost:8000` direct **Environment variables set by start_server.sh:** - `ALLOWED_ORIGINS` — auto-detected from local IP - `DATA_DIR` — absolute path to `/data/` - `LOGS_DIR` — absolute path to `/logs/` - `JWT_SECRET_KEY` — ephemeral per-run if not set externally This session applied the 3 frontend fixes for the login redirect loop. The server was NOT restarted and the login flow was NOT tested. The next AI must test and confirm — or continue debugging if the loop persists. --- ## WHAT WAS DONE THIS SESSION ### 1. `frontend/lib/api.ts` — Lazy baseURL (Fix 1) axiosInstance no longer receives baseURL at creation. `getBackendUrl()` is now called inside the request interceptor, at request time, so SSR can no longer lock it to `http://localhost:8000`. ```typescript // BEFORE (broken): const axiosInstance = axios.create({ baseURL: getBackendUrl() }); // AFTER (fixed): const axiosInstance = axios.create({}); axiosInstance.interceptors.request.use((config) => { if (!config.baseURL) config.baseURL = getBackendUrl(); const token = getToken(); if (token) config.headers.Authorization = `Bearer ${token}`; return config; }); ``` ### 2. `frontend/lib/api.ts` — 401 interceptor guard (Fix 2) ```typescript // BEFORE (broken — infinite loop): if (typeof window !== 'undefined') { window.location.href = '/login'; } // AFTER (fixed): if (typeof window !== 'undefined' && !window.location.pathname.includes('/login')) { window.location.href = '/login'; } ``` ### 3. `frontend/app/page.tsx` — Token guard on both useEffect hooks (Fix 3) Added `if (!localStorage.getItem('inventory_token')) { window.location.href = '/login'; return; }` at the top of BOTH useEffect hooks — the first one (calls `getCategories`) and the second one (calls `loadInventory`). ### 4. Debug cleanup - `frontend/lib/auth.ts` — removed `console.log('[Auth] saveToken...')` statements - `frontend/app/login/page.tsx` — removed `console.log('[LoginPage]...')` statements + unused `memo` import --- ## WHAT THE NEXT AI MUST DO 1. Restart the server: `./start_server.sh` 2. Open `https://192.168.84.140:3003/login` in browser 3. Log in with LDAP user `bede` 4. Verify: main page loads and STAYS — no redirect back to `/login` 5. Verify: `localStorage.getItem('inventory_token')` is non-null after login 6. If loop persists: check browser Network tab for which API endpoint returns 401 first — there may be other API calls in child components (`PageShell`, `Scanner`, etc.) that fire before the token guard --- ## KNOWN PRE-EXISTING ISSUES (not introduced by this session) TypeScript errors in `frontend/app/page.tsx`: - Line 241: `Property 'serial_number' does not exist on type 'Item'` - Lines 598-599: `Property 'type' does not exist on type 'Partial'` These are separate bugs — `Item` type in `frontend/lib/db.ts` is missing fields that the UI uses. Fix separately from the login issue. --- ## SYSTEM STATE **Active database:** `/data/inventory.db` **LDAP config:** `backend/config/ldap_config.json` ```json {"ldap_enabled": true, "server_uri": "ldap://192.168.84.107:3890", "base_dn": "dc=example,dc=com", "user_template": "cn={username},ou=people,dc=example,dc=com", "groups_dn": "ou=groups", "use_tls": false, "role_mappings": [{"group": "inventory_admins", "role": "admin"}, {"group": "inventory_users", "role": "user"}]} ``` **How to start:** ```bash ./start_server.sh ``` - Frontend: `https://:3003` - Backend: `https://:3002` (also `http://localhost:8000` direct) **Environment variables set by start_server.sh:** - `ALLOWED_ORIGINS` — auto-detected from local IP (includes both HTTP and HTTPS variants) - `DATA_DIR` — absolute path to `/data/` - `LOGS_DIR` — absolute path to `/logs/` - `JWT_SECRET_KEY` — ephemeral per-run if not set externally (means tokens invalidated on restart)