Files
PowderCoatingLogix/.claude/settings.local.json
T
spouliot 9a52e7fae5 Ad-hoc quote email, accounting improvements, AI lookup fix, and misc service updates
- Quotes: ad-hoc email modal on Quote Details lets staff send to an address not on file;
  QuotesController passes overrideEmail through to NotificationService
- Quotes/Details view: SMS consent display, email/SMS send button state based on consent
- Accounting module: AccountingDisplayHelpers for consistent ledger formatting;
  AccountsController + Accounts views improvements; AccountingEnums additions
- Bills/Expenses: AI account categorization fixes in BillsController and ExpensesController
- InventoryAiLookupService: TDS cure fallback no longer fires on AiAugmentFromUrl path
  (LookupByUrlAsync already has it built in — was double-fetching)
- PdfService: quote/invoice PDF updates
- PricingCalculationService: minor pricing logic fix
- QuoteProfile: mapping updates for new quote fields
- ApplicationDbContextModelSnapshot: catches up to all 4 migrations in this branch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 20:48:00 -04:00

181 lines
11 KiB
JSON

{
"permissions": {
"allow": [
"Bash(dotnet build:*)",
"Bash(dir:*)",
"Bash(dotnet restore:*)",
"Bash(dotnet clean:*)",
"Bash(findstr:*)",
"Bash(dotnet ef migrations add:*)",
"Bash(dotnet ef migrations remove:*)",
"Bash(ls:*)",
"Bash(dotnet ef database update:*)",
"Bash(sqlcmd:*)",
"Bash(dotnet ef migrations script:*)",
"Bash(dotnet run:*)",
"Bash(timeout /t 15 dotnet run:*)",
"Bash(timeout /t 10 /nobreak)",
"Bash(ping:*)",
"Bash(start /B dotnet run:*)",
"Bash(test:*)",
"Bash(dotnet ef migrations:*)",
"Bash(grep:*)",
"Bash(xargs -I {} bash -c 'echo \"\"=== {} ===\"\" && head -20 {} | grep -E \"\"class|Authorize\"\"')",
"Bash(powershell:*)",
"Bash(dotnet tool install:*)",
"Bash(dotnet tool update:*)",
"Bash(xargs:*)",
"Bash(powershell -Command \"cd src\\\\PowderCoating.Web; dotnet ef migrations add UpdateQuoteForProspects --project ..\\\\PowderCoating.Infrastructure\")",
"Bash(powershell -Command:*)",
"Bash(taskkill:*)",
"Bash(netstat:*)",
"Bash(libman restore:*)",
"Bash(./start-app.bat)",
"Bash(dotnet-ef migrations add:*)",
"Bash(dotnet-ef database update:*)",
"Bash(./stop-app.bat)",
"Bash(timeout /t 3 /nobreak)",
"Bash(curl:*)",
"Bash(if [ -f \"stop-app.bat\" ])",
"Bash(then cmd.exe /c stop-app.bat)",
"Bash(else echo \"stop-app.bat not found\")",
"Bash(fi)",
"Bash(powershell.exe -Command \"Unblock-File -Path 'src/PowderCoating.Web/dotnet-tools.json'\":*)",
"Bash(powershell.exe -Command \"Get-Process | Where-Object {$_ProcessName -like ''*PowderCoating*''} | Stop-Process -Force\")",
"Bash(powershell.exe:*)",
"Bash(Select-String -Pattern \"error|Error\")",
"Bash(Select-String -NotMatch \"warning\")",
"Bash(tasklist:*)",
"Bash(dotnet add package:*)",
"Bash(start-process dotnet run:*)",
"Bash(Select-Object -ExpandProperty Id)",
"Bash(find:*)",
"Bash(cmd.exe:*)",
"Bash(dotnet ef dbcontext:*)",
"Bash(handle \"PowderCoating.Web.pdb\")",
"Bash(timeout:*)",
"Bash(del /F \"Y:\\\\PCC\\\\PowderCoatingApp\\\\src\\\\PowderCoating.Web\\\\obj\\\\Debug\\\\net8.0\\\\PowderCoating.Web.pdb\")",
"Bash(Select-String -Pattern \"Build succeeded|Build FAILED|error\")",
"Bash(Select-Object -Last 10)",
"Bash(del \"Y:\\\\PCC\\\\PowderCoatingApp\\\\src\\\\PowderCoating.Infrastructure\\\\Migrations\\\\20260211031319_RemovePreexistingCatalogData.cs\" \"Y:\\\\PCC\\\\PowderCoatingApp\\\\src\\\\PowderCoating.Infrastructure\\\\Migrations\\\\20260211031319_RemovePreexistingCatalogData.Designer.cs\")",
"Bash(Select-String:*)",
"Bash(Select-Object -Last 5)",
"Bash(start-app.bat)",
"Bash(dotnet script:*)",
"Bash(dotnet list:*)",
"Bash(dotnet new:*)",
"Bash(stop-app.bat)",
"Bash(dotnet watch run:*)",
"Bash(cmd /c \"taskkill /F /PID 42108\")",
"Bash(cmd /c start-app.bat)",
"Bash(\"Y:/PCC/PowderCoatingApp/src/PowderCoating.Application/Services/PdfService.cs\":*)",
"Bash(/y/PCC/PowderCoatingApp/src/PowderCoating.Application/Services/PdfService.cs:*)",
"Bash(/tmp/remove_tempdata.pl:*)",
"Bash(chmod:*)",
"Bash(perl:*)",
"Bash(done)",
"Bash(cmd:*)",
"Bash(tail:*)",
"Bash(del:*)",
"Bash(dotnet add:*)",
"Bash(python3:*)",
"Bash(Stop-Process:*)",
"Bash(mv:*)",
"Bash(dotnet tool:*)",
"Bash(where libman:*)",
"Bash(find \"Y:/PCC/PowderCoatingApp\" -type f \\\\\\( -name \"*template*\" -o -name \"*import*\" -o -name \"*export*\" \\\\\\) -iname \"*.csv\" -o -iname \"*.xlsx\" -o -iname \"*.xls\" 2>/dev/null | head -50)",
"Bash(grep -n \"powderCostOverride\\\\|PowderCostOverride\\\\|pageMeta\\\\|quoteItems\\\\|existingItems\" \"Y:/PCC/PowderCoatingApp/src/PowderCoating.Web/Views/Quotes/Create.cshtml\" | head -20\ngrep -n \"powderCostOverride\\\\|PowderCostOverride\\\\|pageMeta\\\\|quoteItems\\\\|existingItems\" \"Y:/PCC/PowderCoatingApp/src/PowderCoating.Web/Views/Quotes/Edit.cshtml\" 2>/dev/null | head -20)",
"Bash(cat /tmp/sdktest/Program.cs | xxd | head -20)",
"Bash(cd /tmp/sdktest && rm -rf bin obj && cat Program.cs)",
"Bash(cat /tmp/sdktest/Program.cs | xxd | head -5)",
"WebSearch",
"WebFetch(domain:github.com)",
"WebFetch(domain:www.nuget.org)",
"Bash(wmic process:*)",
"Bash(grep -rn \"AI Photo\\\\|ai.*photo\\\\|photo.*quote\\\\|item-type\\\\|AiPhotoQuotes\\\\|ai_photo\" \"Y:\\\\PCC\\\\PowderCoatingApp\\\\src\\\\PowderCoating.Web\\\\Views\\\\Quotes\\\\\" | grep -i \"photo\\\\|ai\" | head -20)",
"Bash(sed -i 's|\"aiAnalyzeUrl\": \"@Url.Action\\(\\\\\"AiAnalyzeItem\\\\\", \\\\\"Quotes\\\\\"\\)\",|\"aiAnalyzeUrl\": \"@Url.Action\\(\\\\\"AiAnalyzeItem\\\\\", \\\\\"Quotes\\\\\"\\)\",\\\\n \"aiPhotoQuotesEnabled\": @Json.Serialize\\(\\(bool\\)\\(ViewBag.AiPhotoQuotesEnabled ?? true\\)\\),|g' \\\\\n \"Y:\\\\PCC\\\\PowderCoatingApp\\\\src\\\\PowderCoating.Web\\\\Views\\\\Quotes\\\\Edit.cshtml\" \\\\\n \"Y:\\\\PCC\\\\PowderCoatingApp\\\\src\\\\PowderCoating.Web\\\\Views\\\\Jobs\\\\Create.cshtml\" \\\\\n \"Y:\\\\PCC\\\\PowderCoatingApp\\\\src\\\\PowderCoating.Web\\\\Views\\\\Jobs\\\\Edit.cshtml\")",
"Bash(cp:*)",
"Bash(dotnet fsi -e \":*)",
"Read(//y/tmp/**)",
"Bash(cp /c/Users/spoul/.nuget/packages/stripe.net/50.4.1/stripe.net.50.4.1.nupkg stripe.zip)",
"Bash(unzip -o stripe.zip *.cs -d stripe_src)",
"Bash(dotnet ef:*)",
"Bash(Payment)",
"Bash(Deposit \")",
"Bash(node:*)",
"WebFetch(domain:quickbooks.intuit.com)",
"WebFetch(domain:www.saasant.com)",
"WebFetch(domain:www.liveflow.com)",
"WebFetch(domain:www.gentlefrog.com)",
"WebFetch(domain:blog.coupler.io)",
"WebFetch(domain:litextension.com)",
"WebFetch(domain:www.dancingnumbers.com)",
"WebFetch(domain:www.bizbooks.pro)",
"WebFetch(domain:support.saasant.com)",
"WebFetch(domain:support.getcount.com)",
"WebFetch(domain:planergy.com)",
"WebFetch(domain:www.wizxpert.com)",
"WebFetch(domain:www.trykeep.com)",
"WebFetch(domain:gentlefrog.com)",
"WebFetch(domain:www.syscloud.com)",
"WebFetch(domain:interopay.zendesk.com)",
"WebFetch(domain:docs.d-tools.cloud)",
"WebFetch(domain:paygration.com)",
"Bash([ ! -d \"Y:/PCC/PowderCoatingApp/src/PowderCoating.Web/Views/$controller\" ])",
"Bash(bash /tmp/check_actions.sh)",
"Bash(bash /tmp/verify_endpoints.sh)",
"Bash(bash /tmp/verify_services.sh)",
"Read(//y/PCC/Deployments/**)",
"Bash(mkdir -p \"Y:/PCC/Deployments\")",
"Bash(dotnet-script -e \"using System.Reflection; var a = Assembly.LoadFrom\\(\\\\\"Anthropic.SDK.dll\\\\\"\\); var types = a.GetTypes\\(\\).Where\\(t => t.Name.Contains\\(\\\\\"Document\\\\\"\\) || t.Name.Contains\\(\\\\\"Content\\\\\"\\)\\).Select\\(t => t.Name\\).OrderBy\\(n => n\\); foreach\\(var t in types\\) Console.WriteLine\\(t\\);\")",
"Bash(sort -t'-' -k3 -r)",
"Bash(wsl grep:*)",
"Bash(find src:*)",
"Bash(dotnet csharp *)",
"Read(//c/Users/spoul/.nuget/packages/stripe.net/50.4.1/lib/netstandard2.0/**)",
"Bash(dotnet publish *)",
"Bash(Compress-Archive -Path * -DestinationPath \"..\\\\deploy.zip\" -Force)",
"Bash(az webapp *)",
"Read(//y/PCC/**)",
"Bash(Get-Date -Format 'yyyyMMdd_HHmmss')",
"PowerShell(Get-Content *)",
"PowerShell(dotnet build *)",
"PowerShell(New-Item *)",
"PowerShell(& \"Y:\\\\PCC\\\\PowderCoatingApp\\\\scripts\\\\generate-migration-script.ps1\")",
"PowerShell(if \\(Test-Path \"Y:\\\\pcc\\\\deployment\\\\migrations.sql\"\\) { $f = Get-Item \"Y:\\\\pcc\\\\deployment\\\\migrations.sql\"; Write-Host \"File exists: $\\($f.Length\\) bytes\" } else { Write-Host \"File not created\" })",
"Bash(git add *)",
"Bash(git commit -m ' *)",
"Bash(git push *)",
"Bash(git commit *)",
"Bash(git checkout *)",
"Bash(git merge *)",
"Bash(dotnet package *)",
"Bash(dotnet test *)",
"Bash(git rm *)",
"Bash(git stash *)",
"Bash(dotnet ef *)",
"Bash(sqlcmd -S \".\\\\SQLEXPRESS\" -d PowderCoatingDb -Q \"SELECT Id, DisplayName, IsCoating, IsActive FROM InventoryCategoryLookups ORDER BY DisplayOrder\" -W)",
"Skill(schedule)",
"Bash(git -C \"//192.168.0.37/SCPSoftware/tmp/PowderCoatingApp-dev-perf\" log --oneline -10)",
"Bash(git -C \"//192.168.0.37/SCPSoftware/tmp/PowderCoatingApp-dev-perf\" status --short)",
"Bash(git *)",
"Bash(get-childitem -Recurse -Filter \"QuotesController.cs\")",
"Bash(Select-Object -ExpandProperty FullName)",
"Bash(dotnet user-secrets *)",
"Bash(Get-ChildItem -Path \"Y:\\\\PCC\\\\PowderCoatingApp\" -Directory)",
"Bash(Select-Object Name)",
"Bash(Get-Content *)",
"Bash(python -c \"import json; data=json.load\\(open\\('prismatic_powders.json','r',encoding='utf-8'\\)\\); print\\(f'Total records: {len\\(data\\)}'\\); print\\('First record:'\\); print\\(json.dumps\\(data[0], indent=2\\)\\)\")",
"Bash(python -c \"import json; data=json.load\\(open\\('prismatic_powders.json','r',encoding='utf-8'\\)\\); keys=list\\(data.keys\\(\\)\\); print\\('Top-level keys:', keys[:10]\\); first=data[keys[0]]; print\\('First record key:', keys[0]\\); print\\(json.dumps\\(first, indent=2\\)\\)\")",
"PowerShell(Get-ChildItem *)",
"PowerShell(Select-String *)",
"Bash(Select-Object -First 20)",
"PowerShell(node -e \"require\\('fs'\\).existsSync\\(require\\('path'\\).join\\(process.cwd\\(\\), 'node_modules', 'sharp'\\)\\) ? console.log\\('sharp ok'\\) : console.log\\('no sharp'\\)\")",
"WebFetch(domain:www.powdercoatinglogix.com)",
"PowerShell($bytes = [System.IO.File]::ReadAllBytes\\('src/PowderCoating.Web/Views/Jobs/Details.cshtml'\\); $text = [System.Text.Encoding]::UTF8.GetString\\($bytes\\); $idx = $text.IndexOf\\('hasPowderData'\\); $snippet = $text.Substring\\($idx - 20, 250\\); [System.Text.Encoding]::Unicode.GetBytes\\($snippet\\) | Format-Hex | Select-Object -First 30)",
"PowerShell($dll = \"C:\\\\Users\\\\spoul\\\\.nuget\\\\packages\\\\questpdf\\\\2024.12.3\\\\lib\\\\net6.0\\\\QuestPDF.dll\"; $asm = [Reflection.Assembly]::LoadFile\\($dll\\); $asm.GetTypes\\(\\) | Where-Object { $_.Name -eq \"ContainerExtensions\" } | ForEach-Object { $_.GetMethods\\(\\) | Where-Object { $_.Name -match \"Canvas|Rotat|Layer\" } | Select-Object Name } | Sort-Object Name -Unique)",
"PowerShell(Get-ChildItem \"C:\\\\Users\\\\spoul\\\\.nuget\\\\packages\\\\\" -ErrorAction SilentlyContinue | Where-Object { $_.Name -match \"quest|skia\" } | Select-Object Name)"
]
}
}