Commit Graph

171 Commits

Author SHA1 Message Date
Forbes
fc0eb6d2be feat: add sourcing type, extended fields, and inline project tagging
- Add migration 009: sourcing_type (manufactured/purchased), sourcing_link,
  long_description, and standard_cost columns on items table
- Update Item struct, repository queries, and API handlers for new fields
- Add sourcing badge, long description block, standard cost, and sourcing
  link display to item detail panel
- Add inline project tag editor in detail panel (add/remove via dropdown)
- Add new fields to create and edit modals
- Update CSV import/export for new columns
- Merge with auth CreatedBy/UpdatedBy changes from stash
2026-01-31 14:27:11 -06:00
Forbes
0888c0210c fix(deploy): add database migration step and auth env vars
Add run_migrations function to deploy.sh that automatically applies
pending SQL migrations during deployment. Migrations are run after
config installation and before service restart.

Migration runner:
- Sources /etc/silo/silod.env for SILO_DB_PASSWORD
- Reads DB host/port/name/user from production config.yaml
- Waits for database connectivity (5 retries)
- Applies each migration file in order, skipping already-applied ones
- Gracefully degrades if psql is missing or DB password is not set

This fixes the missing migration 009 (auth tables) that caused:
- 'column created_by of relation projects does not exist'
- 'relation api_tokens does not exist'

Also adds auth environment variables to silod.env.example:
- SILO_SESSION_SECRET
- SILO_ADMIN_USERNAME / SILO_ADMIN_PASSWORD
- SILO_OIDC_CLIENT_SECRET, SILO_LDAP_BIND_PASSWORD
2026-01-31 12:09:17 -06:00
Forbes
4f0107f1b2 feat(auth): add authentication, RBAC, API tokens, and default admin
Add a complete authentication and authorization system to Silo with
three pluggable backends (local bcrypt, LDAP/FreeIPA, OIDC/Keycloak),
session management, API token support, and role-based access control.

Authentication backends:
- Local: bcrypt (cost 12) password verification against users table
- LDAP: FreeIPA simple bind with group-to-role mapping
- OIDC: Keycloak redirect flow with realm role mapping
- Backends are tried in order; users upserted to DB on first login

Session and token management:
- PostgreSQL-backed sessions via alexedwards/scs + pgxstore
- Opaque API tokens (silo_ prefix, SHA-256 hashed, shown once)
- 24h session lifetime, HttpOnly/SameSite=Lax/Secure cookies

Role-based access control (admin > editor > viewer):
- RequireAuth middleware: Bearer token -> session -> redirect/401
- RequireRole middleware: per-route-group minimum role enforcement
- CSRF protection via justinas/nosurf on web forms, API exempt
- CORS locked to configured origins when auth enabled

Route restructuring:
- Public: /health, /ready, /login, /auth/oidc, /auth/callback
- Web (auth + CSRF): /, /projects, /schemas, /settings
- API read (viewer): GET /api/**
- API write (editor): POST/PUT/PATCH/DELETE /api/**

User context wiring:
- created_by/updated_by columns on items, projects, relationships
- All create/update handlers populate tracking fields from context
- CSV and BOM import handlers pass authenticated username
- Revision creation tracks user across all code paths

Default admin account:
- Configurable via auth.local.default_admin_username/password
- Env var overrides: SILO_ADMIN_USERNAME, SILO_ADMIN_PASSWORD
- Idempotent: created on first startup, skipped if exists

CLI and FreeCAD plugin:
- silo token create/list/revoke subcommands (HTTP API client)
- FreeCAD SiloClient sends Bearer token on all requests
- Token read from ApiToken preference or SILO_API_TOKEN env var

Web UI:
- Login page (Catppuccin Mocha themed, OIDC button conditional)
- Settings page with account info and API token management
- User display name, role badge, and logout button in header
- One-time token display banner with copy-to-clipboard

Database (migration 009):
- users table with role, auth_source, oidc_subject, password_hash
- api_tokens table with SHA-256 hash, prefix, expiry, scopes
- sessions table (scs pgxstore schema)
- audit_log table (schema ready for future use)
- created_by/updated_by ALTER on items, relationships, projects

New dependencies: scs/v2, scs/pgxstore, go-oidc/v3, go-ldap/v3,
justinas/nosurf, golang.org/x/oauth2
2026-01-31 11:20:12 -06:00
Forbes
a5fba7bf99 Add Silo mode toggle, SSL cert browsing, and BOM menu integration
- Silo_ToggleMode: checkable toolbar button that swaps Ctrl+O/S/N
  between standard FreeCAD file commands and Silo equivalents
- _swap_shortcuts() helper stores/restores original QAction shortcuts
- SSL settings: add CA certificate file browser (SslCertPath preference)
  with QFileDialog for .pem/.crt/.cer, loaded in _get_ssl_context()
- Integrate Silo_BOM into workbench toolbar (after upstream BOM merge)
- Add Silo_ToggleMode to toolbar as first item with separator
2026-01-31 09:21:48 -06:00
Forbes
7550b78740 feat: Infor-style split-panel layout, projects page, fuzzy search, Odoo scaffold
Web UI - Infor CloudSuite-style split-panel layout (items.html rewrite):
- Replace modal-based item detail with inline split-panel workspace
- Horizontal mode: item list on left, tabbed detail panel on right
- Vertical mode: detail panel on top, item list below
- Detail tabs: Main, Properties, Revisions, BOM, Where Used
- Ctrl+F opens in-page filter overlay with fuzzy search
- Column config gear icon with per-layout-mode persistence
- Search scope toggle pills (All / Part Number / Description)
- Selected row highlight with accent border
- Responsive breakpoint forces vertical below 900px
- Create/Edit/Delete remain as modal dialogs

Web UI - Projects page:
- New projects.html template with full CRUD
- Project table: Code, Name, Description, Item count, Created, Actions
- Create/Edit/Delete modals
- Click project code navigates to items filtered by project
- 3-tab navigation in base.html: Items, Projects, Schemas

Fuzzy search:
- Add sahilm/fuzzy dependency for ranked text matching
- New internal/api/search.go with SearchableItems fuzzy.Source
- GET /api/items/search endpoint with field scope and type/project filters
- Frontend routes to fuzzy endpoint when search input is non-empty

Odoo ERP integration scaffold:
- Migration 008: integrations and sync_log tables
- internal/odoo/ package: types, client stubs, sync stubs
- internal/db/integrations.go: IntegrationRepository
- internal/config/config.go: OdooConfig struct
- 6 API endpoints for config CRUD, sync log, test, push, pull
- All sync operations return stub responses

Documentation:
- docs/REPOSITORY_STATUS.md: comprehensive repository state report
  with architecture overview, API surface, feature stubs, and
  potential issues analysis
2026-01-31 09:20:27 -06:00
Forbes
1518cbc299 Add BOM handling and routes to API and web UI 2026-01-31 08:38:02 -06:00
Forbes
a2a36141f0 feat: add BOM system with API, database repository, and FreeCAD workbench command
Implement the full Bill of Materials stack on top of the existing
relationships table and bom_single_level view from migration 001.

API endpoints (6 new routes under /api/items/{partNumber}/bom):
- GET    /bom              Single-level BOM for an item
- GET    /bom/expanded     Multi-level BOM via recursive CTE (depth param)
- GET    /bom/where-used   Reverse lookup: which parents use this item
- POST   /bom              Add child to BOM with quantity, ref designators
- PUT    /bom/{child}      Update relationship type, quantity, ref des
- DELETE /bom/{child}       Remove child from BOM

Database layer (internal/db/relationships.go):
- RelationshipRepository with full CRUD operations
- Single-level BOM query joining relationships with items
- Multi-level BOM expansion via recursive CTE (max depth 20)
- Where-used reverse lookup query
- Cycle detection at insert time to prevent circular BOMs
- BOMEntry and BOMTreeEntry types for denormalized query results

Server wiring:
- Added RelationshipRepository to Server struct in handlers.go
- Registered BOM routes in routes.go under /{partNumber} subrouter

FreeCAD workbench (pkg/freecad/silo_commands.py):
- 9 new BOM methods on SiloClient (get, expanded, where-used, add,
  update, delete)
- Silo_BOM command class with two-tab dialog:
  - BOM tab: table of children with Add/Edit/Remove buttons
  - Where Used tab: read-only table of parent assemblies
- Add sub-dialog with fields for part number, type, qty, unit, ref des
- Edit sub-dialog pre-populated with current values
- Remove with confirmation prompt
- silo-bom.svg icon matching existing toolbar style
- Command registered in InitGui.py toolbar

No new migrations required - uses existing relationships table and
bom_single_level view from 001_initial.sql.
2026-01-31 08:09:26 -06:00
Forbes
8b66274a7a Fix SIGSEGV: defer document open after dialog close
Opening documents (especially assemblies) inside the QDialog nested
event loop can crash FreeCAD when the Assembly solver triggers during
document restore. Move FreeCAD.openDocument() to after dialog.exec_()
returns.
2026-01-29 22:42:15 -06:00
Forbes
b200fd06bc Fix API URL: only auto-append /api for bare hostnames
Use urllib.parse to check if the URL has a path component. Only append
/api when the path is empty (e.g. https://silo.kindred.internal).
URLs that already include a path (e.g. http://localhost:8080/api) are
left unchanged. Restore localhost placeholder as the default.
2026-01-29 22:27:10 -06:00
Forbes
383e750a6d Fix API URL handling and SSL certificate verification
- Auto-append /api to base URL if not already present, so users can
  enter just the hostname (e.g. https://silo.kindred.internal)
- Load system CA certificate bundle in SSL context so the bundled
  Python trusts internal CAs (FreeIPA) without disabling verification
- Update settings dialog placeholder and hint text to clarify expected
  URL format
2026-01-29 22:26:26 -06:00
Forbes
bdccb8923d feat(workbench): fix icon loading and add settings dialog
Replace hardcoded FreeCAD addon path searches with __file__-relative
resolution for icons in both InitGui.py and silo_commands.py. Icons now
load correctly regardless of install location.

Add Silo_Settings command with URL and SSL verification fields. Settings
persist via FreeCAD preferences and take priority over env vars. Wire
SSL context into all SiloClient HTTP methods.
2026-01-29 19:28:11 -06:00
Forbes
f39aef0fc7 update documentation and specs 2026-01-29 13:10:12 -06:00
Forbes
d886a44288 update deploy.sh 2026-01-26 22:43:39 -06:00
Forbes
687e645deb improve csv import handling 2026-01-26 21:51:07 -06:00
Forbes
be222307bb add free-ipa setup 2026-01-26 21:37:53 -06:00
Forbes
5201b35d83 update deployment 2026-01-26 21:32:57 -06:00
Forbes
f37052c2f0 update deployment instructions 2026-01-26 21:31:49 -06:00
Forbes
f9324686c5 Add roadmap and deployment examples 2026-01-26 06:06:21 -06:00
Forbes
b396097715 Add revision control and project tagging migration 2026-01-24 16:27:18 -06:00
Forbes
c327baf36f update databasing system with minimum API, schema parsing and FreeCAD
integration
2026-01-24 15:03:17 -06:00
Forbes
eafdc30f32 first commit 2026-01-18 12:08:14 -06:00