34 KiB
Session Handoff
Date: April 1, 2026
Workspace root: /home/sandy/HUB-master
Primary port target: /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 - 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
- old frontend root:
/home/sandy/HUB-master/frontend - old backend root:
/home/sandy/HUB-master/backend - legacy databases:
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:
Useful docs:
/home/sandy/HUB-master/django-port/docs/port-plan.md/home/sandy/HUB-master/django-port/docs/session-handoff-2026-04-01.md
5.2 Backend
Backend root:
Key files:
- Django entrypoint:
- package config:
- settings:
- root URLs:
- local database file:
Backend apps:
- accounts:
- core:
- operations:
- reporting:
- notifications:
- API:
5.3 Frontend
Frontend root:
Key config files:
/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/svelte.config.js/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/components.json
Frontend shared files:
- global styles:
- API client:
- auth store:
- shared types:
- shell/sidebar:
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/card.svelte
Routes:
- shell:
- login:
- protected app:
- dashboard:
- business:
- invoices:
- vendors:
- inventory:
- events:
- schedule:
- settings:
- devices:
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:
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_forbiddenapi_login_requiredrequire_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 - 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:
7.2 API client
The frontend uses fetch, not axios, in:
Key client behaviors:
VITE_API_BASEdefaults tohttp://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:
Key behaviors:
bootstrapAuth()loads current user via/api/auth/me/authReadygates renderinghasPermission()checks permission keys and superuser bypassclearAuth()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.ts
Login route:
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.svelteandcard.svelteare custom placeholderscomponents.jsonexists, butshadcn-sveltehas 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:
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_summaryschema 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:
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.managedashboard.viewevents.createevents.deleteevents.editevents.viewinventory.adjustinventory.stock_countinventory.viewinvoices.createinvoices.deleteinvoices.editinvoices.mark_paidinvoices.viewproducts.createproducts.editproducts.viewshifts.availabilityshifts.manageshifts.viewusers.managevendors.createvendors.deletevendors.editvendors.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:
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:
Commands used during the session:
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:
Commands used:
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:
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:
This produced React/Axios/TanStack console output such as:
react-dom_client.js@tanstack/react-queryaxios/api/auth/refresh
That was the old app, not the port.
Correct 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.tomlwas patched with explicit package discovery/build config
11.3 Frontend install failed on Lucide version
Problem:
npm installfailed with:- no matching version for
@lucide/svelte@^0.475.0
- no matching version for
Fix:
- removed the bad dependency from
/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_summarybecause 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/got405POST /api/auth/loginhitAPPEND_SLASHruntime 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:
11.9 Sign-out button did not work
Problem:
- custom
Buttoncomponent was not forwarding click events properly
Fix:
/home/sandy/HUB-master/django-port/frontend/src/lib/components/ui/button.sveltewas 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_idfilter - if no business filter is passed, user may still see vendors unrelated to allowed businesses
- GET filtering only checks explicit
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 - 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-svelteprimitives are not in place yet components.jsonexists, 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:
- finish business access scoping everywhere, especially inventory/product/vendor edge cases
- add update/delete flows for users and invoices
- 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:
- finish business access scoping first
- add user/invoice update/delete flows second
- replace temporary UI layer with
shadcn-sveltethird - 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:
Suggested first checks:
- make
dashboard_overview_viewscoped to allowed businesses - make
vendors_viewdefault to allowed-business-only results when user is not superuser - make
vendor_detail_viewdeny access for vendors outside allowed businesses - make
invoices_viewdefault to allowed-business-only results when user is not superuser - rework
inventory_viewscoping so it is deterministic and understandable - decide whether
products_viewandcategories_vieware 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:
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.pyso invoice create/update share calculation logic
Likely frontend target:
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/card.svelte- route pages listed above
/home/sandy/HUB-master/django-port/frontend/src/app.css/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
addcommand
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-portis 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/urls.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/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/invoices/+page.svelte