sovrium 0.0.2
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 +3497 -0
- package/LICENSE.md +147 -0
- package/LICENSE_EE.md +297 -0
- package/README.md +321 -0
- package/drizzle/0000_melted_kabuki.sql +163 -0
- package/drizzle/meta/0000_snapshot.json +1216 -0
- package/drizzle/meta/_journal.json +13 -0
- package/package.json +167 -0
- package/schemas/0.0.1/app.openapi.json +70 -0
- package/schemas/0.0.1/app.schema.json +7961 -0
- package/schemas/0.0.2/app.openapi.json +80 -0
- package/schemas/0.0.2/app.schema.json +8829 -0
- package/schemas/development/app.openapi.json +70 -0
- package/schemas/development/app.schema.json +7456 -0
- package/src/application/errors/app-validation-error.ts +14 -0
- package/src/application/errors/static-generation-error.ts +16 -0
- package/src/application/metadata/favicon-transformer.ts +127 -0
- package/src/application/models/server.ts +27 -0
- package/src/application/ports/models/user-metadata.ts +36 -0
- package/src/application/ports/models/user-session.ts +34 -0
- package/src/application/ports/repositories/activity-log-repository.ts +68 -0
- package/src/application/ports/repositories/activity-repository.ts +49 -0
- package/src/application/ports/repositories/analytics-repository.ts +164 -0
- package/src/application/ports/repositories/auth-repository.ts +33 -0
- package/src/application/ports/repositories/batch-repository.ts +86 -0
- package/src/application/ports/repositories/comment-repository.ts +150 -0
- package/src/application/ports/repositories/index.ts +41 -0
- package/src/application/ports/repositories/table-repository.ts +139 -0
- package/src/application/ports/services/css-compiler.ts +55 -0
- package/src/application/ports/services/index.ts +16 -0
- package/src/application/ports/services/page-renderer.ts +79 -0
- package/src/application/ports/services/server-factory.ts +80 -0
- package/src/application/ports/services/static-site-generator.ts +82 -0
- package/src/application/use-cases/activity/programs.ts +66 -0
- package/src/application/use-cases/analytics/collect-page-view.ts +114 -0
- package/src/application/use-cases/analytics/purge-old-data.ts +40 -0
- package/src/application/use-cases/analytics/query-campaigns.ts +43 -0
- package/src/application/use-cases/analytics/query-devices.ts +36 -0
- package/src/application/use-cases/analytics/query-overview.ts +50 -0
- package/src/application/use-cases/analytics/query-pages.ts +40 -0
- package/src/application/use-cases/analytics/query-referrers.ts +43 -0
- package/src/application/use-cases/analytics/ua-parser.ts +89 -0
- package/src/application/use-cases/analytics/visitor-hash.ts +77 -0
- package/src/application/use-cases/auth/bootstrap-admin.ts +270 -0
- package/src/application/use-cases/list-activity-logs.ts +123 -0
- package/src/application/use-cases/server/generate-static-helpers.ts +374 -0
- package/src/application/use-cases/server/generate-static.ts +287 -0
- package/src/application/use-cases/server/start-server.ts +118 -0
- package/src/application/use-cases/server/startup-error-handler.ts +69 -0
- package/src/application/use-cases/server/static-content-generators.ts +182 -0
- package/src/application/use-cases/server/static-language-generators.ts +181 -0
- package/src/application/use-cases/server/static-url-rewriter.ts +237 -0
- package/src/application/use-cases/server/translation-replacer.ts +164 -0
- package/src/application/use-cases/tables/activity-programs.ts +93 -0
- package/src/application/use-cases/tables/batch-operations.ts +156 -0
- package/src/application/use-cases/tables/comment-programs.ts +436 -0
- package/src/application/use-cases/tables/permissions/permissions.ts +25 -0
- package/src/application/use-cases/tables/programs.ts +435 -0
- package/src/application/use-cases/tables/table-operations.ts +412 -0
- package/src/application/use-cases/tables/user-role.ts +52 -0
- package/src/application/use-cases/tables/utils/display-formatter.ts +471 -0
- package/src/application/use-cases/tables/utils/field-read-filter.ts +189 -0
- package/src/application/use-cases/tables/utils/list-helpers.ts +122 -0
- package/src/application/use-cases/tables/utils/record-transformer.ts +319 -0
- package/src/cli.ts +370 -0
- package/src/domain/errors/create-tagged-error.ts +36 -0
- package/src/domain/errors/index.ts +78 -0
- package/src/domain/models/api/analytics.ts +179 -0
- package/src/domain/models/api/auth.ts +231 -0
- package/src/domain/models/api/common.ts +60 -0
- package/src/domain/models/api/error.ts +89 -0
- package/src/domain/models/api/health.ts +38 -0
- package/src/domain/models/api/index.ts +42 -0
- package/src/domain/models/api/request.ts +132 -0
- package/src/domain/models/api/tables.ts +444 -0
- package/src/domain/models/app/analytics/index.ts +129 -0
- package/src/domain/models/app/auth/config.ts +116 -0
- package/src/domain/models/app/auth/index.ts +230 -0
- package/src/domain/models/app/auth/methods/email-and-password.ts +67 -0
- package/src/domain/models/app/auth/methods/index.ts +11 -0
- package/src/domain/models/app/auth/methods/magic-link.ts +54 -0
- package/src/domain/models/app/auth/oauth/index.ts +8 -0
- package/src/domain/models/app/auth/oauth/providers.ts +105 -0
- package/src/domain/models/app/auth/plugins/admin.ts +130 -0
- package/src/domain/models/app/auth/plugins/index.ts +74 -0
- package/src/domain/models/app/auth/plugins/two-factor.ts +63 -0
- package/src/domain/models/app/auth/roles.ts +179 -0
- package/src/domain/models/app/auth/strategies.ts +191 -0
- package/src/domain/models/app/auth/validation.ts +127 -0
- package/src/domain/models/app/common/branded-ids.ts +200 -0
- package/src/domain/models/app/common/definitions.ts +187 -0
- package/src/domain/models/app/component/common/component-children.ts +119 -0
- package/src/domain/models/app/component/common/component-props.ts +89 -0
- package/src/domain/models/app/component/common/component-reference.ts +170 -0
- package/src/domain/models/app/component/component.ts +81 -0
- package/src/domain/models/app/components.ts +65 -0
- package/src/domain/models/app/description.ts +83 -0
- package/src/domain/models/app/index.ts +258 -0
- package/src/domain/models/app/language/language-config.ts +200 -0
- package/src/domain/models/app/languages.ts +205 -0
- package/src/domain/models/app/name.ts +66 -0
- package/src/domain/models/app/page/common/interactions/click-interaction.ts +116 -0
- package/src/domain/models/app/page/common/interactions/entrance-animation.ts +84 -0
- package/src/domain/models/app/page/common/interactions/hover-interaction.ts +144 -0
- package/src/domain/models/app/page/common/interactions/interactions.ts +64 -0
- package/src/domain/models/app/page/common/interactions/scroll-interaction.ts +93 -0
- package/src/domain/models/app/page/common/responsive.ts +114 -0
- package/src/domain/models/app/page/common/url.ts +35 -0
- package/src/domain/models/app/page/common/variable-reference.ts +53 -0
- package/src/domain/models/app/page/id.ts +44 -0
- package/src/domain/models/app/page/index.ts +270 -0
- package/src/domain/models/app/page/meta/analytics.ts +248 -0
- package/src/domain/models/app/page/meta/custom-elements.ts +180 -0
- package/src/domain/models/app/page/meta/dns-prefetch.ts +77 -0
- package/src/domain/models/app/page/meta/favicon-set.ts +203 -0
- package/src/domain/models/app/page/meta/favicon.ts +50 -0
- package/src/domain/models/app/page/meta/favicons-config.ts +73 -0
- package/src/domain/models/app/page/meta/index.ts +278 -0
- package/src/domain/models/app/page/meta/open-graph.ts +166 -0
- package/src/domain/models/app/page/meta/preload.ts +190 -0
- package/src/domain/models/app/page/meta/structured-data/article.ts +211 -0
- package/src/domain/models/app/page/meta/structured-data/breadcrumb.ts +115 -0
- package/src/domain/models/app/page/meta/structured-data/common-fields.ts +201 -0
- package/src/domain/models/app/page/meta/structured-data/education-event.ts +256 -0
- package/src/domain/models/app/page/meta/structured-data/faq-page.ts +127 -0
- package/src/domain/models/app/page/meta/structured-data/index.ts +95 -0
- package/src/domain/models/app/page/meta/structured-data/local-business.ts +247 -0
- package/src/domain/models/app/page/meta/structured-data/organization.ts +171 -0
- package/src/domain/models/app/page/meta/structured-data/person.ts +138 -0
- package/src/domain/models/app/page/meta/structured-data/postal-address.ts +106 -0
- package/src/domain/models/app/page/meta/structured-data/product.ts +214 -0
- package/src/domain/models/app/page/meta/twitter-card.ts +217 -0
- package/src/domain/models/app/page/name.ts +38 -0
- package/src/domain/models/app/page/path.ts +21 -0
- package/src/domain/models/app/page/scripts/external-scripts.ts +163 -0
- package/src/domain/models/app/page/scripts/features.ts +135 -0
- package/src/domain/models/app/page/scripts/inline-scripts.ts +114 -0
- package/src/domain/models/app/page/scripts/scripts.ts +102 -0
- package/src/domain/models/app/page/sections.ts +298 -0
- package/src/domain/models/app/pages.ts +61 -0
- package/src/domain/models/app/permissions/index.ts +61 -0
- package/src/domain/models/app/permissions/resource-action.ts +114 -0
- package/src/domain/models/app/permissions/roles.ts +120 -0
- package/src/domain/models/app/table/check-constraints.ts +105 -0
- package/src/domain/models/app/table/cycle-detection.ts +124 -0
- package/src/domain/models/app/table/database-identifier.ts +153 -0
- package/src/domain/models/app/table/field-name.ts +36 -0
- package/src/domain/models/app/table/field-types/advanced/array-field.ts +33 -0
- package/src/domain/models/app/table/field-types/advanced/autonumber-field.ts +54 -0
- package/src/domain/models/app/table/field-types/advanced/button-field.ts +56 -0
- package/src/domain/models/app/table/field-types/advanced/color-field.ts +57 -0
- package/src/domain/models/app/table/field-types/advanced/count-field.ts +54 -0
- package/src/domain/models/app/table/field-types/advanced/formula-field.ts +58 -0
- package/src/domain/models/app/table/field-types/advanced/geolocation-field.ts +49 -0
- package/src/domain/models/app/table/field-types/advanced/index.ts +16 -0
- package/src/domain/models/app/table/field-types/advanced/json-field.ts +25 -0
- package/src/domain/models/app/table/field-types/advanced/unknown-field.ts +85 -0
- package/src/domain/models/app/table/field-types/base-field.ts +42 -0
- package/src/domain/models/app/table/field-types/date-time/created-at-field.ts +49 -0
- package/src/domain/models/app/table/field-types/date-time/date-field.ts +95 -0
- package/src/domain/models/app/table/field-types/date-time/deleted-at-field.ts +56 -0
- package/src/domain/models/app/table/field-types/date-time/duration-field.ts +73 -0
- package/src/domain/models/app/table/field-types/date-time/index.ts +12 -0
- package/src/domain/models/app/table/field-types/date-time/updated-at-field.ts +50 -0
- package/src/domain/models/app/table/field-types/index.ts +19 -0
- package/src/domain/models/app/table/field-types/media/barcode-field.ts +58 -0
- package/src/domain/models/app/table/field-types/media/index.ts +10 -0
- package/src/domain/models/app/table/field-types/media/multiple-attachments-field.ts +80 -0
- package/src/domain/models/app/table/field-types/media/single-attachment-field.ts +81 -0
- package/src/domain/models/app/table/field-types/numeric/currency-field.ts +144 -0
- package/src/domain/models/app/table/field-types/numeric/decimal-field.ts +113 -0
- package/src/domain/models/app/table/field-types/numeric/index.ts +13 -0
- package/src/domain/models/app/table/field-types/numeric/integer-field.ts +98 -0
- package/src/domain/models/app/table/field-types/numeric/percentage-field.ts +115 -0
- package/src/domain/models/app/table/field-types/numeric/progress-field.ts +71 -0
- package/src/domain/models/app/table/field-types/numeric/rating-field.ts +74 -0
- package/src/domain/models/app/table/field-types/relational/index.ts +10 -0
- package/src/domain/models/app/table/field-types/relational/lookup-field.ts +46 -0
- package/src/domain/models/app/table/field-types/relational/relationship-field.ts +112 -0
- package/src/domain/models/app/table/field-types/relational/rollup-field.ts +58 -0
- package/src/domain/models/app/table/field-types/selection/checkbox-field.ts +51 -0
- package/src/domain/models/app/table/field-types/selection/index.ts +11 -0
- package/src/domain/models/app/table/field-types/selection/multi-select-field.ts +68 -0
- package/src/domain/models/app/table/field-types/selection/single-select-field.ts +54 -0
- package/src/domain/models/app/table/field-types/selection/status-field.ts +37 -0
- package/src/domain/models/app/table/field-types/text/email-field.ts +80 -0
- package/src/domain/models/app/table/field-types/text/index.ts +13 -0
- package/src/domain/models/app/table/field-types/text/long-text-field.ts +77 -0
- package/src/domain/models/app/table/field-types/text/phone-number-field.ts +82 -0
- package/src/domain/models/app/table/field-types/text/rich-text-field.ts +66 -0
- package/src/domain/models/app/table/field-types/text/single-line-text-field.ts +79 -0
- package/src/domain/models/app/table/field-types/text/url-field.ts +81 -0
- package/src/domain/models/app/table/field-types/user/created-by-field.ts +50 -0
- package/src/domain/models/app/table/field-types/user/deleted-by-field.ts +57 -0
- package/src/domain/models/app/table/field-types/user/index.ts +11 -0
- package/src/domain/models/app/table/field-types/user/updated-by-field.ts +51 -0
- package/src/domain/models/app/table/field-types/user/user-field.ts +52 -0
- package/src/domain/models/app/table/field-types/validation-utils.ts +166 -0
- package/src/domain/models/app/table/fields.ts +216 -0
- package/src/domain/models/app/table/foreign-keys.ts +111 -0
- package/src/domain/models/app/table/formula-keywords.ts +326 -0
- package/src/domain/models/app/table/id.ts +31 -0
- package/src/domain/models/app/table/index.ts +290 -0
- package/src/domain/models/app/table/indexes.ts +80 -0
- package/src/domain/models/app/table/name.ts +37 -0
- package/src/domain/models/app/table/permissions/field-permission.ts +83 -0
- package/src/domain/models/app/table/permissions/index.ts +167 -0
- package/src/domain/models/app/table/permissions/permission-evaluator.ts +372 -0
- package/src/domain/models/app/table/permissions/permission.ts +49 -0
- package/src/domain/models/app/table/primary-key.ts +62 -0
- package/src/domain/models/app/table/table-formula-validation.ts +168 -0
- package/src/domain/models/app/table/table-indexes-validation.ts +38 -0
- package/src/domain/models/app/table/table-permissions-validation.ts +77 -0
- package/src/domain/models/app/table/table-primary-key-validation.ts +49 -0
- package/src/domain/models/app/table/table-views-validation.ts +408 -0
- package/src/domain/models/app/table/unique-constraints.ts +79 -0
- package/src/domain/models/app/table/views/fields.ts +28 -0
- package/src/domain/models/app/table/views/filters.ts +162 -0
- package/src/domain/models/app/table/views/group-by.ts +32 -0
- package/src/domain/models/app/table/views/id.ts +50 -0
- package/src/domain/models/app/table/views/index.ts +177 -0
- package/src/domain/models/app/table/views/name.ts +32 -0
- package/src/domain/models/app/table/views/permissions.ts +98 -0
- package/src/domain/models/app/table/views/sorts.ts +31 -0
- package/src/domain/models/app/tables.ts +695 -0
- package/src/domain/models/app/theme/animations.ts +208 -0
- package/src/domain/models/app/theme/border-radius.ts +58 -0
- package/src/domain/models/app/theme/breakpoints.ts +62 -0
- package/src/domain/models/app/theme/colors.ts +110 -0
- package/src/domain/models/app/theme/fonts.ts +164 -0
- package/src/domain/models/app/theme/shadows.ts +61 -0
- package/src/domain/models/app/theme/spacing.ts +115 -0
- package/src/domain/models/app/theme.ts +66 -0
- package/src/domain/models/app/version.ts +87 -0
- package/src/domain/models/record-comment.ts +91 -0
- package/src/domain/utils/content-parsing.ts +49 -0
- package/src/domain/utils/format-detection.ts +69 -0
- package/src/domain/utils/index.ts +9 -0
- package/src/domain/utils/route-matcher.ts +184 -0
- package/src/domain/utils/translation-resolver.ts +170 -0
- package/src/index.ts +208 -0
- package/src/infrastructure/analytics/tracking-script.ts +48 -0
- package/src/infrastructure/auth/better-auth/auth.ts +216 -0
- package/src/infrastructure/auth/better-auth/email-handlers.ts +162 -0
- package/src/infrastructure/auth/better-auth/index.ts +16 -0
- package/src/infrastructure/auth/better-auth/layer.ts +97 -0
- package/src/infrastructure/auth/better-auth/plugins/admin.ts +56 -0
- package/src/infrastructure/auth/better-auth/plugins/magic-link.ts +31 -0
- package/src/infrastructure/auth/better-auth/plugins/two-factor.ts +19 -0
- package/src/infrastructure/auth/better-auth/schema.ts +152 -0
- package/src/infrastructure/auth/index.ts +27 -0
- package/src/infrastructure/css/cache/css-cache-service.ts +130 -0
- package/src/infrastructure/css/compiler.ts +210 -0
- package/src/infrastructure/css/css-compiler-live.ts +20 -0
- package/src/infrastructure/css/index.ts +25 -0
- package/src/infrastructure/css/styles/animation-styles-generator.ts +177 -0
- package/src/infrastructure/css/styles/click-animations.ts +147 -0
- package/src/infrastructure/css/styles/component-layer-generators.ts +147 -0
- package/src/infrastructure/css/theme/theme-generators.ts +130 -0
- package/src/infrastructure/css/theme/theme-layer-generators.ts +219 -0
- package/src/infrastructure/css/theme/theme-token-resolver.ts +76 -0
- package/src/infrastructure/database/activity-queries.ts +111 -0
- package/src/infrastructure/database/auth/auth-validation.ts +101 -0
- package/src/infrastructure/database/drizzle/db-bun.ts +17 -0
- package/src/infrastructure/database/drizzle/db.ts +17 -0
- package/src/infrastructure/database/drizzle/index.ts +16 -0
- package/src/infrastructure/database/drizzle/layer.ts +34 -0
- package/src/infrastructure/database/drizzle/migrate.ts +77 -0
- package/src/infrastructure/database/drizzle/schema/activity-log.ts +111 -0
- package/src/infrastructure/database/drizzle/schema/analytics-page-views.ts +116 -0
- package/src/infrastructure/database/drizzle/schema/migration-audit.ts +68 -0
- package/src/infrastructure/database/drizzle/schema/record-comments.ts +79 -0
- package/src/infrastructure/database/drizzle/schema.ts +12 -0
- package/src/infrastructure/database/field-utils.ts +87 -0
- package/src/infrastructure/database/filter-operators.ts +136 -0
- package/src/infrastructure/database/formula/formula-trigger-generators.ts +114 -0
- package/src/infrastructure/database/formula/formula-utils.ts +440 -0
- package/src/infrastructure/database/generators/index-generators.ts +152 -0
- package/src/infrastructure/database/generators/trigger-generators.ts +154 -0
- package/src/infrastructure/database/index.ts +35 -0
- package/src/infrastructure/database/lookup/lookup-expression-generators.ts +356 -0
- package/src/infrastructure/database/lookup/lookup-expressions.ts +116 -0
- package/src/infrastructure/database/lookup/lookup-view-generators.ts +403 -0
- package/src/infrastructure/database/lookup/lookup-view-helpers.ts +65 -0
- package/src/infrastructure/database/lookup/lookup-view-triggers.ts +121 -0
- package/src/infrastructure/database/migration-audit-trail.ts +375 -0
- package/src/infrastructure/database/repositories/activity-log-repository-live.ts +99 -0
- package/src/infrastructure/database/repositories/activity-repository-live.ts +21 -0
- package/src/infrastructure/database/repositories/analytics-repository-live.ts +316 -0
- package/src/infrastructure/database/repositories/auth-repository-live.ts +42 -0
- package/src/infrastructure/database/repositories/batch-repository-live.ts +29 -0
- package/src/infrastructure/database/repositories/comment-repository-live.ts +39 -0
- package/src/infrastructure/database/repositories/table-repository-live.ts +38 -0
- package/src/infrastructure/database/schema/schema-dependency-sorting.ts +142 -0
- package/src/infrastructure/database/schema/schema-initializer.ts +598 -0
- package/src/infrastructure/database/schema-migration/column-detection.ts +286 -0
- package/src/infrastructure/database/schema-migration/constants.ts +31 -0
- package/src/infrastructure/database/schema-migration/constraint-sync.ts +288 -0
- package/src/infrastructure/database/schema-migration/index-sync.ts +108 -0
- package/src/infrastructure/database/schema-migration/index.ts +66 -0
- package/src/infrastructure/database/schema-migration/migration-statements.ts +106 -0
- package/src/infrastructure/database/schema-migration/rename-detection.ts +87 -0
- package/src/infrastructure/database/schema-migration/table-operations.ts +65 -0
- package/src/infrastructure/database/schema-migration/type-utils.ts +98 -0
- package/src/infrastructure/database/schema-migration/types.ts +14 -0
- package/src/infrastructure/database/schema-migration-helpers.ts +53 -0
- package/src/infrastructure/database/session-context.ts +20 -0
- package/src/infrastructure/database/sql/sql-check-constraints.ts +252 -0
- package/src/infrastructure/database/sql/sql-column-generators.ts +174 -0
- package/src/infrastructure/database/sql/sql-execution.ts +245 -0
- package/src/infrastructure/database/sql/sql-field-predicates.ts +81 -0
- package/src/infrastructure/database/sql/sql-generators.ts +91 -0
- package/src/infrastructure/database/sql/sql-junction-tables.ts +79 -0
- package/src/infrastructure/database/sql/sql-key-constraints.ts +210 -0
- package/src/infrastructure/database/sql/sql-type-mappings.ts +106 -0
- package/src/infrastructure/database/sql/sql-utils.ts +53 -0
- package/src/infrastructure/database/table-live-layers.ts +30 -0
- package/src/infrastructure/database/table-operations/column-generators.ts +82 -0
- package/src/infrastructure/database/table-operations/create-table-sql.ts +81 -0
- package/src/infrastructure/database/table-operations/index.ts +55 -0
- package/src/infrastructure/database/table-operations/migration-utils.ts +157 -0
- package/src/infrastructure/database/table-operations/table-effects.ts +234 -0
- package/src/infrastructure/database/table-operations/table-features.ts +96 -0
- package/src/infrastructure/database/table-operations/type-compatibility.ts +58 -0
- package/src/infrastructure/database/table-operations.ts +47 -0
- package/src/infrastructure/database/table-queries/batch/batch-create.ts +80 -0
- package/src/infrastructure/database/table-queries/batch/batch-delete.ts +212 -0
- package/src/infrastructure/database/table-queries/batch/batch-helpers.ts +124 -0
- package/src/infrastructure/database/table-queries/batch/batch-restore.ts +161 -0
- package/src/infrastructure/database/table-queries/batch/batch-update.ts +146 -0
- package/src/infrastructure/database/table-queries/batch/batch-upsert.ts +357 -0
- package/src/infrastructure/database/table-queries/batch/batch.ts +14 -0
- package/src/infrastructure/database/table-queries/crud/crud-read.ts +351 -0
- package/src/infrastructure/database/table-queries/crud/crud-write.ts +399 -0
- package/src/infrastructure/database/table-queries/crud/crud.ts +16 -0
- package/src/infrastructure/database/table-queries/index.ts +11 -0
- package/src/infrastructure/database/table-queries/mutation-helpers/authorship-helpers.ts +152 -0
- package/src/infrastructure/database/table-queries/mutation-helpers/create-record-helpers.ts +90 -0
- package/src/infrastructure/database/table-queries/mutation-helpers/delete-helpers.ts +163 -0
- package/src/infrastructure/database/table-queries/mutation-helpers/record-fetch-helpers.ts +79 -0
- package/src/infrastructure/database/table-queries/mutation-helpers/update-helpers.ts +74 -0
- package/src/infrastructure/database/table-queries/query-helpers/activity-log-helpers.ts +53 -0
- package/src/infrastructure/database/table-queries/query-helpers/activity-queries.ts +106 -0
- package/src/infrastructure/database/table-queries/query-helpers/aggregation-helpers.ts +314 -0
- package/src/infrastructure/database/table-queries/query-helpers/comment-queries.ts +414 -0
- package/src/infrastructure/database/table-queries/query-helpers/record-validation-queries.ts +126 -0
- package/src/infrastructure/database/table-queries/query-helpers/trash-helpers.ts +58 -0
- package/src/infrastructure/database/table-queries/shared/error-handling.ts +47 -0
- package/src/infrastructure/database/table-queries/shared/typed-execute.ts +27 -0
- package/src/infrastructure/database/table-queries/shared/user-join-helpers.ts +38 -0
- package/src/infrastructure/database/table-queries/shared/validation.ts +39 -0
- package/src/infrastructure/database/views/view-generators.ts +258 -0
- package/src/infrastructure/devtools/devtools-layer.ts +43 -0
- package/src/infrastructure/devtools/index.ts +8 -0
- package/src/infrastructure/email/email-config.ts +103 -0
- package/src/infrastructure/email/email-service.ts +152 -0
- package/src/infrastructure/email/index.ts +107 -0
- package/src/infrastructure/email/nodemailer.ts +125 -0
- package/src/infrastructure/email/templates.ts +244 -0
- package/src/infrastructure/errors/auth-config-required-error.ts +21 -0
- package/src/infrastructure/errors/auth-error.ts +16 -0
- package/src/infrastructure/errors/css-compilation-error.ts +14 -0
- package/src/infrastructure/errors/index.ts +26 -0
- package/src/infrastructure/errors/schema-initialization-error.ts +19 -0
- package/src/infrastructure/errors/server-creation-error.ts +14 -0
- package/src/infrastructure/filesystem/copy-directory.ts +136 -0
- package/src/infrastructure/layers/app-layer.ts +61 -0
- package/src/infrastructure/layers/page-renderer-layer.ts +41 -0
- package/src/infrastructure/logging/index.ts +8 -0
- package/src/infrastructure/logging/logger.ts +204 -0
- package/src/infrastructure/schema/file-loader.ts +53 -0
- package/src/infrastructure/schema/index.ts +15 -0
- package/src/infrastructure/schema/remote-loader.ts +48 -0
- package/src/infrastructure/server/index.ts +26 -0
- package/src/infrastructure/server/language-detection.ts +87 -0
- package/src/infrastructure/server/lifecycle.ts +67 -0
- package/src/infrastructure/server/route-setup/api-routes.ts +310 -0
- package/src/infrastructure/server/route-setup/auth-route-utils.ts +399 -0
- package/src/infrastructure/server/route-setup/auth-routes.ts +245 -0
- package/src/infrastructure/server/route-setup/openapi-routes.ts +45 -0
- package/src/infrastructure/server/route-setup/openapi-schema.ts +120 -0
- package/src/infrastructure/server/route-setup/page-routes.ts +219 -0
- package/src/infrastructure/server/route-setup/static-assets.ts +191 -0
- package/src/infrastructure/server/server-factory-live.ts +45 -0
- package/src/infrastructure/server/server.ts +275 -0
- package/src/infrastructure/server/ssg-adapter.ts +196 -0
- package/src/infrastructure/server/static-site-generator-live.ts +20 -0
- package/src/infrastructure/utils/accept-language-parser.ts +106 -0
- package/src/infrastructure/utils/glob-matcher.ts +50 -0
- package/src/presentation/api/client.ts +114 -0
- package/src/presentation/api/middleware/auth.ts +233 -0
- package/src/presentation/api/middleware/table.ts +155 -0
- package/src/presentation/api/middleware/validation.ts +88 -0
- package/src/presentation/api/routes/activity/get-activity-by-id-handler.ts +77 -0
- package/src/presentation/api/routes/activity/index.ts +28 -0
- package/src/presentation/api/routes/activity.ts +339 -0
- package/src/presentation/api/routes/analytics.ts +328 -0
- package/src/presentation/api/routes/auth.ts +169 -0
- package/src/presentation/api/routes/index.ts +11 -0
- package/src/presentation/api/routes/tables/activity-handlers.ts +57 -0
- package/src/presentation/api/routes/tables/batch-permission-helpers.ts +163 -0
- package/src/presentation/api/routes/tables/batch-routes.ts +355 -0
- package/src/presentation/api/routes/tables/comment-handlers.ts +377 -0
- package/src/presentation/api/routes/tables/create-record-helpers.ts +179 -0
- package/src/presentation/api/routes/tables/effect-runner.ts +58 -0
- package/src/presentation/api/routes/tables/error-handlers.ts +53 -0
- package/src/presentation/api/routes/tables/field-permission-validation.ts +167 -0
- package/src/presentation/api/routes/tables/filter-parser.ts +75 -0
- package/src/presentation/api/routes/tables/formula-parser.ts +118 -0
- package/src/presentation/api/routes/tables/index.ts +113 -0
- package/src/presentation/api/routes/tables/list-records-filter.ts +54 -0
- package/src/presentation/api/routes/tables/param-parsers.ts +59 -0
- package/src/presentation/api/routes/tables/record-handlers.ts +484 -0
- package/src/presentation/api/routes/tables/record-routes.ts +53 -0
- package/src/presentation/api/routes/tables/record-update-handler.ts +200 -0
- package/src/presentation/api/routes/tables/sort-validation.ts +85 -0
- package/src/presentation/api/routes/tables/table-routes.ts +76 -0
- package/src/presentation/api/routes/tables/timezone-validation.ts +41 -0
- package/src/presentation/api/routes/tables/upsert-helpers.ts +471 -0
- package/src/presentation/api/routes/tables/utils.ts +159 -0
- package/src/presentation/api/routes/tables/view-routes.ts +51 -0
- package/src/presentation/api/routes/tables.ts +9 -0
- package/src/presentation/api/utils/context-helpers.ts +43 -0
- package/src/presentation/api/utils/error-sanitizer.ts +235 -0
- package/src/presentation/api/utils/field-permission-validator.ts +53 -0
- package/src/presentation/api/utils/filter-field-validator.ts +90 -0
- package/src/presentation/api/utils/index.ts +13 -0
- package/src/presentation/api/utils/run-effect.ts +94 -0
- package/src/presentation/api/utils/validate-request.ts +89 -0
- package/src/presentation/api/validation/index.ts +29 -0
- package/src/presentation/api/validation/rules/field-rules.ts +158 -0
- package/src/presentation/api/validation/rules/record-rules.ts +73 -0
- package/src/presentation/cli/index.ts +19 -0
- package/src/presentation/cli/schema-loader.ts +172 -0
- package/src/presentation/hooks/use-breakpoint.ts +155 -0
- package/src/presentation/rendering/render-error-pages.tsx +60 -0
- package/src/presentation/rendering/render-homepage.tsx +137 -0
- package/src/presentation/scripts/script-renderers.ts +112 -0
- package/src/presentation/styling/animation-composer.ts +117 -0
- package/src/presentation/styling/index.ts +13 -0
- package/src/presentation/styling/parse-style.ts +243 -0
- package/src/presentation/styling/style-utils.ts +50 -0
- package/src/presentation/styling/theme-colors.ts +53 -0
- package/src/presentation/translations/component-utils.ts +54 -0
- package/src/presentation/translations/index.ts +16 -0
- package/src/presentation/translations/translation-resolver.ts +22 -0
- package/src/presentation/ui/languages/language-switcher.tsx +119 -0
- package/src/presentation/ui/metadata/analytics-builders.tsx +174 -0
- package/src/presentation/ui/metadata/analytics-head.tsx +39 -0
- package/src/presentation/ui/metadata/custom-elements-builders.tsx +157 -0
- package/src/presentation/ui/metadata/extract-component-meta.ts +108 -0
- package/src/presentation/ui/metadata/head-elements.tsx +164 -0
- package/src/presentation/ui/metadata/index.tsx +35 -0
- package/src/presentation/ui/metadata/meta-utils.tsx +42 -0
- package/src/presentation/ui/metadata/open-graph-meta.tsx +57 -0
- package/src/presentation/ui/metadata/structured-data-from-component.tsx +134 -0
- package/src/presentation/ui/metadata/structured-data.tsx +88 -0
- package/src/presentation/ui/metadata/twitter-card-meta.tsx +80 -0
- package/src/presentation/ui/pages/DefaultHomePage.tsx +43 -0
- package/src/presentation/ui/pages/DefaultPageConfigs.ts +220 -0
- package/src/presentation/ui/pages/DynamicPage.tsx +307 -0
- package/src/presentation/ui/pages/ErrorPage.tsx +25 -0
- package/src/presentation/ui/pages/NotFoundPage.tsx +25 -0
- package/src/presentation/ui/pages/PageBodyScripts.tsx +242 -0
- package/src/presentation/ui/pages/PageBodyStyles.ts +52 -0
- package/src/presentation/ui/pages/PageHead.tsx +380 -0
- package/src/presentation/ui/pages/PageLangResolver.ts +58 -0
- package/src/presentation/ui/pages/PageMain.tsx +58 -0
- package/src/presentation/ui/pages/PageMetadata.ts +168 -0
- package/src/presentation/ui/pages/PageMetadataI18n.ts +169 -0
- package/src/presentation/ui/pages/PageScripts.ts +78 -0
- package/src/presentation/ui/pages/SectionRenderer.tsx +67 -0
- package/src/presentation/ui/pages/SectionSpacing.tsx +131 -0
- package/src/presentation/ui/sections/component-renderer.tsx +426 -0
- package/src/presentation/ui/sections/component-renderer.types.ts +33 -0
- package/src/presentation/ui/sections/components/component-reference-handler.tsx +74 -0
- package/src/presentation/ui/sections/components/component-resolution.ts +65 -0
- package/src/presentation/ui/sections/components/index.ts +9 -0
- package/src/presentation/ui/sections/hero.tsx +394 -0
- package/src/presentation/ui/sections/props/component-builder.ts +183 -0
- package/src/presentation/ui/sections/props/element-props.ts +179 -0
- package/src/presentation/ui/sections/props/index.ts +9 -0
- package/src/presentation/ui/sections/props/prop-conversion.ts +171 -0
- package/src/presentation/ui/sections/props/props-builder-config.ts +42 -0
- package/src/presentation/ui/sections/props/props-builder.ts +296 -0
- package/src/presentation/ui/sections/renderers/element-renderers/html-element-renderer.tsx +124 -0
- package/src/presentation/ui/sections/renderers/element-renderers/index.ts +59 -0
- package/src/presentation/ui/sections/renderers/element-renderers/interactive-renderers.tsx +231 -0
- package/src/presentation/ui/sections/renderers/element-renderers/media-renderers.tsx +102 -0
- package/src/presentation/ui/sections/renderers/element-renderers/text-content-renderers.tsx +42 -0
- package/src/presentation/ui/sections/renderers/element-renderers.ts +53 -0
- package/src/presentation/ui/sections/renderers/html-element-helpers.ts +100 -0
- package/src/presentation/ui/sections/renderers/specialized-renderers.tsx +212 -0
- package/src/presentation/ui/sections/rendering/component-dispatch-config.ts +31 -0
- package/src/presentation/ui/sections/rendering/component-registry/index.ts +39 -0
- package/src/presentation/ui/sections/rendering/component-registry/interactive-components.ts +54 -0
- package/src/presentation/ui/sections/rendering/component-registry/media-components.ts +36 -0
- package/src/presentation/ui/sections/rendering/component-registry/special-components.tsx +153 -0
- package/src/presentation/ui/sections/rendering/component-registry/structural-components.ts +215 -0
- package/src/presentation/ui/sections/rendering/component-registry/text-components.ts +57 -0
- package/src/presentation/ui/sections/rendering/component-registry-helpers.tsx +29 -0
- package/src/presentation/ui/sections/rendering/component-registry.tsx +21 -0
- package/src/presentation/ui/sections/rendering/component-type-dispatcher.tsx +33 -0
- package/src/presentation/ui/sections/rendering/index.ts +9 -0
- package/src/presentation/ui/sections/responsive/responsive-children-builder.tsx +96 -0
- package/src/presentation/ui/sections/responsive/responsive-content-builder.tsx +95 -0
- package/src/presentation/ui/sections/responsive/responsive-props-merger.ts +195 -0
- package/src/presentation/ui/sections/responsive/responsive-resolver.ts +213 -0
- package/src/presentation/ui/sections/styling/animation-composer-wrapper.ts +65 -0
- package/src/presentation/ui/sections/styling/class-builders.ts +45 -0
- package/src/presentation/ui/sections/styling/color-resolver.ts +43 -0
- package/src/presentation/ui/sections/styling/hover-interaction-handler.ts +107 -0
- package/src/presentation/ui/sections/styling/index.ts +9 -0
- package/src/presentation/ui/sections/styling/interaction-props-builder.ts +55 -0
- package/src/presentation/ui/sections/styling/shadow-resolver.ts +83 -0
- package/src/presentation/ui/sections/styling/spacing-resolver.ts +104 -0
- package/src/presentation/ui/sections/styling/style-processor.ts +170 -0
- package/src/presentation/ui/sections/styling/theme-tokens.ts +184 -0
- package/src/presentation/ui/sections/translations/i18n-content-resolver.ts +198 -0
- package/src/presentation/ui/sections/translations/index.ts +9 -0
- package/src/presentation/ui/sections/translations/translation-handler.ts +143 -0
- package/src/presentation/ui/sections/translations/variable-substitution.ts +225 -0
- package/src/presentation/ui/sections/utils/time-parser.ts +82 -0
- package/src/presentation/utils/link-attributes.ts +50 -0
- package/src/presentation/utils/string-utils.ts +58 -0
- package/src/presentation/utils/styles.ts +50 -0
- package/tsconfig.json +46 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Data } from 'effect'
|
|
9
|
+
import { logInfo } from '@/infrastructure/logging/logger'
|
|
10
|
+
import { isUserReferenceField, isUserField } from '../sql/sql-generators'
|
|
11
|
+
import type { Table } from '@/domain/models/app/table'
|
|
12
|
+
|
|
13
|
+
export class BetterAuthUsersTableRequired extends Data.TaggedError('BetterAuthUsersTableRequired')<{
|
|
14
|
+
readonly message: string
|
|
15
|
+
}> {}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Check if any table needs the users table for foreign keys
|
|
19
|
+
*/
|
|
20
|
+
export const needsUsersTable = (tables: readonly Table[]): boolean =>
|
|
21
|
+
tables.some((table) =>
|
|
22
|
+
table.fields.some((field) => isUserReferenceField(field) || isUserField(field))
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Check if any table has updated-by fields that need the trigger function
|
|
27
|
+
*/
|
|
28
|
+
export const needsUpdatedByTrigger = (tables: readonly Table[]): boolean =>
|
|
29
|
+
tables.some((table) => table.fields.some((field) => field.type === 'updated-by'))
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Verify Better Auth users table exists for foreign key references
|
|
33
|
+
*
|
|
34
|
+
* User fields (user, created-by, updated-by, deleted-by) require Better Auth's users table.
|
|
35
|
+
* Better Auth uses TEXT ids, so user fields store TEXT foreign keys.
|
|
36
|
+
*
|
|
37
|
+
* @throws BetterAuthUsersTableRequired if users table doesn't exist or lacks required columns
|
|
38
|
+
*/
|
|
39
|
+
/* eslint-disable functional/no-throw-statements */
|
|
40
|
+
export const ensureBetterAuthUsersTable = async (tx: {
|
|
41
|
+
unsafe: (sql: string) => Promise<unknown>
|
|
42
|
+
}): Promise<void> => {
|
|
43
|
+
logInfo('[ensureBetterAuthUsersTable] Verifying Better Auth users table exists...')
|
|
44
|
+
|
|
45
|
+
// Check if users table exists (in auth schema)
|
|
46
|
+
const tableExistsResult = (await tx.unsafe(`
|
|
47
|
+
SELECT EXISTS (
|
|
48
|
+
SELECT 1 FROM information_schema.tables
|
|
49
|
+
WHERE table_schema = 'auth' AND table_name = 'user'
|
|
50
|
+
) as exists
|
|
51
|
+
`)) as readonly { exists: boolean }[]
|
|
52
|
+
|
|
53
|
+
if (!tableExistsResult[0]?.exists) {
|
|
54
|
+
throw new BetterAuthUsersTableRequired({
|
|
55
|
+
message:
|
|
56
|
+
'User fields require Better Auth users table. Please configure Better Auth authentication before using user, created-by, updated-by, or deleted-by field types.',
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Verify Better Auth schema (TEXT id column)
|
|
61
|
+
const idColumnResult = (await tx.unsafe(`
|
|
62
|
+
SELECT data_type FROM information_schema.columns
|
|
63
|
+
WHERE table_schema = 'auth' AND table_name = 'user' AND column_name = 'id'
|
|
64
|
+
`)) as readonly { data_type: string }[]
|
|
65
|
+
|
|
66
|
+
if (!idColumnResult[0]) {
|
|
67
|
+
throw new BetterAuthUsersTableRequired({
|
|
68
|
+
message:
|
|
69
|
+
'Users table exists but lacks id column. Please ensure Better Auth is properly configured.',
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const idType = idColumnResult[0].data_type.toLowerCase()
|
|
74
|
+
if (idType !== 'text' && idType !== 'character varying') {
|
|
75
|
+
throw new BetterAuthUsersTableRequired({
|
|
76
|
+
message: `Users table has incompatible id column type '${idType}'. Better Auth uses TEXT ids. Please configure Better Auth authentication.`,
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
logInfo('[ensureBetterAuthUsersTable] Better Auth users table verified successfully')
|
|
81
|
+
}
|
|
82
|
+
/* eslint-enable functional/no-throw-statements */
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Ensure global set_updated_by trigger function exists
|
|
86
|
+
* This function is shared across all tables with updated-by fields
|
|
87
|
+
*/
|
|
88
|
+
/* eslint-disable functional/no-expression-statements */
|
|
89
|
+
export const ensureUpdatedByTriggerFunction = async (tx: {
|
|
90
|
+
unsafe: (sql: string) => Promise<unknown>
|
|
91
|
+
}): Promise<void> => {
|
|
92
|
+
await tx.unsafe(`
|
|
93
|
+
CREATE OR REPLACE FUNCTION set_updated_by()
|
|
94
|
+
RETURNS TRIGGER AS $$
|
|
95
|
+
BEGIN
|
|
96
|
+
RETURN NEW;
|
|
97
|
+
END;
|
|
98
|
+
$$ LANGUAGE plpgsql
|
|
99
|
+
`)
|
|
100
|
+
}
|
|
101
|
+
/* eslint-enable functional/no-expression-statements */
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { drizzle } from 'drizzle-orm/bun-sql'
|
|
9
|
+
import * as schema from './schema'
|
|
10
|
+
|
|
11
|
+
// Bun-specific database driver using native bun:sql
|
|
12
|
+
export const db = drizzle({
|
|
13
|
+
connection: { url: process.env.DATABASE_URL! },
|
|
14
|
+
schema,
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
export type DrizzleDB = typeof db
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { DrizzleDB } from './db-bun'
|
|
9
|
+
|
|
10
|
+
export { db } from './db-bun'
|
|
11
|
+
export type { DrizzleDB } from './db-bun'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Type for Drizzle transaction callback parameter
|
|
15
|
+
* Extracts the transaction type from the db.transaction method
|
|
16
|
+
*/
|
|
17
|
+
export type DrizzleTransaction = Parameters<Parameters<DrizzleDB['transaction']>[0]>[0]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Drizzle Database Module
|
|
10
|
+
*
|
|
11
|
+
* Provides database functionality using Drizzle ORM with Bun SQL.
|
|
12
|
+
* Re-exports all database-related services, schema, and types.
|
|
13
|
+
*/
|
|
14
|
+
export { db, type DrizzleDB } from './db'
|
|
15
|
+
export { Database, DatabaseLive } from './layer'
|
|
16
|
+
export * from './schema'
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Context, Layer } from 'effect'
|
|
9
|
+
import { db, type DrizzleDB } from './db.js'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Database Effect Context
|
|
13
|
+
*
|
|
14
|
+
* Provides Drizzle database instance for dependency injection in Effect programs.
|
|
15
|
+
* Use this in Application layer to access database without direct imports.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const program = Effect.gen(function* () {
|
|
20
|
+
* const db = yield* Database
|
|
21
|
+
* const users = yield* Effect.tryPromise(() => db.select().from(usersTable))
|
|
22
|
+
* return users
|
|
23
|
+
* })
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export class Database extends Context.Tag('Database')<Database, DrizzleDB>() {}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Live Database Layer
|
|
30
|
+
*
|
|
31
|
+
* Provides the production Drizzle database instance.
|
|
32
|
+
* Uses DATABASE_URL environment variable for connection.
|
|
33
|
+
*/
|
|
34
|
+
export const DatabaseLive = Layer.succeed(Database, db)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { SQL } from 'bun'
|
|
9
|
+
import { drizzle } from 'drizzle-orm/bun-sql'
|
|
10
|
+
import { migrate } from 'drizzle-orm/bun-sql/migrator'
|
|
11
|
+
import { Effect, Console, Data } from 'effect'
|
|
12
|
+
import * as schema from './schema'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Error when database connection fails
|
|
16
|
+
*/
|
|
17
|
+
export class DatabaseConnectionError extends Data.TaggedError('DatabaseConnectionError')<{
|
|
18
|
+
readonly message: string
|
|
19
|
+
readonly cause?: unknown
|
|
20
|
+
}> {}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Error when migration fails
|
|
24
|
+
*/
|
|
25
|
+
export class MigrationError extends Data.TaggedError('MigrationError')<{
|
|
26
|
+
readonly message: string
|
|
27
|
+
readonly cause?: unknown
|
|
28
|
+
}> {}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Run Drizzle migrations to create/update database schema
|
|
32
|
+
*
|
|
33
|
+
* This applies all migrations from the ./drizzle folder:
|
|
34
|
+
* - Better Auth tables (users, sessions, accounts, etc.)
|
|
35
|
+
* - Migration audit tables (system.migration_history, etc.)
|
|
36
|
+
* - Auth schema with helper functions (auth.is_authenticated, auth.user_has_role)
|
|
37
|
+
*
|
|
38
|
+
* CRITICAL: Must run BEFORE initializeSchema() because:
|
|
39
|
+
* 1. User fields (created-by, updated-by, user) need users table to exist
|
|
40
|
+
* 2. The users table must be created before app-specific tables
|
|
41
|
+
* 3. initializeSchema() creates app-specific tables that reference users
|
|
42
|
+
*
|
|
43
|
+
* @param databaseUrl - PostgreSQL connection URL
|
|
44
|
+
* @returns Effect that completes when migrations are applied
|
|
45
|
+
*/
|
|
46
|
+
export const runMigrations = (
|
|
47
|
+
databaseUrl: string
|
|
48
|
+
): Effect.Effect<void, DatabaseConnectionError | MigrationError> =>
|
|
49
|
+
Effect.gen(function* () {
|
|
50
|
+
yield* Console.log('[runMigrations] Running Drizzle migrations...')
|
|
51
|
+
|
|
52
|
+
const client = new SQL(databaseUrl)
|
|
53
|
+
const db = drizzle({ client, schema })
|
|
54
|
+
|
|
55
|
+
// Test database connection first to fail fast on connection errors
|
|
56
|
+
yield* Effect.tryPromise({
|
|
57
|
+
try: () => client.unsafe('SELECT 1'),
|
|
58
|
+
catch: (error) =>
|
|
59
|
+
new DatabaseConnectionError({
|
|
60
|
+
message: `Database connection failed: ${String(error)}`,
|
|
61
|
+
cause: error,
|
|
62
|
+
}),
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
yield* Effect.tryPromise({
|
|
66
|
+
try: () => migrate(db, { migrationsFolder: './drizzle' }),
|
|
67
|
+
catch: (error) =>
|
|
68
|
+
new MigrationError({
|
|
69
|
+
message: `Migration failed: ${String(error)}`,
|
|
70
|
+
cause: error,
|
|
71
|
+
}),
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
yield* Effect.promise(() => client.close())
|
|
75
|
+
|
|
76
|
+
yield* Console.log('[runMigrations] ✓ Drizzle migrations completed')
|
|
77
|
+
})
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { sql } from 'drizzle-orm'
|
|
9
|
+
import { text, timestamp, jsonb, index } from 'drizzle-orm/pg-core'
|
|
10
|
+
import { users } from '../../../auth/better-auth/schema'
|
|
11
|
+
import { systemSchema } from './migration-audit'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Activity Action Type
|
|
15
|
+
*
|
|
16
|
+
* Defines the types of actions that can be recorded in the activity log.
|
|
17
|
+
* - create: A new record was created
|
|
18
|
+
* - update: An existing record was modified
|
|
19
|
+
* - delete: A record was soft-deleted or hard-deleted
|
|
20
|
+
* - restore: A soft-deleted record was restored
|
|
21
|
+
*/
|
|
22
|
+
export type ActivityAction = 'create' | 'update' | 'delete' | 'restore'
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Activity Log Changes Type
|
|
26
|
+
*
|
|
27
|
+
* Captures the before/after state of record modifications.
|
|
28
|
+
* - For 'create': only 'after' is populated
|
|
29
|
+
* - For 'update': both 'before' and 'after' are populated with changed fields
|
|
30
|
+
* - For 'delete': only 'before' is populated (or null for hard deletes)
|
|
31
|
+
* - For 'restore': both 'before' and 'after' are populated
|
|
32
|
+
*/
|
|
33
|
+
export type ActivityLogChanges = {
|
|
34
|
+
readonly before?: Record<string, unknown>
|
|
35
|
+
readonly after?: Record<string, unknown>
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Activity Log Table Schema
|
|
40
|
+
*
|
|
41
|
+
* Central audit log tracking all data modifications across the application.
|
|
42
|
+
* Optimized for:
|
|
43
|
+
* - Time-range queries (recent activity)
|
|
44
|
+
* - User activity lookups (user audit trail)
|
|
45
|
+
* - Record history queries (record-specific changes)
|
|
46
|
+
*
|
|
47
|
+
* Retention: 1 year (compliance requirement)
|
|
48
|
+
*
|
|
49
|
+
* Authentication Optional:
|
|
50
|
+
* - userId is nullable to support anonymous activity logging
|
|
51
|
+
* - When Better Auth is not configured, activities are logged without user context
|
|
52
|
+
*/
|
|
53
|
+
export const activityLogs = systemSchema.table(
|
|
54
|
+
'activity_logs',
|
|
55
|
+
{
|
|
56
|
+
// Primary key - UUID for distributed systems compatibility
|
|
57
|
+
// Default generates UUID automatically via PostgreSQL gen_random_uuid()
|
|
58
|
+
id: text('id')
|
|
59
|
+
.primaryKey()
|
|
60
|
+
.default(sql`gen_random_uuid()`),
|
|
61
|
+
|
|
62
|
+
// Event metadata
|
|
63
|
+
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
|
64
|
+
|
|
65
|
+
// User who performed the action (null when auth disabled)
|
|
66
|
+
userId: text('user_id').references(() => users.id, { onDelete: 'set null' }),
|
|
67
|
+
|
|
68
|
+
// Optional session tracking for additional context
|
|
69
|
+
sessionId: text('session_id'),
|
|
70
|
+
|
|
71
|
+
// Action type: create, update, delete, restore
|
|
72
|
+
action: text('action').notNull().$type<ActivityAction>(),
|
|
73
|
+
|
|
74
|
+
// Table identification
|
|
75
|
+
tableName: text('table_name').notNull(),
|
|
76
|
+
// tableId is optional - not all activity sources have a table schema ID
|
|
77
|
+
tableId: text('table_id'),
|
|
78
|
+
|
|
79
|
+
// Record identification within the table
|
|
80
|
+
recordId: text('record_id').notNull(),
|
|
81
|
+
|
|
82
|
+
// Change tracking - JSONB for efficient storage and querying
|
|
83
|
+
// Contains { before?: {...}, after?: {...} }
|
|
84
|
+
changes: jsonb('changes').$type<ActivityLogChanges>(),
|
|
85
|
+
|
|
86
|
+
// Request context for security auditing
|
|
87
|
+
ipAddress: text('ip_address'),
|
|
88
|
+
userAgent: text('user_agent'),
|
|
89
|
+
},
|
|
90
|
+
(table) => [
|
|
91
|
+
// Index for recent activity queries (most common)
|
|
92
|
+
// Supports: GET /api/activity (sorted by createdAt DESC)
|
|
93
|
+
index('activity_logs_created_at_idx').on(table.createdAt),
|
|
94
|
+
|
|
95
|
+
// Composite index for user activity queries
|
|
96
|
+
// Supports: GET /api/users/:userId/activity
|
|
97
|
+
index('activity_logs_user_created_at_idx').on(table.userId, table.createdAt),
|
|
98
|
+
|
|
99
|
+
// Composite index for record history queries
|
|
100
|
+
// Supports: GET /api/tables/:tableId/records/:recordId/history
|
|
101
|
+
index('activity_logs_table_record_idx').on(table.tableName, table.recordId),
|
|
102
|
+
|
|
103
|
+
// Index for filtering by action type
|
|
104
|
+
// Supports: GET /api/activity?action=create
|
|
105
|
+
index('activity_logs_action_idx').on(table.action),
|
|
106
|
+
]
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
// Type exports for consumers
|
|
110
|
+
export type ActivityLog = typeof activityLogs.$inferSelect
|
|
111
|
+
export type NewActivityLog = typeof activityLogs.$inferInsert
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { sql } from 'drizzle-orm'
|
|
9
|
+
import { boolean, index, smallint, text, timestamp } from 'drizzle-orm/pg-core'
|
|
10
|
+
import { systemSchema } from './migration-audit'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Analytics Page Views Table Schema
|
|
14
|
+
*
|
|
15
|
+
* Stores individual page view events for the built-in analytics engine.
|
|
16
|
+
* Designed for privacy-first tracking without cookies or PII.
|
|
17
|
+
*
|
|
18
|
+
* Key design decisions:
|
|
19
|
+
* - visitorHash: SHA-256(date + IP + UA + salt) — rotates daily, no PII stored
|
|
20
|
+
* - sessionHash: SHA-256(visitorHash + time-window) — groups views into sessions
|
|
21
|
+
* - No foreign keys to users table — analytics is anonymous
|
|
22
|
+
* - All device/browser/OS data parsed server-side from User-Agent
|
|
23
|
+
* - UTM parameters captured from tracking script payload
|
|
24
|
+
*
|
|
25
|
+
* Indexes optimized for:
|
|
26
|
+
* - Time-series queries (overview, trends)
|
|
27
|
+
* - Unique visitor counting
|
|
28
|
+
* - Per-page analytics
|
|
29
|
+
* - Referrer analysis
|
|
30
|
+
* - UTM campaign analysis
|
|
31
|
+
* - Device breakdown queries
|
|
32
|
+
*/
|
|
33
|
+
export const analyticsPageViews = systemSchema.table(
|
|
34
|
+
'analytics_page_views',
|
|
35
|
+
{
|
|
36
|
+
// Primary key - UUID for distributed systems compatibility
|
|
37
|
+
id: text('id')
|
|
38
|
+
.primaryKey()
|
|
39
|
+
.default(sql`gen_random_uuid()`),
|
|
40
|
+
|
|
41
|
+
// Event timestamp
|
|
42
|
+
timestamp: timestamp('timestamp', { withTimezone: true }).notNull().defaultNow(),
|
|
43
|
+
|
|
44
|
+
// Application identifier (supports multi-app deployments)
|
|
45
|
+
// Default 'default' enables direct INSERTs via system.page_views view without explicit app_name
|
|
46
|
+
appName: text('app_name').notNull().default('default'),
|
|
47
|
+
|
|
48
|
+
// Page information
|
|
49
|
+
pagePath: text('page_path').notNull(),
|
|
50
|
+
pageTitle: text('page_title'),
|
|
51
|
+
|
|
52
|
+
// Privacy-safe visitor identification (no cookies, no PII)
|
|
53
|
+
// SHA-256(date + IP + UA + salt) — rotates daily
|
|
54
|
+
visitorHash: text('visitor_hash').notNull(),
|
|
55
|
+
|
|
56
|
+
// Session identification
|
|
57
|
+
// SHA-256(visitorHash + time-window) — groups views into sessions
|
|
58
|
+
// Default gen_random_uuid() enables direct INSERTs via system.page_views view without explicit session_hash
|
|
59
|
+
sessionHash: text('session_hash')
|
|
60
|
+
.notNull()
|
|
61
|
+
.default(sql`gen_random_uuid()`),
|
|
62
|
+
|
|
63
|
+
// Whether this is the first page view in a session
|
|
64
|
+
isEntrance: boolean('is_entrance').notNull().default(false),
|
|
65
|
+
|
|
66
|
+
// Referrer information
|
|
67
|
+
referrerUrl: text('referrer_url'),
|
|
68
|
+
referrerDomain: text('referrer_domain'),
|
|
69
|
+
|
|
70
|
+
// UTM campaign parameters
|
|
71
|
+
utmSource: text('utm_source'),
|
|
72
|
+
utmMedium: text('utm_medium'),
|
|
73
|
+
utmCampaign: text('utm_campaign'),
|
|
74
|
+
utmContent: text('utm_content'),
|
|
75
|
+
utmTerm: text('utm_term'),
|
|
76
|
+
|
|
77
|
+
// Device information (parsed from User-Agent server-side)
|
|
78
|
+
deviceType: text('device_type'), // 'desktop' | 'mobile' | 'tablet'
|
|
79
|
+
browserName: text('browser_name'),
|
|
80
|
+
osName: text('os_name'),
|
|
81
|
+
|
|
82
|
+
// Visitor locale (from Accept-Language header)
|
|
83
|
+
language: text('language'),
|
|
84
|
+
|
|
85
|
+
// Screen dimensions (from tracking script)
|
|
86
|
+
screenWidth: smallint('screen_width'),
|
|
87
|
+
screenHeight: smallint('screen_height'),
|
|
88
|
+
},
|
|
89
|
+
(table) => [
|
|
90
|
+
// Primary time-series index (overview queries, date range filtering)
|
|
91
|
+
index('analytics_pv_app_timestamp_idx').on(table.appName, table.timestamp),
|
|
92
|
+
|
|
93
|
+
// Unique visitor counting
|
|
94
|
+
index('analytics_pv_app_visitor_timestamp_idx').on(
|
|
95
|
+
table.appName,
|
|
96
|
+
table.visitorHash,
|
|
97
|
+
table.timestamp
|
|
98
|
+
),
|
|
99
|
+
|
|
100
|
+
// Per-page analytics (top pages queries)
|
|
101
|
+
index('analytics_pv_app_path_timestamp_idx').on(table.appName, table.pagePath, table.timestamp),
|
|
102
|
+
|
|
103
|
+
// Referrer analysis (traffic sources queries)
|
|
104
|
+
index('analytics_pv_app_referrer_idx').on(table.appName, table.referrerDomain),
|
|
105
|
+
|
|
106
|
+
// UTM campaign analysis
|
|
107
|
+
index('analytics_pv_app_utm_source_idx').on(table.appName, table.utmSource),
|
|
108
|
+
|
|
109
|
+
// Device breakdown queries
|
|
110
|
+
index('analytics_pv_app_device_idx').on(table.appName, table.deviceType),
|
|
111
|
+
]
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
// Type exports for consumers
|
|
115
|
+
export type AnalyticsPageView = typeof analyticsPageViews.$inferSelect
|
|
116
|
+
export type NewAnalyticsPageView = typeof analyticsPageViews.$inferInsert
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { pgSchema, serial, integer, text, timestamp, jsonb } from 'drizzle-orm/pg-core'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* System Schema
|
|
12
|
+
*
|
|
13
|
+
* Dedicated PostgreSQL schema for internal Sovrium tables.
|
|
14
|
+
* Isolates system tables from user data tables.
|
|
15
|
+
*/
|
|
16
|
+
export const systemSchema = pgSchema('system')
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Migration History Table Schema
|
|
20
|
+
*
|
|
21
|
+
* Tracks all schema migrations with timestamps and checksums.
|
|
22
|
+
* Each migration is recorded with a version number and the complete schema snapshot.
|
|
23
|
+
*/
|
|
24
|
+
export const sovriumMigrationHistory = systemSchema.table('migration_history', {
|
|
25
|
+
id: serial('id').primaryKey(),
|
|
26
|
+
version: integer('version').notNull(),
|
|
27
|
+
checksum: text('checksum').notNull(),
|
|
28
|
+
schema: jsonb('schema'),
|
|
29
|
+
appliedAt: timestamp('applied_at').defaultNow(),
|
|
30
|
+
rolledBackAt: timestamp('rolled_back_at'),
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Migration Log Table Schema
|
|
35
|
+
*
|
|
36
|
+
* Tracks migration operations including rollbacks with status and reason.
|
|
37
|
+
* Used for debugging and audit trail of schema changes.
|
|
38
|
+
*/
|
|
39
|
+
export const sovriumMigrationLog = systemSchema.table('migration_log', {
|
|
40
|
+
id: serial('id').primaryKey(),
|
|
41
|
+
operation: text('operation').notNull(),
|
|
42
|
+
fromVersion: integer('from_version'),
|
|
43
|
+
toVersion: integer('to_version'),
|
|
44
|
+
reason: text('reason'),
|
|
45
|
+
status: text('status').notNull(),
|
|
46
|
+
createdAt: timestamp('created_at').defaultNow(),
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Schema Checksum Table Schema
|
|
51
|
+
*
|
|
52
|
+
* Singleton table storing current schema checksum for change detection.
|
|
53
|
+
* Uses a single row with id='singleton' to track the current state.
|
|
54
|
+
*/
|
|
55
|
+
export const sovriumSchemaChecksum = systemSchema.table('schema_checksum', {
|
|
56
|
+
id: text('id').primaryKey(),
|
|
57
|
+
checksum: text('checksum').notNull(),
|
|
58
|
+
schema: jsonb('schema').notNull(),
|
|
59
|
+
updatedAt: timestamp('updated_at').defaultNow(),
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// Type exports for consumers
|
|
63
|
+
export type SovriumMigrationHistory = typeof sovriumMigrationHistory.$inferSelect
|
|
64
|
+
export type NewSovriumMigrationHistory = typeof sovriumMigrationHistory.$inferInsert
|
|
65
|
+
export type SovriumMigrationLog = typeof sovriumMigrationLog.$inferSelect
|
|
66
|
+
export type NewSovriumMigrationLog = typeof sovriumMigrationLog.$inferInsert
|
|
67
|
+
export type SovriumSchemaChecksum = typeof sovriumSchemaChecksum.$inferSelect
|
|
68
|
+
export type NewSovriumSchemaChecksum = typeof sovriumSchemaChecksum.$inferInsert
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { text, timestamp, index } from 'drizzle-orm/pg-core'
|
|
9
|
+
import { users } from '../../../auth/better-auth/schema'
|
|
10
|
+
import { systemSchema } from './migration-audit'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Record Comments Table Schema
|
|
14
|
+
*
|
|
15
|
+
* Enables users to add comments to records in any table, similar to Airtable/Notion.
|
|
16
|
+
* Comments are flat (no threading), chronological, and support @mentions.
|
|
17
|
+
*
|
|
18
|
+
* Features:
|
|
19
|
+
* - Authentication required: Comments must have a user_id (no anonymous comments)
|
|
20
|
+
* - Soft delete: deleted_at for restoration capability
|
|
21
|
+
* - @mentions: Stored as user IDs in content (e.g., @[user_123])
|
|
22
|
+
* - Table validation: Comments tied to specific table_id for validation
|
|
23
|
+
*
|
|
24
|
+
* Authorization:
|
|
25
|
+
* - Read: Same permissions as the record itself (if you can read the record, you can read comments)
|
|
26
|
+
* - Create: Any authenticated user who can read the record can comment
|
|
27
|
+
* - Update: Only comment author can edit their own comments
|
|
28
|
+
* - Delete: Comment author OR admins can delete comments
|
|
29
|
+
*
|
|
30
|
+
* Optimized for:
|
|
31
|
+
* - Fetching all comments for a record (most common query)
|
|
32
|
+
* - User activity lookups (all comments by a user)
|
|
33
|
+
* - Soft delete filtering (excluding deleted comments by default)
|
|
34
|
+
*/
|
|
35
|
+
export const recordComments = systemSchema.table(
|
|
36
|
+
'record_comments',
|
|
37
|
+
{
|
|
38
|
+
// Primary key - UUID for distributed systems compatibility
|
|
39
|
+
id: text('id').primaryKey(),
|
|
40
|
+
|
|
41
|
+
// Record identification
|
|
42
|
+
recordId: text('record_id').notNull(),
|
|
43
|
+
tableId: text('table_id').notNull(),
|
|
44
|
+
|
|
45
|
+
// User who created the comment (required - no anonymous comments)
|
|
46
|
+
userId: text('user_id')
|
|
47
|
+
.notNull()
|
|
48
|
+
.references(() => users.id, { onDelete: 'cascade' }),
|
|
49
|
+
|
|
50
|
+
// Comment content - supports @mentions as @[user_id] format
|
|
51
|
+
// Max length enforced at application layer
|
|
52
|
+
content: text('content').notNull(),
|
|
53
|
+
|
|
54
|
+
// Timestamps
|
|
55
|
+
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
|
56
|
+
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
|
57
|
+
|
|
58
|
+
// Soft delete support
|
|
59
|
+
deletedAt: timestamp('deleted_at', { withTimezone: true }),
|
|
60
|
+
},
|
|
61
|
+
(table) => [
|
|
62
|
+
// Composite index for fetching all comments on a record (most common query)
|
|
63
|
+
// Supports: GET /api/tables/:tableId/records/:recordId/comments
|
|
64
|
+
// Ordered by createdAt for chronological display
|
|
65
|
+
index('record_comments_record_created_idx').on(table.tableId, table.recordId, table.createdAt),
|
|
66
|
+
|
|
67
|
+
// Composite index for user activity queries
|
|
68
|
+
// Supports: GET /api/users/:userId/comments
|
|
69
|
+
index('record_comments_user_created_idx').on(table.userId, table.createdAt),
|
|
70
|
+
|
|
71
|
+
// Index for soft delete filtering
|
|
72
|
+
// Supports: WHERE deleted_at IS NULL (default query behavior)
|
|
73
|
+
index('record_comments_deleted_at_idx').on(table.deletedAt),
|
|
74
|
+
]
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
// Type exports for consumers
|
|
78
|
+
export type RecordComment = typeof recordComments.$inferSelect
|
|
79
|
+
export type NewRecordComment = typeof recordComments.$inferInsert
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export * from '../../auth/better-auth/schema'
|
|
9
|
+
export * from './schema/migration-audit'
|
|
10
|
+
export * from './schema/activity-log'
|
|
11
|
+
export * from './schema/analytics-page-views'
|
|
12
|
+
export * from './schema/record-comments'
|