Commit ab1d1cac by Mac Stephens

Document WC migration progress and upcoming BFD integration

parent b86cbd6d
# emiMobile shared server planning
Last updated: October 17, 2026.
## Status
Client relocation and separate static outputs are complete; the user confirmed both clients work. BFD's missing buffalooutline.geojson project/deployment entry was added. WC startup now reads normalized [Application] Client from its INI: WC is supported; missing/unknown clients and BFD stop service startup with a clear log message. WC's web root is derived from the executable directory as static/WC, and its JSON override was removed. The local WC INI has Client=WC. This server change compiled successfully as Win32 Debug into a temporary output folder; the user verified startup behavior. BFD's separate server remains unchanged and uses its JSON web-root configuration. WC response-builder extraction and the shared client boundary are implemented; shared-server Oracle support is still pending.
## Latest implementation checkpoint
- The user verified the previous WC response-builder extraction at runtime.
- Core/Server/Client.Data.pas now defines TClientData, the abstract CAD operations used by the API and WebSocket data model. It also covers connection checks, worker query timeouts, and update-listener operations.
- Core/Server/Client.Selection.pas centralizes ValidateClient and CreateClientData. Startup and creation use the same validation: only WC is supported; missing/unknown clients and BFD retain their existing error messages. No default fallback.
- TWCAPIData implements TClientData and owns its TWCAPIDataModule. API requests, the main-thread notification listener, and the WebSocket worker each get their own instance. The worker creates and frees its instance on its own thread; the listener is freed after the worker stops.
- Api.ServiceImpl and Ws.DataModel no longer reference WC units/classes directly. The six existing worker timeout settings moved into WC.Api.Data without changing their values.
- CAD response methods, API authorization/device logic, WebSocket payloads, and the database PAS/DFM are unchanged from the runtime-verified checkpoint. JSON remains caller-owned; the API registers it with XData and WebSocket callers free it after serialization.
- Win32 Debug compilation succeeded into a temporary folder. Static baseline comparisons passed. The user confirmed the boundary step works after runtime testing on October 17, 2026.
- BFD integration and database-platform device/authentication storage separation remain pending. Existing standalone BFD server is unchanged.
## Agreed architecture
- Keep WC and BFD in one emiMobile repository.
- Use one server project producing one configurable emiMobileServer.exe.
- Continue separate deployments: each running instance serves one client, selected at startup. This is not a single process serving multiple clients simultaneously.
- Select the client in the executable's INI file using [Application] Client=WC or Client=BFD. Use Client, not Department or Version.
- Missing or unrecognized Client must stop startup with a clear error; do not default to WC.
- WC remains on PostgreSQL. BFD remains on Oracle.
- The user clarified that BFD and BPD currently use Oracle, while other clients use PostgreSQL. Clients sharing a database platform can still have slight to substantial query/business differences. BPD has not been reviewed in this repository discussion and its implementation is not yet in scope.
- Initial implementation scope is explicitly WC and BFD only. BPD was an example, not a request to include it.
- No .groupproj is required for the target layout. Client projects are named wcEmiMobile.dproj/.dpr and bfdEmiMobile.dproj/.dpr.
- PostgreSQL client CAD schemas are very similar, with small differences including column names. The user estimates BPD/BFD queries are about 98 percent alike, with differences such as police/fire unit behavior. Do not equate shared SQL with identical client behavior.
- Application data, including device registrations and verification state, belongs in each client's existing database. Do not introduce PostgreSQL for BFD application data.
- Client deployments run on completely different server machines.
- Add Oracle device-registration storage matching PostgreSQL's fields and behavior wherever practical, with appropriate Oracle types and SQL. Exact schema/login details can be confirmed during database implementation.
- Client determines the served web folder automatically; JSON must not independently select a conflicting client folder.
- Deploy only the selected client's web output alongside the server executable.
- BFD must receive WC's newer authentication, device registration/management, and live-update functionality.
- Build web clients into separate static subdirectories, such as static/WC and static/BFD. Unique JavaScript names alone are insufficient because templates, config files, styles, and assets share names.
- Preserve genuine client differences: WC agency/officer behavior and BFD station, manpower, movement, and incident-status behavior.
- The user reports deleting the extra emiMobile_BFD/Source folder as an obsolete copy. BFD's server project references emiMobile_BFD/emiMobileServer/Source.
- Users, Edit User, User Profile, and the older Admin screens are not used today. Do not treat them as required shared features; deletion has not been authorized.
## Working proposal, not yet finalized
- The concrete target layout is documented in FOLDER-LAYOUT.md. Client web relocation, static outputs, WC INI selection, WC database/response-builder separation, and Client.Data/Client.Selection are implemented; the remaining shared units and Oracle integration are still pending.
- Use the clearer proposed name Client.Selection.pas instead of Client.Factory.pas for central implementation selection/creation; no factory framework is intended.
- Organize shared server code and client-specific implementations under one server directory, alongside web client projects and their shared source.
- Keep unrelated existing JSON hosting settings initially; INI gains Client and retains connection settings. Derive the web folder from Client.
- Select the appropriate database/data implementation centrally during startup, preserving UniDAC designer modules and queries.
- Share common authentication and WebSocket behavior while isolating Oracle/PostgreSQL persistence and client CAD rules.
- Proposed refinement: use one CAD/API database module per client, retaining consistent query names within each module. Share application-storage queries by database platform where device-registration schemas and behavior actually match. Do not group all client CAD queries into one Oracle or PostgreSQL module solely because they use the same provider.
- Consider one set of response-building methods per client reused by HTTP and WebSocket paths; both currently construct similar payloads separately.
- Make incremental changes and verify both clients after each coherent step.
## Important findings from source review
- Current web source: emiMobileServer/Clients/WC/Web and emiMobileServer/Clients/BFD/Web. Server source remains emiMobileServer and emiMobile_BFD/emiMobileServer.
- BFD is an older copy with genuine customizations mixed with missing later WC improvements. Do not blindly replace either implementation with the other.
- WC device persistence is directly coupled to PostgreSQL in authentication, API device/access methods, and WebSocket authentication. Sharing files alone does not add Oracle support.
- Client form behavior spans .pas, .dfm, and .html. List card templates and persistent dataset fields are defined in .dfm files.
- Both web projects currently target their server's bin/static directory. The concrete layout proposal preserves emiMobileServer/bin/static and adds WC/BFD subdirectories; this remains a proposal for review.
- WebSocket server port is currently hardcoded as 8091. Confirmed separate server machines mean no cross-client port conflict needs solving for this design.
- BFD has its own nested Git repository and is reported as untracked by the outer repository. Preserve its history deliberately when consolidating; no Git restructuring has been authorized.
- WC's group project references webEmiMobile.dproj, while its current web project is wcEmiMobile.dproj.
- Review was static source analysis, not a successful build or a live database test.
## Questions to resolve
1. Agree on the server boundary: shared services call a small common set of data operations; separate WC and BFD UniDAC data modules retain client queries and persistent fields. This is a proposal pending discussion.
2. Agree on client map separation: share common map lifecycle/update behavior where practical, while preserving client popup/status/marker/layer differences. No map refactoring has been approved yet.
3. Confirm final directory layout and how to preserve BFD Git history before moving files.
4. Confirm Oracle version/schema details when preparing migrations, and verify the complete application-storage requirements beyond the device-registration table.
## Scope preferences
Keep changes minimal and consistent with existing Delphi/TMS conventions. Explain existing flow and the intended change before editing application code. Avoid broad abstractions, scattered client conditionals, unrelated cleanup, and premature restructuring. The user is still choosing the plan.
# emiMobile Current Progress
October 17, 2026
## What we're doing
We're moving toward one emiMobile server project with shared code and separate pieces for each client. Each client will still run on its own server machine. The INI will tell the server which client it is running and which web folder to use.
WC will stay on PostgreSQL and BFD will stay on Oracle. Device registrations and verification data will go in each client's existing database. The queries will stay in the UniQueries in each client's database module.
## What we've done
- Created the `core-and-clients` branch and preserved a backup of the starting point.
- Moved both web projects under the main server directory, with separate WC and BFD folders. The projects are named `wcEmiMobile` and `bfdEmiMobile`.
- Set up separate `static/WC` and `static/BFD` build folders. Both clients built and worked after the move. We also fixed the missing BFD map boundary file.
- Added `Client` to the server INI. It determines the web folder, and the server stops startup if the setting is missing or unrecognized.
- Moved WC's database module into its client folder, keeping its existing queries and fields intact.
- Moved WC's response-building code into `WC.Api.Data`. The API and WebSocket updates now use the same methods instead of maintaining two copies of that logic.
- Added `Client.Data` and `Client.Selection`. The API and WebSocket code now call the shared operations, and the selection code creates the client implementation. Right now, WC is the only implementation wired up.
## Where we are
WC is working after the database, response-building, and shared client-selection changes. The server compiled successfully, and I tested the latest changes and confirmed they work.
BFD still uses its existing Oracle server. We haven't connected it to the common server yet.
## What's next
Next we'll start bringing BFD into the same structure. That includes its Oracle queries and the Oracle tables/storage needed for the newer device registration and authentication features.
After that, we can connect BFD to the shared server functionality and bring its web client up to date, while keeping the things that are different for BFD, especially the maps, markers, and fire-specific information.
We're doing this in pieces so we can keep building and testing as we go. The basic structure is in place now, but the BFD integration and the rest of the shared web/authentication work are still ahead.
# Proposed emiMobile folder and unit layout
Planning specification, October 16, 2026. The client web projects have been moved to Clients/WC/Web and Clients/BFD/Web, and BFD's project has been renamed bfdEmiMobile. Both relocated projects built successfully per the user. Output settings now target bin/static/WC and bin/static/BFD, and the existing separate servers' JSON web roots point to those locations. These output changes still require rebuild/runtime verification. All other separation below remains the proposed target.
## Repository structure
```text
emiMobile/
README.md
CORE-PLAN.md
FOLDER-LAYOUT.md
emiMobileServer/
emiMobileServer.dpr
emiMobileServer.dproj
Core/
Server/
Main.pas / .dfm
Common.Ini.pas
Common.Config.pas
Common.Logging.pas
Common.Middleware.Logging.pas
Api.Service.pas
Api.ServiceImpl.pas
Api.Server.Module.pas / .dfm
Auth.Service.pas
Auth.ServiceImpl.pas
Auth.Server.Module.pas / .dfm
App.Server.Module.pas / .dfm
WebSocket.Manager.pas
Ws.DataModel.pas
Ws.Server.Module.pas / .dfm
Webauthn.Cbor.pas
Webauthn.Crypto.pas
Client.Data.pas [new]
Client.Selection.pas [new]
Device.Store.pas [new]
shared/
BaseRequest.pas
LoginRequest.pas
Pkg.Json.DTO.pas
WsMessages.pas
utils/
DTOGeneratorUtils.pas
Web/
App.Config.pas
App.Types.pas
Auth.Service.pas
ConnectionModule.pas / .dfm
Module.Websocket.pas / .dfm
Utils.pas
Paginator.Plugins.pas
View.Main.pas / .dfm / .html
View.Login.pas / .dfm / .html
View.DeviceRegistration.pas / .dfm / .html
View.DeviceManager.pas / .dfm / .html
View.ErrorPage.pas / .dfm / .html
css/
app.css
spinner.css
Database/
PostgreSQL/
PostgreSQL.Device.Database.pas / .dfm [new]
Migrations/
[reviewed application-schema SQL]
Oracle/
Oracle.Device.Database.pas / .dfm [new]
Migrations/
[equivalent Oracle application-schema SQL]
Clients/
WC/
Server/
WC.Api.Database.pas / .dfm
WC.Auth.Database.pas / .dfm
WC.Api.Data.pas [new]
WC.Library.pas
Web/
wcEmiMobile.dpr
wcEmiMobile.dproj
Client.Settings.pas [new]
index.html
View.Map.pas / .dfm / .html
View.Units.pas / .dfm / .html
View.UnitDetails.pas / .dfm / .html
View.Complaints.pas / .dfm / .html
View.ComplaintDetails.pas / .dfm / .html
View.ComplaintArchive.pas / .dfm / .html
uMapFilters.pas
uMapMarkerJs.pas
config/
config.json
assets/
markers/
[WC boundary files and used assets]
Config/
emiMobileServer.ini.example
emiMobileServer.json.example
BFD/
Server/
BFD.Api.Database.pas / .dfm
BFD.Auth.Database.pas / .dfm
BFD.Api.Data.pas [new]
BFD.Library.pas
Web/
bfdEmiMobile.dpr
bfdEmiMobile.dproj
Client.Settings.pas [new]
index.html
View.Map.pas / .dfm / .html
View.Units.pas / .dfm / .html
View.UnitDetails.pas / .dfm / .html
View.Complaints.pas / .dfm / .html
View.ComplaintDetails.pas / .dfm / .html
View.ComplaintArchive.pas / .dfm / .html
uMapFilters.pas
uMapMarkerJs.pas
config/
config.json
assets/
markers/
[BFD boundary files and used assets]
Config/
emiMobileServer.ini.example
emiMobileServer.json.example
bin/ [generated/local runtime files]
emiMobileServer.exe
emiMobileServer.ini
emiMobileServer.json
logs/
static/
WC/
BFD/
Legacy/
[retained inactive source, described below]
```
## Naming and responsibilities
- Keep current names for shared units. Server and web Auth.Service remain separate, as today; server and web projects must have separate search paths.
- Both client server implementations compile into one executable. Prefix their unit and class names with WC/BFD to avoid collisions. For example, WC.Api.Database contains TWCAPIDataModule and BFD.Api.Database contains TBFDAPIDataModule. Rename DFM class declarations and references consistently during implementation. Keep query names such as uqMapUnits within each module.
- Client.Data defines the narrow CAD/user-access operations required by shared services. It does not expose concrete persistent query fields. Exact Delphi signatures and ownership are to be designed from existing call sites before implementation.
- Client.Selection is the central selection point for creating WC/BFD data implementations and PostgreSQL/Oracle device stores. It creates instances for the relevant request or worker; it does not provide one global shared query connection. Invalid Client fails before service startup. The earlier name Client.Factory meant object creation only; no factory framework is intended.
- WC.Api.Data and BFD.Api.Data implement client CAD response building, using their client database modules. Shared API services and Ws.DataModel call the same builders for corresponding list/map data. Keep XData response ownership and WebSocket serialization ownership explicit.
- Device.Store defines application persistence operations required by shared authentication/device workflows. PostgreSQL.Device.Database and Oracle.Device.Database implement those operations, including verification and redemption storage where required. No duplicate registration workflow belongs in these modules.
- WC.Auth.Database and BFD.Auth.Database retain CAD agency/user lookup and audit differences. Move current raw CAD lookup SQL out of shared Auth.ServiceImpl as needed; route through the selected client implementation. Authentication/token rules remain in core.
- WC.Library and BFD.Library initially preserve each existing uLibrary implementation, including database-specific sequence/audit behavior. Share verified common parts later only when worthwhile.
- Client.Settings is a small web unit for existing presentation differences such as Complaint/Incident labels. Each separately compiled web project explicitly includes its own copy. It does not select server databases or override server access rules.
- Keep client web form unit names unchanged initially: each web project includes only its own forms plus shared forms. Use explicit references, never a search path containing both client Web folders.
- Core/Web/View.Main, login, device forms, styles, and utilities represent reconciled target behavior, not simple file moves. WC is the starting point for new device/live-update behavior; preserve BFD terminology through settings.
- Map, list, detail, archive forms and marker/filter units remain client-local in the initial layout. Preserve each .pas/.dfm/.html set together. Later sharing of map mechanics is separate work.
## Build and runtime rules
- No project group is required or proposed. Open emiMobileServer.dproj, wcEmiMobile.dproj, and bfdEmiMobile.dproj individually. Match client .dpr names to their .dproj names. No second server project remains in the target layout.
- Preserve the existing bin output convention. Web outputs become emiMobileServer/bin/static/WC and emiMobileServer/bin/static/BFD. These are runtime outputs, not source folders.
- Resolve the static root relative to the executable directory, not the process working directory. Client=WC selects static/WC; Client=BFD selects static/BFD. Remove the independent webAppFolder override from the effective runtime configuration when implementing this rule.
- Generated web output contains its HTML templates, JS, shared CSS, client configuration, and required assets. Explicitly configure shared resource deployment and verify it with a pilot shared form; cross-directory TMS packaging is not yet build-tested.
- Keep compiler intermediate output separate per project/configuration; never mix server and web DCUs or WC/BFD web intermediates.
- Deploy the common executable, deployment-specific INI/JSON, and only static/<selected client>. WC and BFD run on different machines.
- Track sanitized configuration examples. Do not copy live connection secrets into tracked examples.
- One local server process selects one client. When testing the other client locally, change its local configuration and restart; simultaneous local instances are outside the initial scope.
## Inactive files and migration
- Preserve unused Users, EditUser, EditUser2, UserProfile, Admin forms and View.Home.html outside active projects in Legacy/Web if/when the move is approved. Do not delete them as incidental cleanup.
- Review Markers.pas, WebSocketServer.pas, Ws.Service.pas, and Ws.ServiceImpl.pas references before assigning them to active Core or Legacy; apparent duplication or empty implementations alone is not permission to delete them. Retain original files until that check is complete.
- Keep old standalone BFD checkout/history intact until Git consolidation is agreed. Do not move its .git directory into the new client source folder.
- Existing SQL files are migration inputs, not an approved automatic migration sequence. Review destructive statements and seed data before creating deployment-ready migrations.
- Implement in small stages. This target structure does not authorize a wholesale move/refactor or imply all units are currently compatible.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment