create-qs 0.0.0 → 0.8.23
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/README.md +140 -2
- package/index.js +1884 -0
- package/package.json +31 -5
- package/template/default/.quicksilver/.gitattributes +4 -0
- package/template/default/.quicksilver/manual/en-US/00-setup.md +199 -0
- package/template/default/.quicksilver/manual/zh-CN/00-setup.md +199 -0
- package/template/default/.quicksilver/manual/zh-TW/00-setup.md +199 -0
- package/template/default/AGENTS.md +333 -0
- package/template/default/README.md +5 -0
- package/template/default/_gitignore +70 -0
- package/template/default/build.gradle.kts +5 -0
- package/template/default/eslint.config.js +137 -0
- package/template/default/gradle/repo.settings.gradle.kts +90 -0
- package/template/default/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/template/default/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/template/default/gradle.properties +15 -0
- package/template/default/gradlew +248 -0
- package/template/default/gradlew.bat +93 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/api/build.gradle.kts +8 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/api/data/demo/README.md +11 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/api/data/init/rows/menus.jsons +1 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/api/data/init/rows/misc.jsons +15 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/api/data/upgrade/draft.jsons +1 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/api/src/main/kotlin/{{API_PACKAGE}}/AutoConfiguration.kt +25 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/api/src/test/kotlin/{{API_PACKAGE}}/SmokeTests.kt +61 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/api/src/test/kotlin/{{API_PACKAGE}}/TestConfiguration.kt +6 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/module.yaml +8 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/web/package.json +25 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/web/src/module.ts +16 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/web/src/vite-env.d.ts +10 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/web/tsconfig.app.json +7 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/web/tsconfig.json +7 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/web/tsconfig.node.json +7 -0
- package/template/default/modules/{{MODULE_DIRECTORY}}/web/vite.config.ts +11 -0
- package/template/default/package.json +76 -0
- package/template/default/pnpm-workspace.yaml +40 -0
- package/template/default/publishing.yaml +52 -0
- package/template/default/quicksilver.yaml +13 -0
- package/template/default/run/api/build.gradle.kts +8 -0
- package/template/default/run/api/config/README.md +76 -0
- package/template/default/run/api/config/application-dev.yaml +45 -0
- package/template/default/run/api/config/application-h2.yaml +22 -0
- package/template/default/run/api/config/application-mariadb.yaml +22 -0
- package/template/default/run/api/config/application-mssql.yaml +22 -0
- package/template/default/run/api/config/application-oracle.yaml +22 -0
- package/template/default/run/api/config/application-postgresql.yaml +22 -0
- package/template/default/run/api/config/application-test.yaml +28 -0
- package/template/default/run/api/config/application.yaml +84 -0
- package/template/default/run/api/config/logback-test.xml +141 -0
- package/template/default/run/api/config/logback.xml +142 -0
- package/template/default/run/web/index.html +14 -0
- package/template/default/run/web/index.ts +6 -0
- package/template/default/run/web/package.json +18 -0
- package/template/default/run/web/static/config.js +15 -0
- package/template/default/run/web/tsconfig.app.json +4 -0
- package/template/default/run/web/tsconfig.json +7 -0
- package/template/default/run/web/tsconfig.node.json +4 -0
- package/template/default/run/web/vite.config.ts +21 -0
- package/template/default/settings.gradle.kts +19 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
package {{API_PACKAGE}}
|
|
2
|
+
|
|
3
|
+
import com.qsrun.quicksilver.core.application.data.Databases
|
|
4
|
+
import com.qsrun.quicksilver.core.application.data.UnitInfoRepo
|
|
5
|
+
import com.qsrun.quicksilver.core.data.constant.DataSourceCodes
|
|
6
|
+
import com.qsrun.quicksilver.core.test.base.QsBaseTests
|
|
7
|
+
import org.junit.jupiter.api.Assertions.assertTrue
|
|
8
|
+
import org.junit.jupiter.api.Test
|
|
9
|
+
import org.springframework.beans.factory.annotation.Autowired
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Environment smoke test: the Spring context starts, and provisioning has actually loaded the metadata.
|
|
13
|
+
*
|
|
14
|
+
* It also covers loading the data files into their tables, so units need no tests of their own for that. The
|
|
15
|
+
* test context runs every init data file on startup. When any command fails, the context cannot start, and this
|
|
16
|
+
* class fails together with every other test.
|
|
17
|
+
*
|
|
18
|
+
* It also guards `run/api/config/logback-test.xml`. Without a single `@Test` in the test tree, Spring never
|
|
19
|
+
* starts, and a broken logging configuration (for example one that references a converter Spring Boot has
|
|
20
|
+
* removed) goes unnoticed. Such an error makes **every** test throw `DynamicClassLoadingException` from
|
|
21
|
+
* `LogbackLoggingSystem` while the context initializes, with a message unrelated to the code under test, which
|
|
22
|
+
* is hard to trace back.
|
|
23
|
+
*
|
|
24
|
+
* The assertion uses plain JDBC instead of `DatabaseInspectors` on purpose. It depends only on the `Databases`
|
|
25
|
+
* of core, and does not rely on lib-database being on the test classpath of downstream projects.
|
|
26
|
+
*/
|
|
27
|
+
class SmokeTests: QsBaseTests() {
|
|
28
|
+
@Autowired
|
|
29
|
+
private lateinit var unitInfoRepo: UnitInfoRepo
|
|
30
|
+
|
|
31
|
+
@Test
|
|
32
|
+
fun `spring context starts and metadata is provisioned`() {
|
|
33
|
+
val unitCount = Databases.getConnection(DataSourceCodes.METADATA).use { cn ->
|
|
34
|
+
cn.createStatement().use { st ->
|
|
35
|
+
st.executeQuery("select count(*) from ac_unit").use { rs ->
|
|
36
|
+
assertTrue(rs.next(), "select count(*) from ac_unit returned no row")
|
|
37
|
+
rs.getInt(1)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
assertTrue(unitCount > 0, "ac_unit is empty: provisioning did not run")
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Every unit, platform units included, passes the metadata self-check.
|
|
46
|
+
*
|
|
47
|
+
* When the self-check finds a problem on startup, it only logs an error and the service starts as usual. This
|
|
48
|
+
* test turns that into a test failure. A unit created with `$add: 'ac.unit'` that fails the self-check already
|
|
49
|
+
* stops provisioning, so what this test adds is catching a unit broken afterwards by other writes, for example
|
|
50
|
+
* data files that rewrite `ac_unit_field` directly. The self-check covers the metadata only (table name,
|
|
51
|
+
* fields, ID fields, the semantic columns of tree units), and does not compare it with the physical table.
|
|
52
|
+
*/
|
|
53
|
+
@Test
|
|
54
|
+
fun `every unit passes the metadata self-check`() {
|
|
55
|
+
val problems = unitInfoRepo.all().flatMap { unit ->
|
|
56
|
+
unit.diagnostics.map { " [${it.kind}] ${unit.code}: ${it.message}" }
|
|
57
|
+
}
|
|
58
|
+
assertTrue(problems.isEmpty(),
|
|
59
|
+
"Unit metadata diagnostics found ${problems.size} problem(s):\n" + problems.joinToString("\n"))
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{WEB_PACKAGE_NAME}}",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./module": "./src/module.ts"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc -b && vite build",
|
|
11
|
+
"clean": "shx rm -rf dist",
|
|
12
|
+
"lint": "eslint .",
|
|
13
|
+
"lint:fix": "eslint . --fix"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@qs-charts/adapter-preact": "catalog:client",
|
|
17
|
+
"@qs-charts/core": "catalog:client",
|
|
18
|
+
"@qs-elements/web": "catalog:client",
|
|
19
|
+
"@qs-elements/web-preact": "catalog:client",
|
|
20
|
+
{{PLATFORM_WEB_DEPENDENCIES}}
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@qs-platform/preset-vite-web": "catalog:quicksilver"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Module } from '@qs-platform/web-module-core';
|
|
2
|
+
|
|
3
|
+
const pages = {};
|
|
4
|
+
|
|
5
|
+
const plugins = {};
|
|
6
|
+
|
|
7
|
+
const components = {};
|
|
8
|
+
|
|
9
|
+
export const module: Module = {
|
|
10
|
+
pages,
|
|
11
|
+
plugins,
|
|
12
|
+
components,
|
|
13
|
+
styles: [],
|
|
14
|
+
icons: [],
|
|
15
|
+
routes: {},
|
|
16
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
|
+
|
|
3
|
+
import { QeIntrinsicElements } from '@qs-elements/web-preact';
|
|
4
|
+
import { QChartsIntrinsicElements } from '@qs-charts/adapter-preact';
|
|
5
|
+
|
|
6
|
+
declare module 'preact' {
|
|
7
|
+
namespace JSX {
|
|
8
|
+
interface IntrinsicElements extends QeIntrinsicElements, QChartsIntrinsicElements {}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import { quicksilverBuildPlugins } from '@qs-platform/preset-vite-web';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
plugins: [...quicksilverBuildPlugins()],
|
|
6
|
+
resolve: {
|
|
7
|
+
alias: [
|
|
8
|
+
{ find: /^~(.*)$/, replacement: '$1' },
|
|
9
|
+
],
|
|
10
|
+
},
|
|
11
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_CODE}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22.13.0",
|
|
8
|
+
"pnpm": ">=11"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"// --- start dev servers -------------------------------------------": "",
|
|
12
|
+
"dev": "quicksilver dev",
|
|
13
|
+
"dev:h2": "PORT=6210 API_PORT=6211 SPRING_PROFILES_ACTIVE=dev,h2 quicksilver dev",
|
|
14
|
+
"dev:postgresql": "PORT=6220 API_PORT=6221 SPRING_PROFILES_ACTIVE=dev,postgresql quicksilver dev",
|
|
15
|
+
"dev:mariadb": "PORT=6230 API_PORT=6231 SPRING_PROFILES_ACTIVE=dev,mariadb quicksilver dev",
|
|
16
|
+
"dev:mssql": "PORT=6240 API_PORT=6241 SPRING_PROFILES_ACTIVE=dev,mssql quicksilver dev",
|
|
17
|
+
"dev:oracle": "PORT=6250 API_PORT=6251 SPRING_PROFILES_ACTIVE=dev,oracle quicksilver dev",
|
|
18
|
+
"dev:debug": "quicksilver dev --debug",
|
|
19
|
+
"dev:api": "quicksilver gradle :run:bootRun",
|
|
20
|
+
"dev:web": "pnpm -C run/web dev",
|
|
21
|
+
"// --- build subprojects -------------------------------------------": "",
|
|
22
|
+
"build": "pnpm build:api && pnpm build:web",
|
|
23
|
+
"build:api": "quicksilver gradle build",
|
|
24
|
+
"build:web": "pnpm -r --fail-if-no-match --filter './modules/*/web' build",
|
|
25
|
+
"build:release": "pnpm build:web",
|
|
26
|
+
"// --- utils -------------------------------------------------------": "",
|
|
27
|
+
"i18n:extract": "quicksilver i18n extract",
|
|
28
|
+
"sources": "quicksilver sources",
|
|
29
|
+
"// --- lint --------------------------------------------------------": "",
|
|
30
|
+
"lint": "eslint .",
|
|
31
|
+
"lint:fix": "eslint . --fix",
|
|
32
|
+
"// --- test --------------------------------------------------------": "",
|
|
33
|
+
"test:api": "quicksilver gradle test",
|
|
34
|
+
"test:install:e2e": "quicksilver test run self-install-e2e",
|
|
35
|
+
"test:install-upgrade:e2e": "quicksilver test run self-install-upgrade-e2e",
|
|
36
|
+
"test:install:keepalive": "quicksilver test run self-install-keepalive",
|
|
37
|
+
"test:verify:dev": "quicksilver test verify --dev",
|
|
38
|
+
"test:list": "quicksilver test list",
|
|
39
|
+
"// --- packaging (output to build/release) -------------------------": "",
|
|
40
|
+
"package:full": "quicksilver gradle :package-current",
|
|
41
|
+
"package:full:exploded": "quicksilver gradle :package-current-exploded",
|
|
42
|
+
"package:full:all": "quicksilver gradle :package-all",
|
|
43
|
+
"package:full:darwin-x64": "quicksilver gradle :package-darwin-x64",
|
|
44
|
+
"package:full:darwin-arm64": "quicksilver gradle :package-darwin-arm64",
|
|
45
|
+
"package:full:linux-x64": "quicksilver gradle :package-linux-x64",
|
|
46
|
+
"package:full:linux-arm64": "quicksilver gradle :package-linux-arm64",
|
|
47
|
+
"package:full:windows-x64": "quicksilver gradle :package-windows-x64",
|
|
48
|
+
"package:full:windows-arm64": "quicksilver gradle :package-windows-arm64",
|
|
49
|
+
"package:module": "quicksilver gradle :package-module",
|
|
50
|
+
"package:module:exploded": "quicksilver gradle :package-module-exploded",
|
|
51
|
+
"// --- release (build is automatically included) -------------------": "",
|
|
52
|
+
"release": "qs release --target=internal",
|
|
53
|
+
"// --- clean -------------------------------------------------------": "",
|
|
54
|
+
"clean:all": "pnpm clean:api && pnpm -r run clean && pnpm clean:root",
|
|
55
|
+
"clean:api": "quicksilver gradle clean",
|
|
56
|
+
"clean:root": "shx rm -rf build/release build/test",
|
|
57
|
+
"clean:web": "pnpm -r --filter './modules/*/web' --filter './run/web' run clean",
|
|
58
|
+
"// --- lifecycle hooks (run automatically on install) --------------": "",
|
|
59
|
+
"postinstall": "quicksilver docs && playwright install chromium"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@qs-platform/cli": "catalog:quicksilver",
|
|
63
|
+
"@eslint/js": "^10.0.1",
|
|
64
|
+
"@playwright/test": "^1.62.1",
|
|
65
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
66
|
+
"@types/node": "catalog:tooling",
|
|
67
|
+
"@typescript-eslint/eslint-plugin": "^8.69.0",
|
|
68
|
+
"@typescript-eslint/parser": "^8.69.0",
|
|
69
|
+
"eslint": "^10.9.1",
|
|
70
|
+
"globals": "^17.11.0",
|
|
71
|
+
"sass": "catalog:tooling",
|
|
72
|
+
"shx": "catalog:tooling",
|
|
73
|
+
"typescript": "catalog:tooling",
|
|
74
|
+
"vite": "catalog:tooling"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Quicksilver's own packages are not on the public registry. Point the @qs-platform, @qs-elements
|
|
2
|
+
# and @qs-charts scopes at your Nexus in ~/.npmrc, once per machine. To pin them to this project
|
|
3
|
+
# instead, add a `registries` section here. Either way, see .quicksilver/manual/en-US/00-setup.md.
|
|
4
|
+
packages:
|
|
5
|
+
- modules/{{MODULE_DIRECTORY}}/web
|
|
6
|
+
- run/web
|
|
7
|
+
|
|
8
|
+
allowBuilds:
|
|
9
|
+
'@parcel/watcher': true
|
|
10
|
+
esbuild: true
|
|
11
|
+
|
|
12
|
+
engineStrict: true
|
|
13
|
+
|
|
14
|
+
# The scripts in package.json use POSIX sh syntax (single-quoted arguments, `VAR=value command`).
|
|
15
|
+
# On Windows, pnpm runs scripts with cmd.exe by default, which supports neither. The shell emulator
|
|
16
|
+
# runs them the same way on every platform.
|
|
17
|
+
shellEmulator: true
|
|
18
|
+
|
|
19
|
+
minimumReleaseAgeExclude:
|
|
20
|
+
- '@qs-elements/*'
|
|
21
|
+
- '@qs-charts/*'
|
|
22
|
+
- '@qs-platform/*'
|
|
23
|
+
|
|
24
|
+
catalogs:
|
|
25
|
+
client:
|
|
26
|
+
"@qs-charts/adapter-preact": "0.2.11"
|
|
27
|
+
"@qs-charts/core": "0.2.11"
|
|
28
|
+
"@qs-elements/web": "1.0.158"
|
|
29
|
+
"@qs-elements/web-preact": "1.0.158"
|
|
30
|
+
quicksilver:
|
|
31
|
+
"@qs-platform/cli": "0.8.23"
|
|
32
|
+
"@qs-platform/preset-vite-web": "0.8.23"
|
|
33
|
+
"@qs-platform/web-module-core": "0.8.23"
|
|
34
|
+
"@qs-platform/web-module-org": "0.8.23"
|
|
35
|
+
tooling:
|
|
36
|
+
"@types/node": "^26.4.0"
|
|
37
|
+
"sass": "^1.103.1"
|
|
38
|
+
"shx": "^0.4.0"
|
|
39
|
+
"typescript": "^6.0.3"
|
|
40
|
+
"vite": "^7.3.6"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Publishing targets: where artifacts go, and which packages get published.
|
|
2
|
+
#
|
|
3
|
+
# Read by `pnpm qs release --target=<name>`, which covers both halves — Maven artifacts and npm
|
|
4
|
+
# packages — and drives Gradle with the arguments it needs. **Do not run `./gradlew publish`
|
|
5
|
+
# directly**: the Maven URL and credentials prefix are resolved from this file and passed in by
|
|
6
|
+
# `pnpm qs release`. Use `pnpm qs release --only=maven` when you want the Maven half alone.
|
|
7
|
+
#
|
|
8
|
+
# The lookup starts at the **project root** (the directory holding pnpm-workspace.yaml) and walks
|
|
9
|
+
# up, stopping at the .git directory — or at the project root itself before the project is a git
|
|
10
|
+
# repository. The Gradle side uses the same rule; both must find the same file.
|
|
11
|
+
#
|
|
12
|
+
# At every level, local/publishing.yaml is checked first. local/ is not under version control, so a
|
|
13
|
+
# copy of this file placed there is a machine-local override: copy it as-is and edit the URLs, the
|
|
14
|
+
# `packages` paths stay valid (their base is still the parent of local/). When that copy is in
|
|
15
|
+
# effect, both the release summary and the Gradle log name the file being used.
|
|
16
|
+
#
|
|
17
|
+
# Credentials do NOT go here. Put the npm token in ~/.npmrc as `//<host>/:_authToken=<token>`,
|
|
18
|
+
# and the Maven account in ~/.gradle/gradle.properties as
|
|
19
|
+
# `<maven-credentials-prefix>.user` / `.password`.
|
|
20
|
+
#
|
|
21
|
+
# An empty URL means the target is not configured yet: publishing fails with an error rather
|
|
22
|
+
# than falling back to a default registry.
|
|
23
|
+
#
|
|
24
|
+
# Maven artifacts never carry a draft with changes (data/upgrade/draft.jsons): the release refuses
|
|
25
|
+
# them on every target. Run `pnpm qs data freeze` on the main branch and commit before releasing.
|
|
26
|
+
#
|
|
27
|
+
# Paths under `packages` are relative to this file — or, for the local/ copy, to the parent of
|
|
28
|
+
# local/ — and may contain globs.
|
|
29
|
+
|
|
30
|
+
default-target: internal
|
|
31
|
+
|
|
32
|
+
targets:
|
|
33
|
+
internal:
|
|
34
|
+
label: Internal repository
|
|
35
|
+
# Fill both in before the first release. Add more targets (staging, public, per-customer)
|
|
36
|
+
# by copying this block — the names are yours, the CLI does not know any of them.
|
|
37
|
+
npm-registry:
|
|
38
|
+
# Publishing Maven artifacts additionally requires enabling it in build.gradle.kts:
|
|
39
|
+
# quicksilverRoot { publishing { enabled = true } }
|
|
40
|
+
# Until then, leave this blank and pnpm release publishes npm packages only.
|
|
41
|
+
maven-url:
|
|
42
|
+
# quicksilver.repo is the default login for pulling the platform (quicksilver.repo.user /
|
|
43
|
+
# .password), so one account covers both. When gradle.properties names another prefix in
|
|
44
|
+
# quicksilver.repo.credentials, or publishing needs a different account, change this to match.
|
|
45
|
+
maven-credentials-prefix: quicksilver.repo
|
|
46
|
+
# Publishing straight from a dirty working tree is fine for an internal repository.
|
|
47
|
+
# Drop this line on a target that ships releases.
|
|
48
|
+
git-checks: false
|
|
49
|
+
allow-prerelease: true
|
|
50
|
+
|
|
51
|
+
packages:
|
|
52
|
+
- modules/*/web
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
display:
|
|
2
|
+
title: {{PROJECT_CODE}}
|
|
3
|
+
description: Description for your product here
|
|
4
|
+
|
|
5
|
+
names:
|
|
6
|
+
kotlin-package: {{API_PACKAGE}}
|
|
7
|
+
maven-group: {{API_PACKAGE}}
|
|
8
|
+
maven-prefix: {{PROJECT_CODE}}
|
|
9
|
+
|
|
10
|
+
packaging:
|
|
11
|
+
archive-name: {{PROJECT_CODE}}
|
|
12
|
+
fixed-modules: [{{PLATFORM_MODULE_CODES_QUOTED}}, '{{MODULE_CODE}}']
|
|
13
|
+
visible-modules:
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# `run/api/config`
|
|
2
|
+
|
|
3
|
+
Configuration for the API server in development. Everything here is read by Spring Boot at
|
|
4
|
+
startup; nothing in this directory ships to your users.
|
|
5
|
+
|
|
6
|
+
## Files
|
|
7
|
+
|
|
8
|
+
| File | What it is |
|
|
9
|
+
|---|---|
|
|
10
|
+
| `application.yaml` | Base configuration: ports, CORS, cache, upload, Atomikos. **Declares no datasources** — those live in the profile files below |
|
|
11
|
+
| `application-dev.yaml` | The `dev` profile, active by default. Datasources for local development, plus `auto-init` (with `draft-sync` on) and `fail-on-unregistered-data-source` |
|
|
12
|
+
| `application-<dialect>.yaml` | One overlay per database dialect (`h2`, `postgresql`, `mariadb`, `mssql`, `oracle`). Each carries its own datasources, log directory and Atomikos log directory, so several can run side by side |
|
|
13
|
+
| `application-test.yaml` | Used by `modules/*/api` tests. In-memory H2, wiped on every run |
|
|
14
|
+
| `logback.xml` / `logback-test.xml` | Logging |
|
|
15
|
+
|
|
16
|
+
## Choosing a database
|
|
17
|
+
|
|
18
|
+
`pnpm dev` runs on a file-based H2 database with no setup. To use another dialect, run its script
|
|
19
|
+
— `pnpm dev:postgresql`, `pnpm dev:mariadb`, and so on — which sets
|
|
20
|
+
`SPRING_PROFILES_ACTIVE=dev,<dialect>` and its own ports.
|
|
21
|
+
|
|
22
|
+
The H2 profiles ship with working credentials (`sa` / `sa`) — H2 creates the database on first
|
|
23
|
+
connect, so there is nothing to change. In every other dialect file the user and `PASSWORD` are
|
|
24
|
+
placeholders you must replace.
|
|
25
|
+
|
|
26
|
+
**Do not drop the `dev,` prefix.** Without it `application-dev.yaml` is not loaded, and since
|
|
27
|
+
`application.yaml` declares no datasources, startup fails with `Missing required datasource code`.
|
|
28
|
+
That is deliberate: a missing datasource list must fail loudly rather than fall back to some
|
|
29
|
+
default database.
|
|
30
|
+
|
|
31
|
+
Create the databases before use — the server-based dialects only. Each of those files names its
|
|
32
|
+
database after this project — a project called `power-crm` gets `power_crm_dev` — so several
|
|
33
|
+
Quicksilver products can share one database server without colliding. Two files sit outside that
|
|
34
|
+
rule: Oracle, whose "database" is a PDB with a name fixed by the container image (`FREEPDB1`), and
|
|
35
|
+
the H2 profiles, whose databases are plain files under this project's own `local/data/h2/`
|
|
36
|
+
(`database1` for `dev`, `database2` for `dev:h2`) and so have nothing to collide with. The
|
|
37
|
+
datasource list is replaced as a whole, so when you change one entry, keep the other one listed
|
|
38
|
+
as well.
|
|
39
|
+
|
|
40
|
+
## H2 URLs
|
|
41
|
+
|
|
42
|
+
The two H2 parameters below are not optional. Both failures are quiet and show up far from the
|
|
43
|
+
configuration, so keep them when you edit an H2 URL:
|
|
44
|
+
|
|
45
|
+
- File database — `DB_CLOSE_ON_EXIT=FALSE`. Without it H2 registers a JVM shutdown hook that races
|
|
46
|
+
Spring's own. On Ctrl+C H2 often closes the database first, and Atomikos' XA recovery scan then
|
|
47
|
+
hits "Database is already closed" and prints a screenful of stack traces.
|
|
48
|
+
- In-memory database — `DB_CLOSE_DELAY=-1`. The connection pool's `minSize` is 0, so when the last
|
|
49
|
+
idle connection is reclaimed H2 destroys the whole in-memory database with it, and the next
|
|
50
|
+
connection hands you an empty one.
|
|
51
|
+
|
|
52
|
+
## MySQL
|
|
53
|
+
|
|
54
|
+
MySQL works, but **you have to supply the driver**: Connector/J is GPLv2, so it is not bundled.
|
|
55
|
+
Add `runtimeOnly("com.mysql:mysql-connector-j")` to `run/api/build.gradle.kts`, then add a
|
|
56
|
+
`application-mysql.yaml` overlay and a `dev:mysql` script of your own, modelled on the other
|
|
57
|
+
dialects. Every other dialect listed above ships with its driver.
|
|
58
|
+
|
|
59
|
+
## The dev database
|
|
60
|
+
|
|
61
|
+
The `dev` profile turns on `draft-sync` and turns off `drop-first`. Every start runs the upgrade
|
|
62
|
+
drafts that changed since the last start, and keeps the data already in the dev database. To
|
|
63
|
+
rebuild the database from init and demo data, set `drop-first: true` for one start and then set it
|
|
64
|
+
back. Switching `draft-sync` on or off also needs one such rebuild: the two modes record drafts
|
|
65
|
+
differently, and startup refuses a database built in the other mode.
|
|
66
|
+
|
|
67
|
+
## Local edits
|
|
68
|
+
|
|
69
|
+
`application-dev.yaml` is committed, but **by convention your local edits to it are not** — a
|
|
70
|
+
different database host, `drop-first` turned on for a rebuild, a different
|
|
71
|
+
`fail-on-unregistered-data-source`. Commit it only when you are deliberately changing the team
|
|
72
|
+
default, and say so in the commit message.
|
|
73
|
+
|
|
74
|
+
For an override that never enters version control, point `QUICKSILVER_CONFIG_LOCATION` at a config
|
|
75
|
+
directory of your own: it is appended to the tail of `spring.config.location`, so it wins over
|
|
76
|
+
every profile file.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Overlay for the `dev` profile. Activated by default via `spring.profiles.active` in
|
|
3
|
+
# application.yaml, and by every `pnpm dev:*` script.
|
|
4
|
+
#
|
|
5
|
+
spring:
|
|
6
|
+
application.name: DEV
|
|
7
|
+
|
|
8
|
+
quicksilver:
|
|
9
|
+
datasource:
|
|
10
|
+
# Keep the quotes around passwords: special characters (# : @ ...) then paste in as is.
|
|
11
|
+
items:
|
|
12
|
+
- code: metadata
|
|
13
|
+
url: "jdbc:h2:./local/data/h2/database1;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
|
|
14
|
+
user: sa
|
|
15
|
+
password: "sa"
|
|
16
|
+
- code: business
|
|
17
|
+
url: "jdbc:h2:./local/data/h2/database1;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
|
|
18
|
+
user: sa
|
|
19
|
+
password: "sa"
|
|
20
|
+
# Each ac_table row records the datasource its table lives in. When a row names a code that is
|
|
21
|
+
# not listed under items, true stops startup with an error and false only logs a warning. Unset,
|
|
22
|
+
# it is false. Keep it true in development so that a datasource removed from this file is
|
|
23
|
+
# noticed at the next start.
|
|
24
|
+
fail-on-unregistered-data-source: true
|
|
25
|
+
auto-init:
|
|
26
|
+
# Install and upgrade the modules at every start by running their data files. Takes effect
|
|
27
|
+
# only when quicksilver.application.mode is development. In production the installer does it.
|
|
28
|
+
enabled: true
|
|
29
|
+
# Drop the tables and views that Quicksilver manages before provisioning, so the database is
|
|
30
|
+
# rebuilt from init and demo data. Set drop-first: true for one start, then set it back to false.
|
|
31
|
+
drop-first: false
|
|
32
|
+
# Draft sync. Every start runs the upgrade drafts that changed since the last start. Data in
|
|
33
|
+
# the dev database is kept, including rows entered through the UI. Switching draft-sync on or
|
|
34
|
+
# off needs one rebuild with drop-first.
|
|
35
|
+
draft-sync: true
|
|
36
|
+
# Demo data: on a fresh install of a module, the .jsons files in its data/demo/ run after its
|
|
37
|
+
# init. A database that already exists does not pick up demo files added later, rebuild it with
|
|
38
|
+
# drop-first as described above.
|
|
39
|
+
demo-data: true
|
|
40
|
+
webhook:
|
|
41
|
+
# Webhook targets that resolve to a private or loopback address (10.0.0.0/8, 127.0.0.0/8, ...)
|
|
42
|
+
# are refused unless the address falls in one of these CIDR ranges. The dev profile allows
|
|
43
|
+
# 127.0.0.1 so that a receiver running on this machine can be tested. Link-local addresses,
|
|
44
|
+
# which include the cloud metadata endpoint, are always refused whatever is listed here.
|
|
45
|
+
restricted-exceptions: ["127.0.0.1/32"]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Overlay for the `h2` profile: only the keys that differ from application-dev.yaml,
|
|
3
|
+
# everything else is inherited key by key. Activate with SPRING_PROFILES_ACTIVE=dev,h2
|
|
4
|
+
# (or run `pnpm dev:h2`).
|
|
5
|
+
#
|
|
6
|
+
logging:
|
|
7
|
+
file.path: local/log/application/h2
|
|
8
|
+
|
|
9
|
+
quicksilver:
|
|
10
|
+
datasource:
|
|
11
|
+
# Keep the quotes around passwords: special characters (# : @ ...) then paste in as is.
|
|
12
|
+
items:
|
|
13
|
+
- code: metadata
|
|
14
|
+
url: "jdbc:h2:./local/data/h2/database2;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
|
|
15
|
+
user: sa
|
|
16
|
+
password: "sa"
|
|
17
|
+
- code: business
|
|
18
|
+
url: "jdbc:h2:./local/data/h2/database2;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
|
|
19
|
+
user: sa
|
|
20
|
+
password: "sa"
|
|
21
|
+
atomikos:
|
|
22
|
+
log_base_dir: local/log/atomikos/h2
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Overlay for the `mariadb` profile: only the keys that differ from application-dev.yaml,
|
|
3
|
+
# everything else is inherited key by key. Activate with SPRING_PROFILES_ACTIVE=dev,mariadb
|
|
4
|
+
# (or run `pnpm dev:mariadb`).
|
|
5
|
+
#
|
|
6
|
+
logging:
|
|
7
|
+
file.path: local/log/application/mariadb
|
|
8
|
+
|
|
9
|
+
quicksilver:
|
|
10
|
+
datasource:
|
|
11
|
+
# Keep the quotes around passwords: special characters (# : @ ...) then paste in as is.
|
|
12
|
+
items:
|
|
13
|
+
- code: metadata
|
|
14
|
+
url: "jdbc:mariadb://localhost:3308/{{DB_PREFIX}}_dev?characterEncoding=utf8mb4"
|
|
15
|
+
user: root
|
|
16
|
+
password: "PASSWORD"
|
|
17
|
+
- code: business
|
|
18
|
+
url: "jdbc:mariadb://localhost:3308/{{DB_PREFIX}}_dev?characterEncoding=utf8mb4"
|
|
19
|
+
user: root
|
|
20
|
+
password: "PASSWORD"
|
|
21
|
+
atomikos:
|
|
22
|
+
log_base_dir: local/log/atomikos/mariadb
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Overlay for the `mssql` profile: only the keys that differ from application-dev.yaml,
|
|
3
|
+
# everything else is inherited key by key. Activate with SPRING_PROFILES_ACTIVE=dev,mssql
|
|
4
|
+
# (or run `pnpm dev:mssql`).
|
|
5
|
+
#
|
|
6
|
+
logging:
|
|
7
|
+
file.path: local/log/application/mssql
|
|
8
|
+
|
|
9
|
+
quicksilver:
|
|
10
|
+
datasource:
|
|
11
|
+
# Keep the quotes around passwords: special characters (# : @ ...) then paste in as is.
|
|
12
|
+
items:
|
|
13
|
+
- code: metadata
|
|
14
|
+
url: "jdbc:sqlserver://localhost:1433;DatabaseName={{DB_PREFIX}}_dev;trustServerCertificate=true"
|
|
15
|
+
user: sa
|
|
16
|
+
password: "PASSWORD"
|
|
17
|
+
- code: business
|
|
18
|
+
url: "jdbc:sqlserver://localhost:1433;DatabaseName={{DB_PREFIX}}_dev;trustServerCertificate=true"
|
|
19
|
+
user: sa
|
|
20
|
+
password: "PASSWORD"
|
|
21
|
+
atomikos:
|
|
22
|
+
log_base_dir: local/log/atomikos/mssql
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Overlay for the `oracle` profile: only the keys that differ from application-dev.yaml,
|
|
3
|
+
# everything else is inherited key by key. Activate with SPRING_PROFILES_ACTIVE=dev,oracle
|
|
4
|
+
# (or run `pnpm dev:oracle`).
|
|
5
|
+
#
|
|
6
|
+
logging:
|
|
7
|
+
file.path: local/log/application/oracle
|
|
8
|
+
|
|
9
|
+
quicksilver:
|
|
10
|
+
datasource:
|
|
11
|
+
# Keep the quotes around passwords: special characters (# : @ ...) then paste in as is.
|
|
12
|
+
items:
|
|
13
|
+
- code: metadata
|
|
14
|
+
url: "jdbc:oracle:thin:@//localhost:1521/FREEPDB1"
|
|
15
|
+
user: system
|
|
16
|
+
password: "PASSWORD"
|
|
17
|
+
- code: business
|
|
18
|
+
url: "jdbc:oracle:thin:@//localhost:1521/FREEPDB1"
|
|
19
|
+
user: system
|
|
20
|
+
password: "PASSWORD"
|
|
21
|
+
atomikos:
|
|
22
|
+
log_base_dir: local/log/atomikos/oracle
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Overlay for the `postgresql` profile: only the keys that differ from application-dev.yaml,
|
|
3
|
+
# everything else is inherited key by key. Activate with SPRING_PROFILES_ACTIVE=dev,postgresql
|
|
4
|
+
# (or run `pnpm dev:postgresql`).
|
|
5
|
+
#
|
|
6
|
+
logging:
|
|
7
|
+
file.path: local/log/application/postgresql
|
|
8
|
+
|
|
9
|
+
quicksilver:
|
|
10
|
+
datasource:
|
|
11
|
+
# Keep the quotes around passwords: special characters (# : @ ...) then paste in as is.
|
|
12
|
+
items:
|
|
13
|
+
- code: metadata
|
|
14
|
+
url: "jdbc:postgresql://127.0.0.1/{{DB_PREFIX}}_dev?stringtype=unspecified"
|
|
15
|
+
user: postgres
|
|
16
|
+
password: "PASSWORD"
|
|
17
|
+
- code: business
|
|
18
|
+
url: "jdbc:postgresql://127.0.0.1/{{DB_PREFIX}}_dev?stringtype=unspecified"
|
|
19
|
+
user: postgres
|
|
20
|
+
password: "PASSWORD"
|
|
21
|
+
atomikos:
|
|
22
|
+
log_base_dir: local/log/atomikos/postgresql
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#
|
|
2
|
+
# This file is for testing of modules/xxx/api. Paths use ${quicksilver.config.dir},
|
|
3
|
+
# which ModulePlugin sets to the absolute path of this config directory.
|
|
4
|
+
#
|
|
5
|
+
spring.application.name: QsTest
|
|
6
|
+
logging.config: ${quicksilver.config.dir}/logback-test.xml
|
|
7
|
+
quicksilver:
|
|
8
|
+
# Tests run with the module's api directory as the working directory, and a missing key file is
|
|
9
|
+
# auto-generated outside production mode. Without this line the key would land in the module's
|
|
10
|
+
# own config/ (the relative path inherited from application.yaml) instead of under build/.
|
|
11
|
+
security.cipher.key-file: build/test/cipher.key
|
|
12
|
+
datasource:
|
|
13
|
+
# Keep the quotes around passwords: special characters (# : @ ...) then paste in as is.
|
|
14
|
+
items:
|
|
15
|
+
- code: metadata
|
|
16
|
+
url: "jdbc:h2:mem:metadata;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL"
|
|
17
|
+
user: sa
|
|
18
|
+
password: "sa"
|
|
19
|
+
- code: business
|
|
20
|
+
url: "jdbc:h2:mem:business;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL"
|
|
21
|
+
user: sa
|
|
22
|
+
password: "sa"
|
|
23
|
+
atomikos:
|
|
24
|
+
log_base_dir: build/test/log/atomikos
|
|
25
|
+
upload.directory: build/test/upload
|
|
26
|
+
# Tests run under the test profile, which does not inherit auto-init from
|
|
27
|
+
# application-dev.yaml, so it must be declared here.
|
|
28
|
+
auto-init.enabled: true
|