npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@primocaredentgroup/magazzino

v0.5.0

Published

Componente Convex per gestione magazzino cliniche (ordini, inventario, fornitori).

Readme

@primocaredentgroup/magazzino

Componente Convex per ordini, inventario, fornitori, catalogo acquisti, configurazione delle stanze e controlli di magazzino delle cliniche.

Confini di responsabilità

Il componente possiede:

  • schema e dati di magazzino;
  • regole di dominio per ordini, inventario, catalogo e controlli;
  • lifecycle dei materiali clinici, classificazioni prodotto, OCR/UDI normalizzato e record minimo del passaporto implantare;
  • righe ordine normalizzate, dispatch vendor e ricezione DDT manuale;
  • configurazione warehouse delle cliniche;
  • audit tramite identificativi esterni dell'actor.

L'app host possiede:

  • autenticazione, utenti, ruoli e permessi;
  • aziende, gruppi, brand e anagrafica primaria delle cliniche;
  • UI, routing e orchestrazione fra componenti.

Il componente non contiene tabelle utenti/ruoli e non assegna cliniche al primo login. Ogni chiamata riceve dal server host un WarehouseActorContext corrente; questo rende effettive immediatamente revoche e modifiche dello scope.

Installazione e mount

npm install @primocaredentgroup/magazzino convex
// convex/convex.config.ts
import { defineApp } from "convex/server";
import magazzino from "@primocaredentgroup/magazzino/convex.config.js";

const app = defineApp();
app.use(magazzino);
export default app;

API host tipizzata

exposeApi è il solo punto pubblico destinato al frontend. L'actor non compare negli argomenti browser: l'host lo costruisce server-side e traduce le operazioni astratte del componente nei propri permessi RBAC.

// convex/lib/magazzinoExposeApi.ts
import { exposeApi } from "@primocaredentgroup/magazzino";
import { components } from "../_generated/api";
import { buildWarehouseActorContext } from "./warehouseAccess";

export const magazzinoApi = exposeApi(components.magazzino, {
  getActorContext: async (ctx, operation) => {
    return await buildWarehouseActorContext(ctx, operation);
  },
});

Le operazioni stabili esposte al mapping host sono:

  • configurazione: warehouse.approval-rules.manage, warehouse.authorizations.manage, warehouse.categories.manage, warehouse.clinic-macro-scopes.manage, warehouse.clinics.manage e la proiezione host-only tramite client tipizzato;
  • operatività: warehouse.inventory.read, warehouse.inventory.write, warehouse.reporting.read, warehouse.news.read, warehouse.news.manage, warehouse.orders.read, warehouse.cart.read, warehouse.cart.write, warehouse.orders.write e warehouse.orders.approve;
  • cataloghi: warehouse.products.manage, warehouse.catalog-events.read, warehouse.vendor-catalog.manage e warehouse.vendors.manage;
  • workflow specializzati: warehouse.feedback.write, warehouse.feedback.manage, warehouse.rooms-guide.manage, warehouse.safety-stock.manage e warehouse.tap-refill.manage.
  • materiali clinici: warehouse.clinical-materials.read, warehouse.clinical-materials.write e warehouse.clinical-materials.manage;
  • vendor/DDT: warehouse.vendor-orders.read, warehouse.vendor-orders.dispatch, warehouse.vendor-orders.receive e warehouse.vendor-orders.manage.

Il package esporta anche MagazzinoClient, ComponentApi e tutti i validator pubblici tramite @primocaredentgroup/magazzino/validators. Non servono wrapper generati, patch a node_modules o cast del component handle.

Scope dell'actor nella 0.5

WarehouseActorContext distingue due concetti che l'host deve derivare server-side:

  • clinicExternalIds elenca le cliniche sulle quali l'actor può operare;
  • clinicScope vale assigned_clinics oppure all_clinics e dichiara se un amministratore può modificare configurazioni globali condivise da tutte le cliniche.

clinicScope: "all_clinics" non sostituisce l'elenco clinicExternalIds: le normali letture e scritture clinica-specifiche restano sempre verificate contro quell'elenco. L'accesso system è riservato alle orchestrazioni host fidate.

Nella 0.5 richiedono un amministratore con scope all_clinics:

  • modifica delle policy temporali e delle regole di eleggibilità clinica;
  • classificazione clinica dei prodotti;
  • lettura e modifica della configurazione globale dei provider vendor.

Il rollout deve quindi essere coordinato: prima di usare queste scritture con la 0.5, l'host deve popolare clinicScope nel proprio hook getActorContext. Un amministratore senza questo campo viene trattato in modo prudente come non globale e la scrittura viene rifiutata.

Proiezione delle cliniche

La chiave di integrazione è clinicExternalId: string. In PrimoUpCore deve corrispondere al codice clinica stabile, preservando anche zeri iniziali e codici non numerici. Non usare _id Convex del Core e non convertire il codice in numero.

L'host sincronizza soltanto la proiezione organizzativa mediante clinics.upsertProjection. L'upsert aggiorna nome, area, azienda, gruppo, brand, timezone e stato senza sovrascrivere stanze, riuniti e budget warehouse.

Sviluppo e verifica

npm test
npm run typecheck
npm run verify
npm pack --dry-run

npm run codegen richiede un deployment Convex configurato ed è intenzionale, ma non fa parte di prepublishOnly: il contratto ComponentApi del package è derivato dal codice sorgente locale e non da un deployment host potenzialmente obsoleto.

Gli helper di @primocaredentgroup/magazzino/test costruiscono un actor fidato senza persistere utenti nel componente.

Materiali clinici e vendor nella 0.5

Il client tipizzato espone due namespace aggiuntivi:

await client.clinicalMaterials.ensureDefaultWindowPolicies(ctx, { actor });
await client.clinicalMaterials.syncCase(ctx, {
  actor,
  caseCode: "core:clinical-case:...",
  clinicExternalId: "001",
  domain: "implant",
  patientCode: "core:patient:...",
  appointmentCode: "core:appointment:...",
  carePlanRowCode: "core:care-plan-row:...",
  appointmentDate: "2026-08-18",
  evaluationDate: "2026-08-13",
  sourceFacts: [{ kind: "service_code", code: "IMPLANT" }],
});

await client.vendorOrders.requestDispatch(ctx, {
  actor,
  orderId,
  provider: "astidental",
  idempotencyKey: "host-request-id",
});

Le policy delle finestre sono configurazioni versionate e inizializzabili in modo idempotente con ensureDefaultWindowPolicies. Gli identificativi host sono codici opachi; in particolare list_row_external_id è un ripiego transitorio finché Listini non espone una chiave business durevole.

Il gate host deve usare clinicalMaterials.countRequiredOpenCases, che valuta senza il limite di paginazione della workspace tutti i casi aperti dei domini richiesti. listCases resta invece una query di presentazione con limite massimo di 200 elementi.

orders.items e lo stato italiano restano leggibili nella fase di widen. I nuovi flussi vendor usano orderLines e stati distinti per approvazione, dispatch e ricezione.

Gli adapter supportati in questa release sono intenzionalmente fake o manual: non eseguono traffico reale. OCR reale, autenticazione Straumann, credenziali e contratti Astidental/Straumann devono essere forniti dall'host al momento dell'attivazione e non vengono memorizzati nelle tabelle del componente.

Migrazione alla 0.5

La 0.5 aggiunge soltanto tabelle e campi opzionali allo schema 0.4. Il vecchio array orders.items resta disponibile durante il dual-read e viene trasformato idempotentemente in orderLines. Nessun reset o backfill distruttivo è incluso.

Le modifiche a policy temporali o regole di eleggibilità non riscrivono lo storico in autonomia: i casi aperti conservano la versione applicata e devono essere rivalutati dall'orchestrazione host. Prima di attivare un gate su dati già esistenti, l'host deve inoltre eseguire il proprio bootstrap degli appuntamenti nel perimetro concordato.

Migrazione alla 0.4

La 0.4 è un cambio di contratto:

  • rimuove API e tabelle component-owned per utenti, ruoli e permessi;
  • sostituisce gli ID clinica numerici con clinicExternalId stringa;
  • richiede l'hook host getActorContext;
  • deriva nomi e audit dal contesto fidato o dai dati di dominio;
  • espone argomenti e ritorni completamente tipizzati.

Come previsto dal piano di integrazione 2026, gli ambienti correnti non contengono dati reali di magazzino: la 0.4 parte da uno stato componente nuovo. Non è previsto un backfill automatico dei vecchi dati demo.

La pubblicazione npm resta manuale perché richiede il 2FA dell'owner.

Licenza

Proprietario — Primo Care Dent Group. Uso interno.