Files
jdescopingtool/CLAUDE.md
T
Joseph Doherty e5fe2f06e9 feat: add startup config validation and document ConfigManager pipeline editor
Add ConfigurationValidationRunner with IConfigurationValidator interface for
validating required settings at startup. Includes SecureStore and LDAP validators.
Expand ConfigManager with pipeline editing UI, dialogs, and step editors.
Update documentation with config validation guidance.
2026-01-21 17:47:15 -05:00

8.9 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a migration project to convert a legacy .NET Framework 4.8 application ("LotFinder" / JDE Scoping Tool) to .NET 10.

Folder Structure

JdeScopingTool/
├── OLD/            # Legacy .NET Framework 4.8 source code (read-only reference)
├── NEW/            # New .NET 10 solution (build here)
│   └── JdeScoping.slnx   # Solution file (.slnx format)
├── openspec/       # OpenSpec specifications and design documents
├── PLANS/          # Design plans, implementation plans, and task lists
└── DOCUMENTATION/  # Project documentation

Build Commands

The solution uses the .slnx format (XML-based solution file):

# Build entire solution
dotnet build NEW/JdeScoping.slnx

# Run all tests
dotnet test NEW/JdeScoping.slnx

# Build specific project
dotnet build NEW/src/JdeScoping.Host/JdeScoping.Host.csproj

Legacy System Purpose

A manufacturing/ERP search tool that:

  • Caches data from JDE (JD Edwards - Oracle) and CMS (Sybase) enterprise systems into SQL Server
  • Allows users to create complex searches across work orders, lots, items, operators, and work centers
  • Processes searches asynchronously and exports results to Excel
  • Provides real-time status updates via SignalR

Migration Target

  • Single .NET 10 service (combines the legacy web app + worker service)
  • Blazor WebAssembly UI (replaces ASP.NET MVC + Razor views)

Legacy Architecture (OLD/)

Solution Structure

OLD/LotFinder.sln
├── WebInterface/       # ASP.NET MVC 5 web application
├── WorkerService/      # Windows Service (Topshelf) - search processor + data refresher
├── DataModel/          # Shared library (Commons.csproj) - models, DB access, helpers
├── Database/           # SQL Server database project (.sqlproj)
└── TestApp/            # Console test application

Key Components

WebInterface - ASP.NET MVC with SignalR

  • Controllers: SearchController (main), LookupController (autocomplete APIs), AccountController (LDAP auth)
  • SignalR Hub: StatusHub for real-time search status updates
  • Uses Forms auth with LDAP backend

WorkerService - Background processor (Topshelf service)

  • WorkProcessor: Main work loop - checks for pending data updates, then processes queued searches
  • UpdateProcessor: Syncs data from JDE/CMS to local SQL Server cache (mass/daily/hourly schedules)
  • ExcelWriter: Generates Excel output using EPPlus
  • Data source configs in dsconfig/*.json files

DataModel (Commons) - Shared library

  • Process/LotFinderDB*.cs: SQL Server cache database access (Dapper)
  • Process/JDE*.cs: Oracle JDE queries
  • Process/CMS*.cs: Sybase CMS queries
  • Models/: Domain models (WorkOrder, Lot, Item, Search, etc.)
  • ViewModels/: DTOs for API responses
  • Config.cs: Connection strings (encrypted passwords)

Data Flow

  1. User submits search via web UI -> stored in Search table with status=Queued
  2. WorkerService polls for queued searches
  3. Service executes search against local cache, generates Excel
  4. Results stored in Search.Results (VARBINARY), status updated
  5. SignalR pushes status updates to connected clients

Key Database Tables

  • Search: User search requests and results
  • DataUpdate: Tracks cache refresh timestamps per table
  • WorkOrder_Curr/Hist, LotUsage_Curr/Hist, etc.: Cached JDE data (current + historical)
  • Lot, Item, ProfitCenter, WorkCenter, JdeUser: Reference data

External Dependencies

  • DDTek.Oracle: Progress DataDirect Oracle driver
  • Sybase.AdoNet4.AseClient: Sybase database driver
  • Dapper: Micro-ORM for SQL queries
  • EPPlus: Excel generation
  • Topshelf: Windows service hosting
  • SignalR: Real-time web communication

Migration Considerations

What to Preserve

  • Search criteria model (SearchCriteria, SearchCriteriaViewModel)
  • JDE/CMS query logic (files in DataModel/Process/JDE*.cs, CMS*.cs)
  • Excel generation logic (WorkerService/Process/ExcelWriter.cs)
  • Data sync scheduling patterns (mass/daily/hourly from dsconfig)
  • Query templates (WorkerService/Templates/QueryTemplate.cs)

What Changes

  • Topshelf -> .NET hosted service with BackgroundService
  • SignalR (legacy) -> modern ASP.NET Core SignalR
  • ASP.NET MVC -> Blazor WebAssembly
  • Forms auth -> ASP.NET Core Identity with LDAP
  • System.Data.SqlClient -> Microsoft.Data.SqlClient

Authentication Pattern

Legacy uses LDAP authentication with group membership check. Config values:

  • LDAPUrl: Directory server URL(s)
  • LDAPGroup: Required group membership

OpenSpec Workflow

This project uses OpenSpec for change management. Specifications are stored in the openspec/ directory using the standard OpenSpec layout.

Directory Structure

openspec/
├── project.md          # Project overview and spec organization
├── AGENTS.md           # Agent guidelines and templates
├── specs/              # Specification files by functional area
│   ├── domain-models/
│   ├── database-schema/
│   ├── data-access/
│   ├── data-sync/
│   ├── search-processing/
│   ├── excel-export/
│   └── web-api-auth/
└── changes/            # Change proposals

Spec Formatting Rules

Specs MUST follow OpenSpec format for validation to pass:

  1. Purpose section: Use ## Purpose (not ## Overview)

  2. Requirements: Use SHALL/MUST language

    ### Requirement: Search entity
    The system SHALL store user search requests containing filter criteria.
    
  3. Scenarios: Use WHEN/THEN format (not Given/When/Then)

    #### Scenario: Submit new search
    - **WHEN** a user creates a search with name and criteria
    - **THEN** a new Search record is created with Status = New
    

Validation

Validate specs with the OpenSpec CLI:

openspec validate --specs        # Validate all specs
openspec list --specs            # List specs with requirement counts

Change Workflows

See .claude/commands/openspec/ for proposal, apply, and archive workflows. Key principles:

  • Favor minimal implementations
  • Keep changes tightly scoped
  • Create design docs before implementation

Documentation Guidelines

When writing or updating documentation, consult the DOCUMENTATION/Instructions/ folder:

Key principles:

  • Read source code before documenting
  • Use code snippets from actual codebase (never invent examples)
  • Follow the component mapping for file organization
  • Update documentation when code changes

Plans and Task Lists

Store design plans, implementation plans, and task list files in the PLANS/ folder:

  • Design plans - Architecture decisions, component designs
  • Implementation plans - Step-by-step implementation guides
  • Task lists - Tracked work items and checklists

This keeps planning artifacts organized and separate from specifications (SPECS/) and documentation (DOCUMENTATION/).

Local Development Database

The db_info.md file contains connection information for the local SQL Server development database:

  • Docker container details (scopingtool-sqlserver on port 1434)
  • SA credentials (admin access)
  • Application credentials (scopingapp user with read/write/execute/truncate permissions)
  • Connection strings for .NET configuration

Note: This file contains plain-text credentials for local development only. Do not commit to source control or use in production.

Coding Guidelines

DTOs and Models: Use Classes, Not Records

This project uses classes (not C# records) for all DTOs, ViewModels, and model types. This convention provides:

  • Consistency - All model types follow the same pattern
  • Explicit mutability - Properties use { get; set; } for clear intent
  • Serialization compatibility - Better compatibility with JSON serializers and Dapper
  • Debugging ease - Standard class behavior in debuggers and test assertions
// Preferred: class with explicit properties
public class WorkOrderViewModel
{
    public string OrderNumber { get; set; } = string.Empty;
    public DateTime? CompletionDate { get; set; }
}

// Avoid: record types for DTOs
public record WorkOrderViewModel(string OrderNumber, DateTime? CompletionDate);