Commit f9ea66fca344906d90f5e533a5fe8f98f7cf0914
1 parent
24cae0bd
feat(distribution): Spring Boot fat-jar assembly + Liquibase changelogs (platform + identity)
Showing
6 changed files
with
680 additions
and
0 deletions
distribution/build.gradle.kts
0 → 100644
| 1 | +// distribution — assembles the runnable vibe_erp fat-jar. | ||
| 2 | +// | ||
| 3 | +// This module is the only one that pulls every PBC and platform module | ||
| 4 | +// together into a bootable Spring Boot application. It is referenced by | ||
| 5 | +// the Dockerfile (stage 1) which produces the shipping image documented | ||
| 6 | +// in the architecture spec, sections 10 and 11. | ||
| 7 | + | ||
| 8 | +plugins { | ||
| 9 | + alias(libs.plugins.kotlin.jvm) | ||
| 10 | + alias(libs.plugins.kotlin.spring) | ||
| 11 | + alias(libs.plugins.spring.boot) | ||
| 12 | + alias(libs.plugins.spring.dependency.management) | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +java { | ||
| 16 | + toolchain { | ||
| 17 | + languageVersion.set(JavaLanguageVersion.of(21)) | ||
| 18 | + } | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +dependencies { | ||
| 22 | + implementation(project(":platform:platform-bootstrap")) | ||
| 23 | + implementation(project(":platform:platform-persistence")) | ||
| 24 | + implementation(project(":platform:platform-plugins")) | ||
| 25 | + implementation(project(":pbc:pbc-identity")) | ||
| 26 | + | ||
| 27 | + implementation(libs.spring.boot.starter) | ||
| 28 | + implementation(libs.spring.boot.starter.web) | ||
| 29 | + implementation(libs.spring.boot.starter.data.jpa) | ||
| 30 | + implementation(libs.spring.boot.starter.actuator) | ||
| 31 | + implementation(libs.kotlin.stdlib) | ||
| 32 | + implementation(libs.kotlin.reflect) | ||
| 33 | + implementation(libs.jackson.module.kotlin) | ||
| 34 | + runtimeOnly(libs.postgres) | ||
| 35 | + runtimeOnly(libs.liquibase.core) | ||
| 36 | + | ||
| 37 | + testImplementation(libs.spring.boot.starter.test) | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +// The fat-jar produced here is what the Dockerfile copies into the | ||
| 41 | +// runtime image as /app/vibe-erp.jar. | ||
| 42 | +tasks.bootJar { | ||
| 43 | + mainClass.set("org.vibeerp.platform.bootstrap.VibeErpApplicationKt") | ||
| 44 | + archiveFileName.set("vibe-erp.jar") | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +// `./gradlew :distribution:bootRun` — used by `make run` for local dev. | ||
| 48 | +// Activates the dev profile so application-dev.yaml on the classpath is | ||
| 49 | +// layered on top of application.yaml. | ||
| 50 | +tasks.bootRun { | ||
| 51 | + systemProperty("spring.profiles.active", "dev") | ||
| 52 | +} |
distribution/src/main/resources/application-dev.yaml
0 → 100644
| 1 | +# vibe_erp — developer overrides (active under -Dspring.profiles.active=dev). | ||
| 2 | +# | ||
| 3 | +# Activated by `./gradlew :distribution:bootRun` (see distribution/build.gradle.kts). | ||
| 4 | +# These values point at a local Postgres started via `make up` or any other | ||
| 5 | +# locally-running Postgres on port 5432. | ||
| 6 | + | ||
| 7 | +spring: | ||
| 8 | + datasource: | ||
| 9 | + url: jdbc:postgresql://localhost:5432/vibeerp | ||
| 10 | + username: vibeerp | ||
| 11 | + password: vibeerp | ||
| 12 | + | ||
| 13 | +vibeerp: | ||
| 14 | + plugins: | ||
| 15 | + directory: ./plugins-dev | ||
| 16 | + files: | ||
| 17 | + local-path: ./files-dev | ||
| 18 | + | ||
| 19 | +logging: | ||
| 20 | + level: | ||
| 21 | + org.vibeerp: DEBUG |
distribution/src/main/resources/application.yaml
0 → 100644
| 1 | +# vibe_erp — production-ish defaults. | ||
| 2 | +# | ||
| 3 | +# This is the baseline configuration baked into the shipping image. It is | ||
| 4 | +# deliberately non-secret: every sensitive value is read from an environment | ||
| 5 | +# variable so the same image works for self-hosted and (eventually) hosted | ||
| 6 | +# deployments. See architecture spec sections 10 and 11. | ||
| 7 | +# | ||
| 8 | +# Customer overrides live in /opt/vibe-erp/config/vibe-erp.yaml on the | ||
| 9 | +# mounted volume. Plug-in configuration lives in metadata__plugin_config, | ||
| 10 | +# never here. | ||
| 11 | + | ||
| 12 | +spring: | ||
| 13 | + application: | ||
| 14 | + name: vibe-erp | ||
| 15 | + datasource: | ||
| 16 | + url: ${VIBEERP_DB_URL} | ||
| 17 | + username: ${VIBEERP_DB_USER} | ||
| 18 | + password: ${VIBEERP_DB_PASSWORD} | ||
| 19 | + driver-class-name: org.postgresql.Driver | ||
| 20 | + jpa: | ||
| 21 | + # Liquibase owns the schema; Hibernate must never touch DDL. | ||
| 22 | + hibernate: | ||
| 23 | + ddl-auto: validate | ||
| 24 | + open-in-view: false | ||
| 25 | + liquibase: | ||
| 26 | + change-log: classpath:db/changelog/master.xml | ||
| 27 | + | ||
| 28 | +server: | ||
| 29 | + port: 8080 | ||
| 30 | + shutdown: graceful | ||
| 31 | + | ||
| 32 | +management: | ||
| 33 | + endpoints: | ||
| 34 | + web: | ||
| 35 | + exposure: | ||
| 36 | + include: health,info,prometheus | ||
| 37 | + | ||
| 38 | +vibeerp: | ||
| 39 | + instance: | ||
| 40 | + mode: ${VIBEERP_INSTANCE_MODE:self-hosted} | ||
| 41 | + default-tenant: ${VIBEERP_DEFAULT_TENANT:default} | ||
| 42 | + plugins: | ||
| 43 | + directory: ${VIBEERP_PLUGINS_DIR:/opt/vibe-erp/plugins} | ||
| 44 | + auto-load: true | ||
| 45 | + i18n: | ||
| 46 | + default-locale: en-US | ||
| 47 | + fallback-locale: en-US | ||
| 48 | + available-locales: en-US,zh-CN,de-DE,ja-JP,es-ES | ||
| 49 | + files: | ||
| 50 | + backend: local | ||
| 51 | + local-path: ${VIBEERP_FILES_DIR:/opt/vibe-erp/files} | ||
| 52 | + | ||
| 53 | +logging: | ||
| 54 | + level: | ||
| 55 | + org.vibeerp: INFO | ||
| 56 | + org.springframework: WARN |
distribution/src/main/resources/db/changelog/master.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!-- | ||
| 3 | + vibe_erp — Liquibase master changelog. | ||
| 4 | + | ||
| 5 | + This file composes per-PBC changelogs via <include>. Each PBC owns its own | ||
| 6 | + changelog under db/changelog/<pbc-name>/ and is responsible for its own | ||
| 7 | + table prefix (architecture spec section 8 — schema namespacing). | ||
| 8 | +--> | ||
| 9 | +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" | ||
| 10 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 11 | + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog | ||
| 12 | + https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.27.xsd"> | ||
| 13 | + <include file="classpath:db/changelog/platform/000-platform-init.xml"/> | ||
| 14 | + <include file="classpath:db/changelog/pbc-identity/001-identity-init.xml"/> | ||
| 15 | +</databaseChangeLog> |
distribution/src/main/resources/db/changelog/pbc-identity/001-identity-init.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" | ||
| 3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog | ||
| 5 | + https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.27.xsd"> | ||
| 6 | + | ||
| 7 | + <!-- | ||
| 8 | + pbc-identity initial schema. | ||
| 9 | + | ||
| 10 | + Owns: identity__user, identity__role, identity__user_role. | ||
| 11 | + | ||
| 12 | + Conventions enforced for every business table in vibe_erp: | ||
| 13 | + • UUID primary key | ||
| 14 | + • tenant_id varchar(64) NOT NULL | ||
| 15 | + • Audit columns: created_at, created_by, updated_at, updated_by | ||
| 16 | + • Optimistic-locking version column | ||
| 17 | + • ext jsonb NOT NULL DEFAULT '{}' for key-user custom fields | ||
| 18 | + • GIN index on ext for fast custom-field queries | ||
| 19 | + • Composite index on (tenant_id, ...) for tenant-scoped lookups | ||
| 20 | + • Postgres Row-Level Security enabled, with a simple per-tenant | ||
| 21 | + policy bound to the GUC `vibeerp.current_tenant` set by the | ||
| 22 | + platform on every transaction (see TODO below) | ||
| 23 | + | ||
| 24 | + TODO(v0.2): the platform's `RlsTransactionHook` is not yet | ||
| 25 | + implemented, so the RLS policy in this file uses | ||
| 26 | + `current_setting('vibeerp.current_tenant', true)` and is enabled | ||
| 27 | + but not yet enforced (NO FORCE). When the hook lands, change to | ||
| 28 | + FORCE ROW LEVEL SECURITY in a follow-up changeset. | ||
| 29 | + --> | ||
| 30 | + | ||
| 31 | + <changeSet id="identity-init-001" author="vibe_erp"> | ||
| 32 | + <comment>Create identity__user table</comment> | ||
| 33 | + <sql> | ||
| 34 | + CREATE TABLE identity__user ( | ||
| 35 | + id uuid PRIMARY KEY, | ||
| 36 | + tenant_id varchar(64) NOT NULL, | ||
| 37 | + username varchar(128) NOT NULL, | ||
| 38 | + display_name varchar(256) NOT NULL, | ||
| 39 | + email varchar(320), | ||
| 40 | + enabled boolean NOT NULL DEFAULT true, | ||
| 41 | + ext jsonb NOT NULL DEFAULT '{}'::jsonb, | ||
| 42 | + created_at timestamptz NOT NULL, | ||
| 43 | + created_by varchar(128) NOT NULL, | ||
| 44 | + updated_at timestamptz NOT NULL, | ||
| 45 | + updated_by varchar(128) NOT NULL, | ||
| 46 | + version bigint NOT NULL DEFAULT 0 | ||
| 47 | + ); | ||
| 48 | + CREATE UNIQUE INDEX identity__user_tenant_username_uk | ||
| 49 | + ON identity__user (tenant_id, username); | ||
| 50 | + CREATE INDEX identity__user_ext_gin | ||
| 51 | + ON identity__user USING GIN (ext jsonb_path_ops); | ||
| 52 | + </sql> | ||
| 53 | + <rollback> | ||
| 54 | + DROP TABLE identity__user; | ||
| 55 | + </rollback> | ||
| 56 | + </changeSet> | ||
| 57 | + | ||
| 58 | + <changeSet id="identity-init-002" author="vibe_erp"> | ||
| 59 | + <comment>Enable Row-Level Security on identity__user (advisory until RlsTransactionHook lands)</comment> | ||
| 60 | + <sql> | ||
| 61 | + ALTER TABLE identity__user ENABLE ROW LEVEL SECURITY; | ||
| 62 | + CREATE POLICY identity__user_tenant_isolation ON identity__user | ||
| 63 | + USING (tenant_id = current_setting('vibeerp.current_tenant', true)); | ||
| 64 | + </sql> | ||
| 65 | + <rollback> | ||
| 66 | + DROP POLICY IF EXISTS identity__user_tenant_isolation ON identity__user; | ||
| 67 | + ALTER TABLE identity__user DISABLE ROW LEVEL SECURITY; | ||
| 68 | + </rollback> | ||
| 69 | + </changeSet> | ||
| 70 | + | ||
| 71 | + <changeSet id="identity-init-003" author="vibe_erp"> | ||
| 72 | + <comment>Create identity__role table</comment> | ||
| 73 | + <sql> | ||
| 74 | + CREATE TABLE identity__role ( | ||
| 75 | + id uuid PRIMARY KEY, | ||
| 76 | + tenant_id varchar(64) NOT NULL, | ||
| 77 | + code varchar(64) NOT NULL, | ||
| 78 | + name varchar(256) NOT NULL, | ||
| 79 | + description text, | ||
| 80 | + ext jsonb NOT NULL DEFAULT '{}'::jsonb, | ||
| 81 | + created_at timestamptz NOT NULL, | ||
| 82 | + created_by varchar(128) NOT NULL, | ||
| 83 | + updated_at timestamptz NOT NULL, | ||
| 84 | + updated_by varchar(128) NOT NULL, | ||
| 85 | + version bigint NOT NULL DEFAULT 0 | ||
| 86 | + ); | ||
| 87 | + CREATE UNIQUE INDEX identity__role_tenant_code_uk | ||
| 88 | + ON identity__role (tenant_id, code); | ||
| 89 | + CREATE INDEX identity__role_ext_gin | ||
| 90 | + ON identity__role USING GIN (ext jsonb_path_ops); | ||
| 91 | + ALTER TABLE identity__role ENABLE ROW LEVEL SECURITY; | ||
| 92 | + CREATE POLICY identity__role_tenant_isolation ON identity__role | ||
| 93 | + USING (tenant_id = current_setting('vibeerp.current_tenant', true)); | ||
| 94 | + </sql> | ||
| 95 | + <rollback> | ||
| 96 | + DROP TABLE identity__role; | ||
| 97 | + </rollback> | ||
| 98 | + </changeSet> | ||
| 99 | + | ||
| 100 | + <changeSet id="identity-init-004" author="vibe_erp"> | ||
| 101 | + <comment>Create identity__user_role join table</comment> | ||
| 102 | + <sql> | ||
| 103 | + CREATE TABLE identity__user_role ( | ||
| 104 | + id uuid PRIMARY KEY, | ||
| 105 | + tenant_id varchar(64) NOT NULL, | ||
| 106 | + user_id uuid NOT NULL REFERENCES identity__user(id) ON DELETE CASCADE, | ||
| 107 | + role_id uuid NOT NULL REFERENCES identity__role(id) ON DELETE CASCADE, | ||
| 108 | + created_at timestamptz NOT NULL, | ||
| 109 | + created_by varchar(128) NOT NULL, | ||
| 110 | + updated_at timestamptz NOT NULL, | ||
| 111 | + updated_by varchar(128) NOT NULL, | ||
| 112 | + version bigint NOT NULL DEFAULT 0 | ||
| 113 | + ); | ||
| 114 | + CREATE UNIQUE INDEX identity__user_role_uk | ||
| 115 | + ON identity__user_role (tenant_id, user_id, role_id); | ||
| 116 | + ALTER TABLE identity__user_role ENABLE ROW LEVEL SECURITY; | ||
| 117 | + CREATE POLICY identity__user_role_tenant_isolation ON identity__user_role | ||
| 118 | + USING (tenant_id = current_setting('vibeerp.current_tenant', true)); | ||
| 119 | + </sql> | ||
| 120 | + <rollback> | ||
| 121 | + DROP TABLE identity__user_role; | ||
| 122 | + </rollback> | ||
| 123 | + </changeSet> | ||
| 124 | + | ||
| 125 | +</databaseChangeLog> |
distribution/src/main/resources/db/changelog/platform/000-platform-init.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!-- | ||
| 3 | + vibe_erp — platform init changelog. | ||
| 4 | + | ||
| 5 | + Creates the cross-cutting platform tables: a tenant table, an audit | ||
| 6 | + table, and the metadata__* registry tables described in architecture | ||
| 7 | + spec section 8 ("The metadata store"). | ||
| 8 | + | ||
| 9 | + These are intentionally minimal v0.1 stubs: id + tenant_id + source + | ||
| 10 | + timestamps + (where useful) a payload jsonb. Real columns are added by | ||
| 11 | + later changesets in the PBCs that own them. pbc-identity owns the User | ||
| 12 | + schema and ships its own changelog. | ||
| 13 | + | ||
| 14 | + NOTE: Postgres Row-Level Security policies are NOT enabled here. RLS | ||
| 15 | + policies are added in a dedicated changeset in the v1.0 cut, so that | ||
| 16 | + they can be authored alongside the application-level @TenantId filter | ||
| 17 | + (architecture spec section 8 — "Tenant isolation"). The build pattern | ||
| 18 | + for that changeset will mirror the changesets below. | ||
| 19 | +--> | ||
| 20 | +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" | ||
| 21 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 22 | + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog | ||
| 23 | + https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.27.xsd"> | ||
| 24 | + | ||
| 25 | + <!-- ─── platform__tenant ─────────────────────────────────────────── --> | ||
| 26 | + <changeSet id="platform-init-001" author="vibe_erp"> | ||
| 27 | + <createTable tableName="platform__tenant"> | ||
| 28 | + <column name="id" type="uuid"> | ||
| 29 | + <constraints primaryKey="true" nullable="false"/> | ||
| 30 | + </column> | ||
| 31 | + <column name="tenant_id" type="varchar(64)"> | ||
| 32 | + <constraints nullable="false"/> | ||
| 33 | + </column> | ||
| 34 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 35 | + <constraints nullable="false"/> | ||
| 36 | + </column> | ||
| 37 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 38 | + <constraints nullable="false"/> | ||
| 39 | + </column> | ||
| 40 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 41 | + <constraints nullable="false"/> | ||
| 42 | + </column> | ||
| 43 | + </createTable> | ||
| 44 | + <rollback> | ||
| 45 | + <dropTable tableName="platform__tenant"/> | ||
| 46 | + </rollback> | ||
| 47 | + </changeSet> | ||
| 48 | + | ||
| 49 | + <!-- ─── platform__audit ──────────────────────────────────────────── --> | ||
| 50 | + <changeSet id="platform-init-002" author="vibe_erp"> | ||
| 51 | + <createTable tableName="platform__audit"> | ||
| 52 | + <column name="id" type="uuid"> | ||
| 53 | + <constraints primaryKey="true" nullable="false"/> | ||
| 54 | + </column> | ||
| 55 | + <column name="tenant_id" type="varchar(64)"> | ||
| 56 | + <constraints nullable="false"/> | ||
| 57 | + </column> | ||
| 58 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 59 | + <constraints nullable="false"/> | ||
| 60 | + </column> | ||
| 61 | + <column name="payload" type="jsonb" defaultValueComputed="'{}'::jsonb"> | ||
| 62 | + <constraints nullable="false"/> | ||
| 63 | + </column> | ||
| 64 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 65 | + <constraints nullable="false"/> | ||
| 66 | + </column> | ||
| 67 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 68 | + <constraints nullable="false"/> | ||
| 69 | + </column> | ||
| 70 | + </createTable> | ||
| 71 | + <rollback> | ||
| 72 | + <dropTable tableName="platform__audit"/> | ||
| 73 | + </rollback> | ||
| 74 | + </changeSet> | ||
| 75 | + | ||
| 76 | + <!-- ─── metadata__entity ─────────────────────────────────────────── --> | ||
| 77 | + <changeSet id="platform-init-003" author="vibe_erp"> | ||
| 78 | + <createTable tableName="metadata__entity"> | ||
| 79 | + <column name="id" type="uuid"> | ||
| 80 | + <constraints primaryKey="true" nullable="false"/> | ||
| 81 | + </column> | ||
| 82 | + <column name="tenant_id" type="varchar(64)"> | ||
| 83 | + <constraints nullable="false"/> | ||
| 84 | + </column> | ||
| 85 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 86 | + <constraints nullable="false"/> | ||
| 87 | + </column> | ||
| 88 | + <column name="payload" type="jsonb" defaultValueComputed="'{}'::jsonb"> | ||
| 89 | + <constraints nullable="false"/> | ||
| 90 | + </column> | ||
| 91 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 92 | + <constraints nullable="false"/> | ||
| 93 | + </column> | ||
| 94 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 95 | + <constraints nullable="false"/> | ||
| 96 | + </column> | ||
| 97 | + </createTable> | ||
| 98 | + <createIndex tableName="metadata__entity" indexName="idx_metadata__entity__tenant_source"> | ||
| 99 | + <column name="tenant_id"/> | ||
| 100 | + <column name="source"/> | ||
| 101 | + </createIndex> | ||
| 102 | + <rollback> | ||
| 103 | + <dropTable tableName="metadata__entity"/> | ||
| 104 | + </rollback> | ||
| 105 | + </changeSet> | ||
| 106 | + | ||
| 107 | + <!-- ─── metadata__custom_field ───────────────────────────────────── --> | ||
| 108 | + <changeSet id="platform-init-004" author="vibe_erp"> | ||
| 109 | + <createTable tableName="metadata__custom_field"> | ||
| 110 | + <column name="id" type="uuid"> | ||
| 111 | + <constraints primaryKey="true" nullable="false"/> | ||
| 112 | + </column> | ||
| 113 | + <column name="tenant_id" type="varchar(64)"> | ||
| 114 | + <constraints nullable="false"/> | ||
| 115 | + </column> | ||
| 116 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 117 | + <constraints nullable="false"/> | ||
| 118 | + </column> | ||
| 119 | + <column name="payload" type="jsonb" defaultValueComputed="'{}'::jsonb"> | ||
| 120 | + <constraints nullable="false"/> | ||
| 121 | + </column> | ||
| 122 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 123 | + <constraints nullable="false"/> | ||
| 124 | + </column> | ||
| 125 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 126 | + <constraints nullable="false"/> | ||
| 127 | + </column> | ||
| 128 | + </createTable> | ||
| 129 | + <createIndex tableName="metadata__custom_field" indexName="idx_metadata__custom_field__tenant_source"> | ||
| 130 | + <column name="tenant_id"/> | ||
| 131 | + <column name="source"/> | ||
| 132 | + </createIndex> | ||
| 133 | + <rollback> | ||
| 134 | + <dropTable tableName="metadata__custom_field"/> | ||
| 135 | + </rollback> | ||
| 136 | + </changeSet> | ||
| 137 | + | ||
| 138 | + <!-- ─── metadata__form ───────────────────────────────────────────── --> | ||
| 139 | + <changeSet id="platform-init-005" author="vibe_erp"> | ||
| 140 | + <createTable tableName="metadata__form"> | ||
| 141 | + <column name="id" type="uuid"> | ||
| 142 | + <constraints primaryKey="true" nullable="false"/> | ||
| 143 | + </column> | ||
| 144 | + <column name="tenant_id" type="varchar(64)"> | ||
| 145 | + <constraints nullable="false"/> | ||
| 146 | + </column> | ||
| 147 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 148 | + <constraints nullable="false"/> | ||
| 149 | + </column> | ||
| 150 | + <column name="payload" type="jsonb" defaultValueComputed="'{}'::jsonb"> | ||
| 151 | + <constraints nullable="false"/> | ||
| 152 | + </column> | ||
| 153 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 154 | + <constraints nullable="false"/> | ||
| 155 | + </column> | ||
| 156 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 157 | + <constraints nullable="false"/> | ||
| 158 | + </column> | ||
| 159 | + </createTable> | ||
| 160 | + <createIndex tableName="metadata__form" indexName="idx_metadata__form__tenant_source"> | ||
| 161 | + <column name="tenant_id"/> | ||
| 162 | + <column name="source"/> | ||
| 163 | + </createIndex> | ||
| 164 | + <rollback> | ||
| 165 | + <dropTable tableName="metadata__form"/> | ||
| 166 | + </rollback> | ||
| 167 | + </changeSet> | ||
| 168 | + | ||
| 169 | + <!-- ─── metadata__workflow ───────────────────────────────────────── --> | ||
| 170 | + <changeSet id="platform-init-006" author="vibe_erp"> | ||
| 171 | + <createTable tableName="metadata__workflow"> | ||
| 172 | + <column name="id" type="uuid"> | ||
| 173 | + <constraints primaryKey="true" nullable="false"/> | ||
| 174 | + </column> | ||
| 175 | + <column name="tenant_id" type="varchar(64)"> | ||
| 176 | + <constraints nullable="false"/> | ||
| 177 | + </column> | ||
| 178 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 179 | + <constraints nullable="false"/> | ||
| 180 | + </column> | ||
| 181 | + <column name="payload" type="jsonb" defaultValueComputed="'{}'::jsonb"> | ||
| 182 | + <constraints nullable="false"/> | ||
| 183 | + </column> | ||
| 184 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 185 | + <constraints nullable="false"/> | ||
| 186 | + </column> | ||
| 187 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 188 | + <constraints nullable="false"/> | ||
| 189 | + </column> | ||
| 190 | + </createTable> | ||
| 191 | + <createIndex tableName="metadata__workflow" indexName="idx_metadata__workflow__tenant_source"> | ||
| 192 | + <column name="tenant_id"/> | ||
| 193 | + <column name="source"/> | ||
| 194 | + </createIndex> | ||
| 195 | + <rollback> | ||
| 196 | + <dropTable tableName="metadata__workflow"/> | ||
| 197 | + </rollback> | ||
| 198 | + </changeSet> | ||
| 199 | + | ||
| 200 | + <!-- ─── metadata__rule ───────────────────────────────────────────── --> | ||
| 201 | + <changeSet id="platform-init-007" author="vibe_erp"> | ||
| 202 | + <createTable tableName="metadata__rule"> | ||
| 203 | + <column name="id" type="uuid"> | ||
| 204 | + <constraints primaryKey="true" nullable="false"/> | ||
| 205 | + </column> | ||
| 206 | + <column name="tenant_id" type="varchar(64)"> | ||
| 207 | + <constraints nullable="false"/> | ||
| 208 | + </column> | ||
| 209 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 210 | + <constraints nullable="false"/> | ||
| 211 | + </column> | ||
| 212 | + <column name="payload" type="jsonb" defaultValueComputed="'{}'::jsonb"> | ||
| 213 | + <constraints nullable="false"/> | ||
| 214 | + </column> | ||
| 215 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 216 | + <constraints nullable="false"/> | ||
| 217 | + </column> | ||
| 218 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 219 | + <constraints nullable="false"/> | ||
| 220 | + </column> | ||
| 221 | + </createTable> | ||
| 222 | + <createIndex tableName="metadata__rule" indexName="idx_metadata__rule__tenant_source"> | ||
| 223 | + <column name="tenant_id"/> | ||
| 224 | + <column name="source"/> | ||
| 225 | + </createIndex> | ||
| 226 | + <rollback> | ||
| 227 | + <dropTable tableName="metadata__rule"/> | ||
| 228 | + </rollback> | ||
| 229 | + </changeSet> | ||
| 230 | + | ||
| 231 | + <!-- ─── metadata__permission ─────────────────────────────────────── --> | ||
| 232 | + <changeSet id="platform-init-008" author="vibe_erp"> | ||
| 233 | + <createTable tableName="metadata__permission"> | ||
| 234 | + <column name="id" type="uuid"> | ||
| 235 | + <constraints primaryKey="true" nullable="false"/> | ||
| 236 | + </column> | ||
| 237 | + <column name="tenant_id" type="varchar(64)"> | ||
| 238 | + <constraints nullable="false"/> | ||
| 239 | + </column> | ||
| 240 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 241 | + <constraints nullable="false"/> | ||
| 242 | + </column> | ||
| 243 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 244 | + <constraints nullable="false"/> | ||
| 245 | + </column> | ||
| 246 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 247 | + <constraints nullable="false"/> | ||
| 248 | + </column> | ||
| 249 | + </createTable> | ||
| 250 | + <createIndex tableName="metadata__permission" indexName="idx_metadata__permission__tenant_source"> | ||
| 251 | + <column name="tenant_id"/> | ||
| 252 | + <column name="source"/> | ||
| 253 | + </createIndex> | ||
| 254 | + <rollback> | ||
| 255 | + <dropTable tableName="metadata__permission"/> | ||
| 256 | + </rollback> | ||
| 257 | + </changeSet> | ||
| 258 | + | ||
| 259 | + <!-- ─── metadata__role_permission ────────────────────────────────── --> | ||
| 260 | + <changeSet id="platform-init-009" author="vibe_erp"> | ||
| 261 | + <createTable tableName="metadata__role_permission"> | ||
| 262 | + <column name="id" type="uuid"> | ||
| 263 | + <constraints primaryKey="true" nullable="false"/> | ||
| 264 | + </column> | ||
| 265 | + <column name="tenant_id" type="varchar(64)"> | ||
| 266 | + <constraints nullable="false"/> | ||
| 267 | + </column> | ||
| 268 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 269 | + <constraints nullable="false"/> | ||
| 270 | + </column> | ||
| 271 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 272 | + <constraints nullable="false"/> | ||
| 273 | + </column> | ||
| 274 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 275 | + <constraints nullable="false"/> | ||
| 276 | + </column> | ||
| 277 | + </createTable> | ||
| 278 | + <createIndex tableName="metadata__role_permission" indexName="idx_metadata__role_permission__tenant_source"> | ||
| 279 | + <column name="tenant_id"/> | ||
| 280 | + <column name="source"/> | ||
| 281 | + </createIndex> | ||
| 282 | + <rollback> | ||
| 283 | + <dropTable tableName="metadata__role_permission"/> | ||
| 284 | + </rollback> | ||
| 285 | + </changeSet> | ||
| 286 | + | ||
| 287 | + <!-- ─── metadata__menu ───────────────────────────────────────────── --> | ||
| 288 | + <changeSet id="platform-init-010" author="vibe_erp"> | ||
| 289 | + <createTable tableName="metadata__menu"> | ||
| 290 | + <column name="id" type="uuid"> | ||
| 291 | + <constraints primaryKey="true" nullable="false"/> | ||
| 292 | + </column> | ||
| 293 | + <column name="tenant_id" type="varchar(64)"> | ||
| 294 | + <constraints nullable="false"/> | ||
| 295 | + </column> | ||
| 296 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 297 | + <constraints nullable="false"/> | ||
| 298 | + </column> | ||
| 299 | + <column name="payload" type="jsonb" defaultValueComputed="'{}'::jsonb"> | ||
| 300 | + <constraints nullable="false"/> | ||
| 301 | + </column> | ||
| 302 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 303 | + <constraints nullable="false"/> | ||
| 304 | + </column> | ||
| 305 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 306 | + <constraints nullable="false"/> | ||
| 307 | + </column> | ||
| 308 | + </createTable> | ||
| 309 | + <createIndex tableName="metadata__menu" indexName="idx_metadata__menu__tenant_source"> | ||
| 310 | + <column name="tenant_id"/> | ||
| 311 | + <column name="source"/> | ||
| 312 | + </createIndex> | ||
| 313 | + <rollback> | ||
| 314 | + <dropTable tableName="metadata__menu"/> | ||
| 315 | + </rollback> | ||
| 316 | + </changeSet> | ||
| 317 | + | ||
| 318 | + <!-- ─── metadata__report ─────────────────────────────────────────── --> | ||
| 319 | + <changeSet id="platform-init-011" author="vibe_erp"> | ||
| 320 | + <createTable tableName="metadata__report"> | ||
| 321 | + <column name="id" type="uuid"> | ||
| 322 | + <constraints primaryKey="true" nullable="false"/> | ||
| 323 | + </column> | ||
| 324 | + <column name="tenant_id" type="varchar(64)"> | ||
| 325 | + <constraints nullable="false"/> | ||
| 326 | + </column> | ||
| 327 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 328 | + <constraints nullable="false"/> | ||
| 329 | + </column> | ||
| 330 | + <column name="payload" type="jsonb" defaultValueComputed="'{}'::jsonb"> | ||
| 331 | + <constraints nullable="false"/> | ||
| 332 | + </column> | ||
| 333 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 334 | + <constraints nullable="false"/> | ||
| 335 | + </column> | ||
| 336 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 337 | + <constraints nullable="false"/> | ||
| 338 | + </column> | ||
| 339 | + </createTable> | ||
| 340 | + <createIndex tableName="metadata__report" indexName="idx_metadata__report__tenant_source"> | ||
| 341 | + <column name="tenant_id"/> | ||
| 342 | + <column name="source"/> | ||
| 343 | + </createIndex> | ||
| 344 | + <rollback> | ||
| 345 | + <dropTable tableName="metadata__report"/> | ||
| 346 | + </rollback> | ||
| 347 | + </changeSet> | ||
| 348 | + | ||
| 349 | + <!-- ─── metadata__translation ────────────────────────────────────── --> | ||
| 350 | + <changeSet id="platform-init-012" author="vibe_erp"> | ||
| 351 | + <createTable tableName="metadata__translation"> | ||
| 352 | + <column name="id" type="uuid"> | ||
| 353 | + <constraints primaryKey="true" nullable="false"/> | ||
| 354 | + </column> | ||
| 355 | + <column name="tenant_id" type="varchar(64)"> | ||
| 356 | + <constraints nullable="false"/> | ||
| 357 | + </column> | ||
| 358 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 359 | + <constraints nullable="false"/> | ||
| 360 | + </column> | ||
| 361 | + <column name="payload" type="jsonb" defaultValueComputed="'{}'::jsonb"> | ||
| 362 | + <constraints nullable="false"/> | ||
| 363 | + </column> | ||
| 364 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 365 | + <constraints nullable="false"/> | ||
| 366 | + </column> | ||
| 367 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 368 | + <constraints nullable="false"/> | ||
| 369 | + </column> | ||
| 370 | + </createTable> | ||
| 371 | + <createIndex tableName="metadata__translation" indexName="idx_metadata__translation__tenant_source"> | ||
| 372 | + <column name="tenant_id"/> | ||
| 373 | + <column name="source"/> | ||
| 374 | + </createIndex> | ||
| 375 | + <rollback> | ||
| 376 | + <dropTable tableName="metadata__translation"/> | ||
| 377 | + </rollback> | ||
| 378 | + </changeSet> | ||
| 379 | + | ||
| 380 | + <!-- ─── metadata__plugin_config ──────────────────────────────────── --> | ||
| 381 | + <changeSet id="platform-init-013" author="vibe_erp"> | ||
| 382 | + <createTable tableName="metadata__plugin_config"> | ||
| 383 | + <column name="id" type="uuid"> | ||
| 384 | + <constraints primaryKey="true" nullable="false"/> | ||
| 385 | + </column> | ||
| 386 | + <column name="tenant_id" type="varchar(64)"> | ||
| 387 | + <constraints nullable="false"/> | ||
| 388 | + </column> | ||
| 389 | + <column name="source" type="varchar(32)" defaultValue="core"> | ||
| 390 | + <constraints nullable="false"/> | ||
| 391 | + </column> | ||
| 392 | + <column name="payload" type="jsonb" defaultValueComputed="'{}'::jsonb"> | ||
| 393 | + <constraints nullable="false"/> | ||
| 394 | + </column> | ||
| 395 | + <column name="created_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 396 | + <constraints nullable="false"/> | ||
| 397 | + </column> | ||
| 398 | + <column name="updated_at" type="timestamptz" defaultValueComputed="now()"> | ||
| 399 | + <constraints nullable="false"/> | ||
| 400 | + </column> | ||
| 401 | + </createTable> | ||
| 402 | + <createIndex tableName="metadata__plugin_config" indexName="idx_metadata__plugin_config__tenant_source"> | ||
| 403 | + <column name="tenant_id"/> | ||
| 404 | + <column name="source"/> | ||
| 405 | + </createIndex> | ||
| 406 | + <rollback> | ||
| 407 | + <dropTable tableName="metadata__plugin_config"/> | ||
| 408 | + </rollback> | ||
| 409 | + </changeSet> | ||
| 410 | + | ||
| 411 | +</databaseChangeLog> |