Commit graph

25 commits

Author SHA1 Message Date
Arthur Bassi
1edcf479ae fix(work-orders): apply account scope across create and reads [SH-221]
Stamp WorkOrder.AccountId on all create paths and filter board/list/search/detail by server-derived account claims so scoped callers cannot cross accounts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 10:45:37 -03:00
Arthur Bassi
ea2dedf579 !fix(work-orders): fail-closed media account scope with org_scope claim [SH-221] 2026-08-06 10:26:04 -03:00
Alexandre Brandizzi
7d245eb717
refactor: enforce backend boundaries and optimize dispatch (#30)
* refactor(api): enforce service and data-service boundaries

* refactor(api): complete feature service boundaries

* refactor(identity): enforce service and data boundaries

* refactor(vendors): enforce service and data boundaries

* refactor(workorders): enforce service and data boundaries

* refactor(backend): enforce architecture and optimize dispatch

* style(backend): format changed architecture files

* fix(architecture): address backend review follow-ups

* fix(backend): sanitize exception disclosure in changed API endpoints

Replace raw exception-message disclosure (ex.Message) returned to API
callers with a stable sanitized public message plus correlated structured
internal logging, across the endpoints changed in this PR.

- Add SanitizedErrors helper: logs the original exception at Error with a
  generated correlation id and returns a stable public message referencing
  it so support can trace without exposing internals.
- Inject ILogger<T> into the 14 changed controllers and route every
  ex.Message/dbex.Message disclosure through the helper, preserving status
  codes, response shapes, and business data (e.g. OpenWorkOrders).
- Leave FluentValidation (vex.Errors) and existing fixed-message catches
  untouched; out-of-scope controllers (Account/Contact/Employee/Asset/
  PMSchedule) are unchanged.
- Add focused tests proving internal exception text is not returned and
  that Error logging carrying the original exception is invoked.

* fix(architecture): abstract job run state access

* style: format board update service

* test: use collection assertion idiom
2026-07-24 17:35:34 -03:00
Alexandre Brandizzi
4863d1fdaf feat(vendors): complete operations roadmap backend 2026-07-23 19:18:06 -03:00
Alexandre Brandizzi
8cf49afc2c feat(vendors): complete core vendor workflows 2026-07-23 17:02:40 -03:00
Alexandre Brandizzi
1162c68596
feat(vendors): add directory filters and details API (#25)
* feat(vendors): add directory filters and details API

* fix(vendors): preserve omitted status

* fix(vendors): align facet filtering

* fix(vendors): address directory review findings
2026-07-23 15:55:47 +00:00
Adam Moussa
1f3972ae49
Add calendar/events backend API (#8)
* Align EntityFrameworkCore.SqlServer and Tools to 8.0.8

* Add calendar/events backend API

Cherry-picked from main-backup (19994ef); scratch notes file removed.

* Require authentication on CalendarController

Security review found [Authorize] commented out, leaving all 6 calendar
endpoints anonymous. Enforce auth to match the API convention (17/23
controllers).

* Add CalendarController unit tests (xUnit + EF InMemory)
2026-06-22 18:46:46 -04:00
npalOmega
59385cf5b1 backend changes 2026-05-14 11:00:12 -05:00
npalOmega
5e4d9894e9 backend architectural template 2026-05-06 10:49:33 -05:00
Adam Moussa
81472bf729 Add dispatch sign-offs with signature capture
- DispatchSignoff model (DispatchId, SignoffType, Name, Signature base64, SignatureMethod, SignedAt)
- AddDispatchSignoff endpoint — one per type per dispatch, validates no duplicate
- GetDispatchById includes signoffs in response
- Migration for DispatchSignoffs table
2026-04-17 15:51:20 -04:00
Adam Moussa
3a25fa8559 Add dispatch checklist items with template support
- DispatchChecklistItem model (DispatchId, WorkOrderId, ItemText, IsCompleted, CompletedBy, CompletedAt)
- DispatchToVendor copies template items when TaskListTemplateId provided
- Supports custom checklist items alongside template items
- UpdateChecklistItem endpoint to toggle completion with user name
- AddChecklistItem endpoint for ad-hoc items
- GetDispatchById includes checklist items in response
- Migration for DispatchChecklistItems table
2026-04-17 15:28:52 -04:00
Adam Moussa
be190836a4 Add multi-WO dispatch support with junction table
- DispatchWorkOrder junction table for 1:N dispatch-to-WO relationship
- Make Dispatch.WorkOrderId nullable (backward compat)
- Add AcceptToken and AcknowledgedAt to Dispatch model
- Dispatch_DTO accepts WorkOrderIds array
- DispatchToVendor creates junction rows, email lists all WOs in table
- GetDispatches queries both junction table and direct FK
- GetDispatchById includes workOrders list from junction table
- Migration with DispatchWorkOrder table
2026-04-17 15:16:28 -04:00
Adam Moussa
1f4bd12cd7 Add Task List Templates with CRUD controller
- TaskListTemplate and TaskListTemplateItem models
- TaskListTemplateController: list, get by ID, create with items, update (replace items), soft delete
- Migration for new tables
2026-04-17 14:57:18 -04:00
Adam Moussa
63f76e9b2c Add dispatch detail modal backend + vendor reply sync
- Add DispatchNumber and CompletedDate to Dispatch model
- Add DispatchId to Comments for per-dispatch vendor threads
- GetDispatchById endpoint with vendor communication thread
- UpdateDispatch endpoint for status, NTE, dates, description
- AddDispatchComment endpoint — saves comment + sends email to vendor with sender name
- BackfillDispatchNumbers endpoint for existing dispatches
- SyncVendorReplies endpoint — pulls from DynamoDB VendorReplies table
- Fix reply-to address to include dispatch number
- Include sender name in dispatch and comment emails
2026-04-17 14:01:03 -04:00
Adam Moussa
ee69a1863a Add vendor scheduled date to dispatch workflow
- Add ScheduledDate field to Dispatch model and DTO
- Save scheduled date when dispatching to vendor
- Include ScheduledDate in dispatch response projections
2026-04-17 11:47:00 -04:00
Adam Moussa
d24c4643f5 Add vendor dispatch workflow backend
- Create Vendor model with company info, trade specialties, active flag
- Create Dispatch model (doubles as Vendor PO) with PO number, NTE, status, reply-to address
- VendorController: CRUD, paginated list, dropdown endpoint with trade filtering
- DispatchToVendor endpoint: multi-vendor dispatch, auto-generated PO numbers (VPO-00001),
  HTML email with full WO details via SendGrid, reply-to wo-{number}@int.seahaven.com
- GetDispatches endpoint for listing dispatches by WO
- Include dispatches in GetWorkorderById response
- SendMessage.SendDispatchEmail with reply-to support
- Audit log entry for each dispatch
2026-04-17 11:37:35 -04:00
Adam Moussa
05b36ef7dd Add configurable dropdowns, new WO fields, and seed data
- Create DropdownOption model with Category, Value, ParentValue for Trade/SubTrade/Problem
- Add DropdownOptionsController with CRUD + ByCategory endpoint with parent filtering
- Add Problem, Trade, SubTrade, VendorNTE, ScheduledDate, CompletedDate, Source to WorkOrder
- Update EditWorkorder_DTO and GetWorkorderById with new fields
- Audit log tracks changes to all new fields
- Seed default Trades (10), SubTrades (20), and Problems (11) on startup
2026-04-17 10:40:38 -04:00
Adam Moussa
be70c84add Make Comments_DTO fields nullable for JSON endpoint compatibility
- Text, UserId, CreatedDate are set server-side, not required from client
2026-04-16 18:24:04 -04:00
Adam Moussa
e1f57d3fb2 Add comment types, audit logging, and WorkOrderAuditLog table
- Add CommentType field to Comments (customer, vendor, internal)
- Add Status field to EditWorkorder_DTO
- Create WorkOrderAuditLog model tracking field-level changes
- Log all field changes on work order edit and status change
- Include commentType and auditLog in GetWorkorderById response
- Set CommentType=customer on synced comments from DynamoDB
- Add BackfillCommentTypes endpoint for existing data
2026-04-16 18:09:57 -04:00
Adam Moussa
93fa76a5aa Handle string-to-int AccountId conversion in Location DTOs
- Frontend sends accountId as empty string when not set
- Change DTO AccountId to string with GetAccountId() parser
- Prevents JSON deserialization error on empty/non-numeric values
2026-04-16 17:15:28 -04:00
Adam Moussa
534f97d6f1 Add LocationController with full CRUD and extended model
- Extend Locations model with Address, City, State, ZipCode, Phone, Contact, ContactEmail, Status, AccountId
- Update Location DTOs to match new fields
- Create LocationController with paged list, get by ID, create, update, delete
- Support both REST-style routes (/api/Location/{id}) and legacy query routes (/api/Location/DeleteLocation?id=)
- Add migration for new Location columns
2026-04-16 17:09:59 -04:00
npalOmega
a9fc4b8701 fix 2026-03-30 06:49:40 -05:00
npalOmega
cd78c93fa8 fix 2026-01-21 16:24:54 -06:00
npalOmega
9c78cd96fa added new controllers 2026-01-21 15:41:19 -06:00
69b9e69f00 Initial commit 2024-09-28 14:58:36 -04:00