Project

General

Profile

Feature #859 » INTEGRATION_GUIDE.md

Redmine Admin, 03/11/2026 01:59 PM

 

DentPal — Perio Chart Feature Scaffold

Integration Guide

Stack: ABP 8.x · EF Core · Angular Standard · LeptonX · Multi-tenant


File Map

csharp/
  Domain/
    PatientPerioExam.cs              ← Aggregate root entity (IMultiTenant)
    PatientPerioMeasurement.cs       ← Measurement row entity + MeasurementTypes constants
    IPerioExamRepository.cs          ← Repository interfaces
  Application/
    PerioChartDto.cs                 ← All DTOs (PerioExamSummaryDto, PerioChartDto, ToothChartDto, SideMeasurementsDto)
    PerioChartTransformService.cs    ← Pivot + calculation logic (AG, CAL)
    IPerioChartAppService.cs         ← Service interface
    PerioChartAppService.cs          ← Implementation (2 endpoints)
  Permissions/
    DentPalPermissions.cs            ← Permission constants + PermissionDefinitionProvider

angular/
  models/
    perio-chart.model.ts             ← TypeScript interfaces (mirrors C# DTOs)
  pipes/
    pd-color.pipe.ts                 ← 8 pipes: pdColor, mgjColor, agColor, calColor, recColor, furcColor, mobColor, perioDash
  services/
    perio-chart.service.ts           ← HTTP service (ABP RestService pattern)
  perio-chart.component.ts           ← Main component class + stats calculation
  perio-chart.component.helpers.ts   ← Helper methods to add to component class
  perio-chart.component.html         ← OD-convention layout template
  perio-chart.component.scss         ← LeptonX-aware styles
  perio-chart.module.ts              ← Feature module + routing + usage notes

Step-by-Step Integration

1. C# — Add EF Core DbSet entries

In your DentPalDbContext.cs:

public DbSet<PatientPerioExam>        PerioExams        { get; set; }
public DbSet<PatientPerioMeasurement> PerioMeasurements { get; set; }

2. C# — Configure entities in OnModelCreating

builder.Entity<PatientPerioExam>(b => {
    b.ToTable("PerioExams");
    b.ConfigureByConvention();
    b.Property(e => e.PMSPerioExamID).HasMaxLength(100).IsRequired();
    b.Property(e => e.ProviderId).HasMaxLength(100).IsRequired();
    b.Property(e => e.Note).HasMaxLength(2000);
    b.HasIndex(e => new { e.PatientId, e.ExamDate });
});

builder.Entity<PatientPerioMeasurement>(b => {
    b.ToTable("PerioMeasurements");
    b.ConfigureByConvention();
    b.Property(e => e.MeasurementType).HasMaxLength(50).IsRequired();
    b.Property(e => e.SurfaceCode).HasMaxLength(5);
    b.Property(e => e.MeasurementValue).HasPrecision(5, 2);
    b.HasIndex(e => new { e.PerioExamId, e.ToothNum, e.SurfaceCode, e.MeasurementType })
     .IsUnique();
});

3. C# — Implement repositories

Create EfCorePerioExamRepository.cs and EfCorePerioMeasurementRepository.cs
implementing the interfaces in IPerioExamRepository.cs.
Use EfCoreRepository<DentPalDbContext, T, Guid> as base class (ABP pattern).

4. C# — Register services in DependencyInjection

// In your ApplicationModule or DomainModule ConfigureServices:
context.Services.AddTransient<PerioChartTransformService>();

ABP auto-registers PerioChartAppService via convention — no manual registration needed.

5. C# — Add permissions to your existing provider

Do NOT create a new PermissionDefinitionProvider — add the perio group to your
existing DentPalPermissionDefinitionProvider.Define() using the snippet in
DentPalPermissions.cs.

6. C# — Add migration

cd src/DentPal.EntityFrameworkCore
dotnet ef migrations add AddPerioChartTables
dotnet ef database update

7. Angular — Copy files into your project

Copy the angular/ folder contents into:

src/app/perio-chart/

8. Angular — Merge helper methods into component

Open perio-chart.component.ts and add all methods from
perio-chart.component.helpers.ts into the PerioChartComponent class.
Also add the DotsData interface at the top of the component file.

9. Angular — Add lazy route

In app-routing.module.ts:

{
  path: 'patients/:patientId/perio-chart',
  loadChildren: () =>
    import('./perio-chart/perio-chart.module').then(m => m.PerioChartModule),
  canActivate: [authGuard],
  data: { requiredPolicy: 'DentPal.PerioChart.View' },
},

10. Angular — Split routing module

Create perio-chart-routing.module.ts by uncommenting the block at the bottom of
perio-chart.module.ts and removing the inline comment markers.

11. Angular — Embed in patient page

<app-perio-chart
  [patientId]="patient.id"
  [patientName]="patient.fullName">
</app-perio-chart>

API Endpoints (auto-generated by ABP)

Method URL Permission
GET /api/app/perio-chart/patients/{patientId}/exams DentPal.PerioChart.View
GET /api/app/perio-chart/exams/{examId}/chart DentPal.PerioChart.View

Both appear automatically in Swagger once the AppService is registered.


Key Design Decisions (OD Convention Applied)

Decision Value Source
Upper jaw graph direction Bars hang DOWN OD screenshot Q1
Lower jaw graph direction Bars grow UP OD screenshot Q1
Furcation color threshold Red if ≥ 1 OD right panel Q2
Mobility color threshold Red if ≥ 1 OD right panel Q3
BleedSupPlaqCalc storage 4 separate boolean rows per surface OD dots Q4
Missing surface null → dash (–) displayed Spec Q5
Negative AG display Shown as-is, amber (no blocking) OD chart Q6
Tooth numbering Universal 1–32 OD tooth row Q7
Exam note display Banner below exam selector OD left panel Q8
Recession vs GingMargin Two separate measurement rows OD row labels Q9
Graph Y-axis scale None (proportional bars only) OD screenshot Q10

Calculation Rules (backend — PerioChartTransformService.cs)

Attached Gingiva  = MGJ − PD
  → Negative result: amber warning in UI, no clamping

CAL (apical)      = PD + Recession   (when Recession > 0)
CAL (overgrowth)  = max(0, PD − |GM|) (when GingMargin < 0)
CAL (at CEJ)      = PD               (when GM = 0)

Analyzed : 11 Mar 2026 | DentPal Perio Chart v3 | ABP 8.x + EF Core + Angular

(16-16/19)