@digimuza/system-core

中文文档
0.8.1发布于 2026/11/11UNLICENSEDTypeScriptES Module零依赖近 30 天下载 2899

Shared system core for per-tenant Next.js + Convex applications: config, identity, roles, permissions, invites, API keys, feature flags, logging, tracing and audit, an AI assistant, MCP connections for ChatGPT and Claude, automations (email / form → AI ex

原始使用文档

Vienai įmonei diegiama atskira Next.js ir Convex aplikacija. @digimuza/system-core yra bendras NPM paketas. Kliento aplikacija registruoja verslo modulius, o branduolys tvarko konfigūraciją, tapatybes, teises ir diagnostiką. finance ir powerbi yra modulio sutarties pavyzdžiai.

Moduliai ir jų paskirtis

config įkelia ir pagal Zod schemas validuoja serverio konfigūraciją. auth susieja patikimo tiekėjo tapatybę su lokaliu vartotoju. users saugo stabilų ID, tapatybės sąsają, patvirtinto el. pašto būseną ir paskyros būseną. Kliento papildomi įrašai siejami per userId. profile leidžia aktyviam vartotojui tvarkyti savo profilio pateikimo laukus. Tapatybės, el. pašto patvirtinimo, būsenos ir rolių keitimas turi atskirus procesus.

roles valdo roles, subroles, jų sudėtį ir priskyrimus. permissions registruoja kode aprašytus veiksmus ir priima prieigos sprendimus. invites valdo vienkartinius, atšaukiamus kvietimus su galiojimo terminu ir numatomomis rolėmis. api-keys išduoda, rotuoja ir atšaukia agentų raktus. Modulių registras saugo modulių tipą, verslo modulių būseną ir registracijos versiją.

logging registruoja struktūruotus įvykius. tracing sieja Next.js, Convex ir išorinių operacijų žingsnius pagal operacijos ID. feature-flags valdo funkcijų prieinamumą jau įjungtuose moduliuose. Funkcijos žyma negali suteikti teisės. Audito įrašai fiksuoja saugumui svarbių pakeitimų autorių, taikinį, laiką, rezultatą ir pakeistas sąsajas. Diagnostikoje maskuojamos paslaptys, sesijų duomenys ir raktai, taip pat ir Super rodinyje.

Viešasis paketas ir jo naudotojai

Pirmoji versija platinama vienu versijuojamu NPM paketu su atskirais importo keliais. Kiekvienas klientas savo aplikacijoje fiksuoja paketo versiją ir turi atskirą Convex diegimą. Aplikacija pasirenka įtraukiamus verslo modulius, jų ekranus, prisijungimo ir kvietimų pristatymo tiekėjus. Paketas apibrėžia bendras serverio operacijas, duomenų schemas, TypeScript tipus ir sąsajas šioms integracijoms.

Kas integruojaSiūlomas importo keliasKą gauna
Serverio paleidimas@digimuza/system-core/configSystemConfig.load() ir sinchroninį register(schema) po įkėlimo
Modulio autorius@digimuza/system-core/modulesdefineModule(), manifesto tipus ir validaciją
Convex aplikacija@digimuza/system-core/convexSistemos registraciją, užklausų ir mutacijų pagalbines funkcijas, teisių patikrą
Next.js serveris@digimuza/system-core/nextAutentifikuotos sesijos perdavimą ir tipizuotą kreipimąsi į Convex
Next.js kliento komponentai@digimuza/system-core/reactDabartinio vartotojo, matomų modulių ir leidžiamų veiksmų duomenis kliento kuriamam UI
Paieška@digimuza/system-core/searchModulių paieškos tiekėjus ir bendrą search užklausą
Pranešimai@digimuza/system-core/notificationsPranešimų lenteles, tipus, notify ir vartotojo funkcijas
Audito eksportas@digimuza/system-core/auditNaršyklei saugų auditToCsv
AI integracijos@digimuza/system-core/mcp, @digimuza/system-core/mcp/nextMCP modulį, OAuth ir MCP serverio maršrutus Next.js aplikacijai

Šie pavadinimai yra projektuojama v1 sutartis. Paleidimo konfigūracija, Infisical klientas ir paslaptys pasiekiami tik serverio importuose. Kliento komponentų importavimas neturi reikalauti serverio aplinkos kintamųjų.

Funkcijų katalogas

ModulisV1 operacijosTikrinamas rezultatas
configĮkelti vieną konfigūracijos versiją, validuoti kelių modulių schemas, pateikti nuasmenintą būsenąLygiagretūs load() naudoja tą patį įkėlimą. register() iki įkėlimo grąžina aiškią klaidą. Būsena nerodo reikšmių.
modulesRegistruoti manifestus, išvardyti įdiegtus modulius, gauti efektyvią būseną, įjungti ar išjungti verslo modulįPakartotinis registravimas išsaugo kliento pasirinkimą. Sisteminio modulio išjungimo užklausa atmetama.
authPradėti ir užbaigti prisijungimą per pasirinktą tiekėją, nustatyti veikėją, atsijungtiPasibaigusi sesija neleidžia atlikti apsaugoto veiksmo. Neatpažintai paskyrai reikalingas galiojantis kvietimas arba pradinis patvirtintas Super prisijungimas.
usersPeržiūrėti vartotoją, rasti pagal tapatybę, puslapiuoti sąrašą, sustabdyti ir aktyvuoti paskyrąPakartotinai gavus prisijungimo įvykį lieka vienas vartotojas. Aktyvavimas neatkuria atšauktų raktų.
profileSkaityti ir redaguoti savo rodomą vardą, kalbą ir laiko juostąĮrašomi tik leidžiami laukai. Kliento profilio plėtiniai turi atskirą schemą ir prieigos taisykles.
invitesSukurti, pristatyti, pakartotinai išsiųsti, atšaukti, priimti, rodyti būsenąPakartotinis siuntimas pakeičia ankstesnį žetoną. Nepavykus pristatyti galima kartoti nesukuriant naujos paskyros.
permissionsRegistruoti katalogą, išvardyti teises pagal modulį, patikrinti veiksmą, paaiškinti sprendimą įgaliotam operatoriuiUI ir serveris naudoja tą patį sprendimo modelį. Serveris apsaugo veiksmą net tiesiogiai iškvietus Convex funkciją.
rolesKurti, kopijuoti, redaguoti ir archyvuoti roles bei subroles, peržiūrėti ryšius, priskirti roles ir jas atšauktiPrieš keitimą galima matyti paveiktas roles ir gavėjų skaičių. Archyvuotas objektas nebesuteikia teisių.
api-keysSukurti savininko raktą su rolėmis, išvardyti jo raktus, keisti roles, rotuoti ir atšauktiRaktų sąraše matomas identifikavimo prefiksas, galiojimas ir būsena. Paslaptis parodoma vieną kartą.
feature-flagsRegistruoti modulio žymas kode, skaityti efektyvią reikšmę, keisti instaliacijos reikšmę, grąžinti numatytąjąV1 žymos yra loginės ir galioja vienai instaliacijai. Nežinoma žyma nesuaktyvina funkcijos. Žymos reikšmė naudojama kartu su modulio ir teisės patikromis.
loggingRašyti struktūruotus įvykius su lygiu, modulio ID, įvykio vardu ir koreliacijos IDVienos užklausos klaidą galima rasti pagal ID. Tokenai ir slapti laukai pašalinami prieš siunčiant į žurnalų saugyklą.
tracingPradėti operaciją, susieti jos žingsnius, perduoti kontekstą foninei užduočiai, užbaigti su rezultatuPagal vieną trace ID matomi Next.js, Convex ir integracijos žingsniai, jų trukmės ir klaidos vieta.
auditĮrašyti prieigos bei administravimo pakeitimus, leisti įgaliotam asmeniui filtruoti pagal laiką, veikėją ir objektąAgentui išsaugomi rakto ir savininko ID. Sėkmingo saugomo pakeitimo auditas įrašomas kartu su DB pakeitimu.

Naujo modulio sutartis

Modulio autorius pateikia manifestą ir registruoja jį aplikacijos sudėtyje. Identifikatorius nekinta tarp versijų. Kiekviena teisė ir pradinė subrolė turi identifikatorių, pavadinimą ir aprašą. Žemiau pateiktas sutrumpintas siūlomo API pavyzdys.

import { defineModule } from "@digimuza/system-core/modules"

export const finance = defineModule({
  id: "finance",
  kind: "business",
  description: "Sąskaitų peržiūra ir tvirtinimas",
  permissions: [
    { id: "finance:invoice:read", name: "Skaityti", description: "Peržiūrėti sąskaitą" },
    { id: "finance:invoice:approve", name: "Tvirtinti", description: "Patvirtinti sąskaitą" },
  ],
  initialSubroles: [{
    id: "finance:reader",
    name: "Skaitytojas",
    description: "Gali peržiūrėti sąskaitas",
    permissions: ["finance:invoice:read"],
  }],
})

Kiekvieno modulio dokumentacijoje privalomi paskirtis, tipas, viešos operacijos, duomenų savininkas, konfigūracijos raktai, teisės, pradinės subrolės, žymos ir bent vienas sėkmės bei atsisakymo scenarijus. Programinė priklausomybė nuo kito modulio nesuteikia jo teisių. Išimtas iš aplikacijos ar nepažįstamas modulis tampa neprieinamas net turint ankstesnį DB priskyrimą.

Administravimo ir integracijų paviršius

Kliento dashboardas gali pateikti šiuos rodinius: mano profilis ir raktai, vartotojai ir kvietimai, rolės bei subrolės, modulių katalogas, funkcijų žymos, auditas ir diagnostika. Sąrašai palaiko puslapiavimą. Rolės detalė rodo subroles, jų teises ir gavėjus pagal žiūrinčiojo įgaliojimus. Modulio kortelėje rodoma konfigūruota ir konkrečiam veikėjui efektyvi būsena, kad Super aiškiai matytų, ką gali naudoti klientas.

Autentifikacijos adapteris grąžina patikrintą tiekėjo tapatybę. Kvietimų siuntimo adapteris gauna gavėją, vienkartinę nuorodą ir pristatymo operacijos ID. Logų ir trace eksportuotojai gauna jau išvalytus įvykius. Adapterių klaidos turi aiškų rezultatą: privalomos tapatybės patikros gedimas blokuoja prieigą, laiško siuntimo gedimas palieka kartojamą pristatymą, diagnostikos eksportuotojo gedimas nekeičia jau įvykdytos verslo operacijos rezultato.

Viešos funkcijos pateikia stabilius klaidų kodus autentifikacijos, teisių, duomenų validacijos, konflikto ir laikino nepasiekiamumo atvejams. Klientui grąžinamas operacijos ID. Kai pats įrašo egzistavimas yra ribota informacija, svetimas ir neegzistuojantis įrašas išorei atrodo vienodai. Tiksli atmetimo priežastis pasiekiama tik įgaliotame diagnostikos rodinyje.

Diegimo ir leidimų priėmimas

Coolify diegimas turi fiksuoti aplikacijos bei paketo versijas, validuoti konfigūraciją, vykdyti suderinamas Convex migracijas, registruoti manifestus ir patikrinti abiejų vykdymo aplinkų parengtį. Projekto identifikacijai numatomas diegimo parametras INFISCAL_PROJECT_ID. Pakartotinas migracijos ar registracijos paleidimas išsaugo rezultatą. Nepavykęs diegimas neaktyvuoja iš dalies užregistruoto katalogo. Grįžimas prie ankstesnės kodo versijos galimas tik jei ji suderinama su aktyvia schema ir teisių katalogu.

Prieš publikuojant versiją etaloninė Next.js + Convex aplikacija įdiegia supakuotą NPM artefaktą. Tikrinami deklaruoti importai ir tipai, serverio ir naršyklės paketų atskyrimas, įdiegimas į tuščią Convex, atnaujinimas iš ankstesnės palaikomos versijos ir to paties diegimo pakartojimas. Suderinamos Next.js, React, Convex ir Zod versijos nurodomos leidimo peer dependencies ir tikrinamos CI.

Priėmimo bandyme operatorius pakviečia darbuotoją, darbuotojas prisijungia ir susikuria ribotos rolės raktą. Įjungus bandomąjį verslo modulį agentas atlieka leidžiamą veiksmą. Tada pakeičiama rolė, atšaukiamas raktas ir tikrinama, ar jau suplanuotas darbas sustabdomas. Pagal tą pačią operaciją turi būti galima susieti audito įrašą ir techninę diagnostiką. Papildomai kartojamas nepavykęs kvietimo pristatymas, simuliuojamas išjungtas diagnostikos eksportuotojas ir patikrinama, kad jokioje naršyklės ar žurnalo išvestyje nėra paslapčių.

Konfigūracija ir diegimas

import SystemConfig from "@digimuza/system-core/config" → await SystemConfig.load() → const env = SystemConfig.register(schema). Coolify pateikia pradinius INFISCAL_BASE_URL, INFISCAL_CLIENT_ID, INFISCAL_SECRET, INFISCAL_PATH ir INFISCAL_ENV. Diegimo konfigūracija taip pat turi vienareikšmiškai identifikuoti Infisical projektą. Aplikacijos paslapčių šaltinis yra Infisical. Trūkstant privalomos reikšmės atitinkamas servisas nepasiekia parengties būsenos. Klaidoje pateikiamas rakto pavadinimas.

Next.js ir Convex vykdymo aplinkoms konfigūracija pateikiama atskirai. Convex užklausos ir mutacijos prieigos patikrą atlieka naudodamos lokaliai prieinamą aktyvios versijos konfigūraciją. Diegimas laikomas baigtu, kai ankstesnės versijos instancijos nebeaptarnauja užklausų. Naršyklė gauna tik aiškiai viešomis paskelbtas reikšmes.

Peržiūra kaip rolė

Tikras Super (patvirtintas el. paštas SUPER_USER_EMAILS sąraše) gali laikinai peržiūrėti sistemą kaip vienos rolės turėtojas. Peržiūros metu kiekvienas prieigos sprendimas taikomas kaip tai rolei: verslo teisės, modulių būsena, tik Super leidžiami veiksmai, administravimo funkcijos, delegavimas ir kvietimai. Sesija rodo isSuper: false ir rolės teises. Super savo API raktams lieka tikruoju Super. Pradžia ir pabaiga įrašomos į auditą; archyvuota rolė peržiūrą užbaigia.

Verslo moduliai pakete

@digimuza/system-core/finance yra pirmasis pakartotinai naudojamas verslo modulis: manifestas, financeTables, defineFinance(system) funkcijos ir teisės. Aplikacija tik įtraukia lenteles į schemą ir eksportuoja funkcijas; vartotojo sąsaja lieka aplikacijoje.

AI asistentas

@digimuza/system-core/ai yra verslo modulis ai: pokalbis su asistentu, kuris gali naudoti aplikacijos funkcijas kaip įrankius. Asistentas veikia prisijungusio žmogaus vardu ir tik su jo teisėmis. Modulis registruojamas išjungtas; jį įjungia Super.

  1. ai:chat:use (subrolė ai:user) leidžia kalbėtis su asistentu ir matyti tik savo pokalbius. Kito žmogaus pokalbio nemato niekas, ir Super taip pat. API raktai kalbėtis negali.
  2. Ką asistentas gali daryti, lemia kiekvieno įrankio teisė (pvz. finance:invoice:read). Modeliui siūlomi tik tie įrankiai, kurių teisę veikėjas turi dabar, o prieš kiekvieną kvietimą teisė tikrinama iš naujo. Asistentas neturi savo rolių: atėmus rolę, kitas įrankio kvietimas atmetamas (FORBIDDEN), o Super, peržiūrintis kaip rolė, asistentu gali tik tai, ką gali ta rolė.
  3. Įrankį apibrėžia modulis su defineAiTool: teisė yra paties modulio teisė, rašantys veiksmai reikalauja žmogaus patvirtinimo (requiresApproval), o tvarkyklė viską patikrina prieš pirmą įrašymą, nes nepavykusios tvarkyklės ankstesni įrašai lieka.
  4. Kiekvienas įrankio kvietimas, patvirtinimas ir atmetimas įrašomas į auditą. Nepavykęs atsakymas rodo klaidos kodą ir operationId.
  5. Modelis kviečiamas Convex Node veiksme (Mastra, OpenAI suderinamas Chat Completions API). OPENAI_BASE_URL nurodo tarpinį serverį (pvz. 9Router https://router.digimuza.ai/v1), OPENAI_API_KEY yra jo raktas, AI_MODEL yra jame esantis modelio pavadinimas. Be OPENAI_API_KEY asistentas atsako, kad nesukonfigūruotas. Naudojimas apmokamas pagal žetonus.

Įdiegimo žingsniai ir įrankio pavyzdys: INTEGRATION.md, skyrius „AI assistant“.

AI integracijos (MCP)

@digimuza/system-core/mcp yra verslo modulis mcp (priklauso nuo ai): ChatGPT ir Claude (claude.ai, Claude Desktop, Claude Code) kalbasi su aplikacijos AI asistentu per MCP serverį. Modulis registruojamas išjungtas; jį įjungia Super.

  1. Žmogus su mcp:connection:create ir ai:chat:use sukuria vienkartinę nuorodą https://<svetainė>/mcp/c/<kodas> ir pasirenka jos roles. Rolės ribojamos kaip API raktų: tik turimos, ne saugomos, bent viena turi leisti naudotis asistentu. Nuoroda rodoma vieną kartą, galioja 30 minučių ir panaudojama vieną kartą. Saugoma tik maiša.
  2. Klientas vykdo OAuth 2.1 (RFC 9728, RFC 8414, dinaminė registracija, PKCE S256, besisukantys atnaujinimo žetonai). Autorizacijos žingsnis vietoje prisijungimo panaudoja nuorodą. Antrą kartą ta pačia nuoroda prisijungti negalima.
  3. Ryšys veikia per API raktą su paskirtimi mcp: teisės yra rakto rolių ir dabartinių savininko teisių sankirta. Atšaukus ryšį, sustabdžius savininką ar išjungus modulį žetonai iš karto nebeveikia.
  4. Įrankiai: ask_agent, respond_to_approval (pakeitimus tvirtina žmogus kliento lange), list_agents, list_threads, get_thread. Ryšys mato tik savo pradėtus pokalbius. Pokalbiai yra žmogaus AI pokalbiai su žyma mcp ir kliento vardu, todėl aplikacijoje matoma, ką ChatGPT ar Claude klausė, gyvai.
  5. Viskas įrašoma į auditą: mcp.link.created, mcp.link.redeemed, mcp.connection.revoked, mcp.token.reuse, mcp.tool.*.

Įdiegimas, keliai ir aplinka: INTEGRATION.md, skyrius „AI integrations over MCP“.

Automatizacijos

@digimuza/system-core/automations yra verslo modulis automations: kanalas → AI ištraukimas → įrašymas. Laiškas ar formos pateikimas virsta įvykiu, modelis iš jo ištraukia nurodytus laukus, o rezultatas įrašomas per aplikacijos rašančius AI įrankius (pvz. „rasti arba sukurti klientą, tada sukurti užklausą“). Modulis registruojamas išjungtas; jį įjungia Super.

  1. Teisės: automations:automation:read (matyti automatizacijas ir vykdymus), automations:automation:manage (kurti, keisti, įjungti, raktai; tik žmogus), automations:run:review (tvirtinti ar atmesti). Subrolės automations:viewer, automations:reviewer, automations:admin.
  2. Kanalai: webhook / forma (/api/automations/hook/<id>, slaptas ahk_… raktas rodomas vieną kartą, keičiamas; JSON ar formos duomenys; 30 kvietimų per minutę, 256 KB) ir el. paštas: kiekviena automatizacija gauna savo adresą Resend priėmimo domene (vienas pasirašytas email.received webhook visoms automatizacijoms, paskirstoma pagal gavėją), arba kito tiekėjo (Postmark, Mailgun, SendGrid, Cloudflare Email Worker) webhook į automatizacijos hook adresą. Visi kanalai virsta ta pačia žinutės forma.
  3. Ištraukimas: instrukcija ir laukų schema (string, number, date, email, phone, enum, array). Modelis kviečiamas per tą pačią OpenAI suderinamą konfigūraciją kaip AI asistentas (OPENAI_BASE_URL, OPENAI_API_KEY, AI_MODEL arba AUTOMATIONS_AI_MODEL) su griežta JSON schema; atsakymas tikrinamas ir, jei reikia, taisomas vieną kartą.
  4. Įrašymas: 1–2 veiksmai per aplikacijos įrankius (defineAiTool), laukų susiejimas tikrinamas pagal įrankio zod schemą; antrasis veiksmas gali naudoti pirmojo rezultatą ({{previous.customerId}}).
  5. Pagal nutylėjimą rezultatas laukia patvirtinimo („Laukia patvirtinimo“): tvirtintojas mato originalią žinutę, gali pataisyti laukus, patvirtinti ar atmesti (ir keletą iš karto). Automatinis režimas (įrašyti be peržiūros) galimas tik įjungus vėliavą automations:auto-mode, ir tik kai rezultatas be klaidų.
  6. Įrašai daromi automatizacijos savininko vardu per API raktą su paskirtimi automation: pasirinktos rolės, apribotos dabartinėmis savininko teisėmis (kaip API raktai ir MCP). Kitas žmogus, išsaugojęs automatizaciją, tampa jos savininku.
  7. Auditas: automations.create, .update, .enable, .disable, .archive, .secret.rotate, .run.approve, .run.reject, .run.auto_insert, o kiekvienas įrašas dar ir ai.tool.run bei paties įrankio įvykis.

Sėkmės scenarijus: forma atsiunčia vardą ir el. paštą → vykdymas „Laukia patvirtinimo“ → tvirtintojas patvirtina → sukuriamas klientas ir su juo susieta užklausa. Atmetimo scenarijus: webhook be rakto gauna 401, išjungta automatizacija 403, savininkas be įrankio teisės automatizacijos sukurti negali (FORBIDDEN).

Įdiegimas: INTEGRATION.md, skyrius „Automations“.

Gavimas (Ingest)

@digimuza/system-core/ingest yra verslo modulis ingest: Resend integracija, pašto dėžutės ir pasirašytas gaunamų laiškų webhook. Kiti moduliai (automatizacijos) skaito dėžutes. Modulis registruojamas išjungtas; jį įjungia Super.

  1. Teisės: ingest:inbox:read (matyti integraciją, dėžutes ir laiškus), ingest:inbox:manage (kurti, išjungti, trinti, prijungti dėžutes), ingest:integration:manage (webhook, domenas, bandomasis laiškas; tik žmogus). Subrolės ingest:viewer, ingest:editor, ingest:admin.
  2. Resend raktas tik aplinkoje (RESEND_RECEIVING_API_KEY, pilnos prieigos); jis niekada nesaugomas DB ir nerodomas naršyklėje.
  3. Mygtukas „Prijungti / Sutvarkyti automatiškai“ sukuria email.received webhook į <SITE_URL>/api/ingest/resend, užšifruotai išsaugo jo pasirašymo raktą (INGEST_ENCRYPTION_KEY), ištrina pasenusius šios svetainės webhook, parenka gavimo domeną ir išsiunčia bandomąjį laišką. Kartojamas saugiai; raktas pakeičiamas (senasis galioja valandą).
  4. Gavimo domenas: savas domenas su įjungtu gavimu, valdomas <id>.resend.app arba naujas subdomenas (pvz. in.example.com), kurį modulis sukuria Resend tik gavimui ir parodo DNS įrašus. Pagrindinio domeno siuntimo nustatymai ir DNS nekeičiami.
  5. Webhook: Svix parašas, 5 min. laiko langas, pakartojimai atpažįstami pagal Svix id; atsakoma iš karto, laiškas apdorojamas fone. Laiško turinys parsiunčiamas tik jei yra jo dėžutė.
  6. AI įrankiai: ingest.list_inboxes, ingest.create_inbox (su patvirtinimu, gali prijungti automatizaciją).

Sėkmės scenarijus: administratorius paspaudžia mygtuką → bandomasis laiškas atkeliauja → sukuriama uzklausos@… dėžutė, prijungiama automatizacija → laiškai matomi dėžutėje su vykdymo būsena. Atmetimo scenarijus: žiūrovas negali kurti dėžučių (FORBIDDEN), suklastotas webhook gauna 401.

Įdiegimas: INTEGRATION.md, skyrius „Ingest“.

Paieška, auditas ir pranešimai

@digimuza/system-core/search: viena paieška per visus modulius. Kiekvienas modulis pateikia tiekėją su savo teise. Užklausa vykdoma tik tiems tiekėjams, kurių modulis įjungtas ir kurių teisę žmogus turi dabar (Super, peržiūrintis kaip rolė, gauna tos rolės rezultatus). Užklausa yra 2–100 simbolių, rezultatų skaičius ribojamas. API raktai paieškos nenaudoja. Skaitymas į auditą neįrašomas.

Auditą galima filtruoti pagal modulį ir veiksmo prefiksą. listAuditFacets grąžina esamus veiksmus ir modulius filtrams. CSV eksportą sudaro naršyklėje auditToCsv (RFC 4180, apsauga nuo formulių įterpimo), o pats eksportas įrašomas į auditą (audit.export).

@digimuza/system-core/notifications yra bendras pranešimų pagrindas. Branduolys saugo tipą ir JSON parametrus, o tekstą (LT/EN, UI ir el. laiške) kuria aplikacija. Gavėjai nurodomi vartotojų ID arba teise; teisės turėtojai nustatomi tuo metu galiojančiu prieigos sprendimu, veiksmo autorius praleidžiamas. Kiekvienas vartotojas mato ir tvarko tik savo pranešimus ir nustatymus (kaip profilį). El. laiškus siunčia aplikacijos adapteris; nepavykęs siuntimas pažymimas failed ir verslo operacijos nesugadina. Pranešimai siunčiami priskyrus roles ir sukūrus sąskaitą, kurią reikia patvirtinti; be įdiegtų pranešimų šie veiksmai veikia kaip anksčiau.

Rolės ir modulio registracija

Vienintelė įmonės valdomų suteikimų grandinė yra gavėjas → rolė → subrolė → teisė. Gavėjas yra vartotojas arba agento API raktas. Kiekviename lygyje leidžiama turėti kelias sąsajas. Viena subrolė priklauso vienam moduliui. Rolė gali sujungti kelių modulių subroles. Tiesioginis subrolės ar teisės suteikimas gavėjui yra neleistina operacija.

Teisės raktas yra stabilus modulis:objektas:veiksmas. Kiekvienas modulis kode deklaruoja savo ID, tipą, paskirtį, teises ir pradinių subrolių šablonus. Diegimo registracija pagal stabilius ID sukuria trūkstamus įrašus. Esamų subrolių administratoriaus pakeitimai ir modulio būsena išsaugomi. Nauja teisė atsiranda kataloge. Jos įtraukimas į jau naudojamą subrolę turi būti sąmoningas DB pakeitimas. Pasenusi arba nežinoma teisė atmetama, identifikatoriai naujai prasmei nenaudojami. Nesuderinamos registracijos ir ID kolizijos sustabdo diegimą.

Sisteminiai moduliai visada įjungti. Verslo modulis pirmą kartą registruojamas išjungtas. Jį įjungti ar išjungti gali tik Super. Išjungus išlieka duomenys ir priskyrimai. Admin yra įprasta administravimo rolė su konkrečiomis teisėmis. Super nustatomas pagal aktyvios paskyros patikimo autentifikacijos tiekėjo patvirtintą el. paštą ir diegimo SUPER_USER_EMAILS sąrašą. Sąrašas taikomas po pakartotinio diegimo. DB rolės pavadinimas šio statuso nesuteikia.

Prieigos sprendimas

Serveris nustato veikėją iš sesijos arba API rakto. Neaiški tapatybė, nežinoma teisė, neveikianti paskyra ar prieigos patikros klaida užklausą atmeta. Autentifikacijos pradžia ir kvietimo priėmimas turi atskirus aiškiai aprašytus įėjimo taškus. Verslo kode kviečiama await requirePermission(ctx, "finance:invoice:approve"). Konkretų objektą turinčioms teisėms serverio funkcija papildomai tikrina objekto ryšį ir leistiną būsenos perėjimą.

Žmogui teisė galioja, kai bent viena jo rolė ją suteikia ir modulis įjungtas. Aktyviam vartotojui automatiškai priskiriama apsaugota profilio rolė, suteikianti visas savo profilio teises. Profilio savininką serveris nustato iš sesijos. Aktyvus Super gali naudoti visus registruotus modulius ir visas teises, įskaitant diagnostiką. Verslo duomenų vientisumo taisyklės galioja visiems.

Agentui būtinas aktyvus raktas, aktyvus savininkas, įjungtas modulis, teisė per rakto roles ir ta pati šiuo metu galiojanti savininko teisė. Tikrinama teisės, o ne rolės ID sankirta. Kiekvieno rakto rolės nepriklausomos. Super statusas, išjungtų modulių išimtis ir asmeninės sesijos veiksmai raktui nepersiduoda. Pirmajai versijai raktų išdavimas, prieigos administravimas ir Super diagnostika skirti tik žmogaus sesijai.

Delegavimas ir paskyrų gyvavimo ciklas

Rolės priskyrimui reikia ir roles:assignment:create, ir leidimo suteikti konkrečią tikslinę rolę. Delegavimo apimtis saugoma pagal stabilius rolių ID. Rolę galima suteikti tik jei visos jos suteikiamos teisės telpa į suteikiančiojo įgaliojimus. Vertinamos ir išjungtų modulių teisės, kad modulis vėliau neaktyvuotų neautorizuotų priskyrimų. Įprastas delegatas negali keisti savo įgaliojimų, saugomų rolių ar delegavimo ribų. Pradinę Admin rolę įmonei suteikia Super.

Subrolės redagavimas keičia visas ją naudojančias roles. Prieš pakeitimą serveris įvertina paveiktas roles ir gavėjus. Pakeitimas leidžiamas tik valdant visas paveiktas roles ir galint deleguoti pridedamas teises. Jei bendrą subrolę naudoja saugoma rolė, administratorius gali kurti atskirą kopiją savo valdomai rolei. Šios taisyklės galioja ir importui, masiniams veiksmams bei kvietimams.

Kvietimas susiejamas su el. paštu ir konkrečių rolių ID. Priėmimo metu tikrinamas patvirtintas gavėjo adresas, galiojimas, vienkartinis panaudojimas ir dabartinė kvietėjo teisė suteikti kiekvieną rolę. Pasikeitus įgaliojimams visas priėmimas atmetamas. Paskyra, priskyrimai ir kvietimo panaudojimas įrašomi atominiu veiksmu. Prisijungimo tapatybė susiejama pagal patikimo tiekėjo stabilų subjekto ID. Vien sutampančio el. pašto nepakanka sulieti paskyras.

API rakto paslaptis rodoma vieną kartą. Convex saugo rakto ID, kriptografinę patikros reikšmę, savininką, pavadinimą, galiojimą ir atšaukimo būseną. Panaikinus raktą jo atkurti negalima. Blokavus arba uždarius savininko paskyrą atšaukiami jo raktai. Savininkui praradus tik vieną teisę kitos rakto teisės išlieka. Savininkui vėl gavus teisę ji vėl veikia, jei raktas tebėra aktyvus ir jo rolė vis dar ją suteikia.

Convex įgyvendinimo sutartis

Ryšiams numatytos atskiros indeksuotos lentelės: userRoles, apiKeyRoles, roleSubroles, subrolePermissions. Atskirai saugomi users, roles, subroles, modules, apiKeys, invites, delegavimo ribos ir audito įvykiai. Užtikrinamas porų unikalumas, pakartotinių operacijų saugumas ir puslapiavimas. Nėra produkto nustatyto rolių skaičiaus limito. Didžiausiai palaikomai instaliacijai prieš išleidimą atliekamas apkrovos bandymas. Jei prieigos sprendimo nepavyksta apskaičiuoti iki galo, jis atmetamas.

Next.js UI gali paslėpti veiksmą, tačiau visos viešos Convex funkcijos tikrina veikėją serveryje. Mutacija tikrina teises ir keičia duomenis vienoje transakcijoje. Užklausa skaito aktualius priskyrimus. Ilgalaikis JWT arba naršyklės kešas negali išsaugoti atšauktos teisės. Po atšaukimo patikra taikoma ir aktyvioms prenumeratoms. Jau vartotojui perduotų duomenų atšaukimas nesugrąžina.

Foninė užduotis saugo veikėjo ir rakto ID, vykdymo metu iš naujo tikrina būseną ir teises. Išorinis veiksmas vykdomas pagal identifikuojamą operaciją su apsauga nuo pakartojimo. Atšaukimas sustabdo dar nepradėtą darbą. Jei išorinė sistema jau priėmė komandą, rezultatas užfiksuojamas audite. Vidiniams sistemos priežiūros darbams naudojamas siauras atskiras įėjimo taškas be vartotojo Super privilegijų.

Privalomi priėmimo scenarijai

  1. Gavėjas gauna tą pačią teisę per dvi roles. Pašalinus vieną kelią veiksmas leidžiamas, pašalinus paskutinį atmetamas.

  2. Pasikeitus subrolei pokytis pasiekia ir vartotoją, ir rakto roles nuo kitos patikros. Agentui savininko teisės išlieka viršutine riba.

  3. Raktui tiesiogiai siunčiamas teisės arba subrolės ID. Serveris atmeta visą priskyrimą.

  4. Super savininko raktas be rolių neturi verslo teisių. Su finansų role jis gali naudoti tik įjungtą finance modulį.

  5. Išjungus modulį blokuojami UI, tiesioginė API, agentas ir laukiančios užduotys. Žmogaus Super sesijai modulis prieinamas. Įjungus grįžta anksčiau suteiktos teisės.

  6. Pakeitęs profilio užklausos userId, vartotojas negali perskaityti ar redaguoti kito profilio. Asmeninis profilio veiksmas negali pakeisti Super identiteto.

  7. Kvietimas panaudojamas du kartus, pasibaigia arba kvietėjas netenka įgaliojimų. Papildomų priskyrimų nesukuriama.

  8. Raktas atšaukiamas tarp užduoties sukūrimo ir vykdymo. Užduotis nesukuria šalutinio poveikio.

  9. Delegatas mėgina suteikti Admin per kvietimą, pakeisti bendrą subrolę ar savo delegavimo ribas. Operacija atmetama.

  10. Du lygiagretūs pakeitimai mėgina apeiti delegavimo ribą. Galutinė būsena tenkina tas pačias taisykles kaip nuosekliai įvykdyti patikrinti pakeitimai.

  11. Pakartotinė modulio registracija išsaugo vartotojų pakeitimus ir įjungimo būseną. Nauja teisė savaime nepatenka į seną Full subrolę.

  12. Po diegimo iš SUPER_USER_EMAILS pašalinta aktyvi sesija praranda Super. Nepatvirtintas adresas arba DB rolė vardu Super privilegijos nesuteikia.

  13. Nežinoma teisė, ištrinta rolė, pasibaigęs raktas ar užblokuotas savininkas nesuteikia prieigos. Audite galima atskirti agentą nuo jo savininko.

Techniniai šaltiniai

OWASP Authorization Cheat Sheet · Convex transakcijos · Convex actions

版本与发布记录

@digimuza/system-core 共发布 19 个版本,首次发布于 2026/11/09;过去 12 个月发布了 19 个版本。

版本发布日期距今
0.8.1latest2026/11/111 天前
0.8.1-rc.1next2026/11/111 天前
0.8.02026/11/111 天前
0.8.0-rc.12026/11/111 天前
0.7.02026/11/111 天前
0.7.0-rc.12026/11/111 天前

关于 @digimuza/system-core 的常见问题

@digimuza/system-core 是什么?

Shared system core for per-tenant Next.js + Convex applications: config, identity, roles, permissions, invites, API keys, feature flags, logging, tracing and audit, an AI assistant, MCP connections for ChatGPT and Claude, automations (email / form → AI ex

如何安装 @digimuza/system-core?

在项目目录运行 npm install @digimuza/system-core,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:zod(^4.0.0)、convex(^1.31.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@digimuza/system-core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@digimuza/system-core 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@digimuza/system-core 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@digimuza/system-core 可以商用吗?

@digimuza/system-core 使用 UNLICENSED 许可。作者声明为 UNLICENSED,即不授予公开使用许可(与公共领域的 Unlicense 不同)。使用前需获得作者授权。以上为概括,不构成法律意见,请以许可原文为准。

@digimuza/system-core 的下载量有多少?

根据 npm 官方下载统计,@digimuza/system-core 在 2026/10/12 – 2026/11/10 这 30 天内被下载 2,899 次,日均约 97 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@digimuza/system-core 还在维护吗?

最新版本 0.8.1 发布于 2026/11/11(1 天前);至今共发布 19 个版本,其中过去 12 个月发布了 19 个;首次发布于 2026/11/09。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。