7.4 KiB
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 thedata/directory in Git without committing runtime data -
logs/.gitkeep— Added to track thelogs/directory in Git without committing log files -
scripts/init_data.sh(NEW) — Shared first-run init script: createsdata/+logs/dirs, copiesldap_config.json.example→data/ldap_config.jsonif missing -
backend/entrypoint.sh(NEW) — Docker entrypoint: runsinit_data.shthen starts uvicorn viaexec -
backend/Dockerfile— ChangedCMD→ENTRYPOINT, addedCOPY scripts/, made scripts executable -
docker-compose.yml— Added./scripts:/app/scripts:rovolume to backend service -
start_server.sh— Added call toscripts/init_data.shafter env vars, before uvicorn -
.gitignore— Changeddata/→data/*with!/data/.gitkeepexception; same forlogs/ -
Git index cleaned —
data/inventory.dbanddata/ldap_config.jsonremoved from tracking viagit 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
uppercaseandtracking-wideststyles perAI_RULES.mdSection 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
<datalist>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 inVERSION.json, commits all changes, creates a snapshot branchv.X.Y.Z, and generates the production ZIP via./export_prod.sh. - Registered as an official AI Command Shortcut in
AI_RULES.mdSection 6.
WHAT THE NEXT AI MUST DO
- Run
save-versionto finalize version1.3.6if not already done. - Monitor TypeScript warnings as the
Iteminterface infrontend/lib/db.tsmay be missing fields. - If the Item Type datalist grows too large, consider a dedicated "Category/Type Management" settings page.
- Periodically review
dev_docs/SECURITY_REPORT.md.
SYSTEM STATE
Active database: <project_root>/data/inventory.db
LDAP config: backend/config/ldap_config.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:
./start_server.sh
- Frontend:
https://<LOCAL_IP>:3003 - Backend:
http://localhost:8000direct
Environment variables set by start_server.sh:
ALLOWED_ORIGINS— auto-detected from local IPDATA_DIR— absolute path to<project_root>/data/LOGS_DIR— absolute path to<project_root>/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.
// 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)
// 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— removedconsole.log('[Auth] saveToken...')statementsfrontend/app/login/page.tsx— removedconsole.log('[LoginPage]...')statements + unusedmemoimport
WHAT THE NEXT AI MUST DO
- Restart the server:
./start_server.sh - Open
https://192.168.84.140:3003/loginin browser - Log in with LDAP user
bede - Verify: main page loads and STAYS — no redirect back to
/login - Verify:
localStorage.getItem('inventory_token')is non-null after login - 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<Item>'
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: <project_root>/data/inventory.db
LDAP config: backend/config/ldap_config.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:
./start_server.sh
- Frontend:
https://<LOCAL_IP>:3003 - Backend:
https://<LOCAL_IP>:3002(alsohttp://localhost:8000direct)
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<project_root>/data/LOGS_DIR— absolute path to<project_root>/logs/JWT_SECRET_KEY— ephemeral per-run if not set externally (means tokens invalidated on restart)