Overview
This document is a single-page navigator for two enterprise modules in the GB5 backend & frontend: WI Work Instruction and CMS Content Management System. For every feature you'll find the BE C# file paths (DAL / BLL / SL) and the matching FE Angular file paths (services, components, models).
Use the search box in the left sidebar to filter section headings. Use the back-to-top button bottom-right to jump back. Every section has a stable anchor for deep linking.
Architecture Diagram
Browser / Mobile
│
Angular 20 FE ←─── projects/wi/ and projects/cms/
│ HTTP
▼
FastEndpoints SL ←─── WiSL / CMSSL
│
BLL (Business Logic) ←─── WiBLL / CMSBLL
│
DAL (Data Access) ←─── WiDAL / CMSDAL
│ Dapper + raw SQL
SQL Server (WI.* and DBO.* schemas)
Three-Layer Pattern
SL (*.cs in EndPoints/) → BaseEndpoint<TReq, TResp> ↓ injects IBll BLL (*.cs in WiBLL/) → validates, orchestrates ↓ injects IDal DAL (*.cs in WiDAL/CustomCode/) → IQueryExecutor → Dapper ↑ SQL constants in WiDAL/Query/Wi/*QB.cs
- SL must never call DAL directly — always go through BLL.
- BLL must never reference ASP.NET types (
HttpContext, etc.). - DAL must never contain business logic; only data retrieval/mutation.
- All SQL lives in
*QB.csfiles — never inline in BLL or DAL.
Legend & Conventions
| Badge | Meaning |
|---|---|
| BE | Backend / C# (DAL, BLL, SL) |
| FE | Frontend / Angular 20 |
| DB | Database / SQL Server table or query |
| API | HTTP endpoint / route |
| WI | Work Instruction module (blue accent) |
| CMS | Content Management module (green accent) |
WI BE Section 1: WI Module — Backend (C#)
1.1 Database Schema DB
WI tables live in the WI. schema. Supplementary infrastructure tables (workstations, lines, rosters) live in the DBO. schema.
| Table | Schema | Purpose |
|---|---|---|
MWIPROCESS | WI | Process hierarchy root |
MWISUBPROCESS | WI | SubProcess within a Process |
MWI | WI | WI document header (title, version, status, etc.) |
MWISECTION | WI | Ordered sections within a WI |
MWISTEP | WI | Steps within a section; WORKSTATIONID column (-1 = inherit) |
MWISTEPCONTENT | WI | Content blocks per step; CONTAINERID / CONTAINERTYPE / ZONENAME columns |
MWIASSIGNMENT | WI | Specificity-scored assignment rules (WI ↔ Workstation/Line/Model/Routing) |
MWIACTIVITYSCHEDULE | WI | Scheduled maintenance activities |
MWORKSTATIONCONFIG | WI | Per-workstation display configuration |
MWISKILLREQUIREMENT | WI | Required skills for a WI |
MWICOMPETENCYREQUIREMENT | WI | Required competencies for a WI |
TWIEXECUTION | WI | Execution run header (start/complete/flag) |
TWISTEPEXECUTION | WI | Per-step execution record (actual duration) |
TWIACKNOWLEDGEMENT | WI | Operator acknowledgement record |
LWIVERSION | WI | Immutable version change log |
MWORKSTATION | DBO | Workstation master (code, type, workcenter) |
MPRODUCTIONLINESTATION | DBO | Append-only: which workstations are on each line |
TLINESHIFTROSTER | DBO | Shift roster header (line + shift + date) |
TLINESHIFTSTAFFING | DBO | Who is staffed at which workstation for a roster |
MLINEOPERATIONMAP | DBO | V4 flat: maps production line + routing detail → workstation |
- Full DDL:
DB/Schema/wi-complete-ddl.sql - Container evolution migration:
DB/Migrations/20260610_WI_StepContentContainerEvolution.sql
1.2 Query Builders (SQL Constants) BE
All SQL lives in *QB.cs files as public const string. Never embedded inline in BLL/DAL.
| QB File | Path | Key Constants |
|---|---|---|
WiMasterQB | WiDAL/Query/Wi/WiMasterQB.cs | GET_WI_LIST, GET_WI_BY_ID, GET_WI_FULL_DETAIL, SAVE_WI, GET_STEPS_WITH_EFFECTIVE_WORKSTATION |
WiSectionQB | WiDAL/Query/Wi/WiSectionQB.cs | GET_SECTIONS, SAVE_SECTION, DELETE_SECTION |
WiStepQB | WiDAL/Query/Wi/WiStepQB.cs | GET_STEPS, SAVE_STEP, DELETE_STEP (includes WORKSTATIONID) |
WiStepContentQB | WiDAL/Query/Wi/WiStepContentQB.cs | GET_CONTENTS, SAVE_CONTENT, DELETE_CONTENT (includes container columns) |
WiAssignmentQB | WiDAL/Query/Wi/WiAssignmentQB.cs | GET_BY_WI, SAVE_ASSIGNMENT, RESOLVE_FOR_WORKSTATION |
WiExecutionQB | WiDAL/Query/Wi/WiExecutionQB.cs | INSERT_EXECUTION, UPDATE_STEP_STATUS, COMPLETE_EXECUTION, CHECK_ACK, SAVE_ACK |
WiAnalyticsQB | WiDAL/Query/Wi/WiAnalyticsQB.cs | GET_EXECUTION_HISTORY, GET_TIME_STUDY, GET_COMPLIANCE_SUMMARY |
WorkstationQB | WiDAL/Query/Wi/WorkstationQB.cs | GET_LIST, GET_BY_ID, INSERT, UPDATE, GET_SELECT_LIST |
LineStationQB | WiDAL/Query/Wi/LineStationQB.cs | GET_CURRENT_BY_LINE, CLOSE_CURRENT, INSERT_NEW |
LineRosterQB | WiDAL/Query/Wi/LineRosterQB.cs | GET_ROSTER_HEADER, INSERT_ROSTER, GET_STAFFING_BY_ROSTER, INSERT_STAFFING, MARK_ABSENT, GET_PLANNED_VS_ACTUAL |
LineMapQB | WiDAL/Query/Wi/LineMapQB.cs | GET_CURRENT_MAP, GET_STAFFING_GAP, CLOSE_CURRENT, INSERT_NEW |
WiProcessQB | WiDAL/Query/Wi/WiProcessQB.cs | GET_LIST, GET_BY_ID, SAVE |
WiSkillRequirementQB | WiDAL/Query/Wi/WiSkillRequirementQB.cs | GET_BY_WI, SAVE, DELETE |
1.3 DTOs and Enums BE
| File | Path | Key Types |
|---|---|---|
WiDTO.cs |
WiDAL/DTO/Wi/WiDTO.cs |
WiHeaderDTO, WiSectionDTO, WiStepDTO, WiStepContentDTO, WiStepContainerDTO, WiAssignmentDTO, WiExecutionDTO, WorkstationDTO, LineShiftRosterDTO, LineShiftStaffingDTO, LineOperationMapDTO, WiStepSwimLaneDTO, WiExecutionHistoryDTO, WiTimeStudyDTO, WiComplianceSummaryDTO |
WiEnums.cs |
WiDAL/DTO/Wi/WiEnums.cs |
WiStatus, ContentType (0–9), WiContainerType (Single / TwoColumn / Banner / Accordion / Tab), ContentSource, RosterType, RosterStatus, StaffingRole, WorkstationType |
1.4 DAL Layer (Data Access) BE DB
| Feature | Interface | Implementation | Key Methods |
|---|---|---|---|
| WI Master | WiDAL/CustomCode/WiMaster/IWiMasterDAL.cs | WiMasterDAL.cs | GetWiList, GetWiById, GetWiFullDetail, SaveWiFull, GetVersionHistory, GetStepsWithWorkstationAsync |
| WI Section | WiDAL/CustomCode/WiSection/IWiSectionDAL.cs | WiSectionDAL.cs | GetByWi, Save, Delete |
| WI Step | WiDAL/CustomCode/WiStep/IWiStepDAL.cs | WiStepDAL.cs | GetBySection, Save, Delete |
| WI Step Content | WiDAL/CustomCode/WiStepContent/IWiStepContentDAL.cs | WiStepContentDAL.cs | GetByStep, Save, Delete |
| WI Assignment | WiDAL/CustomCode/WiAssignment/IWiAssignmentDAL.cs | WiAssignmentDAL.cs | GetByWi, Save, Delete, ResolveForWorkstation |
| WI Execution | WiDAL/CustomCode/WiExecution/IWiExecutionDAL.cs | WiExecutionDAL.cs | ResolveForWorkstation, StartExecution, UpdateStepStatus, CompleteExecution, CheckAcknowledgement, SaveAcknowledgement |
| WI Analytics | WiDAL/CustomCode/WiAnalytics/IWiAnalyticsDAL.cs | WiAnalyticsDAL.cs | GetExecutionHistoryAsync, GetTimeStudyAsync, GetComplianceSummaryAsync |
| WI Process | WiDAL/CustomCode/WiProcess/IWiProcessDAL.cs | WiProcessDAL.cs | GetList, GetById, Save, Delete |
| WI SubProcess | WiDAL/CustomCode/WiSubProcess/IWiSubProcessDAL.cs | WiSubProcessDAL.cs | GetList, GetById, Save, Delete |
| WI Version | WiDAL/CustomCode/WiVersion/IWiVersionDAL.cs | WiVersionDAL.cs | GetByWi, Save |
| WI Skill Req. | WiDAL/CustomCode/WiSkillRequirement/IWiSkillRequirementDAL.cs | WiSkillRequirementDAL.cs | GetByWi, Save, Delete |
| Workstation | WiDAL/CustomCode/Workstation/IWorkstationDAL.cs | WorkstationDAL.cs | GetListAsync, GetByIdAsync, InsertAsync, UpdateAsync, GetSelectListAsync |
| Line Station | WiDAL/CustomCode/LineStation/ILineStationDAL.cs | LineStationDAL.cs | GetCurrentByLineAsync, GetCurrentByWorkstationAsync, CloseCurrentAsync, InsertNewAsync |
| Line Roster | WiDAL/CustomCode/LineRoster/ILineRosterDAL.cs | LineRosterDAL.cs | GetRosterHeaderAsync, InsertRosterAsync, GetStaffingAsync, InsertStaffingAsync, MarkAbsentAsync, GetPlannedVsActualAsync |
| Line Map | WiDAL/CustomCode/LineMap/ILineMapDAL.cs | LineMapDAL.cs | GetCurrentMapAsync, GetStaffingGapAsync, CloseCurrentAsync, InsertNewAsync |
1.5 BLL Layer (Business Logic) BE
Same structure as DAL but adds validation, orchestration, and cache invalidation.
| Feature | Interface | Implementation | Notable Business Rules |
|---|---|---|---|
| WI Master | WiBLL/WiMaster/IWiMasterBLL.cs | WiMasterBLL.cs | Status lifecycle (Draft → Review → Approved → Published → Archived); SaveVersionSnapshot on Publish |
| WI Execution | WiBLL/WiExecution/IWiExecutionBLL.cs | WiExecutionBLL.cs | ResolveForWorkstation uses specificity scoring; CompleteStep records actual duration |
| WI Analytics | WiBLL/WiAnalytics/IWiAnalyticsBLL.cs | WiAnalyticsBLL.cs | Pass-through; cache NOT_REQUIRED (always live) |
| Workstation | WiBLL/Workstation/IWorkstationBLL.cs | WorkstationBLL.cs | Cache WiWorkstation at CLIENT_LEVEL; invalidate on Save |
| Line Station | WiBLL/LineStation/ILineStationBLL.cs | LineStationBLL.cs | Append-only: close old row + insert new in transaction |
| Line Roster | WiBLL/LineRoster/ILineRosterBLL.cs | LineRosterBLL.cs | Only one ISPRIMARY per workstation per roster; Draft → Confirmed → Closed only |
| Line Map | WiBLL/LineMap/ILineMapBLL.cs | LineMapBLL.cs | WorkCenter match validation; append-only save |
1.6 SL Layer (FastEndpoints — HTTP) BE API
Base path for all WI endpoints: /wi/{Group}/{Action}.
| Endpoint File | HTTP | Route | Key Params | Cache |
|---|---|---|---|---|
GetWIList | GET | /WI/GetWIList | WiProcessId, WiStatus | CLIENT_LEVEL |
GetWIById | GET | /WI/GetWIById | WiId | CLIENT_LEVEL |
GetWIFullDetail | GET | /WI/GetWIFullDetail | WiId | CLIENT_LEVEL |
SaveWIFull | POST | /WI/SaveWIFull | (body: WiSaveRequest) | null |
DeleteWI | DELETE | /WI/DeleteWI | WiId | null |
SubmitForReview | PUT | /WI/SubmitForReview | WiId | null |
ApproveWI | PUT | /WI/ApproveWI | WiId | null |
PublishWI | PUT | /WI/PublishWI | WiId | null |
ArchiveWI | PUT | /WI/ArchiveWI | WiId | null |
GetVersionHistory | GET | /WI/GetVersionHistory | WiId | CLIENT_LEVEL |
GetWiStepsWithWorkstation | GET | /WI/GetWiStepsWithWorkstation | WiId | CLIENT_LEVEL |
GetSelectListWI | GET | /WI/GetSelectListWI | — | CLIENT_LEVEL |
ResolveForWorkstation | GET | /WiExecution/ResolveForWorkstation | WorkstationId, Trigger | NOT_REQUIRED |
StartExecution | POST | /WiExecution/StartExecution | (body) | null |
CompleteStep | PUT | /WiExecution/CompleteStep | (body) | null |
CompleteExecution | PUT | /WiExecution/CompleteExecution | WiExecutionId, TotalActualSecs | null |
CheckAcknowledgement | GET | /WiExecution/CheckAcknowledgement | WiId, EmployeeId, WorkOrderId | NOT_REQUIRED |
SaveAcknowledgement | POST | /WiExecution/SaveAcknowledgement | (body) | null |
GetExecutionHistory | GET | /WiAnalytics/GetExecutionHistory | WiId=-1, WorkstationId=-1, EmployeeId=-1, FromDate, ToDate | null |
GetTimeStudySummary | GET | /WiAnalytics/GetTimeStudySummary | WiId, FromDate, ToDate | null |
GetComplianceSummary | GET | /WiAnalytics/GetComplianceSummary | WiId=-1, FromDate, ToDate | null |
GetWorkstationList | GET | /Workstation/GetWorkstationList | — | CLIENT_LEVEL |
GetWorkstation | GET | /Workstation/GetWorkstation | WorkstationId | CLIENT_LEVEL |
SaveWorkstation | POST | /Workstation/SaveWorkstation | (body) | null |
GetSelectListWorkstation | GET | /Workstation/GetSelectListWorkstation | — | CLIENT_LEVEL |
GetLineStationByLine | GET | /LineStation/GetLineStationByLine | LineId | CLIENT_LEVEL |
SaveLineStation | POST | /LineStation/SaveLineStation | (body) | null |
GetLineShiftRoster | GET | /LineShiftRoster/GetLineShiftRoster | LineId, ShiftId, Date | NOT_REQUIRED |
SaveLineShiftRoster | POST | /LineShiftRoster/SaveLineShiftRoster | (body) | null |
ConfirmLineShiftRoster | PUT | /LineShiftRoster/ConfirmLineShiftRoster | RosterId | null |
CopyForwardRoster | POST | /LineShiftRoster/CopyForwardRoster | (body) | null |
GetPlannedVsActual | GET | /LineShiftRoster/GetPlannedVsActual | LineId, ShiftId, Date | NOT_REQUIRED |
GetLineShiftStaffing | GET | /LineShiftStaffing/GetLineShiftStaffing | RosterId | NOT_REQUIRED |
SaveLineShiftStaffing | POST | /LineShiftStaffing/SaveLineShiftStaffing | (body) | null |
MarkAbsent | PUT | /LineShiftStaffing/MarkAbsent | (body) | null |
GetLineOperationMap | GET | /LineOperationMap/GetLineOperationMap | LineId | CLIENT_LEVEL |
GetStaffingGap | GET | /LineOperationMap/GetStaffingGap | LineId, RosterId | NOT_REQUIRED |
SaveLineOperationMap | POST | /LineOperationMap/SaveLineOperationMap | (body) | null |
WI FE Section 2: WI Module — Frontend (Angular 20)
2.1 Key Services
| Service | File | Purpose | Key Methods |
|---|---|---|---|
WiDbService |
projects/wi/src/lib/services/wi-db.service.ts |
All HTTP API calls for WI | getWiList(), getWiFullDetail(), saveWiFull(), resolveForWorkstation(), startExecution(), completeStep(), completeExecution(), saveAcknowledgement(), getWorkstationList(), saveWorkstation(), getRosterHeader(), getExecutionHistory(), etc. |
WiPlayerService |
projects/wi/src/lib/services/wi-player.service.ts |
Manages player state machine: execution flow, current step, display config | start(), advance(), goBack(), pause(), complete(), setConfig() |
WiStepTimerService |
projects/wi/src/lib/player/wi-step-timer.service.ts |
Per-step countdown timer | start(), pause(), reset(), elapsed() |
WiLiveShiftPollingService |
projects/wi/src/lib/shift-roster/wi-live-shift-polling.service.ts |
Polls roster/staffing updates | poll(), stop() |
2.2 Models and Enums
| File | Key Interfaces | Key Enums |
|---|---|---|
projects/wi/src/lib/models/wi.models.ts |
WiProcess, WiSubProcess, WiHeader, WiSection, WiStep, WiStepContent, WiStepContainer, WiAssignment, WiExecution, LineShiftRosterDTO, LineShiftStaffingDTO, StaffingGapDTO, WorkstationDTO, WiExecutionHistoryDTO, WiTimeStudyDTO, WiComplianceSummaryDTO | — |
projects/wi/src/lib/enums/wi.enums.ts |
— | WiStatus, ActivityType, TriggerEvent, ContentType, WiContainerType, DisplayMode, FontScale, StepAdvanceMode, RosterType, RosterStatus, StaffingRole, WarningLevel, StepStatus, ExecStatus |
2.3 Player Components
All under projects/wi/src/lib/player/.
| Selector | Class | File | Key Inputs | Purpose |
|---|---|---|---|---|
wi-player-shell | WiPlayerShellComponent | wi-player-shell.component.ts | — | Root layout (responsive: kiosk / normal / fullscreen) |
wi-player-header | WiPlayerHeaderComponent | wi-player-header.component.ts | — | WI title, status, timer display |
wi-player-step-list | WiPlayerStepListComponent | wi-player-step-list.component.ts | — | Left-panel step navigation list |
wi-player-step | WiPlayerStepComponent | wi-player-step.component.ts | step: WiStep | Content area; delegates to ContentDocumentRendererComponent |
wi-player-footer | WiPlayerFooterComponent | wi-player-footer.component.ts | paused: boolean | Navigation controls (Next / Back / Pause / Complete) |
wi-print | WiPrintComponent | wi-print.component.ts | wiId: number (required) | Print-optimized layout of full WI document |
wi-acknowledgement | WiAcknowledgementComponent | wi-acknowledgement.component.ts | wiHeader, employeeId, workOrderId, workStationId | Digital acknowledgement capture |
| (dialog) | WiDangerAckDialogComponent | wi-danger-ack-dialog.component.ts | MAT_DIALOG_DATA: {stepTitle} | Warning confirmation before marking dangerous step done |
2.4 Content Block Renderers
All under projects/wi/src/lib/player/content/.
| Selector | Class | Content Type | Key Features |
|---|---|---|---|
wi-content-richtext | WiContentRichtextComponent | RichText (0) | DOMPurify-sanitized HTML |
wi-content-image | WiContentImageComponent | Image (1) | Zoom region support; pan on touch |
wi-content-video | WiContentVideoComponent | Video (2) | Controls based on DisplayMode |
wi-content-pdf | WiContentPdfComponent | PDF (3) | Inline or link based on screen size |
wi-content-checklist | WiContentChecklistComponent | Checklist (4) | Interactive; emits allChecked |
wi-content-warning | WiContentWarningComponent | Warning (5) | WarningLevel enum → CSS class |
wi-content-decision | WiContentDecisionComponent | DecisionBranch (6) | Tree branches; emits branchSelected |
wi-content-file | WiContentFileComponent | File (7) | Download link |
wi-content-table | WiContentTableComponent | DataTable (9) | Renders headers/rows from JSON |
wi-content-banner | WiContentBannerComponent | Banner | Full-width background image + text |
2.5 Renderer Components (Layout Layer)
All under projects/wi/src/lib/renderer/.
| Selector | Class | File | Input | Purpose |
|---|---|---|---|---|
content-document-renderer | ContentDocumentRendererComponent | content-document-renderer.component.ts | containers: WiStepContainer[] | Top-level step document, iterates containers |
content-container-renderer | ContentContainerRendererComponent | content-container-renderer.component.ts | container: WiStepContainer | Applies CSS layout (Single / TwoColumn / Banner / Accordion / Tab) |
content-block-renderer | ContentBlockRendererComponent | content-block-renderer.component.ts | block: WiStepContent | @switch on ContentType → routes to block component |
- Single —
flex-column - TwoColumn — CSS grid
1fr 1fr - Banner —
position: relative, full-width - Accordion — CDK Accordion
- Tab — tab strip using ContainerLabel per block
2.6 Authoring / Master Components
All under projects/wi/src/lib/master/.
| Selector | Class | File | Key Inputs | Purpose |
|---|---|---|---|---|
wi-list | WiListComponent | master/wi/wi-list.component.ts | — | Browse all WIs (searchable) |
wi-form | WiFormComponent | master/wi/wi-form.component.ts | MAT_DIALOG_DATA: WiSaveRequest | Create/edit WI header + sections + assignments |
wi-process-list | WiProcessListComponent | master/process/wi-process-list.component.ts | — | Browse processes |
wi-process-form | WiProcessFormComponent | master/process/wi-process-form.component.ts | MAT_DIALOG_DATA: WiProcess | Create/edit process |
wi-subprocess-list | WiSubProcessListComponent | master/subprocess/wi-subprocess-list.component.ts | wiProcessId: number | Browse subprocesses for a process |
wi-subprocess-form | WiSubProcessFormComponent | master/subprocess/wi-subprocess-form.component.ts | MAT_DIALOG_DATA: Partial<WiSubProcess> | Create/edit subprocess |
wi-section-editor | WiSectionEditorComponent | master/sections/wi-section-editor.component.ts | sections: WiSection[]; readOnly: boolean | Drag-drop section list with embedded step forms |
wi-step-form | WiStepFormComponent | master/steps/wi-step-form.component.ts | step: WiStep; readOnly: boolean | Edit step properties (title, duration, workstation) |
wi-step-content-editor | WiStepContentEditorComponent | master/step-content/wi-step-content-editor.component.ts | stepId, contents, readOnly | Drag-drop content blocks per step |
wi-assignment-list | WiAssignmentListComponent | assignment/wi-assignment-list.component.ts | wiId: number | List assignments with specificity scores |
wi-assignment-form | WiAssignmentFormComponent | assignment/wi-assignment-form.component.ts | MAT_DIALOG_DATA: Partial<WiAssignment> | Create/edit assignment rule |
wi-activity-schedule-form | WiActivityScheduleFormComponent | assignment/wi-activity-schedule-form.component.ts | wiAssignmentId, schedules | Edit activity schedules |
wi-workstation-config | WiWorkstationConfigComponent | workstation-config/wi-workstation-config.component.ts | workStationId: number | Per-workstation player settings |
wi-workstation-config-form | WiWorkstationConfigFormComponent | assignment/wi-workstation-config-form.component.ts | workStationId: number | Form for player config |
2.7 Shared UI Components
| Selector | Class | File | Key Inputs | Purpose |
|---|---|---|---|---|
wi-status-badge | WiStatusBadgeComponent | shared/wi-status-badge.component.ts | status: WiStatus | Colored status chip |
wi-activity-type-icon | WiActivityTypeIconComponent | shared/wi-activity-type-icon.component.ts | activityType: ActivityType | Icon for activity schedule type |
wi-specificity-score | WiSpecificityScoreComponent | shared/wi-specificity-score.component.ts | assignment: Partial<WiAssignment> | Shows scoring breakdown (7 dimensions, max 90) |
wi-version-history | WiVersionHistoryComponent | shared/wi-version-history.component.ts | history: WiVersionLog[] | Table of version log entries |
2.8 Line Setup Components
| Selector | Class | File | Key Inputs | Purpose |
|---|---|---|---|---|
wi-line-master | WiLineMasterComponent | line-setup/wi-line-master.component.ts | — | Production line selection; emits lineSelected |
wi-workstation-master | WiWorkstationMasterComponent | line-setup/wi-workstation-master.component.ts | — | Manage workstations (CRUD) |
wi-line-operation-map | WiLineOperationMapComponent | line-setup/wi-line-operation-map.component.ts | lineId, routingVersionId | Show/edit operation-to-workstation mapping |
2.9 Shift Roster Components
| Selector | Class | File | Key Inputs | Purpose |
|---|---|---|---|---|
wi-roster-plan | WiRosterPlanComponent | shift-roster/wi-roster-plan.component.ts | type, lineId, rosterDate | Plan roster (Planned / Actual view) |
wi-live-shift | WiLiveShiftComponent | shift-roster/wi-live-shift.component.ts | lineId, shiftId, rosterDate | Live shift view with polling |
wi-staffing-gap | WiStaffingGapComponent | shift-roster/wi-staffing-gap.component.ts | — (signals) | Required vs assigned per workstation |
wi-shift-confirm | WiShiftConfirmComponent | shift-roster/wi-shift-confirm.component.ts | lineId, shiftId, rosterDate | Confirm/close roster |
2.10 Analytics Components
| Selector | Class | File | Purpose |
|---|---|---|---|
wi-analytics-shell | WiAnalyticsShellComponent | analytics/wi-analytics-shell.component.ts | Shell containing compliance + time study |
wi-compliance | WiComplianceComponent | analytics/wi-compliance.component.ts | Acknowledgement compliance rates; calls GET_COMPLIANCE_SUMMARY |
wi-time-study | WiTimeStudyComponent | analytics/wi-time-study.component.ts | Step actual vs standard timing; calls GET_TIME_STUDY |
CMS BE Section 3: CMS Module — Backend (C#)
3.1 Database Schema DB
CMS tables live in the DBO. schema.
| Table | Purpose |
|---|---|
TCONTENT | Content document header (title, slug, status, DATAJSON, METADATAJSON) |
MCONTENTTYPE | Content type definition (field schema) |
MSPACE | Content space (workspace / namespace) |
MBLOCK | Block type registry (code, name, SCHEMAJSON, DEFAULTPROPSJSON, CATEGORY) |
MCONTENTCONTAINERTYPE | Container layout types (SINGLE, TWO_COL, BANNER, ACCORDION, TABS); ZONEDEFINITIONSJSON |
TCONTENTCONTAINER | Container instances within a content document |
TCONTENTBLOCK | Block instances within a container zone |
TCONTENTVERSION | Immutable snapshot on each publish |
MCMSCHANNEL | Channel (content feed) definition |
TCMSSUBSCRIPTION | Employee ↔ Channel subscriptions |
TCMSCHANNELCONTENT | Content items within a channel |
MCMSCOLLECTION | Dynamic or manual content collections |
TCMSCOLLECTIONITEM | Items in a manual collection |
MCMSCAMPAIGN | Push campaign header |
TCMSASSIGNMENT | Per-employee content assignment (opened/completed tracking) |
MCMSLEARNINGPATH | Ordered learning path definition |
TCMSLEARNINGPATHITEM | Content items within a learning path |
MDESIGNSYSTEM | Branding/design tokens (colors, fonts, spacing) |
MRENDERINGPROFILE | Output profile (PDF / PPT / Email / Video; links to DesignSystem) |
TCONTENTOUTPUT | Generated output tracking (Pending → Done) |
MCONTENTCATEGORY | Content category taxonomy |
MTAXONOMY | Taxonomy definition |
MTAXONOMYTERM | Terms within a taxonomy |
MTAG | Content tags |
DB/Migrations/20260610_CMS_ContentBlockContainer.sql— Container, Block, ContainerType tablesDB/Migrations/20260610_CMS_FullPlatform.sql— Channel, Collection, Campaign, LearningPath, DesignSystem, RenderingProfile, ContentVersion tables
3.2 Query Builders BE
| QB File | Path | Key Constants |
|---|---|---|
ContentQB | CMSDAL/Query/Content/ContentQB.cs | GET_CONTENT, SAVE_CONTENT, UPDATE_CONTENT, DELETE_CONTENT, GET_CONTENT_LIST, SEARCH_CONTENT, UPDATE_STATUS, UPDATE_STATUS_WITH_PUBLISH |
ContentTypeQB | CMSDAL/Query/ContentType/ContentTypeQB.cs | GET_LIST, GET_BY_ID, SAVE, DELETE |
BlockQB | CMSDAL/Query/Block/BlockQB.cs | GET_LIST, GET_BY_ID, SAVE, GET_SELECT_LIST |
ContentContainerTypeQB | CMSDAL/Query/ContentContainerType/ContentContainerTypeQB.cs | GET_LIST, GET_SELECT_LIST, GET_BY_ID, INSERT, UPDATE |
ContentContainerQB | CMSDAL/Query/ContentContainer/ContentContainerQB.cs | GET_BY_CONTENT, INSERT_CONTAINER, REORDER_CONTAINERS, SOFT_DELETE |
ContentBlockQB | CMSDAL/Query/ContentBlock/ContentBlockQB.cs | GET_BY_CONTAINER, GET_FULL_DOCUMENT, INSERT_BLOCK, UPDATE_PROPS, SOFT_DELETE |
ContentVersionQB | CMSDAL/Query/ContentVersion/ContentVersionQB.cs | GET_BY_CONTENT, INSERT, GET_SNAPSHOT, RESTORE_TO_DRAFT, GET_NEXT_VERSION |
ChannelQB | CMSDAL/Query/Channel/ChannelQB.cs | GET_LIST, SAVE_CHANNEL, GET_CHANNEL_CONTENT, ADD_CHANNEL_CONTENT |
CollectionQB | CMSDAL/Query/Collection/CollectionQB.cs | GET_LIST, SAVE_COLLECTION, GET_ITEMS (manual), RESOLVE_DYNAMIC |
CampaignQB | CMSDAL/Query/Campaign/CampaignQB.cs | GET_LIST, GET_BY_ID, INSERT, UPDATE, GET_ASSIGNMENTS, INSERT_ASSIGNMENT, UPDATE_ASSIGNMENT_STATUS |
LearningPathQB | CMSDAL/Query/LearningPath/LearningPathQB.cs | GET_LIST, GET_ITEMS, INSERT, UPDATE, INSERT_ITEM, DELETE_ITEMS |
DesignSystemQB | CMSDAL/Query/DesignSystem/DesignSystemQB.cs | GET_LIST, GET_SELECT_LIST, SAVE |
RenderingProfileQB | CMSDAL/Query/RenderingProfile/RenderingProfileQB.cs | GET_LIST, GET_SELECT_LIST, SAVE, INSERT_OUTPUT |
3.3 DAL Layer BE
| Feature | Interface | Implementation |
|---|---|---|
| Content | CMSDAL/CustomCode/Content/IContentDAL.cs | ContentDAL.cs |
| ContentType | CMSDAL/CustomCode/ContentType/IContentTypeDAL.cs | ContentTypeDAL.cs |
| ContentCategory | CMSDAL/CustomCode/ContentCategory/IContentCategoryDAL.cs | ContentCategoryDAL.cs |
| Block | CMSDAL/CustomCode/Block/IBlockDAL.cs | BlockDAL.cs |
| ContentContainerType | CMSDAL/CustomCode/ContentContainerType/IContentContainerTypeDAL.cs | ContentContainerTypeDAL.cs |
| ContentContainer | CMSDAL/CustomCode/ContentContainer/IContentContainerDAL.cs | ContentContainerDAL.cs |
| ContentBlock | CMSDAL/CustomCode/ContentBlock/IContentBlockDAL.cs | ContentBlockDAL.cs |
| ContentVersion | CMSDAL/CustomCode/ContentVersion/IContentVersionDAL.cs | ContentVersionDAL.cs |
| Channel | CMSDAL/CustomCode/Channel/IChannelDAL.cs | ChannelDAL.cs |
| Collection | CMSDAL/CustomCode/Collection/ICollectionDAL.cs | CollectionDAL.cs |
| Campaign | CMSDAL/CustomCode/Campaign/ICampaignDAL.cs | CampaignDAL.cs |
| LearningPath | CMSDAL/CustomCode/LearningPath/ILearningPathDAL.cs | LearningPathDAL.cs |
| DesignSystem | CMSDAL/CustomCode/DesignSystem/IDesignSystemDAL.cs | DesignSystemDAL.cs |
| RenderingProfile | CMSDAL/CustomCode/RenderingProfile/IRenderingProfileDAL.cs | RenderingProfileDAL.cs |
| Taxonomy | CMSDAL/CustomCode/Taxonomy/ITaxonomyDAL.cs | TaxonomyDAL.cs |
| Tag | CMSDAL/CustomCode/Tag/ITagDAL.cs | TagDAL.cs |
| FieldComponent | CMSDAL/CustomCode/FieldComponent/IFieldComponentDAL.cs | FieldComponentDAL.cs |
3.4 BLL Layer BE
Same interface names with the CMSBLL namespace. Key business rules:
- ContentBLL — Status workflow Draft(0) → InReview(1) → Approved(2) → Published(3) → Archived(4). No backward transitions.
- ContentVersionBLL —
SaveSnapshotAsynccalled byContentBLL.PublishContentAsync;RestoreVersionAsynccopiesSNAPSHOTJSONback toTCONTENT.DATAJSONand resets STATUS=0. - CollectionBLL — Dynamic collections execute
QUERYJSONfilter at resolve-time; manual collections returnTCMSCOLLECTIONITEMin order. - CampaignBLL —
SendCampaignAsynccreatesTCMSASSIGNMENTrows for each employee;UpdateAssignmentStatusAsyncsetsOPENEDON/COMPLETEDONautomatically. - LearningPathBLL —
SaveAsyncreplaces all items (DELETE_ITEMS then re-INSERT). - RenderingProfileBLL —
GenerateOutputAsyncinsertsTCONTENTOUTPUTrow with Status=Pending; actual generation is async.
3.5 SL Layer (FastEndpoints) BE API
Base path: /cms/{Group}/{Action}.
| Endpoint File | HTTP | Route | Cache |
|---|---|---|---|
GetContent | GET | /Content/GetContent | CLIENT_LEVEL |
GetContentList | GET | /Content/GetContentList | NOT_REQUIRED |
SearchContent | GET | /Content/SearchContent | null |
SaveContent | POST | /Content/SaveContent | null |
GetContentFullDocument | GET | /Content/GetContentFullDocument | CLIENT_LEVEL |
SubmitForReview | PUT | /Content/SubmitForReview | null |
ApproveContent | PUT | /Content/ApproveContent | null |
PublishContent | PUT | /Content/PublishContent | null |
ArchiveContent | PUT | /Content/ArchiveContent | null |
RestoreVersion | POST | /Content/RestoreVersion | null |
GetContentVersionHistory | GET | /Content/GetContentVersionHistory | NOT_REQUIRED |
GetContentContainersByContent | GET | /ContentContainer/GetContentContainersByContent | CLIENT_LEVEL |
SaveContentContainer | POST | /ContentContainer/SaveContentContainer | null |
ReorderContentContainers | PUT | /ContentContainer/ReorderContentContainers | null |
DeleteContentContainer | DELETE | /ContentContainer/DeleteContentContainer | null |
GetContentBlocksByContainer | GET | /ContentBlock/GetContentBlocksByContainer | CLIENT_LEVEL |
SaveContentBlock | POST | /ContentBlock/SaveContentBlock | null |
UpdateBlockProps | PUT | /ContentBlock/UpdateBlockProps | null |
ReorderBlocks | PUT | /ContentBlock/ReorderBlocks | null |
DeleteContentBlock | DELETE | /ContentBlock/DeleteContentBlock | null |
GetChannelList | GET | /Channel/GetChannelList | CLIENT_LEVEL |
SaveChannel | POST | /Channel/SaveChannel | null |
GetChannelContent | GET | /Channel/GetChannelContent | CLIENT_LEVEL |
AddChannelContent | POST | /Channel/AddChannelContent | null |
GetCollectionList | GET | /Collection/GetCollectionList | CLIENT_LEVEL |
SaveCollection | POST | /Collection/SaveCollection | null |
ResolveCollection | GET | /Collection/ResolveCollection | NOT_REQUIRED |
GetCampaignList | GET | /Campaign/GetCampaignList | NOT_REQUIRED |
SaveCampaign | POST | /Campaign/SaveCampaign | null |
SendCampaign | POST | /Campaign/SendCampaign | null |
GetAssignmentList | GET | /Campaign/GetAssignmentList | NOT_REQUIRED |
UpdateAssignmentStatus | PUT | /Campaign/UpdateAssignmentStatus | null |
GetLearningPathList | GET | /LearningPath/GetLearningPathList | CLIENT_LEVEL |
GetLearningPathItems | GET | /LearningPath/GetLearningPathItems | CLIENT_LEVEL |
SaveLearningPath | POST | /LearningPath/SaveLearningPath | null |
GetSelectListDesignSystem | GET | /DesignSystem/GetSelectListDesignSystem | CLIENT_LEVEL |
SaveDesignSystem | POST | /DesignSystem/SaveDesignSystem | null |
GetSelectListRenderingProfile | GET | /RenderingProfile/GetSelectListRenderingProfile | CLIENT_LEVEL |
SaveRenderingProfile | POST | /RenderingProfile/SaveRenderingProfile | null |
GenerateOutput | POST | /RenderingProfile/GenerateOutput | null |
GetContentContainerTypeList | GET | /ContentContainerType/GetContentContainerTypeList | CLIENT_LEVEL |
GetSelectListContentContainerType | GET | /ContentContainerType/GetSelectListContentContainerType | CLIENT_LEVEL |
SaveContentContainerType | POST | /ContentContainerType/SaveContentContainerType | null |
CMS FE Section 4: CMS Module — Frontend (Angular 20)
4.1 Services
| Service | File | Purpose |
|---|---|---|
CmsDbService | projects/cms/dbservice/cms.db.service.ts | Central HTTP wrapper for all CMS endpoints; ~40 typed methods |
CmsEditorService | projects/cms/service/cms-editor.service.ts | Signals-based editor state (currentDocument, selectedContainerIdx, selectedBlockId, isDirty); auto-save debounce |
ContentCreatorService | projects/cms/service/contentcreator.service.ts | 3-step wizard state: space → type → form |
ContentspaceService | projects/cms/service/contentspace.service.ts | Content space creation wizard |
CreateContentTypeService | projects/cms/service/createcontenttype.service.ts | Content type field builder wizard |
CreatenewchannelService | projects/cms/service/createnewchannel.service.ts | Channel creation/edit flow |
FieldComponentService | projects/cms/service/fieldcomponent.service.ts | Field component type management |
OntologyService | projects/cms/service/ontology.service.ts | Taxonomy/ontology management |
4.2 Components
| Selector | Class | File | DB Methods Called | Purpose |
|---|---|---|---|---|
gb-contentcatalogue | ContentCatalogueComponent | master/contentcatalogue/contentcatalogue.component.ts | getContentList(), searchContent() | Main content browsing (filter, search, paginate) |
gb-contenteditor | ContentEditorComponent | master/contenteditor/contenteditor.component.ts | getSelectListContainerType() | 4-tab editor: Fields / Layout / Preview / Metadata |
gb-contentcreator | ContentCreatorComponent | master/contentcreator/contentcreator.component.ts | via ContentCreatorService | 3-step wizard: space → type → form |
gb-contentspace | ContentspaceComponent | master/contentspace/contentspace.component.ts | via ContentspaceService | Content space creation wizard |
gb-createcontenttype | CreateContentTypeComponent | master/createcontenttype/createcontenttype.component.ts | via CreateContentTypeService | Content type field builder |
gb-blocklibrary | BlockLibraryComponent | master/blocklibrary/blocklibrary.component.ts | getContainerTypeList() | Browse block types by category with preview |
gb-createnewchannel | CreatenewchannelComponent | master/createnewchannel/createnewchannel.component.ts | via CreatenewchannelService | Channel create/edit form |
gb-collections | CollectionsComponent | master/collections/collections.component.ts | getCollectionList(), resolveCollection(), saveCollection() | Dynamic + manual collection management |
gb-campaigns | CampaignsComponent | master/campaigns/campaigns.component.ts | getCampaignList(), saveCampaign(), sendCampaign(), getAssignmentList() | Campaign management + assignment tracking |
gb-learningpaths | LearningPathsComponent | master/learningpaths/learningpaths.component.ts | getLearningPathList(), saveLearningPath() | Learning path builder |
gb-contentanalytics | ContentAnalyticsComponent | master/contentanalytics/contentanalytics.component.ts | getChannelList(), getContentList() | CMS engagement metrics |
gb-renderoutput | RenderOutputComponent | master/renderoutput/renderoutput.component.ts | getSelectListRenderingProfile(), getSelectListDesignSystem(), generateOutput() | Multi-format content output generator |
gb-ontology | OntologyComponent | master/ontology/ontology.component.ts | via OntologyService | Taxonomy/ontology management |
gb-fieldcomponent | FieldComponentComponent | master/fieldcomponents/fieldcomponent.component.ts | via FieldComponentService | Field component type management |
gb-portal | PortalComponent | master/portal/portal.component.ts | getContentList(), getContentFullDocument(), searchContent() | Consumer portal (browse + view content) |
4.3 CmsEditorService State Shape
// projects/cms/service/cms-editor.service.ts
currentDocument = signal<ContentFullDocumentDTO | null>(null);
selectedContainerIdx = signal<number>(-1);
selectedBlockId = signal<number>(-1);
isDirty = signal<boolean>(false);
// auto-save: debounce 2s after last edit → calls CmsDbService.saveContentBlock()
Section 5: Key Design Patterns & Conventions
5.1 Query Builder Pattern BE
// WiDAL/Query/Wi/WiMasterQB.cs
public static class WiMasterQB {
public const string GET_WI_FULL_DETAIL = @"
SELECT w.WIID, w.WICODE, ...
FROM WI.MWI w
WHERE w.WIID = @WiId AND w.TENANTID = @TenantId";
}
5.2 DAL via IQueryExecutor BE
// Never store IDbConnection; always use IQueryExecutor
var result = await _qe.QueryAsync<WiHeaderDTO>(login, WiMasterQB.GET_WI_LIST,
new { TenantId = login.ClientId, WiProcessId = wiProcessId },
cancellationToken: ct).ConfigureAwait(false);
5.3 FastEndpoint SL Template BE API
public class GetWIList : BaseEndpoint<GetWIList.Parameters, ResponseStandardDTO<object>> {
public override void Configure() { Get("/WI/GetWIList"); AllowAnonymous(); }
protected override string? GetCacheKey(Parameters req, LoginDTO login)
=> $"WiList:{login.ClientId}:{req.WiProcessId}:{req.WiStatus}";
protected override async Task<ResponseStandardDTO<object>> ExecuteAsync(
Parameters req, LoginDTO login, CancellationToken ct)
=> await _bll.GetWiList(req.WiProcessId, req.WiStatus, login, ct);
}
5.4 Angular Signal Pattern FE
// Reactive data with rxResource
readonly wiDetail = rxResource({
request: () => ({ wiId: this.wiId() }),
loader: ({ request }) => this.db.getWiFullDetail(request.wiId)
});
5.5 Specificity Scoring Algorithm (Assignment Resolution)
Score = RoutingDetailId match: +30
+ WorkstationId match: +15
+ RoutingId match: +20
+ WorkCenterId match: +10
+ ModelId match: +10
+ ProductFamilyId match: +5
Max = 90 points. Highest score wins.
5.6 Content Lifecycle (CMS)
Draft (0) → Submit → InReview (1) → Approve → Approved (2)
→ Publish → Published (3) → Archive → Archived (4)
No backward transitions.
TCONTENTVERSION snapshot created on each Publish.
5.7 Append-Only Tables DB
- When "updating": set
EFFECTIVETO = todayon old row, INSERT new row withEFFECTIVEFROM = today + 1. - Never
UPDATE, neverDELETE.
- When marking absent:
UPDATE ISABSENT = 1+ABSENCEREASON. - Never
DELETE.
GB5 WI & CMS Developer Reference · Generated for the GB5 build team · Anchors stable for deep linking · Last revised 2026-06-16