Bu belge public runtime plugin sozlesmesinin normatif ozetidir. Plugin kaynaklari guvenilir deploy girdisidir; request veya tenant ayarindan modul yolu kabul edilmez.
CTXHUB_PLUGINS, plugin manifest dosyalarinin mutlak yollarini JSON dizi olarak alir:
CTXHUB_PLUGINS=["/opt/ctxhub/plugins/example/plugin.manifest.json"]Bos veya tanimsiz deger community runtime davranisini degistirmez. Host tum manifestleri boot sirasinda dogrular; surum, route, permission, feature veya consumer cakismasinda process fail-fast durur.
Guncel public extension contract'i:
- API version:
1 - API revision:
5 - Admin API version/revision:
1/3 - Domain event schema version:
1
Major version kirici degisikliklerde, revision ayni major icindeki geriye uyumlu
eklemelerde artar. Plugin manifesti ihtiyac duydugu minimum revision'i apiRevision
ile bildirir.
Manifest entrypoints.api ile ESM veya CJS modulunu gosterir. Modul en az
registerApi export etmelidir. Manifest consumer bildiriyorsa registerConsumers da
zorunludur:
export async function registerApi(app, context) {}
export async function registerConsumers(context) {
context.events.register('example-consumer', {
types: ['content.updated'],
batchSize: 100,
maxAttempts: 8,
initialPosition: 'latest',
retry: {
baseDelayMs: 1000,
maxDelayMs: 300000,
multiplier: 2,
},
async handle(events) {},
})
}API ve consumer process'leri ayni manifesti ayri ayri yukler. Process-ici kayitlar paylasilmaz.
Context dondurulmus, dar ve versioned bir yuzeydir:
{
version,
revision,
plugin: { name, version },
events,
sources,
auth,
entitlements,
settings,
secrets, // only with tenant.secrets.manage
log,
}context.sources API revision 2 ile eklenmistir:
await context.sources.getContentSnapshot({ tenantId, contentId })
await context.sources.getCollectionEntrySnapshot({
tenantId,
collectionKey,
entryId,
})Her iki metod da tenant sinirini sorguda uygular, kaynak yoksa null doner ve lifecycle
status'unu filtrelemez. Plugin published/draft/archived kararini kendi yetkili
politikasiyla verir. Content snapshot kategori/etiket etiketlerini ve custom field
definition metadata'sini; collection snapshot normalize data ve enum dataLabels
alanlarini tasir. Raw Mongoose model, Mongo client veya credential aciga cikmaz.
Source facade salt okunurdur. Plugin kaynak Content/CollectionEntry kayitlarini bu yuzeyden olusturamaz, guncelleyemez veya silemez.
context.auth ve context.settings API revision 3 ile eklenmistir. Auth facade
yalniz manifestte bildirilen izinler icin session/JWT guard'i uretir; tenant ve user
kimligini dogrulanmis request context'inden verir. Settings facade plugin adiyla
namespace edilmis, tenant-scoped JSON ayarlarini optimistic revision kontroluyle
okur/yazar. Raw model veya baska plugin namespace'i aciga cikmaz.
API revision 4 context.entitlements facade'ini ekler. Plugin yalniz manifestinde
bildirdigi feature key'ler icin guard uretebilir; aktif tenant planinda feature yoksa
route 403 FeatureNotEntitled doner. Commercial feature key'leri public core'da sabitlenmez.
API revision 5, varsayilan plugin yuzeyini genisletmeden manifest capability'leri
ekler. tenant.backup.export capability'sini acikca bildiren trusted plugin su salt
okunur metodlari alir:
context.sources.streamTenantBackupRecords({ tenantId })
context.sources.listTenantBackupFiles({ tenantId })
context.sources.openTenantBackupFile({ tenantId, key })Export edilen veritabani kayitlari Mongo Extended JSON bicimindedir. Her sorgu
tenantId filtresini uygular; media key'i hem tenant-scoped Media kaydiyla hem de
tenant slug prefix'iyle dogrulanir. Facade baska tenant kaydi veya storage key'i
gorurse islemi fail-closed sonlandirir.
tenant.secrets.manage, plugin'e context.secrets kasasini verir. Secret deger AES-256-GCM
ile sifrelenir ve tenant ID + plugin adi + key authenticated additional data (AAD)
olarak baglanir. tenant.settings.enumerate yalniz plugin'in kendi setting key'i olan
tenant ID'lerini listeler; baska plugin namespace'ini goremez. Bu uc capability
manifestte yoksa ilgili metodlar context'e hic eklenmez.
API revision 6, hosted tenant restore icin tenant.backup.restore capability'sini
ekler. Bu capability yalniz trusted backup plugin'ine tenant-scoped database ve media
yazma facade'i verir:
context.restore.getTenant({ tenantId })
context.restore.findPopulatedCollections({ tenantId, collections })
context.restore.checkIdentity({ collection, id, tenantId })
context.restore.upsert({ collection, id, tenantId, document })
context.restore.delete({ collection, id, tenantId })
context.restore.getMediaTarget({ tenantId })
context.restore.putFile({ tenantId, key, body, contentType, contentLength })
context.restore.deleteFile({ tenantId, key })Facade yalniz allowlist'teki tenant-owned CMS koleksiyonlarini kabul eder. Tenant, User, Membership, Role, token, billing ve operasyonel kayitlar yazilamaz; user referansi iceren dokumanlar core tarafinda da fail-closed reddedilir. Media key'i hedef tenant slug prefix'i ile eslesmelidir. Mongo veya R2 credential'i plugin'e aciga cikmaz.
Admin API revision 3, community fallback'li virtual:ctxhub-plugins girisini,
plugin page/menu kaydina ek olarak tenant tab, content-search ve content-editor panel
katkilarini ve bunlarin fail-fast kontrolunu ekler. Hosted composition
commercial admin kaynagini local workspace'ten verir; private npm registry gerekmez.
- Manifest yollarini yalniz deploy composition belirler.
- Pluginler guvenilir uygulama kodudur; host bir guvenlik sandbox'i degildir.
- Private plugin core ic servis/model dosyalarini import etmemeli, yalniz context facade'larini kullanmalidir.
- Secret degerleri manifest, Git, log veya public health cevabina yazilmaz.
- Manifest permission guard'i revision 3, plan feature entitlement guard'i revision 4'tedir. Authenticated commercial route'lar hem permission hem entitlement uygular.
- Public tenant aramasi ayrica opt-in, public entitlement ve rate limit tamamlanana kadar kapali kalir.