@stratum-hq/create 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +6 -4
- package/dist/index.js +78 -44
- package/package.json +17 -3
- package/src/generators/readme.ts +5 -5
- package/src/index.ts +5 -5
- package/src/matrix.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @stratum-hq/create
|
|
2
2
|
|
|
3
|
+
## 0.5.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- b737034: Improve the npm metadata so that npm search finds the packages. Each `description` now starts with the problem the package solves. Each package carries the same multi-tenancy keywords, including `multitenancy`. The `homepage` field now points at the package's page on https://docs.stratum-hq.org instead of a GitHub folder. The first lines of each README link the documentation. No code changes.
|
|
8
|
+
- a1bd9aa: Replace em dashes in user-visible text with ordinary punctuation. This touches READMEs, package descriptions, CLI output, control plane startup log messages, the text that `@stratum-hq/create` writes into generated projects, and the assertion messages in `@stratum-hq/test-utils`. The CLI `health` and `migrate` tables now print `no` instead of a dash for an unset flag. No behavior changes.
|
|
9
|
+
|
|
3
10
|
## 0.5.0
|
|
4
11
|
|
|
5
12
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @stratum-hq/create
|
|
2
2
|
|
|
3
|
-
Scaffold a complete [Stratum](https://github.com/stratum-hq/Stratum) multi-tenancy project with one command
|
|
3
|
+
Scaffold a complete [Stratum](https://github.com/stratum-hq/Stratum) multi-tenancy project with one command: package.json, Docker Compose, environment files, and framework-specific starter code.
|
|
4
|
+
|
|
5
|
+
Read the documentation at [docs.stratum-hq.org/packages/create](https://docs.stratum-hq.org/packages/create/).
|
|
4
6
|
|
|
5
7
|
## Usage
|
|
6
8
|
|
|
@@ -28,9 +30,9 @@ npx @stratum-hq/create my-app [options]
|
|
|
28
30
|
|
|
29
31
|
## Templates
|
|
30
32
|
|
|
31
|
-
- **express** (default)
|
|
32
|
-
- **fastify
|
|
33
|
-
- **nextjs
|
|
33
|
+
- **express** (default): Express server with Stratum middleware, tenant-aware routes, and TypeScript config.
|
|
34
|
+
- **fastify**: Fastify server with the Stratum plugin registered.
|
|
35
|
+
- **nextjs**: Next.js project with edge middleware that resolves the tenant from a verified JWT.
|
|
34
36
|
|
|
35
37
|
## After Scaffolding
|
|
36
38
|
|
package/dist/index.js
CHANGED
|
@@ -1012,14 +1012,17 @@ function generateTsconfig(framework, extraSources = []) {
|
|
|
1012
1012
|
// ../hono/package.json
|
|
1013
1013
|
var package_default = {
|
|
1014
1014
|
name: "@stratum-hq/hono",
|
|
1015
|
-
version: "1.
|
|
1016
|
-
description: "
|
|
1015
|
+
version: "1.3.1",
|
|
1016
|
+
description: "Hono multi-tenancy middleware: tenant resolution with AsyncLocalStorage context",
|
|
1017
1017
|
keywords: [
|
|
1018
1018
|
"multi-tenancy",
|
|
1019
|
+
"multitenancy",
|
|
1019
1020
|
"multi-tenant",
|
|
1020
1021
|
"saas",
|
|
1021
1022
|
"tenant",
|
|
1023
|
+
"tenant-isolation",
|
|
1022
1024
|
"hono",
|
|
1025
|
+
"asynclocalstorage",
|
|
1023
1026
|
"middleware",
|
|
1024
1027
|
"typescript",
|
|
1025
1028
|
"stratum"
|
|
@@ -1063,7 +1066,7 @@ var package_default = {
|
|
|
1063
1066
|
},
|
|
1064
1067
|
license: "MIT",
|
|
1065
1068
|
author: "Christian Crank",
|
|
1066
|
-
homepage: "https://
|
|
1069
|
+
homepage: "https://docs.stratum-hq.org/packages/hono/",
|
|
1067
1070
|
bugs: "https://github.com/stratum-hq/Stratum/issues",
|
|
1068
1071
|
engines: {
|
|
1069
1072
|
node: ">=20.0.0"
|
|
@@ -1078,18 +1081,27 @@ var package_default = {
|
|
|
1078
1081
|
// ../db-adapters/package.json
|
|
1079
1082
|
var package_default2 = {
|
|
1080
1083
|
name: "@stratum-hq/db-adapters",
|
|
1081
|
-
version: "1.
|
|
1082
|
-
description: "
|
|
1084
|
+
version: "1.4.0",
|
|
1085
|
+
description: "Multi-tenant PostgreSQL row-level security for pg, Prisma, Drizzle, and Sequelize, plus schema-per-tenant and database-per-tenant isolation",
|
|
1083
1086
|
keywords: [
|
|
1084
1087
|
"multi-tenancy",
|
|
1088
|
+
"multitenancy",
|
|
1085
1089
|
"multi-tenant",
|
|
1086
1090
|
"saas",
|
|
1087
1091
|
"tenant",
|
|
1088
1092
|
"tenant-isolation",
|
|
1089
|
-
"postgresql",
|
|
1090
|
-
"postgres",
|
|
1091
1093
|
"row-level-security",
|
|
1092
1094
|
"rls",
|
|
1095
|
+
"postgresql",
|
|
1096
|
+
"prisma",
|
|
1097
|
+
"drizzle",
|
|
1098
|
+
"drizzle-orm",
|
|
1099
|
+
"sequelize",
|
|
1100
|
+
"pg",
|
|
1101
|
+
"node-postgres",
|
|
1102
|
+
"schema-per-tenant",
|
|
1103
|
+
"database-per-tenant",
|
|
1104
|
+
"postgres",
|
|
1093
1105
|
"schema-isolation",
|
|
1094
1106
|
"database",
|
|
1095
1107
|
"stratum"
|
|
@@ -1100,6 +1112,10 @@ var package_default2 = {
|
|
|
1100
1112
|
".": {
|
|
1101
1113
|
types: "./dist/index.d.ts",
|
|
1102
1114
|
default: "./dist/index.js"
|
|
1115
|
+
},
|
|
1116
|
+
"./pglite": {
|
|
1117
|
+
types: "./dist/pglite/index.d.ts",
|
|
1118
|
+
default: "./dist/pglite/index.js"
|
|
1103
1119
|
}
|
|
1104
1120
|
},
|
|
1105
1121
|
files: [
|
|
@@ -1119,18 +1135,23 @@ var package_default2 = {
|
|
|
1119
1135
|
registry: "https://registry.npmjs.org/"
|
|
1120
1136
|
},
|
|
1121
1137
|
dependencies: {
|
|
1122
|
-
"@stratum-hq/core": "^1.
|
|
1138
|
+
"@stratum-hq/core": "^1.5.1",
|
|
1123
1139
|
pg: "^8.11.0"
|
|
1124
1140
|
},
|
|
1125
1141
|
peerDependencies: {
|
|
1142
|
+
"@electric-sql/pglite": "^0.4.2",
|
|
1126
1143
|
"drizzle-orm": ">=0.29.0"
|
|
1127
1144
|
},
|
|
1128
1145
|
peerDependenciesMeta: {
|
|
1146
|
+
"@electric-sql/pglite": {
|
|
1147
|
+
optional: true
|
|
1148
|
+
},
|
|
1129
1149
|
"drizzle-orm": {
|
|
1130
1150
|
optional: true
|
|
1131
1151
|
}
|
|
1132
1152
|
},
|
|
1133
1153
|
devDependencies: {
|
|
1154
|
+
"@electric-sql/pglite": "^0.4.6",
|
|
1134
1155
|
"@prisma/client": "^5.10.0",
|
|
1135
1156
|
"@types/pg": "^8.11.0",
|
|
1136
1157
|
"drizzle-orm": "^0.45.3",
|
|
@@ -1139,7 +1160,7 @@ var package_default2 = {
|
|
|
1139
1160
|
},
|
|
1140
1161
|
license: "MIT",
|
|
1141
1162
|
author: "Christian Crank",
|
|
1142
|
-
homepage: "https://
|
|
1163
|
+
homepage: "https://docs.stratum-hq.org/packages/db-adapters/",
|
|
1143
1164
|
bugs: "https://github.com/stratum-hq/Stratum/issues",
|
|
1144
1165
|
engines: {
|
|
1145
1166
|
node: ">=20.0.0"
|
|
@@ -1154,21 +1175,28 @@ var package_default2 = {
|
|
|
1154
1175
|
// ../lib/package.json
|
|
1155
1176
|
var package_default3 = {
|
|
1156
1177
|
name: "@stratum-hq/lib",
|
|
1157
|
-
version: "1.
|
|
1158
|
-
description: "
|
|
1178
|
+
version: "1.7.0",
|
|
1179
|
+
description: "Multi-tenancy for Node.js and PostgreSQL: tenant hierarchy, config inheritance, row-level security, ABAC, audit log, and GDPR tooling",
|
|
1159
1180
|
keywords: [
|
|
1160
1181
|
"multi-tenancy",
|
|
1182
|
+
"multitenancy",
|
|
1161
1183
|
"multi-tenant",
|
|
1162
1184
|
"saas",
|
|
1163
|
-
"b2b",
|
|
1164
1185
|
"tenant",
|
|
1165
|
-
"tenant-management",
|
|
1166
1186
|
"tenant-isolation",
|
|
1167
|
-
"node",
|
|
1168
|
-
"typescript",
|
|
1169
|
-
"postgresql",
|
|
1170
1187
|
"row-level-security",
|
|
1171
1188
|
"rls",
|
|
1189
|
+
"postgresql",
|
|
1190
|
+
"tenant-hierarchy",
|
|
1191
|
+
"ltree",
|
|
1192
|
+
"abac",
|
|
1193
|
+
"audit-log",
|
|
1194
|
+
"encryption",
|
|
1195
|
+
"webhooks",
|
|
1196
|
+
"b2b",
|
|
1197
|
+
"tenant-management",
|
|
1198
|
+
"node",
|
|
1199
|
+
"typescript",
|
|
1172
1200
|
"schema-isolation",
|
|
1173
1201
|
"config-inheritance",
|
|
1174
1202
|
"gdpr",
|
|
@@ -1199,10 +1227,10 @@ var package_default3 = {
|
|
|
1199
1227
|
registry: "https://registry.npmjs.org/"
|
|
1200
1228
|
},
|
|
1201
1229
|
dependencies: {
|
|
1202
|
-
"@opentelemetry/api": "^1.
|
|
1203
|
-
"@stratum-hq/core": "^1.5.
|
|
1204
|
-
"@stratum-hq/db-adapters": "^1.
|
|
1205
|
-
"@stratum-hq/sdk": "^1.3.
|
|
1230
|
+
"@opentelemetry/api": "^1.0.0",
|
|
1231
|
+
"@stratum-hq/core": "^1.5.1",
|
|
1232
|
+
"@stratum-hq/db-adapters": "^1.4.0",
|
|
1233
|
+
"@stratum-hq/sdk": "^1.3.1",
|
|
1206
1234
|
pg: "^8.11.0"
|
|
1207
1235
|
},
|
|
1208
1236
|
peerDependencies: {
|
|
@@ -1214,13 +1242,14 @@ var package_default3 = {
|
|
|
1214
1242
|
}
|
|
1215
1243
|
},
|
|
1216
1244
|
devDependencies: {
|
|
1245
|
+
"@electric-sql/pglite": "^0.4.6",
|
|
1217
1246
|
"@types/pg": "^8.11.0",
|
|
1218
1247
|
typescript: "^5.4.0",
|
|
1219
1248
|
vitest: "^4.1.11"
|
|
1220
1249
|
},
|
|
1221
1250
|
license: "MIT",
|
|
1222
1251
|
author: "Christian Crank",
|
|
1223
|
-
homepage: "https://
|
|
1252
|
+
homepage: "https://docs.stratum-hq.org/packages/lib/",
|
|
1224
1253
|
bugs: "https://github.com/stratum-hq/Stratum/issues",
|
|
1225
1254
|
engines: {
|
|
1226
1255
|
node: ">=20.0.0"
|
|
@@ -1235,10 +1264,11 @@ var package_default3 = {
|
|
|
1235
1264
|
// ../mongodb/package.json
|
|
1236
1265
|
var package_default4 = {
|
|
1237
1266
|
name: "@stratum-hq/mongodb",
|
|
1238
|
-
version: "0.
|
|
1239
|
-
description: "MongoDB tenant isolation for Stratum
|
|
1267
|
+
version: "0.6.1",
|
|
1268
|
+
description: "MongoDB tenant isolation for Stratum: shared collection, collection-per-tenant, and database-per-tenant strategies",
|
|
1240
1269
|
keywords: [
|
|
1241
1270
|
"multi-tenancy",
|
|
1271
|
+
"multitenancy",
|
|
1242
1272
|
"multi-tenant",
|
|
1243
1273
|
"saas",
|
|
1244
1274
|
"tenant",
|
|
@@ -1271,8 +1301,8 @@ var package_default4 = {
|
|
|
1271
1301
|
clean: "rm -rf dist"
|
|
1272
1302
|
},
|
|
1273
1303
|
dependencies: {
|
|
1274
|
-
"@stratum-hq/core": "^1.5.
|
|
1275
|
-
"@stratum-hq/sdk": "^1.3.
|
|
1304
|
+
"@stratum-hq/core": "^1.5.1",
|
|
1305
|
+
"@stratum-hq/sdk": "^1.3.1"
|
|
1276
1306
|
},
|
|
1277
1307
|
peerDependencies: {
|
|
1278
1308
|
mongodb: "^6.0.0 || ^7.0.0"
|
|
@@ -1294,7 +1324,7 @@ var package_default4 = {
|
|
|
1294
1324
|
},
|
|
1295
1325
|
license: "MIT",
|
|
1296
1326
|
author: "Christian Crank",
|
|
1297
|
-
homepage: "https://
|
|
1327
|
+
homepage: "https://docs.stratum-hq.org/packages/mongodb/",
|
|
1298
1328
|
bugs: "https://github.com/stratum-hq/Stratum/issues",
|
|
1299
1329
|
engines: {
|
|
1300
1330
|
node: ">=20.0.0"
|
|
@@ -1309,10 +1339,11 @@ var package_default4 = {
|
|
|
1309
1339
|
// ../mysql/package.json
|
|
1310
1340
|
var package_default5 = {
|
|
1311
1341
|
name: "@stratum-hq/mysql",
|
|
1312
|
-
version: "0.
|
|
1313
|
-
description: "MySQL tenant isolation for Stratum
|
|
1342
|
+
version: "0.6.1",
|
|
1343
|
+
description: "MySQL tenant isolation for Stratum: shared table, table-per-tenant, and database-per-tenant strategies",
|
|
1314
1344
|
keywords: [
|
|
1315
1345
|
"multi-tenancy",
|
|
1346
|
+
"multitenancy",
|
|
1316
1347
|
"multi-tenant",
|
|
1317
1348
|
"saas",
|
|
1318
1349
|
"tenant",
|
|
@@ -1347,8 +1378,8 @@ var package_default5 = {
|
|
|
1347
1378
|
clean: "rm -rf dist"
|
|
1348
1379
|
},
|
|
1349
1380
|
dependencies: {
|
|
1350
|
-
"@stratum-hq/core": "^1.5.
|
|
1351
|
-
"@stratum-hq/sdk": "^1.3.
|
|
1381
|
+
"@stratum-hq/core": "^1.5.1",
|
|
1382
|
+
"@stratum-hq/sdk": "^1.3.1"
|
|
1352
1383
|
},
|
|
1353
1384
|
peerDependencies: {
|
|
1354
1385
|
mysql2: "^3.0.0",
|
|
@@ -1370,6 +1401,7 @@ var package_default5 = {
|
|
|
1370
1401
|
devDependencies: {
|
|
1371
1402
|
knex: "^3.3.0",
|
|
1372
1403
|
mysql2: "^3.24.4",
|
|
1404
|
+
sequelize: "^6.37.8",
|
|
1373
1405
|
typeorm: "^1.1.1",
|
|
1374
1406
|
typescript: "^5.9.0",
|
|
1375
1407
|
vitest: "^4.1.11"
|
|
@@ -1379,7 +1411,7 @@ var package_default5 = {
|
|
|
1379
1411
|
},
|
|
1380
1412
|
license: "MIT",
|
|
1381
1413
|
author: "Christian Crank",
|
|
1382
|
-
homepage: "https://
|
|
1414
|
+
homepage: "https://docs.stratum-hq.org/packages/mysql/",
|
|
1383
1415
|
bugs: "https://github.com/stratum-hq/Stratum/issues",
|
|
1384
1416
|
engines: {
|
|
1385
1417
|
node: ">=20.0.0"
|
|
@@ -1394,13 +1426,15 @@ var package_default5 = {
|
|
|
1394
1426
|
// ../nestjs/package.json
|
|
1395
1427
|
var package_default6 = {
|
|
1396
1428
|
name: "@stratum-hq/nestjs",
|
|
1397
|
-
version: "1.3.
|
|
1398
|
-
description: "
|
|
1429
|
+
version: "1.3.1",
|
|
1430
|
+
description: "NestJS multi-tenancy: tenant guard, @Tenant() decorator, and module for Stratum",
|
|
1399
1431
|
keywords: [
|
|
1400
1432
|
"multi-tenancy",
|
|
1433
|
+
"multitenancy",
|
|
1401
1434
|
"multi-tenant",
|
|
1402
1435
|
"saas",
|
|
1403
1436
|
"tenant",
|
|
1437
|
+
"tenant-isolation",
|
|
1404
1438
|
"nestjs",
|
|
1405
1439
|
"nest",
|
|
1406
1440
|
"guard",
|
|
@@ -1453,7 +1487,7 @@ var package_default6 = {
|
|
|
1453
1487
|
},
|
|
1454
1488
|
license: "MIT",
|
|
1455
1489
|
author: "Christian Crank",
|
|
1456
|
-
homepage: "https://
|
|
1490
|
+
homepage: "https://docs.stratum-hq.org/packages/nestjs/",
|
|
1457
1491
|
bugs: "https://github.com/stratum-hq/Stratum/issues",
|
|
1458
1492
|
engines: {
|
|
1459
1493
|
node: ">=20.0.0"
|
|
@@ -1724,23 +1758,23 @@ npx drizzle-kit push
|
|
|
1724
1758
|
function getStrategyDescription(strategy) {
|
|
1725
1759
|
switch (strategy) {
|
|
1726
1760
|
case "rls":
|
|
1727
|
-
return `- **Row-Level Security
|
|
1761
|
+
return `- **Row-Level Security**: PostgreSQL RLS policies filter rows by tenant automatically
|
|
1728
1762
|
- Each query sets \`app.current_tenant_id\` and RLS enforces isolation
|
|
1729
1763
|
- All tenants share one database and schema`;
|
|
1730
1764
|
case "schema":
|
|
1731
|
-
return `- **Schema-per-tenant
|
|
1765
|
+
return `- **Schema-per-tenant**: each tenant gets a dedicated PostgreSQL schema
|
|
1732
1766
|
- Queries are routed to the correct schema via search_path
|
|
1733
1767
|
- Shared database, isolated schemas`;
|
|
1734
1768
|
case "database":
|
|
1735
|
-
return `- **Database-per-tenant
|
|
1769
|
+
return `- **Database-per-tenant**: each tenant gets a fully isolated database
|
|
1736
1770
|
- Connection routing directs queries to the correct database
|
|
1737
1771
|
- Maximum isolation at the cost of more resource usage`;
|
|
1738
1772
|
case "collection":
|
|
1739
|
-
return `- **Collection-per-tenant
|
|
1773
|
+
return `- **Collection-per-tenant**: each tenant gets dedicated MongoDB collections
|
|
1740
1774
|
- Collection names are prefixed or namespaced by tenant ID
|
|
1741
1775
|
- Shared database, isolated collections`;
|
|
1742
1776
|
case "table-prefix":
|
|
1743
|
-
return `- **Table-prefix
|
|
1777
|
+
return `- **Table-prefix**: tenant-specific tables with a naming prefix
|
|
1744
1778
|
- Tables are prefixed with the tenant identifier
|
|
1745
1779
|
- Shared database, prefixed table names`;
|
|
1746
1780
|
default:
|
|
@@ -2093,7 +2127,7 @@ fastify.listen({ port, host: "0.0.0.0" }, (err) => {
|
|
|
2093
2127
|
`;
|
|
2094
2128
|
}
|
|
2095
2129
|
function generateNextjsPage(projectName) {
|
|
2096
|
-
return `// app/page.tsx
|
|
2130
|
+
return `// app/page.tsx: ${projectName} root page
|
|
2097
2131
|
export default function Home() {
|
|
2098
2132
|
return (
|
|
2099
2133
|
<main style={{ padding: "2rem", fontFamily: "sans-serif" }}>
|
|
@@ -2126,7 +2160,7 @@ docker compose up -d
|
|
|
2126
2160
|
|
|
2127
2161
|
\`\`\`bash
|
|
2128
2162
|
cp .env.example .env
|
|
2129
|
-
# Edit .env
|
|
2163
|
+
# Edit .env: update DATABASE_URL, JWT_SECRET, and STRATUM_API_KEY
|
|
2130
2164
|
\`\`\`
|
|
2131
2165
|
|
|
2132
2166
|
### 3. Install dependencies
|
|
@@ -2156,9 +2190,9 @@ ${template === "nextjs" ? "" : "\u251C\u2500\u2500 tsconfig.json\n"}\u2514\u2500
|
|
|
2156
2190
|
|
|
2157
2191
|
This project uses Stratum for hierarchical multi-tenancy:
|
|
2158
2192
|
|
|
2159
|
-
- **Tenant resolution
|
|
2160
|
-
- **Config inheritance
|
|
2161
|
-
- **Permission ABAC
|
|
2193
|
+
- **Tenant resolution**: from the \`tenant_id\` claim of a bearer token verified with \`JWT_SECRET\` (see \`middleware.ts\`); the subdomain is only a display slug
|
|
2194
|
+
- **Config inheritance**: settings flow down the tenant tree with override support
|
|
2195
|
+
- **Permission ABAC**: role-based permissions with tenant-scoped enforcement
|
|
2162
2196
|
|
|
2163
2197
|
See the [Stratum docs](https://github.com/stratum-hq/Stratum) for full reference.
|
|
2164
2198
|
`;
|
package/package.json
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratum-hq/create",
|
|
3
|
-
"version": "0.5.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"description": "Scaffold a multi-tenant SaaS starter for Node.js: PostgreSQL, MySQL, or MongoDB with Express, Fastify, Next.js, Hono, or NestJS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"multi-tenancy",
|
|
7
|
+
"multitenancy",
|
|
7
8
|
"multi-tenant",
|
|
8
9
|
"saas",
|
|
9
10
|
"tenant",
|
|
11
|
+
"tenant-isolation",
|
|
12
|
+
"row-level-security",
|
|
13
|
+
"rls",
|
|
14
|
+
"postgresql",
|
|
15
|
+
"mysql",
|
|
16
|
+
"mongodb",
|
|
17
|
+
"express",
|
|
18
|
+
"fastify",
|
|
19
|
+
"nextjs",
|
|
20
|
+
"hono",
|
|
21
|
+
"nestjs",
|
|
22
|
+
"prisma",
|
|
23
|
+
"drizzle",
|
|
10
24
|
"create",
|
|
11
25
|
"scaffolding",
|
|
12
26
|
"starter",
|
|
@@ -40,7 +54,7 @@
|
|
|
40
54
|
},
|
|
41
55
|
"license": "MIT",
|
|
42
56
|
"author": "Christian Crank",
|
|
43
|
-
"homepage": "https://
|
|
57
|
+
"homepage": "https://docs.stratum-hq.org/packages/create/",
|
|
44
58
|
"bugs": "https://github.com/stratum-hq/Stratum/issues",
|
|
45
59
|
"engines": {
|
|
46
60
|
"node": ">=20.0.0"
|
package/src/generators/readme.ts
CHANGED
|
@@ -86,23 +86,23 @@ npx drizzle-kit push
|
|
|
86
86
|
function getStrategyDescription(strategy: string): string {
|
|
87
87
|
switch (strategy) {
|
|
88
88
|
case "rls":
|
|
89
|
-
return `- **Row-Level Security
|
|
89
|
+
return `- **Row-Level Security**: PostgreSQL RLS policies filter rows by tenant automatically
|
|
90
90
|
- Each query sets \`app.current_tenant_id\` and RLS enforces isolation
|
|
91
91
|
- All tenants share one database and schema`;
|
|
92
92
|
case "schema":
|
|
93
|
-
return `- **Schema-per-tenant
|
|
93
|
+
return `- **Schema-per-tenant**: each tenant gets a dedicated PostgreSQL schema
|
|
94
94
|
- Queries are routed to the correct schema via search_path
|
|
95
95
|
- Shared database, isolated schemas`;
|
|
96
96
|
case "database":
|
|
97
|
-
return `- **Database-per-tenant
|
|
97
|
+
return `- **Database-per-tenant**: each tenant gets a fully isolated database
|
|
98
98
|
- Connection routing directs queries to the correct database
|
|
99
99
|
- Maximum isolation at the cost of more resource usage`;
|
|
100
100
|
case "collection":
|
|
101
|
-
return `- **Collection-per-tenant
|
|
101
|
+
return `- **Collection-per-tenant**: each tenant gets dedicated MongoDB collections
|
|
102
102
|
- Collection names are prefixed or namespaced by tenant ID
|
|
103
103
|
- Shared database, isolated collections`;
|
|
104
104
|
case "table-prefix":
|
|
105
|
-
return `- **Table-prefix
|
|
105
|
+
return `- **Table-prefix**: tenant-specific tables with a naming prefix
|
|
106
106
|
- Tables are prefixed with the tenant identifier
|
|
107
107
|
- Shared database, prefixed table names`;
|
|
108
108
|
default:
|
package/src/index.ts
CHANGED
|
@@ -296,7 +296,7 @@ fastify.listen({ port, host: "0.0.0.0" }, (err) => {
|
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
function generateNextjsPage(projectName: string): string {
|
|
299
|
-
return `// app/page.tsx
|
|
299
|
+
return `// app/page.tsx: ${projectName} root page
|
|
300
300
|
export default function Home() {
|
|
301
301
|
return (
|
|
302
302
|
<main style={{ padding: "2rem", fontFamily: "sans-serif" }}>
|
|
@@ -330,7 +330,7 @@ docker compose up -d
|
|
|
330
330
|
|
|
331
331
|
\`\`\`bash
|
|
332
332
|
cp .env.example .env
|
|
333
|
-
# Edit .env
|
|
333
|
+
# Edit .env: update DATABASE_URL, JWT_SECRET, and STRATUM_API_KEY
|
|
334
334
|
\`\`\`
|
|
335
335
|
|
|
336
336
|
### 3. Install dependencies
|
|
@@ -360,9 +360,9 @@ ${template === "nextjs" ? "" : "├── tsconfig.json\n"}└── package.jso
|
|
|
360
360
|
|
|
361
361
|
This project uses Stratum for hierarchical multi-tenancy:
|
|
362
362
|
|
|
363
|
-
- **Tenant resolution
|
|
364
|
-
- **Config inheritance
|
|
365
|
-
- **Permission ABAC
|
|
363
|
+
- **Tenant resolution**: from the \`tenant_id\` claim of a bearer token verified with \`JWT_SECRET\` (see \`middleware.ts\`); the subdomain is only a display slug
|
|
364
|
+
- **Config inheritance**: settings flow down the tenant tree with override support
|
|
365
|
+
- **Permission ABAC**: role-based permissions with tenant-scoped enforcement
|
|
366
366
|
|
|
367
367
|
See the [Stratum docs](https://github.com/stratum-hq/Stratum) for full reference.
|
|
368
368
|
`;
|
package/src/matrix.ts
CHANGED
|
@@ -75,7 +75,7 @@ export function parsePresetString(s: string): StackPreset | null {
|
|
|
75
75
|
|
|
76
76
|
const parts = s.toLowerCase().split("-");
|
|
77
77
|
|
|
78
|
-
// Handle "table-prefix" which contains a hyphen
|
|
78
|
+
// Handle "table-prefix" which contains a hyphen; it will split into
|
|
79
79
|
// 5 parts: [db, strategy1, "table", "prefix", orm, framework] or similar.
|
|
80
80
|
// We need to reconstruct multi-word tokens.
|
|
81
81
|
// Format: {database}-{strategy}-{orm}-{framework}
|