Add print cover fields and office profile
- Project settings gain siteAddress, workStage, projectLead and projectEditor (project.update-settings schema version 3, migration 0009); versions 2 and 1 stay executable and keep the current cover values. Snapshot schema 6 carries the fields; older versions upgrade with null. - Global office profile (office name/address) next to the document logo: table document_branding_settings, PUT /api/document-branding/office, editable from the print view toolbar. - Cover page reads all fields; empty values show the "[ergänzen]" marker. The Planstände editor column shows the project editor. - Shared logo constants moved to a dependency-free module so the Next.js bundler can import them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
4779e4a1a7
commit
7692699ee2
35 changed files with 3479 additions and 113 deletions
|
|
@ -1,9 +1,10 @@
|
|||
import { eq } from "drizzle-orm";
|
||||
import { eq, inArray } from "drizzle-orm";
|
||||
import type { AppDatabase } from "../database-context.js";
|
||||
import {
|
||||
documentBrandingAssets,
|
||||
type DocumentBrandingAsset,
|
||||
} from "../schema/document-branding-assets.js";
|
||||
import { documentBrandingSettings } from "../schema/document-branding-settings.js";
|
||||
|
||||
// Plain repository without revision semantics: branding is global office
|
||||
// configuration, not a project mutation.
|
||||
|
|
@ -49,4 +50,37 @@ export class DocumentBrandingRepository {
|
|||
.run().changes > 0
|
||||
);
|
||||
}
|
||||
|
||||
getSettings<TKey extends string>(keys: readonly TKey[]): Record<TKey, string | null> {
|
||||
const rows = this.db
|
||||
.select()
|
||||
.from(documentBrandingSettings)
|
||||
.where(inArray(documentBrandingSettings.key, [...keys]))
|
||||
.all();
|
||||
return Object.fromEntries(
|
||||
keys.map((key) => [key, rows.find((row) => row.key === key)?.value ?? null])
|
||||
) as Record<TKey, string | null>;
|
||||
}
|
||||
|
||||
/** Stores the given values atomically; `null` removes a setting. */
|
||||
setSettings(values: Record<string, string | null>) {
|
||||
const updatedAt = new Date();
|
||||
this.db.transaction((tx) => {
|
||||
for (const [key, value] of Object.entries(values)) {
|
||||
if (value === null) {
|
||||
tx.delete(documentBrandingSettings)
|
||||
.where(eq(documentBrandingSettings.key, key))
|
||||
.run();
|
||||
} else {
|
||||
tx.insert(documentBrandingSettings)
|
||||
.values({ key, value, updatedAt })
|
||||
.onConflictDoUpdate({
|
||||
target: documentBrandingSettings.key,
|
||||
set: { value, updatedAt },
|
||||
})
|
||||
.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue