@krizaka /设置
产品的配置为 数据:已解析的设置(标志、整数、选项、子集、双语文本)的类型化注册表 用户→工作区→全局→默认,由管理员更改而无需重新部署, 每一个变化都会留下一条审计线 (谁,什么,什么时候,之前,之后)。一个json安全的注册表描述就是管理屏幕的来源。
import { emitMigration } from "@krizaka/db";
import { defineSettings, flag, integer, dbSettings, settingsSchema, GLOBAL, WORKSPACE_SCOPES } from "@krizaka/settings";
const settings = defineSettings({ "features.apiKeys": flag("features", true, WORKSPACE_SCOPES), "limits.maxFileMb": integer("limits", 10, { min: 1, max: 10, unit: "MB" }) } as const);
emitMigration(settingsSchema, 1, { tables: {} }); // commit the SQL once, in your migrations (idempotent)
const service = dbSettings(settings, { query, workspaceOf, clock: () => performance.now() });
await service.get("features.apiKeys", { userId }); // typed: boolean
await service.set({ id: adminId, label: email }, GLOBAL, "features.apiKeys", false, now);
模式。 这些表格是 @krizaka/db 模块(settings),版本1字节-与此包之前发布的SQL相同,因此具有它们的产品采用没有DDL更改的SQL: adoptMigration(settingsSchema, 1, context) 只写标记, emitMigration(…) 为没有SQL的数据库编写SQL。原来的迁移函数不变, @deprecated,为一个未成年人。价格版本是模块 settings_prices (pricesSchema)。
保留在产品中的内容:它的注册表(键、组、默认值)、它在自己的边界进行的检查(“服务器拒绝关闭的内容”)、谁可能是管理员、HTTP路由。时钟被传了进来;这里什么都看不懂。
价格-目录(ADR-009)
产品的价格也是数据:一种类型 目录 条目(product.plan,单位,以分或“报价”为单位的金额; 计算机辅助设计,
税前、可用性 public · internal · founder-limited · preparing,命名为limits)。产品以前的定价
模块变成 种子;其管理员通过更改条目 从某个日期开始安排一个版本 (现在或以后,永远不会
过去),并且每次更改都会写入审计行 settings_audit (price.<product>.<plan>). 订阅记录它的版本
以(versionId)并保存下来。
import { AVAILABILITY, definePrices, findTypedPrices, priceCatalogue, pricesMigration, priceStore, publicCatalogue, UNIT } from "@krizaka/settings";
const prices = definePrices([
{ product: "akinaza", plan: "starter", unit: UNIT.month, amountCents: 4500, availability: AVAILABILITY.founderLimited, limits: { founderCap: 20 } },
{ product: "akinaza", plan: "scale", unit: UNIT.month, amountCents: 9900, availability: AVAILABILITY.preparing },
]);
await db.query(pricesMigration()); // once, in your migrations (idempotent; includes the settings' tables)
const catalogue = priceCatalogue(prices, priceStore({ query }));
const shown = publicCatalogue(await catalogue.catalogue(now)); // a public page: never internal, « en préparation » without a figure
await catalogue.schedule({ id: adminId, label: email }, "akinaza.starter", { amountCents: 4900 }, effectiveFrom, now);
const sold = await catalogue.version(subscription.priceVersionId); // the price it was sold at, forever
expect(findTypedPrices(messages)).toEqual([]); // a product's test: no amount typed in a message
describePrices(catalogue, now) 是管理屏幕绘制的json安全描述(已经安排的内容);
memoryPriceStore() 服务测试。金额通过 @krizaka/payments,通过入口的钥匙。
postgresSettings名字是dbSettings;它仍然是@deprecated别名一个小调,离开下一个大调。