Infinite Cabinet

A field report on the InfiniteCabinet project — what it is, what we pull into REV.health, and what we leave behind. InfiniteCabinet is the upstream "jig" that produced REV.health's IC framework; this page makes the lineage explicit and books the remaining work.

What InfiniteCabinet is

InfiniteCabinet is a metadata-driven, template-generated, end-to-end enterprise application builder. You hand it a JSON Application Model Interface (AMI) describing a single business noun (an Invoice, a Customer) plus a companion rules file, and its code-generation engine produces a full stack: Cosmos / EF Core schema, .NET 9 minimal-API CRUD endpoints, Angular 21 standalone components packaged as Web Components, validation middleware, OpenAPI spec, xUnit / Vitest tests, and HTML docs — in a fixed pipeline of DB → API → Components → Tests → Docs → Deploy. Three pillars hold the model up: a numeric 0–100 RBAC engine with four permission scopes; a strict version format break.feature.bug.buildtimestamp with cascade deployment that forbids prod from running ahead of lower envs; and a 14-rule "hard rules" contract that the generator (not policy) enforces (OrgID on everything, soft delete only, audit columns auto-injected, max 500 lines per file, API enforces referential integrity because Cosmos has no FKs).

Why it matters to REV.health

REV.health's existing IC framework is already a re-skinned, clinical-aware fork of the InfiniteCabinet generator. Every module page in PRD v2 (clinical-doc, scheduling, rcm, …) implicitly assumes IC-style AMI generation. What is missing is the provenance: which patterns came directly from InfiniteCabinet, which we changed for HIPAA / FHIR / multi-org data sharing, and which we never adopted. This page closes that loop and captures the artifacts the v1 gap report flagged as P0 (per-module IC-application overrides, RBAC matrix per module, versioning worked examples). Anything ADOPT or ADAPT is a candidate copy/port job; anything INSPIRE or DROP needs a one-time decision and then stays decided.

The "Infinite Cabinet" jig

Jig — in metalworking, a fixture that holds a workpiece and guides the cutting tool. The workpiece varies; the jig is reused. The output is identical-to-spec because the jig, not the operator, enforces the geometry.

InfiniteCabinet treats application code the same way. The AMI schema is the workpiece (changes per app: Invoice today, Encounter tomorrow). The CodeGenerationOrchestrator + templates + hard rules are the jig: they hold the schema in place and machine it through a fixed sequence of cuts (DB → API → Frontend → Tests → Docs). Two operators feeding the same AMI to the same jig get byte-identical output, same audit columns, same OrgID partitioning, same RBAC hooks, same component tag names — because the generator, not the developer, enforces the invariants.

For REV.health that translation is straight: Encounter, Appointment, Claim, PriorAuth, Prescription, Referral are workpieces. The jig guarantees that EncounterID is a Short GUID, that OrganizationID partitions the container, that audit fields are present, that the generated component is ic-ng21-clinical-doc-detail-encounter, and that no junior developer can field-rename in prod without an EditAMI (level 90) grant. Hand-written exceptions are still possible, but they are visible: anything not produced by the jig stands out in code review.

Artifact inventory

Each row is one re-usable thing in InfiniteCabinet. Verdict is one of:

ADOPT port file-for-file ADAPT port with clinical changes INSPIRE idea only, no direct port DROP not applicable
Artifact Source path Concept Verdict Target REV.health module Effort Priority
AMI schema model src/IC.Models/Ami/AmiSchema.cs
AmiEntity.cs, AmiField.cs, AmiFieldType.cs
Top-level schema, entities, fields, FK metadata ADAPT Cross-cutting — data-model M P0
AMI rules companion src/IC.Models/Ami/AmiRule.cs Independently-versioned validation rules linked by version range ADOPT coding-cds, eligibility S P1
BreakingChangeDetector src/IC.Models/Ami/BreakingChangeDetector.cs Diffs two schema versions, classifies each change as breaking / feature ADOPT Cross-cutting — codegen tooling S P0
AuditFieldInjector src/IC.Models/Ami/AuditFieldInjector.cs Auto-adds OrgID, LastUpdatedDateTimeUTC, LastUpdatedByUserID, IsSoftDeletedBool to every entity ADAPT Cross-cutting — data-model audit S P0
CodeGenerationOrchestrator src/IC.CodeGen/CodeGenerationOrchestrator.cs Orders phases DB → API → FE → Tests → Docs; path-traversal guards; max-lines-per-file check ADOPT Platform tooling L P0
TemplateEngine src/IC.CodeGen/TemplateEngine.cs Scriban/Handlebars-style template binding ADOPT Platform tooling S P1
RBAC engine (PermissionGrant) src/IC.Security/Models/PermissionGrant.cs
PermissionScope.cs, EffectivePermission.cs, PermissionLevel.cs
Numeric 0–100 grants over (app, env, entity) with Object / Row / Column / ComplexAlgorithm scopes; hierarchical merge across User → Role → RoleGroup ADAPT Cross-cutting — ic-reference RBAC L P0
RbacMiddleware + ResponseShapingMiddleware src/IC.Api/Middleware/ Resolves EffectivePermission per request, strips Column-hidden fields from response ADOPT Platform — API gateway M P0
DefaultOrgProvisioner src/IC.Security/Services/ On org create: seed default roles (Admin, Editor, Viewer), groups, settings ADAPT Platform onboarding M P1
L1 component library libs/components/src/lib/l1/ (10 primitives) text-input, number-input, date-picker, currency-display, dropdown, boolean-toggle, textarea, guid-display, title, badge-status — all Shadow DOM Web Components ADOPT Cross-cutting — shared UI M P0
L2 structured components libs/components/src/lib/l2/ address-form, phone-input, email-input, file-upload, image-picker, rich-text-editor ADAPT Cross-cutting — need clinical extensions (allergy-picker, problem-search, sig-builder) M P1
JTable grid libs/components/src/lib/jtable/jtable.ts Standard grid: sortable, filterable, paged, ARIA-correct, Shadow DOM ADOPT All worklists (RCM denials, task inbox, prior-auth queue, scribe review) S P0
ComponentMappingService libs/components/src/lib/component-mapping.service.ts Type → component tag resolution table with custom overrides ADOPT Cross-cutting — ic-reference default bindings S P0
WebComponentRegistry libs/components/src/lib/web-component-registry.ts Lazy registration of ic-* tags on first DOM appearance via import map ADOPT Shell / patient-portal / clinician shell M P1
AMI Editor (SSMS-style) libs/ami-editor/ Visual schema editor: root noun far left, children flow left-to-right, FKs above PKs, breaking-change controls disabled below EditAMI INSPIRE Internal platform tooling (not customer-facing) L P2
API Gateway (YARP) src/IC.Gateway/ Reverse proxy on port 5472, route per app/env/version, session auth, rate limit, CORS ADAPT Platform — replace YARP with Azure API Management for SMART-on-FHIR launch context support L P1
Hard rules (14) rules/hard-rules.md Non-negotiable invariants enforced by generator: OrgID on everything, soft-delete only, version format, build-once-run-everywhere, … ADOPT Cross-cutting (with one carve-out, see below) S P0
Naming conventions rules/naming-conventions.md Tag format ic-{fw}{ver}-{scope}-{break}-{name}; field type suffixes InvoiceNumber200, IsActiveBool ADAPT Already partially in ic-reference; needs the field-type-suffix rule added S P1
Version format rules/versioning.md
src/IC.Models/Ami/AmiVersion.cs
break.feature.bug.buildtimestamp on every artifact; only break goes in component tag ADOPT Cross-cutting S P0
Cascade deployment rule rules/hard-rules.md #6 Deploying to env X auto-promotes all envs left of X; prod always has lowest-or-equal version ADOPT Platform CI/CD — architecture M P1
Blue-green DB strategy rules/hard-rules.md #13
context/decisions-log.md DEC-012
Breaking schema change creates new DB + ETL; old DB stays for rollback; never in-place migration ADOPT Cross-cutting Cosmos strategy L P1
Component picker / FK auto-naming context/decisions-log.md DEC-014 In editor, pick target noun first; system creates field {Noun}ID with FK metadata ADOPT Internal AMI editor + codegen tooling S P2
Apps-are-nouns rule context/decisions-log.md DEC-003 One business noun = one app = one AMI; cross-noun via FK only ADAPT Already in ic-reference module nouns; surface as a hard rule S P0
Sample AMIs (Bogus seeded) data/ami/ (Invoice, Customer, Location, Product) Faker-seeded JSON; "one-button schema-to-hero demo" INSPIRE Need clinical equivalents: Patient, Encounter, Appointment, Claim, Prescription M P1
Test scale (~1,869 tests) tests/IC.Api.Tests/ + Vitest specs 915 xUnit + 441 shell + 227 components + 286 ami-editor INSPIRE Sets the bar for REV.health module test coverage P1
Compodoc + HTML doc set docs/ (architecture, api-reference, component-library, security, versioning, PRD) Auto-generated documentation per artifact INSPIRE This PRD v2 is the equivalent surface; doc-gen for generated components is P1 M P1
JSON-file dev storage data/ JSON files under data/{orgId}/… as Cosmos stand-in for local dev INSPIRE Worth doing for local clinician shell dev; not for prod S P2
NX monorepo layout nx.json, apps/, libs/ NX 22.6.3 + pnpm workspaces, Angular 21 + .NET 9 side-by-side INSPIRE REV.health uses separate repos per module (DEC-RH style); NX stays a reference P2

AMI schema model

source: src/IC.Models/Ami/AmiSchema.cs + AmiEntity.cs + AmiField.cs + AmiFieldType.cs

AmiSchema shape ADAPT

The top-level schema. One AMI per business noun. Inherits BaseEntity which gives Id, OrgId, LastUpdatedDateTimeUtc, LastUpdatedByUserId, IsSoftDeletedBool.

public class AmiSchema : BaseEntity
{
    public string  Name { get; set; }            // "Invoice"
    public string? Description { get; set; }
    public string  RootNoun { get; set; }        // "Invoice" — apps are nouns
    public string  Version { get; set; }         // "1.3.0.20260401120000"
    public List<AmiEntity>          Entities { get; set; }
    public List<VersionHistoryEntry> VersionHistory { get; set; }
}

Adaptation for clinical: add SourceOrganizationID (nullable) for global entities (Patient, Problem, Diagnosis, Prescription — see data-model). Add FhirResourceType hint (Encounter, MedicationRequest) so the generator can emit a FHIR mapper alongside the CRUD endpoint.

AmiField shape ADOPT

public class AmiField
{
    public string  Name { get; set; }
    public string  Type { get; set; }              // AmiFieldType constants
    public bool    Required { get; set; }
    public bool    IsPrimaryKey { get; set; }
    public bool    IsForeignKey { get; set; }
    public string? FkTargetSchema { get; set; }    // "Customer"
    public string? FkTargetEntity { get; set; }
    public string? ComponentMapping { get; set; }  // override default tag
}

AmiFieldType constants ADAPT

Source list: String, Int, Decimal, Money, Bool, DateTime, Guid, Text, Email, Phone, Url. Clinical extensions needed (these become the bridge to ic-reference default bindings):

New AMI typeDefault REV componentPurpose
ShortGuidshort-guid-display22-char Base62 PK — already in data-model
Snomedsnomed-pickerSNOMED CT concept selector
Icd10icd10-pickerICD-10-CM diagnosis selector
Cptcpt-pickerCPT/HCPCS procedure selector with 4 modifier slots
RxNormrxnorm-pickerMedication name → RxCUI / NDC
Loincloinc-pickerLab observation code
FhirReferencefhir-ref-inputPolymorphic { resourceType, id } reference

Code generation orchestrator

source: src/IC.CodeGen/CodeGenerationOrchestrator.cs

Five-phase pipeline with strict ordering. Adopt the orchestrator skeleton verbatim, then swap in REV-specific templates per phase.

graph LR
  AMI["AMI schema
(+ optional Rules)"] --> P0["Phase 0
Parse & validate
path-safe names"] P0 --> P1["Phase 1
Database
(Cosmos / EF Core)"] P1 --> P2["Phase 2
API
(CRUD + Validation + OpenAPI)"] P2 --> P3["Phase 3
Frontend
(Grid / Form / Detail)"] P3 --> P4["Phase 4
Tests
(CRUD + Validation + Contract)"] P4 --> P5["Phase 5
Docs
(SchemaDoc + ApiDoc)"] P5 --> OUT["GenerationResult
+ 500-line check
+ path-traversal guard"]

Why adopt the skeleton: the orchestrator already enforces three things we want in every REV codegen run —

  1. IsNameSafeForPath() rejects .., slashes, leading non-letters before writing anything (HIPAA-relevant: prevents tenant boundary escape via crafted entity names).
  2. IsPathUnderBase() resolves the absolute path and verifies it stays under the output dir — defence in depth.
  3. MaxLinesPerFile rejects any generated file over the rule-9 threshold (default 500). Forces template authors to split.

Integration sketch:

var orchestrator = new CodeGenerationOrchestrator(new CodeGenOptions
{
    SelectedPhases   = { GenerationPhase.Database, GenerationPhase.Api,
                         GenerationPhase.Frontend, GenerationPhase.Tests,
                         GenerationPhase.Docs },
    MaxLinesPerFile  = 500,
    TemplateSet      = "rev-health-v1"   // REV-specific templates
});

var result = orchestrator.Generate(encounterSchema, encounterRules);
if (!result.Success) throw new CodeGenException(result.Errors);
CodeGenerationOrchestrator.WriteToDirectory(result, "out/clinical-doc/");

RBAC engine (0–100)

source: src/IC.Security/

The numeric scale — identical to the one already documented in ic-reference, but with InfiniteCabinet's two extra layers:

Permission levels ADOPT

public static class PermissionLevel
{
    public const int NoAccess       = 0;
    public const int Read           = 1;
    public const int Write          = 51;
    public const int Deploy         = 70;
    public const int ManageFeatures = 80;
    public const int EditAmi        = 90;
    public const int Admin          = 100;
}

REV.health needs four more named levels in the middle — Clinical-Read (30), Clinical-Write (50), Administrative (70), Platform-Op (100) — matched to the existing IC reference table. The two ladders coexist by leaving the integer scale unchanged and adding more named constants.

Four scopes ADOPT

ScopeWhat it controlsREV use case
ObjectWhole-entity access (most common)"MA can read Appointment but not Claim"
RowPer-row filter expression on top of OrgID partition"Provider sees only encounters where RenderingProviderID = self"
ColumnHide specific fields below a threshold level"Hide SsnLastFour from Reception (level 30); show to Billing (level 70)"
ComplexAlgorithmCustom function for break-the-glass / consent gatesSensitive-class gating (42 CFR Part 2 SUD records, HIV, behavioral health)

PermissionGrant shape ADAPT

public class PermissionGrant
{
    public string AppName     { get; set; } = "*";     // "scheduling", "rcm"
    public string Environment { get; set; } = "*";     // "Dev", "QA", "UAT", "Prod"
    public string EntityName  { get; set; } = "*";     // "Appointment"
    public string Scope       { get; set; }            // Object / Row / Column / ComplexAlgorithm
    public int    Level       { get; set; }            // 0–100
    public bool   Recursive   { get; set; } = true;
    public string TargetType  { get; set; } = "RoleGroup"; // User | Role | RoleGroup
    public string TargetId    { get; set; }

    // Column scope
    public List<string>? RestrictedFields { get; set; }
    public int?          FieldVisibilityLevel { get; set; }

    // Row scope
    public string? RowFilterExpression { get; set; }

    // ComplexAlgorithm scope
    public string? AlgorithmId { get; set; }
    public string? AlgorithmParameters { get; set; }
}

Clinical adaptations: add SensitiveClassRequirement (matches SensitiveClassGating in patient-portal); add ConsentTokenRequired bool for cross-org reads of global entities; rename OrgIdOrganizationID to match REV naming.

EffectivePermission resolver ADOPT

The middleware merges User → Role → RoleGroup grants (recursive), takes the max numeric level per scope, collects all HiddenFields from Column grants, all RowFilters from Row grants, and stores the result in HttpContext.Items for the rest of the request. ResponseShapingMiddleware then strips hidden fields from the JSON response body before send.

Reuse this as-is — it solves the Column-scope problem we already documented in data-model read-access audit.

L1 / L2 / JTable components

source: libs/components/src/lib/

InfiniteCabinet ships 17 ready Web Components, all ViewEncapsulation.ShadowDom, all mobile-first, all framework-agnostic at consumption time:

TierComponents (source tag prefix ic-ng21-core-1-)
L1 primitives (10)text-input, number-input, boolean-toggle, date-picker, currency-display, dropdown, textarea, guid-display, title, badge-status
L2 structured (6)address-form, phone-input, email-input, file-upload, image-picker, rich-text-editor
JTable (1)Sortable, filterable, paged grid. ARIA roles, Shadow DOM, ~335 LOC, fully tested

Default type-to-component mapping ADOPT

Verbatim from component-mapping.service.ts:

export const DEFAULT_COMPONENT_MAP: ComponentMapping = {
  String:   'ic-ng21-core-1-text-input',
  Text:     'ic-ng21-core-1-textarea',
  Int:      'ic-ng21-core-1-number-input',
  Decimal:  'ic-ng21-core-1-number-input',
  Money:    'ic-ng21-core-1-currency-display',
  Bool:     'ic-ng21-core-1-boolean-toggle',
  DateTime: 'ic-ng21-core-1-date-picker',
  GUID:     'ic-ng21-core-1-guid-display',
  Enum:     'ic-ng21-core-1-dropdown',
  Address:  'ic-ng21-core-1-address-form',
  Phone:    'ic-ng21-core-1-phone-input',
  Email:    'ic-ng21-core-1-email-input',
};

This is already partially documented in ic-reference default bindings; the inventory there lists 13 rows but the source has the same 13 plus the case-insensitive normalize + override mechanism. Port the service, not just the table.

Breaking-change detector

source: src/IC.Models/Ami/BreakingChangeDetector.cs

What counts as breaking ADOPT

ChangeVerdictRequired level
Add optional fieldFeature bumpWrite (51)
Add required fieldBreakingEditAMI (90)
Remove fieldBreakingEditAMI (90)
Change field typeBreakingEditAMI (90)
Add entityFeature bumpWrite (51)
Remove entityBreakingEditAMI (90)
Rules-only changeRules version bumpWrite (51)

The detector explicitly ignores the four audit fields (OrgID, LastUpdatedDateTimeUTC, LastUpdatedByUserID, IsSoftDeletedBool) when computing diffs. Adopt this filter and extend it with REV's audit set (CreatedDateTimeUTC, ModifiedDateTimeUTC, ModifiedByUserID, SourceOrganizationID).

Versioning & cascade deploy

source: rules/versioning.md + rules/hard-rules.md (rules 1, 6, 7, 8, 9)

Version format break.feature.bug.buildtimestamp ADOPT

Universal across schemas, components, APIs, rules, deployments, docs — never semver. The build timestamp is ISO-8601 UTC (e.g. 1.3.0.20260401120000) and is what makes every artifact uniquely traceable.

Only the break segment goes in the component tag (ic-ng21-core-1-text-input). Feature and bug updates ship the same tag with a different CDN URL. Consumers never need to update tag names for non-breaking changes.

Cascade deployment ADOPT

Deploying to env X auto-promotes Dev → QA → UAT → X. Prod always has the lowest-or-equal version. Combined with rule #8 ("no testing in prod") this is a structural rather than policy enforcement.

REV.health implication: the prod cascade rule replaces our current ad-hoc release notes. Worth picking up as a P1 CI/CD change.

Build-once-run-everywhere & cosmos blue-green ADOPT

Components are immutable env-agnostic bundles; only DI config differs per env (Cosmos URL, CDN tag). For schema-breaking DB changes, never migrate in place — create new Cosmos database, ETL, keep old DB live for rollback grace period. This pairs naturally with the version-pinning rule (rule #12: every CDN module requires explicit version).

Glossary & naming

source: rules/naming-conventions.md + glossary terms scattered across docs/ and context/

TermMeaning in InfiniteCabinetREV.health equivalent
AMIApplication Model Interface — JSON schema for one app's data + relationshipsSame term, same meaning; canonical noun for every schema page
Apps are nounsOne business noun = one app = one AMI = one repoModule nouns: scheduling, clinical-doc, rcm, erx-epcs, … (see ic-reference module nouns)
Jig(implicit) The codegen pipeline + hard rules that hold an AMI in place while machiningSame; this page introduces the term explicitly
BoxApps viewThe SSMS-style schema editor visualisation where root noun is far left and children flow right with FKs above PKsInternal AMI editor tooling — not customer-facing
Core bundleAll L1 + L2 + JTable shipped as one bundle.js CDN file (one HTTP call)Adopt for clinician shell and patient portal
Trust tier(absent from InfiniteCabinet)REV.health-only concept — see clinical-doc scribe + v1 gap report
Scribe(absent)REV.health-only — ambient AI documentation flow
FK-as-component viewEditor mode where CustomerID renders as the linked entity ("Customer") with an arrow to the targetWorth importing into the data-model page diagrams
Short name toggleEditor mode that displays InvoiceLineItem as LineItem when context is unambiguousApply to EncounterNoteNote in chart UIs
Field-type suffix conventionInvoiceNumber200 (max-len), IsActiveBool (positive bool only)Not currently in REV naming — ADD to ic-reference

Cross-module impact

What changes in each REV.health module if we land the ADOPT and ADAPT artifacts above:

REV.health moduleWhat lands hereWhat changes
data-model AMI schema model, AuditFieldInjector, BreakingChangeDetector, ShortGuid + clinical types Existing AMI tables get versioned via break.feature.bug.buildtimestamp; audit injector formalised; breaking-change checker added to CI
ic-reference RBAC scopes (four), ComponentMappingService, naming conventions (field-type suffix), apps-are-nouns hard rule Three new sections: "Four permission scopes", "Field type suffix convention", "Apps are nouns invariant"
architecture CodeGenerationOrchestrator phase order, cascade deployment rule, build-once-run-everywhere, blue-green DB New "Generation pipeline" diagram, env-cascade promotion rule formalised in CI
clinical-doc JTable for scribe review queue, Row-scope grants for "rendering provider only", ComplexAlgorithm for 42 CFR Part 2 gating EncounterNote sensitive-class fields covered by ColumnGrant; scribe inbox becomes a JTable instance
scheduling JTable for slot/waitlist views, Row-scope filter for "resource = self", PermissionGrant per Schedule Resource-graph and waitlist surfaces unified through one grid
rcm JTable for denial queues, ClaimLine generation from CPT picker AMI type, Column grants on patient PHI for billing-only roles Denial worklist becomes a paged JTable; PHI redacted by ResponseShapingMiddleware
eligibility AMI Rules companion for Prior-Auth state machine, BreakingChangeDetector to gate plan-rule edits Rules editor surfaces a "would break" warning before save
erx-epcs RxNorm AMI type, ComplexAlgorithm scope for controlled-substance EPCS challenge Prescription form binds RxNorm picker; EPCS verification routed through scope evaluator
patient-portal Core bundle (L1+L2+JTable) on portal shell, address-form / phone-input / email-input for registration, SensitiveClassGating via ComplexAlgorithm Portal registration form is generated from User AMI instead of hand-coded
coding-cds SNOMED / ICD-10 / CPT AMI types, AMI Rules for CDS hooks, ComponentMappingService overrides per code system CDS rule library uses Rules companion with independent versioning
task-mgmt JTable for task inbox, Row-scope for "assigned to me" Task macros become AMI Rules entries
referrals Apps-are-nouns hard rule (referral is its own noun), JTable for referral inbox Standing referral becomes its own AMI rather than a flag on Referral
payer-opt AMI Rules for PayerRule, ComplexAlgorithm scope for optimization-suggestion gating OptimizationAuditEntry written by ResponseShapingMiddleware shim

Explicitly dropped (and why)

Source artifactWhy dropped
NX monorepo layout (single repo for everything) REV.health is committed to repo-per-module (DEC-RH style, surfaced in ic-reference project structure). NX stays a reference for tooling parallelism, not adopted wholesale.
JSON-file storage as dev backend InfiniteCabinet uses data/{orgId}/*.json for local dev to avoid a Cosmos emulator. Useful pattern, but PHI-touching modules need a Cosmos emulator path anyway for fidelity. Marked INSPIRE, not DROP — kept for the small handful of seedable non-PHI catalogue entities (CodeSet, SpecialistDirectory).
YARP-based gateway YARP is fine in isolation, but REV.health needs SMART-on-FHIR launch context, OAuth 2.1 with PKCE, and per-payer rate-limit policies. Azure API Management gives all three out of the box. The gateway responsibilities are adopted; the YARP implementation is not.
SSMS-style visual AMI editor Internal-tools polish, not customer-facing. INSPIRE rather than ADOPT — we don't need to invest editor effort until non-engineer schema authoring is on the roadmap.
Compodoc-driven docs site PRD v2 is the canonical doc surface. Generated-component reference docs from Compodoc are P1 worth doing but not a doc-site replacement.
Bogus-seeded sample AMIs (Invoice, Customer, Location, Product) Wrong nouns for the clinical domain. We need clinical equivalents (Patient, Encounter, Appointment, Claim, Prescription) seeded with Bogus — same technique, different data.
One global env picker at shell level (Phase 1) REV.health needs per-payer-context env selection (sandbox vs prod) for integrations work. Global picker doesn't model that.
Generic "Editor / Viewer / Admin" default roles Replaced by REV's clinical role ladder (Patient, MA/Nurse/Reception, PA/NP/Physician, Practice Manager / RCM, IT Admin) on the same 0–100 scale.

REV.health-built components (IC adoption candidates)

The following components were built for REV.health during the 2026-06-02 session and are structured to be lift-able into the Infinite Cabinet component library. They are not sourced from InfiniteCabinet but follow IC conventions (props-driven, single-purpose, CSS-token-only styling).

ComponentFileIC merge targetL1/L2 tierPriorityNotes
claim-timelinedemo/assets/claim-timeline.jsbadge-status L1 + new L2 status-pipelineL2P1Headline + full mode; status registry with long labels; per-node rendering merges with badge-status L1 primitive
claim-drawerdemo/assets/claim-drawer.jsNew L2 claim-detail-drawerL2P2Right-side panel with header, timeline, action toolbar, history table; keyboard + backdrop dismiss
patient-encountersdemo/assets/patient-encounters.jsNew L2 encounter-generatorL2P2Deterministic synthetic encounter generator with AI summaries; bucketByMonth() and detectClusters() helpers
fmtRelativedemo/assets/shared.jsNew L1 relative-timeL1P0"5 mins ago" / "3 hours ago" / "2 days ago"; same shape as fmtHours
providerDisplayNamedemo/assets/shared.jsNew L1 entity-nameL1P1Resolves provider ID → full display name with credential suffix
fmtHoursdemo/assets/dashboard.jsNew L1 duration-displayL1P0"50 mins" / "1 hour" / "2.5 hours"; replaces "50m"/"1h" cryptic shorthand
Phone Input (US/CA)demo/assets/ic-phone-input.jsNew L1 phone-inputL1ADOPTOpt-in via data-ic-phone="US"|"CA" (both NANP). Live-formats (NNN) NNN-NNNN; on blur normalizes 10 digits to +1 (NNN) NNN-NNNN; exposes dataset.icPhoneDigits + dataset.icPhoneE164; setCustomValidity for HTML5 validation; idempotent initAllPhoneInputs(root) for dynamic re-renders

Open questions for human review

  1. Permission level overlap. InfiniteCabinet defines Write=51, Deploy=70, ManageFeatures=80, EditAmi=90, Admin=100. ic-reference defines Patient=10, Clinical-Read=30, Clinical-Write=50, Administrative=70, System-Admin=90, Platform-Op=100. Need a single merged ladder — or an explicit decision that the two scales are namespaced (platform-ops vs clinical).
  2. Audit field naming. Source uses OrgID, LastUpdatedDateTimeUTC, LastUpdatedByUserID, IsSoftDeletedBool. REV.health data-model uses OrganizationID, CreatedDateTimeUTC, ModifiedDateTimeUTC, ModifiedByUserID. Pick one; update AuditFieldInjector accordingly.
  3. BaseEntity inheritance vs duck-typed audit. InfiniteCabinet uses class inheritance (: BaseEntity). REV.health AMI is JSON-only and currently has no equivalent base type. Add a "$schema" reference or an explicit base AMI template?
  4. FHIR mapping placement. Generate a FHIR resource mapper in Phase 2 (API) or as a separate Phase 6? Affects whether external systems can hit the generated FHIR endpoint directly.
  5. Rules companion lifecycle. InfiniteCabinet bumps rules independently. For payer/eligibility rule churn this is right. For Prior-Auth state machine changes that imply schema changes (new statuses), should the rules bump cascade-bump the schema?
  6. Tag prefix convention. Keep ic-ng21- or switch to rev-ng21- for clinical components? Affects every component tag REV.health ships.
  7. Build-once-run-everywhere & PHI. Same component bytes in Dev and Prod is fine, but a Dev env that talks to Synthea fake data must never resolve to a Prod Cosmos DI config. Need stronger guarantees than "the import map is correct".
  8. Cascade deployment with regulatory holds. Cascade rule says deploying to UAT promotes Dev / QA automatically. What happens when prod is held back for ONC / EHNAC certification? Need an explicit "frozen prod" exception.