Skip to content

Latest commit

 

History

History
58 lines (48 loc) · 3.14 KB

File metadata and controls

58 lines (48 loc) · 3.14 KB
name project-mtp-pascalcase-db
description Multi-Tenant Platform database conventions — database names, table names, and column names ALWAYS in PascalCase.
metadata
type
project

For the multi-tenant-platform repo at D:\Projects\mtp\mtp-docs:

User stated requirement (verbatim): "database name, table name, column names will be ALWAYS IN PascalCase".

Why: User preference for this project specifically. Industry default for Postgres is snake_case, but this project overrides that. Stated emphatically.

How to apply (this project only):

Naming

  • Database name: PascalCase (e.g. PlatformControl, ClientAcme, ClientBeta).
  • Table names: PascalCase (e.g. Client, FeatureFlowVersion, RuleSet, Rule, FormSchemaField).
  • Column names: PascalCase (e.g. ClientCode, DbHost, CreatedAt, IsActive).
  • Index names: PascalCase with prefix (e.g. IX_Client_Code, UQ_Client_Subdomain).
  • Constraint names: PascalCase (e.g. PK_Client, FK_FormSchemaField_FeatureFlowVersion).
  • Function / procedure names: PascalCase (e.g. GetClientByCode). When SPs needed at all (mostly avoid — see [[feedback-no-cqrs-no-mediatr]] etc.).
  • Schema names (if used): PascalCase.

Postgres-specific gotchas with PascalCase

  • Unquoted identifiers in Postgres are folded to lowercase. PascalCase identifiers must be double-quoted in raw SQL: SELECT "ClientCode" FROM "Client".
  • EF Core with Npgsql handles this automatically when entity properties are PascalCase — generated SQL quotes the identifiers. Do not call UseSnakeCaseNamingConvention().
  • Dapper: column names in queries must match casing exactly when quoted; recommend [Column("ClientCode")] attribute on records, or use DefaultTypeMap.MatchNamesWithUnderscores = false and quote in SQL.
  • Migration scripts: always quote identifiers when writing raw SQL.

Example (correct)

CREATE TABLE "Client" (
    "Id"             uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    "Code"           text NOT NULL UNIQUE,
    "Name"           text NOT NULL,
    "DbHost"         text NOT NULL,
    "DbName"         text NOT NULL,
    "DbPort"         int  NOT NULL DEFAULT 5432,
    "DbUser"         text NOT NULL,
    "DbPasswordRef"  text NOT NULL,
    "Subdomain"      text NOT NULL UNIQUE,
    "IsActive"       boolean NOT NULL DEFAULT true,
    "CreatedAt"      timestamptz NOT NULL DEFAULT now(),
    "UpdatedAt"      timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX "IX_Client_Code_Active" ON "Client" ("Code") WHERE "IsActive";

Hard rules

  • All new schema authored in PascalCase.
  • All raw SQL in repo (migrations, seed scripts, ad-hoc queries) uses double-quoted PascalCase identifiers.
  • All doc examples (HTML pages, README, ADRs) use PascalCase for SQL identifiers.
  • EF Core entity types map naturally — class name = table name, property name = column name; no [Table] / [Column] attributes needed.
  • This rule does NOT apply to other repos (GNSchoolERP uses its own conventions; do not propagate).

Related: pairs with [[project-mtp-postgres-ltree]] (Postgres version + ltree) and [[project-mtp-tenancy-model]] (DB-per-client).