Skip to main content

CMS FAQ Management Extension — Delivery Review v3.0

Extension: FAQ Management (Epic 193) Source Version Reviewed: v1.0.0.73 (V23 archive, dated March 5, 2026) Compiled Version in Sandbox: v1.0.0.73 Vendor: Sataware Technologies LLC Solution Design Date: December 16, 2025 Original Review Date: March 6, 2026 (v1.1 — symbol extraction only) First Source Review Date: March 19, 2026 (v2.0 — v1.0.0.57 source) Current Review Date: March 24, 2026 (v3.0 — v1.0.0.73 source) Prepared by: Phil McCaffrey, ERP Specialist Organization: Bestway (USA) Inc.


Executive Summary

This is the third Delivery Review of the CMS FAQ Management extension (Epic 193). The v2.0 review (March 19, 2026) was based on v1.0.0.57 source code — 16 revisions behind the v1.0.0.73 binary deployed in the sandbox. On March 20, 2026, Sataware delivered a zip archive ("V23 FAQ Management 05-03-2026.zip") containing source code labeled v1.0.0.73, closing the version number gap identified in v2.0.

This review is based on a complete reading of all 17 AL source files in the V23 archive and a successful compilation using the AL Language compiler (v16.3.31.33499). The source compiles with warnings only (no errors), confirming it can produce a functional .app binary.

Key findings in this review:

  1. The core SDD gap analysis from v2.0 is unchanged. The v1.0.0.73 source addresses none of the structural gaps: 2 of 6 tables extended, 0 of 36 required fields delivered, no incremental sync, no code generation, no CSM logging (Story 7), and the same security vulnerabilities (hardcoded credentials).

  2. The FAQ Management page was refactored, not removed. The v2.0 review identified the page as potentially non-functional based on a partial reading. The V23 source reveals the file contains two versions: an 834-line commented-out old version followed by an active rewrite (lines 838–1662). The active version compiles and is functional.

  3. Changes from v1.0.0.57 to v1.0.0.73 are cosmetic. The 16-revision gap produced UI cleanup, email formatting improvements, and minor refactoring — not gap remediation.

  4. All v2.0 recommendations remain in effect. Do not deploy to production. Revoke the hardcoded FAQ API credentials. Determine the path forward (vendor remediation or in-house completion).


1. Background

1.1. Review History

VersionDateBasisKey Finding
v1.1March 6, 2026Symbol extraction from compiled .appSignificant scope gaps visible even through symbols
v2.0March 19, 2026v1.0.0.57 source code (16 revisions behind)Full gap analysis; security findings; 5 of 26 acceptance criteria satisfied
v3.0March 24, 2026v1.0.0.73 source code (version-matched)v2.0 findings confirmed; 16-revision gap contained only UI polish

1.2. Source Code Version Gap — Resolved

Artifactv2.0 Statusv3.0 Status
Source code version1.0.0.571.0.0.73
Compiled .app version1.0.0.731.0.0.73
Gap16 revisions unaccounted forVersion numbers now match

The V23 archive app.json specifies version 1.0.0.73, matching the compiled binary in the sandbox. The source compiles successfully, producing only warnings (AL0482: invalid image "none" on two actions). The version gap that qualified every finding in v2.0 is now closed — the assessments in this document are based on the actual deployed code.

1.3. Compilation Verification

Microsoft (R) AL Compiler version 16.3.31.33499
Compilation started for project 'FAQ Management 1.0' containing '17' files.
Page/FAQManagement.Page.al(954,25): warning AL0482: The image none is not valid
Page/FAQManagement.Page.al(985,25): warning AL0482: The image none is not valid
Compilation ended.

Result: Compiles with warnings only. No errors. The source can produce the deployed binary.

1.4. Project Timeline (updated)

DateEvent
Dec 16, 2025Solution Design approved (~134 hours at $28/hr)
Feb 28, 2026v1.0.0.58 installs in sandbox
Mar 5, 2026v1.0.0.73 uploaded; source withheld pending payment
Mar 6, 2026Delivery Review v1.1 (symbol extraction)
Mar 19, 2026v1.0.0.57 source delivered; Delivery Review v2.0
Mar 20, 2026v1.0.0.73 source delivered (V23 archive)
Mar 24, 2026Delivery Review v3.0 (this document)

2. What Changed Between v1.0.0.57 and v1.0.0.73

The 16-revision gap between the v2.0 review source and the V23 source produced the following changes:

2.1. FAQ Management Page Refactored

The Pag65504.FAQManagement.al file (now Page/FAQManagement.Page.al) was rewritten. The old version was commented out in place (lines 1–834) and a new version written below it (lines 838–1662). The file is 1,662 lines total; approximately 830 lines are dead commented-out code.

Changes in the rewrite:

Areav1.0.0.57 (old version)v1.0.0.73 (new version)
Job Queue setupInline code duplicated in Daily and Weekly branchesExtracted to GetOrCreateJobQueueEntry() helper (line 1515)
Sync log trackingUpdateSyncLogJQ(DateTime, Integer)UpdateSyncLogJQ(DateTime, Integer, Boolean)pIsManual parameter distinguishes manual vs. scheduled syncs
Manual sync emailShowed active/inactive counts and new/modified countsNow includes a full table of all active records after sync
JQ sync emailShowed False→True status changes since last syncSame behavior, minor formatting refinements
Email HTMLBasic styled HTMLMore polished layout with card-style summary boxes, row numbering, alternating row colors

2.2. FAQ Sync Counter Manager Added

A new SingleInstance codeunit (65501 "FAQ Sync Counter Manager") was added to pass insert/modify counts from the Job Queue execution context to the page. This addresses a real problem — the Job Queue runs the codeunit in a separate session, so the page cannot directly read the codeunit's counters. The SingleInstance pattern persists the counts in memory within the same server session.

2.3. No Structural Changes

The following areas are unchanged between v1.0.0.57 and v1.0.0.73:

  • API client (codeunit 65500) — same endpoints, same hardcoded credentials, same full-fetch logic
  • Table extensions — same 2 tables (Fault Area, Fault/Resol. Relationship), same fields
  • Page extensions — same filters, same commented-out Service Item Group filter
  • Job Queue Log Entry trigger — same double-execution pattern
  • Reports — same Report 65501 (mark all as false) and Report 51000 (Excel export)
  • Admin Permission page — same hardcoded admin/12345 credentials
  • API Setup table — still exists, still ignored by the codeunit
  • All custom tables — unchanged

3. SDD Compliance — Section-by-Section Mapping

3.1. Section 2: Objectives

#ObjectiveStatusEvidence
1Synchronize fault-related master data from the FAQ API into BCPartialCodeunit 65500 fetches and upserts 4 of 6 tables. Fault Area/Symptom Relationship (50113) not addressed. Symptom Code, Fault Code, and Resolution Code synced without Status fields
2Ensure BC uses only valid and active codes for new transactionsPartialOnly 2 of 6 tables have Status fields. Fault Code, Symptom Code, Resolution Code, and Fault Area/Symptom Relationship have no active/inactive distinction — all records remain selectable
3Preserve historical Service Orders, PSI records, and posted dataCompliantNo code touches posted documents
4Introduce inactive handling without deleting existing recordsPartialReport 65501 marks Fault/Resol. Relationship and Fault Area records as "false." Remaining 4 tables have no Status field. Additionally, the delete-and-reinsert pattern in codeunit 65500 (line 210) violates the "without deleting" requirement
5Provide controlled synchronization mechanisms as defined in this documentPartialCodeunit and UI exist, but only full sync is implemented — no incremental sync per Section 7.2

3.2. Section 5: Data Entities & Tables

BC TableTable IDSDD In ScopeExtended?Fields AddedSDD Required
Fault Area5915YesYes (TableExt 50076)Status (Option "true"/"false")6 fields per Epic (FAQ ID, Active, Created in FAQ, Updated in FAQ, Created in BC, Updated in BC)
Symptom Code5916YesNO6 fields
Fault Code5918YesNO6 fields
Resolution Code5919YesNO6 fields
Fault/Resol. Relationship5920YesYes (TableExt 65500)Status (Option), Source (Text)6 fields
Fault Area/Symptom Rel.50113YesNO6 fields

Result: 2 of 6 tables extended. 0 of 36 required fields (per Epic Story 2) delivered. The Status fields on the 2 extended tables use Option type with "true"/"false" members — not the Boolean "Active" field specified in the Epic.

3.3. Section 6: Core Design Principles

#PrincipleStatusEvidence
1No deletion of records once used in posted transactionsVIOLATEDCodeunit 65500, lines 209–212: FaultResolutionRel.Delete(true) followed by NewFaultResolutionRel.Insert(true). When a Fault/Resol. Relationship record's Service Item Group Code changes, the existing record is deleted and a new one inserted. If the original record was referenced by a posted Service Order, the reference is now orphaned
2Inactive records retained for historical referencePartialStatus field exists on Fault Area and Fault/Resol. Relationship only. 4 of 6 tables have no inactive capability
3Only active values available for new transactionsPartialOnOpenPage filters on Fault Areas (PageExt 50001, line 16) and Fault/Resol. Relationship page (PageExt 65501, line 42). OnLookup filter on Service Order Subform (PageExt 50000, line 15). Service Item Worksheet Subform (PageExt 50005, line 44) has the Service Item Group Code filter commented out — shows all active fault areas regardless of product category
4Synchronization logic must be safe to re-runVIOLATEDThe delete-and-reinsert pattern means re-running the sync can delete and recreate records with different Service Item Group mappings. The OnAfterInsert trigger on Job Queue Log Entry (line 20) calls GetStandardFormat after the Job Queue has already executed the codeunit, causing double execution per scheduled run
5Existing extension boundaries must be respectedCompliantNo cross-extension ID conflicts observed

3.4. Section 7.1: One-Time Full Rebuild Sync

#RequirementStatusEvidence
1All existing fault-related records will be marked InactivePartialReport 65501 sets Status = "false" on Fault/Resol. Relationship records (line 16) and Fault Area records (lines 18–27). Symptom Code, Fault Code, Resolution Code, and Fault Area/Symptom Relationship have no Status field and cannot be marked
2A complete import will be performed from the FAQ APIImplementedCodeunit 65500 GetStandardFormat fetches the full dataset from /api/1.0/standardFormat
3FAQ API identifiers will be persisted as the primary referenceNOT implementedAPI integer IDs (e.g., "7", "44", "56") are used directly as BC Code field values. No separate FAQ ID field exists on the fault master tables. The ServiceItemGroupCodeBuffer table (50001) has a "FAQ ID" field, but this is a manual mapping table for Fault Area → Service Item Group, not a comprehensive FAQ identifier store
4No legacy-to-API mapping logic will be maintainedCompliantNo legacy mapping code exists
5Historical and posted data will remain unchangedCompliantNo code modifies posted documents. However, the delete-and-reinsert pattern (codeunit 65500, line 210) can orphan references from posted Service Orders to Fault/Resol. Relationship records

3.5. Section 7.2: Automated Incremental Sync

#RequirementStatusEvidence
1Periodic unattended executionImplementedJob Queue scheduling via ScheduleMyCodeunit action (page 65504, line 1005). Supports Daily and Weekly cadences
2Detection of changes between API data and BC cacheNOT implementedGetStandardFormat always fetches the entire dataset. No "last modified" parameter is sent to the API. No per-record change detection against BC cache
3Insert new recordsImplementedUpsert logic in ProcessStandardFormatResponse (codeunit 65500, lines 61–234)
4Update modified recordsImplementedDescription changes detected and applied (e.g., line 116–124 for Fault Area)
5Mark records Inactive when removed from the APINOT implementedNo logic exists to detect records present in BC but absent from the API response. Records that are removed from the FAQ API will remain active in BC indefinitely
6Maintain sync state across executionsPartialFAQ Sync Log table (50012) tracks sync timestamps and record counts. UpdateSyncLogJQ writes a log entry after each sync. However, no per-record sync state exists — there is no way to determine which specific records were added, modified, or should be deactivated in a given sync

3.6. Section 7.3: Stakeholder Notification

#RequirementStatusEvidence
1Configurable recipient listImplementedEmail Recipient Setup table (65550) with user lookup page (65551). Recipients selected from BC Users list via OnLookup
2Summary of newly added recordsImplementedInsert count tracked in codeunit 65500 (FaultResolutionRelInsertCount), passed to page via FAQ Sync Counter Manager SingleInstance codeunit, displayed in email body
3Summary of updated recordsImplementedModify count tracked similarly and included in email summary cards
4Summary of records marked InactiveNOT implementedNo logic exists to mark records Inactive (see Section 3.5 #5), so no summary of deactivated records is possible. The JQ email reports records where Status changed from False → True, but not the reverse

3.7. Section 8: UI & Validation Behavior

RequirementStatusEvidence
Active fault-related values available for selection in new Service Orders, PSIs, and related transactionsPartialOnLookup on Service Order Subform (PageExt 50000, line 15) filters Fault Area Code by Fault/Resol. Relationship Status = "True" and Service Item Group Code. This works for the one table that has both Status and Service Item Group mapping
Inactive values will remain stored for historical reference but will not be selectablePartialOnOpenPage filters hide inactive records on Fault Areas and Fault/Resol. Relationship pages. However, these are soft filters — users can clear them. Service Item Worksheet Subform (PageExt 50005, line 44) has the Service Item Group Code filter commented out, showing all active fault areas regardless of product
UI updated across all fault-related pagesIncompleteOnly 3 page extensions delivered (Fault Areas, Service Order Subform, Service Item Worksheet Subform). No extensions for Symptom Code, Fault Code, or Resolution Code pages — those tables have no Status field to filter on

3.8. Section 9: Data Safety & Integrity

#CommitmentStatusEvidence
1No modification of posted documentsCompliantNo code references posted document tables
2Inactive handling ensures backward compatibilityPartialOnly 2 of 6 tables participate in inactive handling. Historical Service Orders referencing records on the 4 unextended tables will continue to display correctly (no schema change), but those records cannot be marked inactive when they become stale
3Partial updates are avoidedVIOLATEDNo transaction control wraps the sync loop (codeunit 65500, lines 96–234). If the API call succeeds but processing fails mid-array (e.g., a record insert fails on row 500 of 1,000), the first 499 records are committed while the remaining 501 are not. The Commit() in UpdateSyncLogJQ (page 65504, line 1508) forces a commit boundary that prevents rollback of partial data
4Repeat executions do not create duplicate or invalid dataVIOLATEDThe delete-and-reinsert pattern (codeunit 65500, lines 209–212) means a re-run can delete a Fault/Resol. Relationship record and recreate it with a different SystemCreatedAt timestamp, invalidating any SystemModifiedAt-based change detection. The double execution via OnAfterInsert (Job Queue Log Entry ext, line 20) means every scheduled sync runs twice, with the second execution seeing the first execution's modifications as "already exists" rather than "new"

4. Deliverable Status

#Deliverablev1.1 (Mar 6)v2.0 (Mar 19)v3.0 (Mar 24)
D1BC extension logic for FAQ syncPartially deliveredPartially deliveredPartially delivered — unchanged. Core upsert works for 4 tables. Missing: 4 table extensions, 36 fields, incremental logic, inactive marking, code generation
D2One-time full rebuild syncExecuted but unverifiablePartially deliveredPartially delivered — unchanged. Report 65501 marks 2 of 6 tables
D3Automated incremental syncUnknownNOT deliveredNOT delivered — confirmed. Every scheduled run is a full sync. No change detection, no API-side removal detection, no per-record sync state
D4Stakeholder notificationUnknownDeliveredDelivered — confirmed. Email notifications work with configurable recipients, styled HTML reports, and manual/scheduled variants. Minor improvements in v1.0.0.73 (better formatting, row numbering, manual/scheduled distinction in sync log)
D5Final source code deliveryNOT deliveredPartially delivered (v1.0.0.57)Delivered — v1.0.0.73 source matches compiled binary. Source compiles successfully
D6Supporting technical documentationNOT deliveredNOT deliveredNOT delivered — no documentation of any kind

5. Security Findings

All security findings from v2.0 remain present and unchanged in v1.0.0.73.

5.1. Hardcoded FAQ API Credentials (CRITICAL)

File: Codeunit/FAQAPIIntegration.Codeunit.al, line 24 Code: 'https://faq.bestwaycorp.com/ExternalAPI/api/Login/token?username=BWUFAQ&password=BWUFAQ123'

The API Setup table (65503) exists with Login and URL fields but is never read. The codeunit calls RecAPISetup.Get() (line 23) but only to verify the record exists — the actual URL, username, and password are hardcoded.

5.2. Hardcoded Admin Password (CRITICAL)

File: Page/AdminPermission.Page.al, lines 35–36 Code: ExpectedUser := 'admin'; ExpectedPass := '12345';

The "Admin Permission" dialog (page 50001) gates the "First Time Sync" action behind a hardcoded username/password check. This is not BC security — it is a custom cleartext credential check that provides no real access control. Any user who reads the source or decompiles the .app can bypass it.

5.3. Credentials in Source Control

Both sets of credentials are now in source control (this repository). They must be considered compromised regardless of access restrictions on the repo.


6. Code Quality Findings (New in v1.0.0.73)

6.1. Dead Code — 834 Lines of Commented-Out Page

File: Page/FAQManagement.Page.al, lines 1–834

The entire old version of page 65504 is commented out in place rather than removed. This is approximately 50% of the file by line count. The old version and new version are functionally similar — the new version has minor improvements (helper extraction, email formatting) but the same architecture.

This dead code:

  • Doubles the file size with no functional benefit
  • Creates confusion during review (the v2.0 review initially assessed only the commented-out version)
  • Indicates source control was not used to track revisions

6.2. Double Execution — OnAfterInsert Trigger

File: TableExt/JobQueueLogEntryExt.TableExt.al, lines 14–25

The OnAfterInsert trigger on Job Queue Log Entry fires after the Job Queue has already executed codeunit 65500. The trigger then calls FAQIntegration.GetStandardFormat('en') again (line 20), causing the entire sync to run twice per scheduled execution. The second execution creates a new FAQ API Integration codeunit instance (line 11), so it has its own counters — the insert/modify counts reported by the second run do not include the first run's work.

6.3. Delete-and-Reinsert Pattern

File: Codeunit/FAQAPIIntegration.Codeunit.al, lines 209–212

When a Fault/Resol. Relationship record's Service Item Group Code needs to change, the code deletes the existing record and inserts a new one:

FaultResolutionRel.Delete(true);
NewFaultResolutionRel.Validate("Service Item Group Code", ...);
NewFaultResolutionRel.Insert(true);

This pattern:

  • Violates SDD Section 6 principle #1 (no deletion of records used in posted transactions)
  • Violates SDD Section 9 commitment #4 (repeat executions safe)
  • Changes SystemCreatedAt and SystemId on re-insert, breaking any external references
  • Fires OnDelete and OnInsert triggers, which may have side effects from other extensions

6.4. Report Layout Path Reference

File: Report/FaultResolCodRelationshiprep.Report.al, line 7 Code: RDLCLayout = 'src/FaultResolCodRelationshiprepnew.rdl';

The report references src/FaultResolCodRelationshiprepnew.rdl, but the file is located at ReportLayout/FaultResolCodRelationshiprepnew.rdl in the organized folder structure. This path mismatch would cause a runtime error when the report is run. The file must be at the path specified in the RDLCLayout property relative to the project root, or the property must be updated.


7. Gap Analysis Summary

7.1. Story-Level Completion (unchanged from v2.0)

StoryAcceptance CriteriaSatisfiedPartiallyNot Implemented
Story 1: API Client3111
Story 2: Sync Fields3012
Story 3: Periodic Job3201
Story 4: Code Generation2002
Story 5: Active Filtering2020
Story 6: Email Notifications2200
Story 7: CSM Logging3003
Total18549

7.2. Required Fields Gap (unchanged from v2.0)

FieldEpic SpecTables RequiredTables DeliveredGap
FAQ ID (Int)Story 2606 missing
Active (Boolean)Story 2606 missing
Created in FAQ (Timestamp)Story 2606 missing
Updated in FAQ (Timestamp)Story 2606 missing
Created in BC (Timestamp)Story 2606 missing
Updated in BC (Timestamp)Story 2606 missing
Total36036 missing

7.3. Missing Capabilities (unchanged from v2.0)

  1. Incremental sync does not exist. Every run is a full sync. No differential fetch, no API-side removal detection, no per-record sync state.
  2. Inactive marking is incomplete. Only 2 of 6 tables have a Status field.
  3. Code generation does not exist. FAQ API integer IDs used directly as BC Code values.
  4. CSM Quality Report logging is entirely missing. Story 7 has zero implementation.
  5. FAQ API identifiers are not persisted separately. The API ID is the Code field — no separate FAQ ID on fault master tables.

8. Effort vs. Delivery Assessment

MetricAgreedDelivered
Estimated effort134 hours ($3,752)Invoice #466051 submitted for full amount
User stories addressed74 partially, 1 fully (notifications), 2 not addressed (code gen, CSM logging)
Acceptance criteria185 fully satisfied, 4 partially, 9 not implemented
Required field implementations36 (6 fields x 6 tables)0 of the specified fields
Table extensions6 tables2 tables
Deliverables61 fully delivered (notifications), 1 delivered (source code), 2 partially delivered, 2 not delivered
Core sync capabilities3 (rebuild, incremental, notification)1 partially delivered (rebuild), 1 delivered (notification), 1 not delivered (incremental)

9. What v1.0.0.73 Resolved (Relative to v1.0.0.57)

The 16-revision gap between v1.0.0.57 and v1.0.0.73 resolved:

  1. Source code delivery. Bestway now has version-matched source code. D5 is delivered.
  2. FAQ Management page refactoring. The management UI was rewritten with minor improvements (helper extraction, email formatting, manual/scheduled sync log distinction).
  3. Sync counter passing. The FAQ Sync Counter Manager SingleInstance codeunit addresses the cross-session counter problem between Job Queue execution and the management page.

The 16-revision gap did not resolve:

  • Any of the 36 missing field implementations
  • Any of the 4 unextended tables
  • Incremental sync
  • Code generation
  • CSM Quality Report logging (Story 7)
  • Hardcoded credentials (FAQ API or admin)
  • Double execution via OnAfterInsert
  • Delete-and-reinsert pattern
  • Missing documentation (D6)

10. Recommendations

10.1. Immediate Actions (unchanged from v2.0)

  1. Do not deploy to production. The security vulnerabilities (hardcoded credentials), data integrity defects (double execution, delete-and-reinsert, no transaction control), and incomplete scope make this extension unsafe for production use.

  2. Revoke the FAQ API credentials (BWUFAQ / BWUFAQ123) immediately. These credentials are in source control and must be considered compromised.

  3. Fix the report layout path. Report/FaultResolCodRelationshiprep.Report.al references src/FaultResolCodRelationshiprepnew.rdl but the file is at ReportLayout/FaultResolCodRelationshiprepnew.rdl. This will cause a runtime error.

10.2. Path Forward — Decision Required (unchanged from v2.0)

Option A: Require Sataware to remediate.

  • Pro: Vendor accountability.
  • Con: The v1.0.0.57 → v1.0.0.73 gap shows 16 revisions of UI polish with no structural gap remediation. This suggests the vendor either does not acknowledge the gaps or lacks the capability to address them.
  • Requirement: Concrete remediation plan with dates, milestones, and acceptance criteria per story.

Option B: Bring the extension in-house for completion.

  • Pro: Full control over quality, timeline, and architecture. Bestway has the BC development capability and standards infrastructure.
  • Con: Additional internal effort. The existing code requires substantial rework (credential management, transaction safety, inactive handling, 4 additional table extensions, incremental sync, code generation, CSM logging).
  • Consideration: Invoice reconciliation — the delivered extension satisfies 5 of 18 acceptance criteria.

10.3. Discussion Points for Sataware (updated)

  1. Source code is now delivered. Acknowledge receipt of v1.0.0.73 source. This closes D5.
  2. Scope acknowledgment: The 16 revisions between v1.0.0.57 and v1.0.0.73 contain only UI polish. Does Sataware acknowledge the 18 acceptance criteria and 36 field implementations remain unaddressed?
  3. Invoice reconciliation: 5 of 18 acceptance criteria are satisfied. 1 of 6 deliverables is fully delivered. How should Invoice #466051 be reconciled against this delivery?
  4. Security: The hardcoded credentials (FAQ API and admin) are now in source control. Sataware must acknowledge this exposure and participate in credential rotation.

Appendix A: Object Inventory

Object TypeIDNameFileStatus
Codeunit65500FAQ API IntegrationCodeunit/FAQAPIIntegration.Codeunit.alActive — core sync logic
Codeunit65501FAQ Sync Counter ManagerCodeunit/FAQAPIIntegration.Codeunit.alActive — new in v1.0.0.73
Table50001ServiceItemGroupCodeBufferTable/ServiceItemGroupCodeBuffer.Table.alActive — FAQ ID → Service Item Group mapping
Table50012FAQ Sync LogTableExt/Faultcoderelationext.TableExt.alActive — sync history
Table65503API SetupTable/APISetup.Table.alActive — unused by codeunit
Table65550Email Recipient SetupTable/EmailRecipientSetup.Table.alActive — notification recipients
TableExt50076FaultAreaExt (extends 5915)PageExt/FaultAreasExt.PageExt.alActive — adds Status field
TableExt65500Faultcoderelationext (extends 5920)TableExt/Faultcoderelationext.TableExt.alActive — adds Status, Source
TableExt50001JobQueueLogEntryExtTableExt/JobQueueLogEntryExt.TableExt.alActive — OnAfterInsert trigger
Page50001AdminPermissionPage/AdminPermission.Page.alActive — hardcoded credential check
Page50002ServiceItemGroupCodeBufferPagePage/ServiceItemGroupCodeBufferPage.Page.alActive — mapping UI
Page65503API SetupPage/APISetup.Page.alActive — config UI (unused by codeunit)
Page65504FAQ ManagementPage/FAQManagement.Page.alActive — main management page (lines 838–1662)
Page65551Email Recipient LinesPage/EmailRecipientLines.Page.alActive — recipient subpage
PageExt50000ServiceSubformFilterExt (extends Service Order Subform)PageExt/ServiceSubformFilterExt.PageExt.alActive — Fault Area lookup filter
PageExt50001FaultAreasExt (extends Fault Areas)PageExt/FaultAreasExt.PageExt.alActive — Status column + filter
PageExt50005ServiceItemformFilterExt (extends Service Item Worksheet Subform)PageExt/ServiceSubformFilterExt.PageExt.alActive — Fault Area lookup (Service Item Group filter commented out)
PageExt65501Faultcoderelationextpage (extends Fault/Resol. Cod. Relationship)TableExt/Faultcoderelationext.TableExt.alActive — Status column + filter
Report65501Fault/ResolCodRelationshipReport/FaultResolCodRelationship.Report.alActive — marks all records as "false"
Report51000FaultResolCodRelationshiprepReport/FaultResolCodRelationshiprep.Report.alActive — Excel export (broken layout path)
Report50003AttachmentPurposeReport/AttachmentPurpose.Report.alDead code — entirely commented out
PermissionSet50012NC_Extension_AdminTable/APISetup.Table.alActive — FAQ Sync Log access
PermissionSet50100SatawareExtPermissPermissionSet/SatawareExtPermiss.PermissionSet.alActive — extension data access
PermissionSet55101API Setup PermTable/APISetup.Table.alActive — API Setup table access

Appendix B: Reference Documents

DocumentDateLocation
Solution DesignDec 16, 2025docs/V1_CSM_1_0_Fault_Detail_Sync_Solution_Design (2).pdf
Epic 193 RequirementsNov 2025docs/Epic - Sync Business Central with FAQ API.docx
FAQ API to BC MappingDec 2025docs/FAQ API to BC Mapping.png
Delivery Review v1.1Mar 6, 2026docs/CMS FAQ Management - Delivery Review v1.1.docx
Code Quality Review v1.0Mar 19, 2026docs/CMS FAQ Management - Code Quality Review v1.0.docx
Delivery Review v2.0Mar 19, 2026docs/DELIVERY-REVIEW-v2.0.md
Delivery Review v3.0Mar 24, 2026docs/DELIVERY-REVIEW-v3.0.md (this document)

Appendix C: Acceptance Criteria — Detailed Status

Story#Acceptance CriterionStatusEvidence
11API client supports authentication with FAQ APIPartialAuth works but uses hardcoded credentials (codeunit 65500, line 24) instead of API Setup table
12Can fetch data from FAQ APIYesGetStandardFormat() fetches /api/1.0/standardFormat
13Can retrieve updates from FAQ APINoNo incremental fetch — full dataset every time
21Fields added to BC tables (6 fields x 6 tables)No0 of 36 specified fields. 2 non-matching Status fields on 2 tables
22Tables updated (6 specified)Partial2 of 6 tables have extensions
23Mapping logic between FAQ API and BC tablesPartialMapping exists for 4 tables; missing for Fault Area/Symptom Relationship (50113)
31Job can be scheduled and run periodicallyYesDaily/Weekly Job Queue scheduling (page 65504, line 1005)
32Job fetches only updated records since last syncNoFull dataset fetched every run
33Scheduling is configurableYesTime and frequency options on management page
41Code generation ensures uniquenessNoNo code generation — API integer IDs used directly as BC Code values
42Code maps correctly to FAQ API IDNoAPI ID is the Code — no separate mapping field
51UI filters out inactive recordsPartialWorks on 2 tables with Status; 4 tables have no Status to filter
52Validation logic respects Active flagPartialService Order Subform lookup filters by Status on Fault/Resol. Rel. Service Item Worksheet Subform has group filter commented out
61Email includes list of changes syncedYesHTML email with active/inactive counts, change details, record-level tables
62Email sent to configured stakeholdersYesEmail Recipient Setup with user lookup
71Log includes failure codeNoStory 7 entirely unimplemented
72Log includes Service Item ID from PSINoStory 7 entirely unimplemented
73Log includes Fault Area, Symptom, Fault, ResolutionNoStory 7 entirely unimplemented