Skip to main content

PowerSeller SaaS App — Strategic Context

This document captures the strategic discussions, decisions, organizational context, and ecosystem understanding established during the project kickoff session on March 16, 2026. It serves as the foundational reference for all subsequent architectural and product decisions.


1. The PowerSeller Ecosystem

PowerSeller Solutions LLC operates four technology products serving the mortgage secondary marketing industry. These products are at different stages of maturity and serve different parts of the value chain.

1.1 PowerSeller Desktop App (Legacy)

  • Technology: PowerBuilder 22.0, ~2,100 source files across 25+ PBL libraries
  • Age: ~30 years of accumulated business logic
  • Database: SQL Server (pscat_, rmcat_, pxcat_ table prefixes)
  • Deployment models:
    • On-premises at customer sites (customer-managed SQL Server)
    • Hosted in IBM Softlayer private cloud (each customer gets their own VM with their own SQL Server instance)
    • Azure Virtual Desktop running Windows 11 Multisession connected to Azure SQL Managed Instance (MWFI Holdings only, proof of concept)
  • Source control: Being migrated from Team Foundation Server to Azure DevOps Git by Rudy
  • Future: PowerServer (Appeon) is being evaluated as an intermediate step to turn the desktop app into an Integrated Cloud App — a bootstrap launcher downloads PB binaries from PowerServer, executes locally, but all database calls go through a web API to SQL MI
  • Status: Actively maintained by Tom. Existing customers depend on it. Will coexist with the SaaS App for years.

1.2 PowerSeller SaaS App (This Project)

  • Goal: Native web application replicating the core business logic of the desktop app in a modern SaaS stack
  • Technology (decided): .NET 8 / C# backend, React + TypeScript frontend, SQL Server (Azure SQL MI)
  • Target audience: New customers first, migrating customers second
  • Architecture: Modular monolith with bounded contexts, API-first, database-per-tenant on SQL MI
  • Status: Documentation and architecture phase. No code written yet. Specs before code.

1.3 PowerSeller X (PSX)

  • What it is: Anonymous residential mortgage marketplace
  • Technology: Python 3.12 / FastAPI backend, Next.js 14 / React frontend, PostgreSQL 16, Redis, MinIO, Keycloak, Apache Superset, MkDocs
  • Architecture: 9 Docker containers orchestrated via docker-compose
  • Core IP: 8-phase stacking pricing algorithm for auditable best-execution rankings
  • Business model: Technology platform only — PowerSeller does not take loans or risk. Principals (e.g., Watermark TPO) buy from sellers and either sell via PSX or securitize into agency MBS
  • Status: v6.0 as of March 2026. PSX stacking engine validated, buyer profiles built, MWFI/Watermark TPO is anchor principal
  • Relationship to SaaS App: Complementary. SaaS App manages internal secondary marketing operations; PSX provides external marketplace execution. A lender might use the SaaS App to manage their pipeline and the PSX API to check external market pricing.

1.4 PowerSeller MBS Access

  • What it is: B2B subscription platform for MBS market data
  • Technology: Custom Odoo v18 Enterprise modules (22 modules), hosted on Odoo.sh
  • Capabilities: Tiered subscriptions (Files Only $35/mo through Enterprise $1,000+/mo), daily market data file delivery, SAML IdP for dataQollab integration, self-service portal
  • SAML flow: PowerSeller (Odoo) acts as Identity Provider; dataQollab (AWS Cognito) is the Service Provider. Users with active Basic+ subscriptions get SSO to dataQollab's live market view.
  • Data ingest: Receives files from dataQollab via SFTP, transforms to 403-row MBS Values format
  • Status: Live and revenue-generating

2. Odoo as the Business Operating System

Odoo v18 Enterprise is not just the platform for MBS Access. It is PowerSeller's entire back office — the system of record for customers, invoicing, subscriptions, and business relationships.

2.1 Current Odoo Usage

FunctionStatus
Public websiteLive
Customer portalLive (minimal customer access currently)
B2B subscriptions (MBS Access)Live
SAML IdP for dataQollabLive
eSign (master agreements)Live
Events/webinarsBuilt
Portal payments (ACH, credit card w/ surcharge)Built

2.2 Planned Odoo Usage

FunctionOdoo Module
Accounting & invoicingOdoo Accounting
CRMOdoo CRM
Project management (non-dev)Odoo Project
Helpdesk / customer supportOdoo Helpdesk
HROdoo HR
Email marketingOdoo Email Marketing
Social marketingOdoo Social
eLearningOdoo eLearning

2.3 Architectural Implication

Odoo is the commercial layer for all PowerSeller products. The SaaS App should NOT build its own:

  • User management or customer onboarding
  • Subscription management or billing
  • CRM or support ticketing
  • Customer portal for account management

Instead, the SaaS App should receive provisioning signals from Odoo (via API or webhook) that communicate "tenant X is active, with these users, at this tier." Odoo manages the business relationship; the SaaS App delivers the product experience.

This also has identity implications: Odoo is already the SAML IdP for MBS Access. It could potentially serve as the identity authority for all PowerSeller products, either directly or federated through Keycloak.


3. Organizational Structure

3.1 Ownership and Leadership

PersonRoleOwnershipKey Contribution
LisaCEO60%Mortgage executive with 40 years in secondary/capital markets. Also CEO of MWFI Holdings LLC (dba Watermark TPO). Strategic direction, customer relationships, industry authority.
You (Sawyer)CTO40%Product Owner for SaaS migration. Architect of ecosystem modernization. Builds with Cursor + AI agents. Serial entrepreneur, holistic IT. Also owns/operates APCI (MSP/MSSP).
GregContract PresidentPrior owner. Deep hedging and risk management knowledge. The "oracle" for business logic that nobody else fully understands. Critical for validating Risk module port. Time-limited resource.

3.2 Development and Operations Team

PersonRoleStrengthsSaaS App Role
TomSenior DeveloperPowerBuilder veteran (decades). Can do C# for plugins. ~5 years to retirement.Maintains desktop app. NOT migrating to SaaS dev. Source of legacy knowledge.
RudyJunior DeveloperLeading TFS → Azure DevOps Git migration. 10-15 year horizon. Eager to learn SaaS. Reports loosely to Tom. Currently working with Greg on value-add projects.Future SaaS dev lead. Will be exposed to docs and progress organically; no forced handoff.
JoeIT / InfrastructureSwiss-army-knife. Manages infrastructure, security, customer support, customer migrations. Writes decent code out of self-defense.Azure/Docker ops, CI/CD, infrastructure security. Has access to APCI's Kaseya/Datto toolset for managing PowerSeller assets.
JayOperations ManagerCustomer advocate, power user of desktop app. Former secondary marketing professional (decades ago).Acceptance testing, UX validation, domain knowledge for "how users actually work." Key source for loan table customization question.

3.3 Future Team

Additional developers will be brought aboard when the time is right. The current approach uses AI-assisted development (Cursor + agents) to maximize the CTO's individual output during the architecture and early implementation phases.


4. Key Business Relationships

4.1 MWFI Holdings LLC (dba Watermark TPO)

Superseded for product-strategy purposes (2026-04-20): the "design partner and first adopter" framing below was the operating frame through Phase 9 + 8.5 but did not hold up empirically. MWFI/WTPO is reframed as a test partner / R&D collaborator — load-bearing for plumbing validation (PSSaaS↔PSX, multi-tenant runtime, AVD↔SQL MI, auth, embedded SDK) but NOT load-bearing for product-feature-prioritization signal because the business itself is still forming (relationships, capital, MWFI-buys-Watermark-Capital restructure pending). The actual product-strategy signal is migration-pull from existing PowerSeller Desktop App customers. See devlog/2026-04-20-customer-signal-roles-reframe for the full reframe + chunk-selection criterion update. This section is preserved as the kickoff-day record (March 16, 2026).

  • MWFI is a TPO (Third Party Origination) division of Watermark Capital
  • Lisa is CEO of both PowerSeller Solutions and MWFI Holdings
  • Sawyer is a shareholder in MWFI
  • Watermark TPO is a Fannie/Freddie seller-servicer and Ginnie Mae issuer
  • MWFI is the anchor principal for PowerSeller X
  • MWFI is the only customer currently on Azure AVD + SQL MI
  • MWFI is a regular paying customer of the desktop app — with white-glove treatment and high trust
  • MWFI is the design partner and first adopter for the SaaS App
  • MWFI provides real-world validation — they are a production secondary marketing operation

4.2 dataQollab

  • Operates MBS Market Intelligence platform
  • PowerSeller is a value-added reseller
  • Integration: SAML SSO (Odoo IdP → Cognito SP), file ingest API, DQ API key webhook
  • Subscribers with Basic+ tiers get SSO to live market views

4.3 APCI

  • Sawyer's MSP/MSSP business
  • ~12 clients, one of which is PowerSeller (billed at cost)
  • Kaseya/Datto MSP/MSSP toolsets available to Joe for managing PowerSeller infrastructure
  • PowerSeller manages its own Azure tenancy but may use APCI tools for infrastructure management

5. Infrastructure Topology

5.1 Current State

IBM SOFTLAYER PRIVATE CLOUD
├── Customer A VM → SQL Server instance (isolated)
├── Customer B VM → SQL Server instance (isolated)
├── Customer C VM → SQL Server instance (isolated)
└── Each hosted customer is fully isolated (own VM, own SQL)

AZURE
├── SQL Managed Instance
│ ├── MWFI Holdings database (production)
│ └── PowerSeller test/dev databases
│ └── (no other customers yet)
├── Azure Virtual Desktop (Windows 11 Multisession)
│ └── MWFI runs PowerSeller desktop app → connects to SQL MI
└── (future: SaaS App containers, PSX, supporting services)

ODOO.SH
└── PowerSeller MBS Access (Odoo v18 Enterprise)
├── Public website
├── Customer portal
├── B2B subscriptions
└── SAML IdP

ON-PREMISES (customer-managed)
├── Customer X → their own SQL Server, their own install
├── Customer Y → same
└── PowerSeller has no visibility or control

CTO WORKSTATION (Windows 11 Pro)
├── Cursor IDE with AI agents
├── Docker Desktop
├── Git repos for all projects
└── Development inner loop

5.2 Migration Path (Three Hops)

Hop 1: On-premises → Hosted (IBM Softlayer) Joe manages this today. Customer moves off their own hardware into a managed VM with its own SQL Server instance. Same app, same architecture, managed by PowerSeller.

Hop 2: Hosted (VM + local SQL) → PowerServer + SQL MI The desktop app launches via a bootstrap, gets PB binaries from PowerServer, runs locally, but all database calls go through a web API to SQL MI. Customer's data moves from their isolated VM-based SQL Server to a database on SQL MI. This is not yet implemented for any customer except MWFI (who is already on SQL MI via AVD, not PowerServer).

Hop 3: PowerServer app → SaaS App Customer transitions from the PowerServer-hosted desktop app to the native web SaaS App. Same SQL MI, same data. Desktop app becomes unnecessary for that customer.

Critical note: Hop 2 is the bridge that gets customer data into SQL MI without requiring the SaaS App to be ready. But Hop 2 is not yet implemented beyond MWFI's AVD proof of concept. PowerServer evaluation is in early stages (Tom has been too busy with 8.x work to evaluate it deeply).


6. Architectural Decisions Made

The following decisions were made during this session and will be formalized as ADRs:

ADR-001: Backend Technology — .NET 8 / C#

Context: Needed a backend stack for porting PowerBuilder business logic. Options: .NET, Node.js/TypeScript, Python, Java. Decision: .NET 8 / C#. Closest heritage to PowerBuilder (strongly typed, OOP). Superior decimal precision for financial calculations. Excellent SQL Server interop. Strong EF Core data access. Mature enterprise ecosystem. Consequences: Different stack from PSX (Python). Shared business concepts need API contracts, not shared code.

ADR-002: Frontend Technology — React + TypeScript

Context: Needed a frontend framework for dense tabular data views and power-user workflows. Decision: React + TypeScript with AG Grid (or similar) for data-heavy views. Consequences: Aligns with PSX frontend (Next.js/React). Component reuse possible across products.

ADR-003: Cloud Strategy — Azure-Preferred, Azure-Dependent on Nothing

Context: PowerSeller has existing Azure infrastructure (SQL MI, AVD). Other assets in Azure. But wanted to avoid hard vendor lock-in. Decision: Azure as the primary cloud provider. Application code is containerized and uses standard protocols (OpenID Connect, standard SQL, OpenTelemetry). No Azure-specific SDK calls in domain logic. Consequences: Can theoretically run anywhere, but Azure provides managed infrastructure. Monitoring uses OpenTelemetry (exports to Azure Monitor today, Grafana tomorrow).

ADR-004: Architecture Style — Modular Monolith First

Context: The PowerBuilder app is a monolith. Could jump to microservices or start modular. Decision: Modular monolith with separate .NET projects per bounded context sharing a single process and database. Extract services only when scale, team autonomy, or deployment velocity demands it. Consequences: Simpler ops, easier debugging, cheaper hosting initially. Pricing and Risk modules are candidates for future extraction.

ADR-005: Database Strategy — SQL MI with Database-Per-Tenant

Context: Existing customers have isolated SQL Server instances. Need tenant isolation in SaaS. Decision: Each tenant gets their own database on Azure SQL MI. Connection string resolved by tenant context. Schema is uniform across tenants (same pscat_/rmcat_/pxcat_ structure, modernized incrementally). Consequences: Strongest data isolation. Natural migration from existing isolated instances. Higher per-tenant cost than shared schema, but acceptable for this market.

ADR-006: Schema Migration — Preserve Initially, Modernize Incrementally

Context: ~170 tables with pscat_/rmcat_/pxcat_ prefixes. Could rewrite schema or preserve it. Decision: Preserve the existing schema initially (enables side-by-side validation against desktop app). Add proper foreign keys, audit columns (CreatedAt, UpdatedAt, etc.), and soft deletes. Rename tables and restructure in a later phase. Consequences: EF Core database-first scaffolding works immediately. Desktop app and SaaS App can coexist on the same database during migration.

ADR-007: Target Audience — New Customers First, Migrating Customers Second

Context: Could prioritize feature parity for existing customers or a modern experience for new ones. Decision: Build for new customers first. They expect a modern SaaS experience, not a PowerBuilder replica. Existing customer migration is secondary. Consequences: UI design emphasizes guided workflows, progressive disclosure, dashboards. Power-user density views built as a secondary "mode" for migrating customers. API and business logic are the same for both audiences.

Amendment proposal pending (2026-04-20): the "new customers first, migrating customers second" prioritization is incomplete. Existing PowerSeller Desktop App customers (migration pull) are now the primary product-strategy index for chunk-selection conversations; net-new-customer onboarding remains a design constraint but is no longer the prioritization driver. See devlog/2026-04-20-customer-signal-roles-reframe §"What IS Changing." Formal ADR-007 amendment to follow when ADR-007 is next opened for revision.

ADR-008: UX Strategy — Two Modes (Modern Default, Power Opt-In)

Context: New customers want clean/guided UX. Migrating customers want dense/efficient UX. Both need the same business logic. Decision: One frontend with two presentation modes. Modern mode (dashboards, wizards, guided flows) is the default. Power mode (dense grids, all fields visible, keyboard-driven) is opt-in. Same React components underneath, different layout and disclosure. Consequences: More frontend work, but avoids maintaining two separate applications. User preference controls which mode is active.

ADR-009: Documentation Platform — Docusaurus, Containerized

Context: 14 markdown docs needed a presentation layer. Options: MkDocs, Docusaurus, raw markdown. Decision: Docusaurus (React-based). Run locally in Docker for authoring. Deploy to Azure Static Web App for team access. MDX support allows embedding React components (interactive mockups, ER explorers). Consequences: Node.js dependency (contained in Docker). Strategic alignment with React frontend stack. Component prototyping in docs can migrate to the app.

ADR-010: Documentation Framework — Arc42 + ADRs + Specs Before Code

Context: Need structured architecture documentation that scales with the team. Decision: Follow Arc42 template for architecture documentation. Capture all architectural decisions as ADRs. Write feature specifications before writing code. Maintain a devlog for narrative record of development progress. Consequences: Consistent with MBS Access (37+ ADRs) and PowerSeller X (39 ADRs). Higher upfront documentation cost, but dramatically reduces misalignment and rework.

ADR-011: Ecosystem Product Boundaries

Context: Three products (SaaS App, PowerSeller X, MBS Access) have overlapping domain concepts (loans, pricing, investors). Decision: Products are complementary, not competing. SaaS App handles internal operations (pipeline, pooling, trading, hedging). PSX handles external marketplace. MBS Access handles data subscriptions. Integration via API contracts, not shared databases. Consequences: Each product can evolve independently. Shared concepts (loan schema, investor/buyer identity) need formal API contracts and domain alignment documentation.

ADR-012: Business Operations Platform — Odoo

Context: PowerSeller needs CRM, billing, subscriptions, support, website, portal. Decision: Odoo v18 Enterprise is the commercial layer for all products. SaaS App does not build its own billing, CRM, or customer management. Odoo provisions tenants and manages subscriptions; SaaS App delivers the product experience. Consequences: SaaS App receives provisioning signals from Odoo. Identity may flow from Odoo (as IdP) or through a federated Keycloak. Customer-facing business operations are Odoo's responsibility.

ADR-013: Identity Strategy — Open Question

Context: MBS Access uses Odoo as SAML IdP. PSX uses Keycloak (OIDC). SaaS App was considering Azure AD. Decision: Not yet decided. Options: (a) Keycloak as universal IdP federated with Azure AD and Odoo, (b) Azure AD as primary with Keycloak bridge, (c) Odoo as universal IdP for customer-facing auth. Requires further analysis. Status: Proposed — needs ADR.

ADR-014: Backend Language Divergence Accepted

Context: PSX is Python/FastAPI. SaaS App is .NET 8/C#. Decision: Accepted. Different products, different teams, different performance characteristics. Shared domain concepts live in API contracts (OpenAPI specs), not shared code libraries. Consequences: No shared business logic libraries across products. LLPA calculations, MISMO field mappings, and other shared concepts need to be defined in a language-neutral spec and implemented independently in each stack.

ADR-015: PowerSeller Desktop App Coexistence

Context: Desktop app has active customers and an active developer (Tom). SaaS App will take years to reach full feature parity. Decision: Desktop app and SaaS App coexist indefinitely. Tom maintains the desktop app. No forced migration timeline. When a customer is ready (data in SQL MI, SaaS features sufficient), they transition at their own pace. Both can read/write the same database during transition. Consequences: Schema changes must be backward-compatible with the desktop app during the coexistence period. Desktop app plugins could be an early integration point (calling SaaS API instead of local logic).


7. Open Questions

7.1 Requiring Jay's Input

  • Loan table customization: Do customers customize the loan table schema (add columns, change types)? If so, to what degree? This directly affects the SaaS App's data model strategy. Options: JSON extension columns, configurable schema, standardized schema with migration.

7.2 Requiring Research

  • PowerServer transaction semantics: Does PowerServer's web API preserve the same SQL transaction semantics that the desktop app uses (manual commit/rollback via n_cst_transobj)? Needs evaluation of Appeon documentation and community resources.
  • Odoo API and provisioning: How does Odoo's API (XML-RPC, JSON-RPC, REST) work for external systems? How can Odoo trigger provisioning in the SaaS App when a subscription is activated? Needs Odoo platform research.
  • Identity federation: How to unify identity across Odoo (SAML), Keycloak (OIDC), and Azure AD. Needs architecture spike.

7.3 Requiring Greg's Input

  • Risk module validation: The deep-dive documentation for hedging, SFAS, rate cones, and position reconciliation needs validation from Greg. He should review docs/10-deep-dive-risk.md and annotate with business context that the code alone cannot convey.
  • Hedging business rules: Some rules may exist as institutional knowledge rather than code. Structured knowledge extraction sessions with Greg, using the documentation as an interview guide.

7.4 Requiring Lisa's Input

  • V1 feature surface: Which modules are in the initial SaaS release, which are phase 2, and which are deprecated? Lisa's market knowledge determines the product roadmap. (Reframed 2026-04-20: V1 feature-surface decisions now index on existing-Desktop-customer migration pull, not net-new-customer-greenfield criteria. See devlog/2026-04-20-customer-signal-roles-reframe for chunk-selection criterion update.)
  • Rudy's current projects: What value-add projects is Rudy working on with Greg? Understanding these helps plan his transition into SaaS development.

8. Build Priority (Tier Assessment)

Outdated as of 2026-04-20. This Tier Assessment was the kickoff-day framing. Two subsequent reframes have superseded it for product-strategy purposes:

  1. 2026-03-17 priority pivot (devlog/2026-03-17-priority-pivot.md) demoted BestEx to "Future — when agency delivery starts" and promoted Pipeline Management to immediate.
  2. 2026-04-20 customer signal roles reframe (devlog/2026-04-20-customer-signal-roles-reframe) established that migration-pull from existing Desktop App customers is the load-bearing chunk-selection criterion (not WTPO needs, not net-new-customer differentiators). Under that criterion: Reporting moves from Tier 3 to Tier 1 (BI-drill-down is the migration lure; Phase 8.5's Superset embedding built the foundation). Import/Export moves from Tier 3 to Tier 1 (data-ingestion-modernization eliminates the 100+ field manual-mapping ritual that taxes every Desktop App customer's onboarding). PowerFill (Pooling Engine) shipped as chunk #1 in the interim; remains correctly Tier 1.

The original Tier Assessment is preserved below as the kickoff-day record; current chunk-selection conversations should read against the 2026-04-20 reframe + Backlog #32 + Greg/Joe/Tom consultations.

Tier 1 — Core Differentiators (Build First)

  • Best Execution Engine — The 24-step pricing analysis. Intellectual property. The feature customers pay for.
  • Pooling Engine — The 12-step algorithm with constraint satisfaction. Operationally critical.
  • Trade Lifecycle — Creation through designation and settlement. Core workflow.

Tier 2 — Essential Operations (Build Second)

  • Pipeline Management — Loan intake and status tracking. Foundational but less differentiated.
  • Risk Analysis — Position reconciliation and hedging. High value but could initially export to existing tools.
  • Price Ingestion — Replacing DDE with modern price feeds. Needed for BestEx to function.

Tier 3 — Support Functions (Build or Buy)

  • Import/Export — Valuable but commodity. Off-the-shelf ETL options exist.
  • Document Tracking — Important operationally but not unique.
  • Reporting — Could use Power BI, SSRS, or embedded analytics rather than building from scratch.
  • Archive — Database-level concern.

Tier assessment requires Lisa's validation.


9. Next Steps (Agreed Sequence)

  1. Document strategic context — This document (done)
  2. Set up Docusaurus — Docker-containerized, Arc42 structure, ADR section, spec and devlog templates
  3. Migrate existing documentation — Move 13 existing docs + mockups into Docusaurus structure
  4. Write formal ADRs — Capture all decisions from this session
  5. Write first devlog entry — Narrative record of project kickoff
  6. Connect to SQL MI — Pull real schema (replaces extracted approximation)
  7. Write BestEx spec — First feature specification, following specs-before-code discipline
  8. Build BestEx — Port the pricing analysis pipeline to .NET 8, validate against production