Skip to main content

PowerFill Module — Phase 0 Complete

Date: 2026-04-16 Scope: Reverse-engineer the Desktop App's PowerFill plugin and produce the specification, three ADRs, and an assumptions log. No code in this phase — the specs-before-code invariant is binding, and PowerFill is a Tier 1 feature that deserves careful design.

Why

During the team meeting, Kevin identified that Desktop App clients would value a SaaS-based PowerFill offering. PowerFill is the pool allocation optimizer that makes PowerSeller viable for mid-market lenders doing agency delivery — a Tier 1 feature parity requirement for PSSaaS.

Tom and Greg are not available for upfront consultation. Kevin decided to proceed with reverse-engineering the source code as the authoritative spec, documenting every interpretation explicitly, and iterating when Tom/Greg have time to critique.

What Was Done

Reverse-Engineering

Surveyed the entire X:\dev\other\PowerSeller-App\plugins\powerfill\ directory (25 files):

  • 1 main window + 1 modal + 1 menu
  • 2 user object tabs (Constraints, Cost and Carry)
  • 1 NVO with ~19K lines of T-SQL embedded as stored procedure strings
  • ~15 DataWindows (reports + maintenance grids)

Identified the 13 pfill_* tables (4 persistent configuration, 9 run-output/intermediate) and 20+ upstream tables consumed from loan, pscat_*, rmcat_*, pxcat_*.

Documented the 7 core procedures: psp_powerfill_conset, psp_powerfillUE, psp_pfill_bx_cash_grids, psp_pfill_bx_settle_and_price, psp_add_to_pool_lockdown_guide, psp_pfill_ect_params, psp_pfill_trade_params.

Captured the pool action semantics: Remaining, Leaving, Joining, Switching, with internal Swapped In for the destination side of a switch.

Files Produced

  1. docs-site/docs/legacy/powerfill-deep-dive.md — Full legacy reverse-engineering: every file, every table, every procedure, every menu action, business context, algorithm high-level flow.

  2. docs-site/docs/specs/powerfill-engine.md — The spec. Scope, requirements across 8 functional areas, 10 business rules, data contracts, API shapes, algorithm pseudocode, 10-phase implementation roadmap (Phase 0 = this session; Phases 1-9 scoped with estimates).

  3. docs-site/docs/adr/adr-021-powerfill-port-strategy.md — Hybrid strategy: T-SQL stored procedures for the allocation engine (deployed to tenant databases), C# for orchestration/CRUD/APIs/audit. Rejects full T-SQL lift-and-shift (Option A) and full C# port (Option B).

  4. docs-site/docs/adr/adr-022-powerfill-allocation-algorithm.md — Port the iterative multi-pass algorithm verbatim. Rejects MILP and CSP rewrites as Phase 2 modernization candidates rather than Phase 0 scope. Rationale: 19K lines have 15 years of tuning embedded; a rewrite would risk behavioral drift on customer data.

  5. docs-site/docs/adr/adr-023-powerfill-constraint-model.md — Preserve the legacy constraint tree (investor → instrument → sub-constraint with priority ordering). Rejects flat rule list and expression-based rules as Phase 2 modernization. Schema preservation per ADR-006 enables coexistence with Desktop App.

  6. docs-site/docs/specs/powerfill-assumptions-log.md — 25 numbered interpretations made from the code, each with:

    • The claim
    • Source citation (which file/procedure/pattern)
    • Confidence level (low/medium/high)
    • What breaks if wrong
    • Open question for Tom/Greg

Meta-Updates

Key Decisions

  • "Specs-before-code" invariant is binding. No code touched in this phase. Phase 1 (domain model + EF Core schema for pfill_*) begins after spec approval.

  • Code is the spec. With Tom/Greg unavailable, the source code is the authoritative specification. Every ambiguity is resolved by reading the T-SQL, with interpretations logged explicitly in the assumptions log.

  • ADRs commit to specific recommendations rather than defer decisions to future humans. The Product Owner (Kevin) accepts; Tom and Greg critique downstream when available. All three ADRs default to minimize divergence from Desktop App behavior because parity is the goal.

  • Full module scope, phased delivery. The full effort spans 10 phases over an estimated 12-16 weeks if executed serially. Phase 0 unblocks Phase 1 immediately.

What's Next

Phase 1: Domain model + EF Core schema for pfill_* tables. 3-5 day estimate. This phase:

  1. Creates a new PowerSeller.SaaS.Modules.PowerFill project in the .NET solution
  2. Defines 13 EF Core entities matching the legacy pfill_* schema exactly (per ADR-006 and ADR-023)
  3. Registers the new module with TenantDbContext (same pattern as BestEx)
  4. Deploys schema to PS_DemoData for integration testing
  5. No API endpoints, no allocation logic, no UI — just the foundation

Phase 2 adds data access and preflight validation. Phase 3 begins porting the stored procedures.

Risks Captured

Documented in each ADR's "Risks and Mitigations" section, but summarized:

  • Ported algorithm may diverge from Desktop App on edge cases — mitigation: parallel validation on PS_DemoData
  • Legacy code may contain bugs we'll faithfully reproduce — mitigation: Tom/Greg review in Phase 9
  • Performance at scale is unverified — mitigation: benchmark suite in Phase 6
  • Procedure-C# contract drift — mitigation: integration tests + future code generation

Token Economics Note

This session spent significant tokens on the PowerFill Phase 0 artifacts (~10K lines of markdown). The value proposition: if Phase 0 is wrong, Phases 1-9 compound the error. Getting the spec right up front is cheaper than rewriting downstream code.