Architecture Overview
Every Oidis application follows the same architectural principles: a clear frontend/backend split within a single TypeScript project, a namespace-driven filesystem, and a layered dependency chain that promotes code reuse.
Frontend / Backend Split
An Oidis project contains both server-side and client-side code in a single repository. The split is determined by directory structure:
source/typescript/Io/Oidis/YourProject/
├── Models/ # ← Backend (Node.js)
├── Utils/ # ← Backend
├── HttpProcessor/ # ← Backend
├── Connectors/ # ← Backend
├── Interfaces/ # ← Shared
├── Loader.ts # ← Backend entry point
├── ForceCompile.ts # ← Backend compile manifest
│
└── Gui/ # ← Frontend (Browser)
├── Models/ # ← Frontend models
├── Pages/ # ← Frontend page layouts
├── Panels/ # ← Frontend panel views
├── Controllers/ # ← Frontend controllers
├── Connectors/ # ← Frontend RPC stubs
├── Stores/ # ← Frontend state
├── Loader.ts # ← Frontend entry point
└── ForceCompile.ts # ← Frontend compile manifest
The rule is simple: everything under Gui/ runs in the browser. Everything else runs on the server. The Interfaces/ directory can contain types shared by both sides.
Each side has its own Loader.ts that bootstraps the application — registering classes, setting up symbol mappings, and initializing the runtime environment.
Large Project Variant: Separate GUI Repository
In smaller projects, Gui/ is a subdirectory of the same repository. In larger projects — Hub, Home, and Studio — the Gui/ subtree lives in a separate git repository (io-oidis-hub-gui, io-oidis-home-gui, io-oidis-studio-gui) declared as a dependency in package.conf.jsonp.
io-oidis-hub/ ← Backend repository
├── source/typescript/.../ ← BE code
└── dependencies/
└── io-oidis-hub-gui/ ← Frontend repo (cloned by oidis install, gitignored)
io-oidis-hub-gui/ ← Frontend repository (standalone, noServer: true)
└── source/typescript/.../Gui/ ← FE code only
This hard separation prevents native Node.js imports from accidentally reaching the browser bundle. The GUI repo has noServer: true in its package.conf.jsonp and produces only a browser bundle. The backend serves this bundle via its FrontEndLoader.ts resolver.
The developer workflow for editing GUI code in this pattern (using IntelliJ Compare or Beyond Compare to sync changes between the dependencies/ context and the standalone clone) is covered in detail in Separate GUI Repository. For the complete cross-repo workflow including merge pitfalls, reverse sync, and Claude Code automation, see Cross-Repository Workflow.
Namespace Convention
Oidis uses a Java/C#-style namespace convention reflected in the filesystem:
Io/Oidis/[LibraryName]/[SubModule]/[ClassName].ts
For example:
Io/Oidis/YourProject/Models/ProductRecord.ts→ namespaceIo.Oidis.YourProject.ProductRecordIo/Oidis/Hub/Utils/AuthManager.ts→ namespaceIo.Oidis.Hub.AuthManager
This namespace is used throughout the framework for:
- LCP routing — Backend classes are resolved by namespace string
- Symbol mapping —
Loader.setSymbolMapping()creates aliases - Configuration — JSONP config files reference classes by namespace
Dependency Chain
Oidis projects are built on a layered dependency chain. Each layer adds functionality:
io-oidis-commons ← Core utilities, decorators, BaseModel
↓
io-oidis-services ← Backend services, DAO layer, connectors base
↓
io-oidis-gui ← BasePanel, EventsBinding, GuiCommons
↓
io-oidis-usercontrols ← Button, TextField, Table, Dialog, Toast, ...
↓
io-oidis-localhost ← @Extern, @Route, local system connectors
↓
io-oidis-hub ← Hub backend (AuthManager, SystemLog, DB context)
↓
io-oidis-hub-gui ← Hub frontend (BasePanelController, Convert, base panels)
↓
io-oidis-[your-project] ← Your application
Key principle: Lower layers know nothing about higher layers. A utility in io-oidis-commons cannot import from io-oidis-hub. Dependencies flow strictly downward.
What Each Layer Provides
| Package | Key Exports |
|---|---|
io-oidis-commons | BaseModel<T>, @Entity, @Property, @Resolver, @Partial, LogIt, ObjectValidator, StringUtils, JsonUtils, Convert, Echo, Stopwatch, Reflection, Counters — see Utilities Overview |
io-oidis-services | BaseConnector (backend), DAO abstractions, FileFetch |
io-oidis-gui | BasePanel, EventsBinding, GuiCommons, ElementEventsManager, data-oidis-bind system |
io-oidis-usercontrols | Button, TextField, Label, DropDownList, Table<T>, Dialog, Toast, CheckBox, ValidationBinding, DialogBinding |
io-oidis-localhost | @Extern, @Route, BaseConnector (extended), LiveContentResolver |
io-oidis-hub | AuthManager, SystemLog, MongoContext, Threads, ConnectorsRegister |
io-oidis-hub-gui | BasePanelController, BasePageController, Convert, hub base panels |
Import Conventions
Imports always use package aliases with .js extensions:
import { LogIt } from "@io-oidis-commons/.../Utils/LogIt.js";
import { BasePanel } from "@io-oidis-gui/.../BasePanel.js";
import { BasePanelController } from "@io-oidis-hub-gui/.../BasePanelController.js";
For files within the same project, use relative imports:
import { ProductRecord } from "../../Models/ProductRecord.js";
import { InventoryManagerConnector } from "../../Connectors/InventoryManagerConnector.js";
The Loader System
Each side of an Oidis application has a Loader.ts that serves as the bootstrap entry point.
Backend Loader
The backend Loader typically:
- Extends the parent hub Loader
- Sets up
ConnectorsRegistersymbol mappings (namespace aliases) - Registers backend-specific services
- Initializes database connections
// Simplified example — real loaders extend hub Loader
export class Loader extends HubLoader {
public constructor() {
super();
// Map namespace aliases for LCP resolution
ConnectorsRegister.setSymbolMapping(
"*.AuthManager",
"Io.Oidis.YourProject.Utils.AuthManager"
);
}
}
Frontend Loader (Gui/Loader.ts)
The frontend Loader:
- Extends the hub-gui Loader
- Registers frontend-specific classes
- Initializes the GUI environment
Both Loaders inherit from their respective parent layers and add project-specific registrations on top.
ForceCompile.ts
Each side also has a ForceCompile.ts file that ensures certain classes are included in the compiled output even when they have no direct import chain. This is essential for:
- LCP-referenced classes — Backend connectors called via
@Externmust be compiled even though no frontend code directly imports them - Dynamically resolved classes — Any class found by namespace string at runtime
// ForceCompile.ts — ensures these classes are in the bundle
import { AuthManager } from "./Utils/AuthManager.js";
import { InventoryManager } from "./Utils/InventoryManager.js";
// generated-code-start
// Builder auto-generates additional imports here
// NEVER edit between these markers
// generated-code-end
The section between generated-code-start and generated-code-end markers is managed by the Oidis Builder. Manual edits in this section will be overwritten on the next build.
Configuration Layer
The JSONP configuration system — including extendsConfig, imports, and how the Builder generates standard files — is covered in detail in JSONP System.
Oidis projects use a JSONP-based configuration system instead of standard package.json:
package.conf.jsonp— Source of truth for project identity, dependencies, build settingscommons.jsonp— Runtime configuration (database, auth, APIs)licensesRegister.jsonp— Software Content Register entries
The Builder reads these files and generates package.json, tsconfig.json, webpack.config.js, and other standard files. See JSONP System for details.
Build Process
Oidis uses its own build toolchain (Oidis Builder) rather than raw tsc or webpack:
oidis install— Resolves JSONP dependencies, generates config files, installs npm packagesoidis rebuild— Compiles TypeScript, processes SCSS, bundles frontend assetsoidis test— Runs unit tests, Selenium tests, and linting
The Builder handles:
- JSONP → JSON generation (package.json, tsconfig.json, etc.)
extendsConfig/importsresolution (config inheritance and composition)- TypeScript compilation with project-specific settings
- SCSS compilation with theme support
dev:start/dev:endmarker stripping in production builds- Copyright header validation
- Software Content Register generation
Two GUI Systems
The Oidis GUI layer contains two systems: the Bootstrap 5 system (modern, active) and the legacy system (deprecated). All new development must use the Bootstrap 5 system. The legacy system exists for backward compatibility of older projects only.
See Bootstrap 5 vs Legacy for a full comparison, how to identify each, and migration guidance.
Summary
| Concept | Description |
|---|---|
| FE/BE split | Gui/ = browser, everything else = server |
| Separate GUI repo | Large projects (Hub, Home, Studio) keep GUI in a separate git repo — see Separate GUI Repository |
| Cross-repo workflow | Forward and reverse sync between dependencies/ and standalone clones — see Cross-Repository Workflow |
| Namespace | Io.Oidis.[Library].[Class] mirrored in filesystem |
| Dependencies | Layered chain: commons → services → gui → hub → project |
| Two GUI systems | Bootstrap 5 (active) and Legacy (deprecated) — see Bootstrap 5 vs Legacy |
| Loaders | Bootstrap entry points for each side |
| ForceCompile | Ensures dynamically-resolved classes are compiled |
| JSONP config | Source of truth; Builder generates standard files |
| Builder | Custom toolchain for install, build, test, deploy |
| Request Forwarding | Hub acts as reverse proxy for agents behind firewalls via WebSocket tunneling — see Request Forwarding |
| User Profile | Per-user data and preferences (avatar, personal info, 2FA) with admin and self-service interfaces — see User Profile |
| UserContext | Runtime session object holding auth state, user identity, group flags, and device info — see UserContext |
| System Groups | Group-based authorization with predefined roles, wildcard method patterns, and extensible permissions — see System Groups |
| HttpProcessor (Services) | Services-level HTTP layer: JRE-aware HttpManager, DAO-based page controllers, auth/error pages — see HttpProcessor Services |
| Connectors Reference | Comprehensive reference for BaseConnector, transport clients, and all frontend connectors — see Connectors Reference |
| io-oidis-localhost | Core server runtime — HTTP server, routing, connectors, response API, and backend utilities — see Localhost Overview |
| HTTP Processing Pipeline | Request processing chain from raw socket through HttpServer, HttpManager, and HttpResolver — see HTTP Processing Pipeline |
| Response API | Typed HTTP response handlers — REST, Stream, LiveContent, WebSocket, and Callback — see Response API |
| LCP Protocol Internals | Wire format, response deserialization, error propagation, event polling, and callback chain — see LCP Protocol Internals |
See also: Bootstrap 5 vs Legacy | Page-Panel-Controller | Separate GUI Repository | JSONP System | Framework Overview