1047 lines
34 KiB
Markdown
1047 lines
34 KiB
Markdown
# Session Handoff
|
||
|
||
Date: April 1, 2026
|
||
|
||
Workspace root: [`/home/sandy/HUB-master`](/home/sandy/HUB-master)
|
||
|
||
Primary port target: [`/home/sandy/HUB-master/django-port`](/home/sandy/HUB-master/django-port)
|
||
|
||
## 1. Purpose Of This Document
|
||
|
||
This document is the full handoff for the current Django + Svelte porting session.
|
||
|
||
It is written for another Codex instance that needs to continue the work without replaying the entire session. It captures:
|
||
|
||
- what the user originally asked for
|
||
- what was actually built
|
||
- what the user ran locally
|
||
- what broke and how it was fixed
|
||
- the current architecture
|
||
- the current API and UI surface
|
||
- known gaps and risky areas
|
||
- the exact next priorities the user explicitly named
|
||
|
||
The user said the session ends here and specifically requested a comprehensive pickup document before further refactoring.
|
||
|
||
## 2. Original User Request
|
||
|
||
The user asked to:
|
||
|
||
- read `summary.md`
|
||
- port the existing FastAPI + manual migration project into:
|
||
- Django
|
||
- Svelte
|
||
- `shadcn-svelte`
|
||
- place the new implementation in [`/home/sandy/HUB-master/django-port`](/home/sandy/HUB-master/django-port)
|
||
- avoid heavy runtime work on the assistant side
|
||
- leave package installation and similar local setup tasks to the user
|
||
|
||
Important constraint from the start:
|
||
|
||
- do not try to run heavy commands unless absolutely necessary
|
||
- user would handle installs, dev servers, migrations, and manual validation
|
||
|
||
## 3. Legacy App Context
|
||
|
||
The old app is a hospitality/business operations system spanning multiple businesses and covering:
|
||
|
||
- auth and role-based access
|
||
- dashboard reporting
|
||
- invoices
|
||
- vendors
|
||
- products and categories
|
||
- inventory
|
||
- events
|
||
- shifts and schedule
|
||
- users / roles / devices
|
||
- notifications
|
||
|
||
Key legacy artifacts:
|
||
|
||
- summary: [summary.md](/home/sandy/HUB-master/summary.md)
|
||
- old frontend root: [`/home/sandy/HUB-master/frontend`](/home/sandy/HUB-master/frontend)
|
||
- old backend root: [`/home/sandy/HUB-master/backend`](/home/sandy/HUB-master/backend)
|
||
- legacy databases:
|
||
- [`/home/sandy/HUB-master/cincin_phase1.sqlite`](/home/sandy/HUB-master/cincin_phase1.sqlite)
|
||
- [`/home/sandy/HUB-master/dalcorso.sqlite`](/home/sandy/HUB-master/dalcorso.sqlite)
|
||
|
||
Primary structural problems in the legacy app:
|
||
|
||
- backend logic was concentrated in route files
|
||
- migration/import logic lived inside runtime application code
|
||
- the frontend was a large route-heavy monolith
|
||
- business separation and multi-DB logic were brittle
|
||
- auth behavior was custom and not aligned with Django conventions the user wanted
|
||
|
||
## 4. What Exists Now
|
||
|
||
The port is not a blank scaffold anymore. It is a functioning Django backend plus a functioning Svelte frontend with usable CRUD/read flows for most major domains.
|
||
|
||
Current broad state:
|
||
|
||
- backend is Django, session-auth based, and uses Django ORM models
|
||
- frontend is the new Svelte app in `django-port/frontend`
|
||
- imported legacy data is in the Django database
|
||
- admin works
|
||
- invoice/vendor/inventory/dashboard/business/events/schedule/settings/devices screens exist and load data
|
||
- auth gating exists in the Svelte app
|
||
- permission checks exist on much of the API
|
||
- business access scoping exists in some places but is not complete
|
||
|
||
The project is no longer at the “create the port” stage. It is now at the “tighten correctness, complete missing flows, and replace temporary UI layer” stage.
|
||
|
||
## 5. Current Project Structure
|
||
|
||
### 5.1 Root
|
||
|
||
Main port root:
|
||
|
||
- [`/home/sandy/HUB-master/django-port`](/home/sandy/HUB-master/django-port)
|
||
|
||
Useful docs:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/docs/port-plan.md`](/home/sandy/HUB-master/django-port/docs/port-plan.md)
|
||
- [`/home/sandy/HUB-master/django-port/docs/session-handoff-2026-04-01.md`](/home/sandy/HUB-master/django-port/docs/session-handoff-2026-04-01.md)
|
||
|
||
### 5.2 Backend
|
||
|
||
Backend root:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/backend`](/home/sandy/HUB-master/django-port/backend)
|
||
|
||
Key files:
|
||
|
||
- Django entrypoint:
|
||
- [`/home/sandy/HUB-master/django-port/backend/manage.py`](/home/sandy/HUB-master/django-port/backend/manage.py)
|
||
- package config:
|
||
- [`/home/sandy/HUB-master/django-port/backend/pyproject.toml`](/home/sandy/HUB-master/django-port/backend/pyproject.toml)
|
||
- settings:
|
||
- [`/home/sandy/HUB-master/django-port/backend/config/settings.py`](/home/sandy/HUB-master/django-port/backend/config/settings.py)
|
||
- root URLs:
|
||
- [`/home/sandy/HUB-master/django-port/backend/config/urls.py`](/home/sandy/HUB-master/django-port/backend/config/urls.py)
|
||
- local database file:
|
||
- [`/home/sandy/HUB-master/django-port/backend/db.sqlite3`](/home/sandy/HUB-master/django-port/backend/db.sqlite3)
|
||
|
||
Backend apps:
|
||
|
||
- accounts:
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/accounts/models.py`](/home/sandy/HUB-master/django-port/backend/apps/accounts/models.py)
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/accounts/admin.py`](/home/sandy/HUB-master/django-port/backend/apps/accounts/admin.py)
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/accounts/management/commands/import_legacy_data.py`](/home/sandy/HUB-master/django-port/backend/apps/accounts/management/commands/import_legacy_data.py)
|
||
- core:
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/core/models.py`](/home/sandy/HUB-master/django-port/backend/apps/core/models.py)
|
||
- operations:
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/operations/models.py`](/home/sandy/HUB-master/django-port/backend/apps/operations/models.py)
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/operations/services.py`](/home/sandy/HUB-master/django-port/backend/apps/operations/services.py)
|
||
- reporting:
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/reporting/models.py`](/home/sandy/HUB-master/django-port/backend/apps/reporting/models.py)
|
||
- notifications:
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/notifications/models.py`](/home/sandy/HUB-master/django-port/backend/apps/notifications/models.py)
|
||
- API:
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/api/urls.py`](/home/sandy/HUB-master/django-port/backend/apps/api/urls.py)
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/api/views.py`](/home/sandy/HUB-master/django-port/backend/apps/api/views.py)
|
||
|
||
### 5.3 Frontend
|
||
|
||
Frontend root:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend`](/home/sandy/HUB-master/django-port/frontend)
|
||
|
||
Key config files:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend/package.json`](/home/sandy/HUB-master/django-port/frontend/package.json)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/package-lock.json`](/home/sandy/HUB-master/django-port/frontend/package-lock.json)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/svelte.config.js`](/home/sandy/HUB-master/django-port/frontend/svelte.config.js)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/vite.config.ts`](/home/sandy/HUB-master/django-port/frontend/vite.config.ts)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/tsconfig.json`](/home/sandy/HUB-master/django-port/frontend/tsconfig.json)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/components.json`](/home/sandy/HUB-master/django-port/frontend/components.json)
|
||
|
||
Frontend shared files:
|
||
|
||
- global styles:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/app.css`](/home/sandy/HUB-master/django-port/frontend/src/app.css)
|
||
- API client:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/api/client.ts`](/home/sandy/HUB-master/django-port/frontend/src/lib/api/client.ts)
|
||
- auth store:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/stores/auth.ts`](/home/sandy/HUB-master/django-port/frontend/src/lib/stores/auth.ts)
|
||
- shared types:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/types/domain.ts`](/home/sandy/HUB-master/django-port/frontend/src/lib/types/domain.ts)
|
||
- shell/sidebar:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/components/app-shell/sidebar.svelte`](/home/sandy/HUB-master/django-port/frontend/src/lib/components/app-shell/sidebar.svelte)
|
||
|
||
Temporary UI primitives still in use:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/components/ui/button.svelte`](/home/sandy/HUB-master/django-port/frontend/src/lib/components/ui/button.svelte)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/components/ui/card.svelte`](/home/sandy/HUB-master/django-port/frontend/src/lib/components/ui/card.svelte)
|
||
|
||
Routes:
|
||
|
||
- shell:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/+layout.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/+layout.svelte)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/+page.ts`](/home/sandy/HUB-master/django-port/frontend/src/routes/+page.ts)
|
||
- login:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/login/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/login/+page.svelte)
|
||
- protected app:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/+layout.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/+layout.svelte)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/+layout.ts`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/+layout.ts)
|
||
- dashboard:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/dashboard/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/dashboard/+page.svelte)
|
||
- business:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/business/[id]/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/business/[id]/+page.svelte)
|
||
- invoices:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/invoices/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/invoices/+page.svelte)
|
||
- vendors:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/vendors/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/vendors/+page.svelte)
|
||
- inventory:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/inventory/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/inventory/+page.svelte)
|
||
- events:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/events/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/events/+page.svelte)
|
||
- schedule:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/schedule/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/schedule/+page.svelte)
|
||
- settings:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/settings/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/settings/+page.svelte)
|
||
- devices:
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/devices/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/devices/+page.svelte)
|
||
|
||
## 6. Backend Architecture
|
||
|
||
### 6.1 Domain split
|
||
|
||
Backend was intentionally split by business domain:
|
||
|
||
- `accounts`
|
||
- custom user model
|
||
- roles
|
||
- permissions
|
||
- allowed business links
|
||
- allowed devices
|
||
- registration tokens
|
||
- `core`
|
||
- businesses
|
||
- vendors
|
||
- categories
|
||
- products
|
||
- `operations`
|
||
- invoices
|
||
- line items
|
||
- inventory
|
||
- events
|
||
- shifts/schedule
|
||
- `reporting`
|
||
- daily revenue summary table
|
||
- `notifications`
|
||
- inbox/reminder state
|
||
- `api`
|
||
- JSON endpoints consumed by the Svelte app
|
||
|
||
### 6.2 Current API design
|
||
|
||
API is function-based and centralized in one large file:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/api/views.py`](/home/sandy/HUB-master/django-port/backend/apps/api/views.py)
|
||
|
||
This is one of the remaining structural issues. The file works, but it is too large and mixes:
|
||
|
||
- auth/session handling
|
||
- permission checks
|
||
- business-scoping helpers
|
||
- serializers/payload builders
|
||
- endpoint implementations
|
||
|
||
It was acceptable to get the port moving, but the next Codex should treat this as a cleanup candidate after correctness gaps are closed.
|
||
|
||
### 6.3 Important backend helper patterns already present
|
||
|
||
Notable helpers in `views.py`:
|
||
|
||
- `_json_body`
|
||
- `_money`
|
||
- `_bad_request`
|
||
- `_forbidden`
|
||
- `api_login_required`
|
||
- `require_permissions`
|
||
- `_allowed_business_ids`
|
||
- `_ensure_business_access`
|
||
|
||
These helpers are central to current auth and scoping behavior.
|
||
|
||
## 7. Frontend Architecture
|
||
|
||
### 7.1 General shape
|
||
|
||
The frontend is now the Svelte app under `django-port/frontend`. It is not the old React app.
|
||
|
||
Important note from the session:
|
||
|
||
- the user accidentally launched the old frontend once from [`/home/sandy/HUB-master/frontend`](/home/sandy/HUB-master/frontend)
|
||
- when that happens, the browser console shows React/TanStack/Axios traces and `/api/auth/refresh`
|
||
- that is the wrong app
|
||
|
||
The correct app is always:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend`](/home/sandy/HUB-master/django-port/frontend)
|
||
|
||
### 7.2 API client
|
||
|
||
The frontend uses `fetch`, not axios, in:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/api/client.ts`](/home/sandy/HUB-master/django-port/frontend/src/lib/api/client.ts)
|
||
|
||
Key client behaviors:
|
||
|
||
- `VITE_API_BASE` defaults to `http://localhost:8000/api`
|
||
- trailing slashes are normalized
|
||
- CSRF header is added automatically on non-GET/HEAD requests
|
||
- cookies are sent with `credentials: "include"`
|
||
- errors throw `ApiError(status, message)`
|
||
|
||
### 7.3 Auth bootstrap
|
||
|
||
Auth store:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/stores/auth.ts`](/home/sandy/HUB-master/django-port/frontend/src/lib/stores/auth.ts)
|
||
|
||
Key behaviors:
|
||
|
||
- `bootstrapAuth()` loads current user via `/api/auth/me/`
|
||
- `authReady` gates rendering
|
||
- `hasPermission()` checks permission keys and superuser bypass
|
||
- `clearAuth()` clears local auth state on logout
|
||
|
||
Protected app gating:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/+layout.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/+layout.svelte)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/+layout.ts`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/+layout.ts)
|
||
|
||
Login route:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/login/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/login/+page.svelte)
|
||
|
||
### 7.4 UI state
|
||
|
||
The frontend is visually usable, but it is not yet the final `shadcn-svelte` implementation.
|
||
|
||
Current reality:
|
||
|
||
- route structure is real
|
||
- forms/data-loading logic are real
|
||
- layout is real
|
||
- styles/components are still mostly temporary
|
||
|
||
Specifically:
|
||
|
||
- `button.svelte` and `card.svelte` are custom placeholders
|
||
- `components.json` exists, but `shadcn-svelte` has not actually replaced those primitives yet
|
||
|
||
This was one of the user’s explicit remaining tasks.
|
||
|
||
## 8. What Was Implemented In This Session
|
||
|
||
### 8.1 Django project scaffold and model base
|
||
|
||
Built a Django project manually under `django-port/backend` with:
|
||
|
||
- domain-split apps
|
||
- migrations
|
||
- admin registrations
|
||
- custom user model
|
||
- settings for local session auth and cross-origin frontend dev
|
||
|
||
### 8.2 Legacy data import
|
||
|
||
Implemented:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/accounts/management/commands/import_legacy_data.py`](/home/sandy/HUB-master/django-port/backend/apps/accounts/management/commands/import_legacy_data.py)
|
||
|
||
Purpose:
|
||
|
||
- import the two legacy SQLite databases into the Django schema
|
||
- merge master data across them where natural keys match
|
||
|
||
Import behavior and fixes:
|
||
|
||
- businesses matched by `short_code`
|
||
- categories matched by `name`
|
||
- vendors matched by `name`
|
||
- products matched by `(gtin, name)`
|
||
- users matched by `username`
|
||
- roles matched by `name`
|
||
- importer no longer forces legacy user/role primary keys into Django PKs
|
||
- optional legacy link tables are guarded with `_table_exists`
|
||
- actual `daily_revenue_summary` schema is respected
|
||
- operational data only imports from the primary CinCin DB
|
||
- in-memory maps are maintained per source DB to preserve FK wiring during import
|
||
|
||
The importer was debugged through multiple user-reported tracebacks and is currently working well enough for the user to inspect data in admin.
|
||
|
||
### 8.3 Auth/session flow
|
||
|
||
Implemented backend auth API:
|
||
|
||
- `POST /api/auth/login/`
|
||
- `POST /api/auth/logout/`
|
||
- `GET /api/auth/me/`
|
||
- `GET /api/auth/csrf/`
|
||
|
||
Important changes made along the way:
|
||
|
||
- unauthenticated API requests now return JSON `401`, not HTML/login redirects
|
||
- frontend login path now uses trailing slashes consistently
|
||
- local CORS/CSRF/session settings were added for port `5173`
|
||
- superusers are represented properly in frontend auth payload
|
||
|
||
### 8.4 Invoice slice
|
||
|
||
Backend:
|
||
|
||
- invoice payload builder and create logic in:
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/operations/services.py`](/home/sandy/HUB-master/django-port/backend/apps/operations/services.py)
|
||
|
||
Frontend:
|
||
|
||
- invoice list
|
||
- invoice detail pane
|
||
- invoice create form
|
||
- lookup loading for vendors/products/categories/businesses
|
||
|
||
Current API:
|
||
|
||
- `GET /api/invoices/`
|
||
- `POST /api/invoices/`
|
||
- `GET /api/invoices/<id>/`
|
||
|
||
Missing:
|
||
|
||
- invoice update
|
||
- invoice delete
|
||
|
||
Those are explicitly still on the to-do list.
|
||
|
||
### 8.5 Vendor and inventory slice
|
||
|
||
Implemented vendor list/create/update:
|
||
|
||
- `GET /api/vendors/`
|
||
- `POST /api/vendors/`
|
||
- `GET /api/vendors/<id>/`
|
||
- `PUT /api/vendors/<id>/`
|
||
|
||
Implemented inventory list:
|
||
|
||
- `GET /api/inventory/`
|
||
|
||
Frontend vendors page supports:
|
||
|
||
- query filter
|
||
- business filter
|
||
- category filter
|
||
- create vendor
|
||
- update vendor
|
||
|
||
Frontend inventory page supports:
|
||
|
||
- query filter
|
||
- category filter
|
||
- stock summary cards
|
||
- inventory item list
|
||
|
||
Important caveat:
|
||
|
||
- inventory/business scoping is still one of the least trustworthy areas and should be revisited
|
||
|
||
### 8.6 Dashboard and business reporting
|
||
|
||
Implemented:
|
||
|
||
- `GET /api/dashboard/overview/`
|
||
- `GET /api/dashboard/business-summary/`
|
||
- `GET /api/businesses/<id>/summary/`
|
||
|
||
Frontend dashboard includes:
|
||
|
||
- consolidated metrics
|
||
- per-business summary cards
|
||
- links into business detail pages
|
||
|
||
Frontend business page includes:
|
||
|
||
- summary metrics
|
||
- recent revenue rows
|
||
- recent invoices
|
||
|
||
### 8.7 Events and schedule
|
||
|
||
Implemented:
|
||
|
||
- `GET /api/events/`
|
||
- `POST /api/events/`
|
||
- `GET /api/events/<id>/`
|
||
- `PUT /api/events/<id>/`
|
||
- `DELETE /api/events/<id>/`
|
||
- `GET /api/schedule/overview/`
|
||
|
||
Frontend events page supports:
|
||
|
||
- list
|
||
- create
|
||
- edit
|
||
- delete
|
||
|
||
Frontend schedule page supports:
|
||
|
||
- roles
|
||
- templates
|
||
- assignments
|
||
- business filter
|
||
|
||
### 8.8 Settings and devices
|
||
|
||
Implemented:
|
||
|
||
- `GET /api/settings/overview/`
|
||
- `POST /api/settings/users/`
|
||
- `GET /api/devices/`
|
||
- `POST /api/devices/`
|
||
- `PUT /api/devices/<id>/`
|
||
- `DELETE /api/devices/<id>/`
|
||
- `GET /api/devices/tokens/`
|
||
- `POST /api/devices/tokens/`
|
||
- `DELETE /api/devices/tokens/<id>/`
|
||
|
||
Frontend settings page supports:
|
||
|
||
- roles list
|
||
- permissions list
|
||
- users list
|
||
- create-user form
|
||
|
||
Frontend devices page supports:
|
||
|
||
- device list
|
||
- registration token list
|
||
- create device
|
||
- create token
|
||
- delete device
|
||
- delete token
|
||
|
||
Missing:
|
||
|
||
- user update
|
||
- user delete
|
||
|
||
Those are explicitly still on the to-do list.
|
||
|
||
### 8.9 Permission enforcement
|
||
|
||
Permission enforcement was added on many routes using legacy domain-style keys.
|
||
|
||
Known permission keys in use:
|
||
|
||
- `categories.manage`
|
||
- `dashboard.view`
|
||
- `events.create`
|
||
- `events.delete`
|
||
- `events.edit`
|
||
- `events.view`
|
||
- `inventory.adjust`
|
||
- `inventory.stock_count`
|
||
- `inventory.view`
|
||
- `invoices.create`
|
||
- `invoices.delete`
|
||
- `invoices.edit`
|
||
- `invoices.mark_paid`
|
||
- `invoices.view`
|
||
- `products.create`
|
||
- `products.edit`
|
||
- `products.view`
|
||
- `shifts.availability`
|
||
- `shifts.manage`
|
||
- `shifts.view`
|
||
- `users.manage`
|
||
- `vendors.create`
|
||
- `vendors.delete`
|
||
- `vendors.edit`
|
||
- `vendors.view`
|
||
|
||
Frontend sidebar now hides routes by permission, and superusers are treated as allowed everywhere.
|
||
|
||
### 8.10 Business access scoping
|
||
|
||
Business access scoping was started but not completed.
|
||
|
||
Helpers now exist:
|
||
|
||
- `_allowed_business_ids(user)`
|
||
- `_ensure_business_access(request, business_id)`
|
||
|
||
Scoping has been added to several routes, including:
|
||
|
||
- businesses list
|
||
- business summary
|
||
- dashboard business rollup
|
||
- some vendor operations
|
||
- some invoice operations
|
||
- events
|
||
- schedule overview
|
||
- user creation business assignment checks
|
||
|
||
This is incomplete and one of the top-priority remaining tasks.
|
||
|
||
## 9. Exact API Surface At End Of Session
|
||
|
||
Current API routes from:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/api/urls.py`](/home/sandy/HUB-master/django-port/backend/apps/api/urls.py)
|
||
|
||
Routes:
|
||
|
||
- `POST /api/auth/login/`
|
||
- `POST /api/auth/logout/`
|
||
- `GET /api/auth/me/`
|
||
- `GET /api/auth/csrf/`
|
||
- `GET /api/businesses/`
|
||
- `GET /api/businesses/<business_id>/summary/`
|
||
- `GET /api/products/`
|
||
- `GET /api/categories/`
|
||
- `GET /api/dashboard/overview/`
|
||
- `GET /api/dashboard/business-summary/`
|
||
- `GET/POST /api/vendors/`
|
||
- `GET/PUT /api/vendors/<vendor_id>/`
|
||
- `GET/POST /api/invoices/`
|
||
- `GET /api/invoices/<invoice_id>/`
|
||
- `GET /api/inventory/`
|
||
- `GET/POST /api/events/`
|
||
- `GET/PUT/DELETE /api/events/<event_id>/`
|
||
- `GET /api/schedule/overview/`
|
||
- `GET /api/settings/overview/`
|
||
- `POST /api/settings/users/`
|
||
- `GET/POST /api/devices/`
|
||
- `PUT/DELETE /api/devices/<device_id>/`
|
||
- `GET/POST /api/devices/tokens/`
|
||
- `DELETE /api/devices/tokens/<token_id>/`
|
||
- `GET /api/notifications/`
|
||
|
||
## 10. User-Run Commands And Workflow
|
||
|
||
The user handled runtime/bootstrap steps locally.
|
||
|
||
### 10.1 Backend commands
|
||
|
||
Run from:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/backend`](/home/sandy/HUB-master/django-port/backend)
|
||
|
||
Commands used during the session:
|
||
|
||
```bash
|
||
source ../venv/bin/activate
|
||
pip install -e .
|
||
python manage.py makemigrations
|
||
python manage.py migrate
|
||
python manage.py createsuperuser
|
||
python manage.py import_legacy_data
|
||
python manage.py runserver
|
||
```
|
||
|
||
The user also created at least one additional superuser while testing frontend login.
|
||
|
||
### 10.2 Frontend commands
|
||
|
||
Run from:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend`](/home/sandy/HUB-master/django-port/frontend)
|
||
|
||
Commands used:
|
||
|
||
```bash
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
`shadcn-svelte` was discussed and prepared for, but not fully applied.
|
||
|
||
### 10.3 Lightweight verification commands
|
||
|
||
The assistant used lightweight backend verification only, primarily:
|
||
|
||
```bash
|
||
python3 -m compileall django-port/backend
|
||
```
|
||
|
||
This passed after the latest changes.
|
||
|
||
No full backend test suite exists yet.
|
||
No frontend build/test pass was run by the assistant.
|
||
|
||
## 11. Problems Encountered And How They Were Fixed
|
||
|
||
This section matters. The next Codex should not spend time rediscovering these.
|
||
|
||
### 11.1 Wrong frontend was launched
|
||
|
||
The user initially ran:
|
||
|
||
- [`/home/sandy/HUB-master/frontend`](/home/sandy/HUB-master/frontend)
|
||
|
||
This produced React/Axios/TanStack console output such as:
|
||
|
||
- `react-dom_client.js`
|
||
- `@tanstack/react-query`
|
||
- `axios`
|
||
- `/api/auth/refresh`
|
||
|
||
That was the old app, not the port.
|
||
|
||
Correct frontend:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend`](/home/sandy/HUB-master/django-port/frontend)
|
||
|
||
### 11.2 Backend editable install failed
|
||
|
||
Problem:
|
||
|
||
- `pip install -e .` failed because setuptools found multiple top-level packages in a flat layout
|
||
|
||
Fix:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/backend/pyproject.toml`](/home/sandy/HUB-master/django-port/backend/pyproject.toml) was patched with explicit package discovery/build config
|
||
|
||
### 11.3 Frontend install failed on Lucide version
|
||
|
||
Problem:
|
||
|
||
- `npm install` failed with:
|
||
- no matching version for `@lucide/svelte@^0.475.0`
|
||
|
||
Fix:
|
||
|
||
- removed the bad dependency from [`/home/sandy/HUB-master/django-port/frontend/package.json`](/home/sandy/HUB-master/django-port/frontend/package.json)
|
||
|
||
### 11.4 Importer product uniqueness failure
|
||
|
||
Problem:
|
||
|
||
- import hit `UNIQUE constraint failed: core_product.gtin, core_product.name`
|
||
|
||
Cause:
|
||
|
||
- duplicate products across the two legacy DBs
|
||
|
||
Fix:
|
||
|
||
- import logic now matches products by natural key `(gtin, name)` and maintains per-DB in-memory maps
|
||
|
||
### 11.5 Importer user primary key collision
|
||
|
||
Problem:
|
||
|
||
- import hit `UNIQUE constraint failed: accounts_user.id`
|
||
|
||
Cause:
|
||
|
||
- importer was effectively trying to preserve legacy IDs in a way that collided with already-created Django users
|
||
|
||
Fix:
|
||
|
||
- importer no longer forces legacy PKs onto Django user/role PKs
|
||
- users/roles are matched by natural keys instead
|
||
|
||
### 11.6 Importer reporting schema assumption was wrong
|
||
|
||
Problem:
|
||
|
||
- import crashed on `daily_revenue_summary` because expected key was missing
|
||
|
||
Cause:
|
||
|
||
- actual legacy reporting schema did not match the initial assumption
|
||
|
||
Fix:
|
||
|
||
- importer was patched to use the actual table shape
|
||
|
||
### 11.7 Auth failed due to redirect/405/trailing slash issues
|
||
|
||
Problem symptoms:
|
||
|
||
- `GET /api/auth/login/` got `405`
|
||
- `POST /api/auth/login` hit `APPEND_SLASH` runtime error
|
||
- API requests redirected to login instead of returning JSON
|
||
|
||
Fixes:
|
||
|
||
- API auth endpoints now use correct slash-normalized URLs
|
||
- frontend client normalizes paths
|
||
- unauthenticated API access now returns JSON `401`
|
||
|
||
### 11.8 CSRF/CORS/session local dev issues
|
||
|
||
Problem:
|
||
|
||
- local frontend auth still failed after path fixes
|
||
|
||
Fix:
|
||
|
||
- dev settings were patched to trust local frontend origins and support local cookie behavior
|
||
|
||
Primary file:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/backend/config/settings.py`](/home/sandy/HUB-master/django-port/backend/config/settings.py)
|
||
|
||
### 11.9 Sign-out button did not work
|
||
|
||
Problem:
|
||
|
||
- custom `Button` component was not forwarding click events properly
|
||
|
||
Fix:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/components/ui/button.svelte`](/home/sandy/HUB-master/django-port/frontend/src/lib/components/ui/button.svelte) was patched to dispatch click events
|
||
|
||
### 11.10 One syntax error during recent scoping work
|
||
|
||
Problem:
|
||
|
||
- a walrus assignment inside a boolean expression caused Python syntax trouble in `event_detail_view`
|
||
|
||
Fix:
|
||
|
||
- rewritten as separate assignment and check
|
||
|
||
`compileall` passed afterward.
|
||
|
||
## 12. What The User Already Validated
|
||
|
||
The user reported that the following looked good enough to continue:
|
||
|
||
- Django admin loads
|
||
- legacy import succeeded sufficiently for inspection
|
||
- frontend displays the new Svelte app
|
||
- invoices are populated
|
||
- sign out works after the button fix
|
||
- vendor/inventory/dashboard/business/events/settings/devices work well enough to continue
|
||
|
||
This matters because the port is past the initial bootstrapping phase.
|
||
|
||
## 13. Known Gaps And Risk Areas
|
||
|
||
### 13.1 Business access scoping is incomplete
|
||
|
||
This is the highest correctness gap and one of the three explicit remaining tasks from the user.
|
||
|
||
Areas that still need review or stronger implementation:
|
||
|
||
- `products_view`
|
||
- currently permission-scoped, but not clearly business-scoped
|
||
- products are global master data today, but the app likely expects business-aware visibility in some contexts
|
||
- `categories_view`
|
||
- same concern if categories should effectively be filtered by accessible business relationships
|
||
- `vendors_view`
|
||
- GET filtering only checks explicit `business_id` filter
|
||
- if no business filter is passed, user may still see vendors unrelated to allowed businesses
|
||
- `vendor_detail_view`
|
||
- direct vendor fetch does not currently deny access based on linked businesses
|
||
- `invoices_view`
|
||
- GET does not currently auto-scope invoice list to allowed businesses when no explicit business filter is passed
|
||
- `dashboard_overview_view`
|
||
- currently aggregates global invoices/revenue/vendor counts, not allowed-business-only counts
|
||
- `inventory_view`
|
||
- current scoping is a crude relationship chain through categories/vendors/businesses and should be treated as suspect
|
||
- likely needs a cleaner data model or explicit business linkage logic
|
||
- `notifications_view`
|
||
- verify whether notifications should be per-user only or also business-scoped
|
||
- `devices/settings`
|
||
- probably global admin surfaces by design, but confirm intended restrictions
|
||
|
||
Recommendation:
|
||
|
||
- audit every endpoint in [`/home/sandy/HUB-master/django-port/backend/apps/api/views.py`](/home/sandy/HUB-master/django-port/backend/apps/api/views.py)
|
||
- decide endpoint-by-endpoint whether the resource is:
|
||
- global admin-only
|
||
- business-scoped
|
||
- user-scoped
|
||
- then apply scoping consistently for both list and detail endpoints
|
||
|
||
### 13.2 Update/delete flows are incomplete
|
||
|
||
Explicit user-requested remaining work:
|
||
|
||
- user update/delete
|
||
- invoice update/delete
|
||
|
||
Current state:
|
||
|
||
- events update/delete exist
|
||
- devices delete exists
|
||
- token delete exists
|
||
- vendors update exists
|
||
- users are create-only
|
||
- invoices are create + list + detail only
|
||
|
||
### 13.3 UI layer is still temporary
|
||
|
||
Explicit user-requested remaining work:
|
||
|
||
- replace temporary UI primitives with real `shadcn-svelte`
|
||
|
||
Current state:
|
||
|
||
- visual layer is a usable stopgap
|
||
- actual generated `shadcn-svelte` primitives are not in place yet
|
||
- `components.json` exists, but the temporary primitives remain the active UI basis
|
||
|
||
### 13.4 API module is too large
|
||
|
||
`apps/api/views.py` is currently doing too much.
|
||
|
||
Not urgent compared with the three user-named priorities, but still true:
|
||
|
||
- payload serialization should move out
|
||
- route handlers should be slimmer
|
||
- business access logic should be centralized further
|
||
- per-domain modules would reduce risk
|
||
|
||
### 13.5 No robust automated verification
|
||
|
||
Current verification state:
|
||
|
||
- backend syntax check passed
|
||
- user manually inspected admin and major frontend pages
|
||
|
||
Missing:
|
||
|
||
- backend tests
|
||
- API tests
|
||
- frontend tests
|
||
- end-to-end checks
|
||
|
||
## 14. The Three Explicit Remaining Tasks From The User
|
||
|
||
The user explicitly said the next Codex still needs to:
|
||
|
||
1. finish business access scoping everywhere, especially inventory/product/vendor edge cases
|
||
2. add update/delete flows for users and invoices
|
||
3. replace the temporary UI primitives with real `shadcn-svelte`
|
||
|
||
Those should be treated as the authoritative next priorities.
|
||
|
||
## 15. Recommended Order For The Next Codex
|
||
|
||
Recommended order:
|
||
|
||
1. finish business access scoping first
|
||
2. add user/invoice update/delete flows second
|
||
3. replace temporary UI layer with `shadcn-svelte` third
|
||
4. only after that, consider refactoring `apps/api/views.py`
|
||
|
||
Reasoning:
|
||
|
||
- scoping is a correctness/security issue
|
||
- CRUD completion is functional completeness
|
||
- UI primitive replacement is important but less risky than wrong data exposure
|
||
|
||
## 16. Concrete Starting Points For The Next Codex
|
||
|
||
### 16.1 Start with backend scoping audit
|
||
|
||
Primary file:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/api/views.py`](/home/sandy/HUB-master/django-port/backend/apps/api/views.py)
|
||
|
||
Suggested first checks:
|
||
|
||
- make `dashboard_overview_view` scoped to allowed businesses
|
||
- make `vendors_view` default to allowed-business-only results when user is not superuser
|
||
- make `vendor_detail_view` deny access for vendors outside allowed businesses
|
||
- make `invoices_view` default to allowed-business-only results when user is not superuser
|
||
- rework `inventory_view` scoping so it is deterministic and understandable
|
||
- decide whether `products_view` and `categories_view` are global lookup tables or business-filtered lookups
|
||
|
||
### 16.2 Then add user update/delete
|
||
|
||
Likely backend addition:
|
||
|
||
- `GET/PUT/DELETE /api/settings/users/<id>/`
|
||
|
||
Likely frontend target:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/settings/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/settings/+page.svelte)
|
||
|
||
### 16.3 Then add invoice update/delete
|
||
|
||
Likely backend additions:
|
||
|
||
- `PUT /api/invoices/<id>/`
|
||
- `DELETE /api/invoices/<id>/`
|
||
|
||
Potential need:
|
||
|
||
- extend [`/home/sandy/HUB-master/django-port/backend/apps/operations/services.py`](/home/sandy/HUB-master/django-port/backend/apps/operations/services.py) so invoice create/update share calculation logic
|
||
|
||
Likely frontend target:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/invoices/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/invoices/+page.svelte)
|
||
|
||
### 16.4 Finally replace temporary UI with shadcn-svelte
|
||
|
||
Files to revisit:
|
||
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/components/ui/button.svelte`](/home/sandy/HUB-master/django-port/frontend/src/lib/components/ui/button.svelte)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/components/ui/card.svelte`](/home/sandy/HUB-master/django-port/frontend/src/lib/components/ui/card.svelte)
|
||
- route pages listed above
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/app.css`](/home/sandy/HUB-master/django-port/frontend/src/app.css)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/components.json`](/home/sandy/HUB-master/django-port/frontend/components.json)
|
||
|
||
The user was willing to run local install/init steps, so the next Codex can assume:
|
||
|
||
- any actual `npx shadcn-svelte@latest init`
|
||
- any `add` command
|
||
|
||
should be handed to the user if needed instead of run blindly.
|
||
|
||
## 17. Verification State At End Of Session
|
||
|
||
Current confidence level:
|
||
|
||
- medium for basic functionality
|
||
- lower for permission + scoping correctness
|
||
|
||
Verified enough to continue:
|
||
|
||
- Django project boots
|
||
- migrations/import succeeded locally
|
||
- admin is usable
|
||
- frontend is the new Svelte app
|
||
- major pages load
|
||
- invoice data shows up
|
||
- sign out works
|
||
|
||
Not verified:
|
||
|
||
- all CRUD edge cases
|
||
- all permission edge cases
|
||
- all business-scoping edge cases
|
||
- production-grade UI replacement
|
||
|
||
## 18. Short Pickup Summary
|
||
|
||
If another Codex needs the shortest possible summary:
|
||
|
||
- The Django + Svelte port in [`/home/sandy/HUB-master/django-port`](/home/sandy/HUB-master/django-port) is real and functional, not just scaffolded.
|
||
- Legacy data has been imported and admin works.
|
||
- The Svelte frontend has working routes for dashboard, business, invoices, vendors, inventory, events, schedule, settings, and devices.
|
||
- Auth, sessions, and permission-based sidebar gating are in place.
|
||
- The biggest unfinished work is:
|
||
- complete business access scoping
|
||
- add user/invoice update/delete
|
||
- replace temporary UI primitives with real `shadcn-svelte`
|
||
- Primary files to continue from are:
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/api/views.py`](/home/sandy/HUB-master/django-port/backend/apps/api/views.py)
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/api/urls.py`](/home/sandy/HUB-master/django-port/backend/apps/api/urls.py)
|
||
- [`/home/sandy/HUB-master/django-port/backend/apps/operations/services.py`](/home/sandy/HUB-master/django-port/backend/apps/operations/services.py)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/api/client.ts`](/home/sandy/HUB-master/django-port/frontend/src/lib/api/client.ts)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/lib/stores/auth.ts`](/home/sandy/HUB-master/django-port/frontend/src/lib/stores/auth.ts)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/settings/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/settings/+page.svelte)
|
||
- [`/home/sandy/HUB-master/django-port/frontend/src/routes/app/invoices/+page.svelte`](/home/sandy/HUB-master/django-port/frontend/src/routes/app/invoices/+page.svelte)
|
||
|