Baustein 6: Checklisten mit Durchlaeufen und PDF-Export
- Durchlauf aus einer Vorlage, mit Datum, Ticket und Kunde - Schritt fuer Schritt abhaken, Bemerkung je Schritt - Fortschritt gesamt und je Gruppe (Vorbereiten/Durchfuehren/Pruefen/Abschliessen) - Abschliessen erst, wenn alles abgehakt ist; Meldung nennt die offenen Schritte - Abgeschlossene Durchlaeufe sind gesperrt und bleiben als Nachweis - Titel und Schritttexte werden beim Start kopiert, nicht verwiesen - PDF-Export mit gezeichneten Ankreuzkaestchen und Unterschriftenzeilen - Gemeinsame PDF-Grundlage fuer alle kuenftigen Ausgaben - Ausbilder liest mit und darf das PDF abrufen, hakt aber nicht ab - Abgeschlossene Durchlaeufe zaehlen im Wochenfortschritt mit Behoben beim Durchstich: Die Fusszeile wurde unterhalb des Satzspiegels gesetzt, wodurch PDFKit je Fusszeile eine leere Seite anhaengte - aus zwei Seiten wurden sechs. Ein Test zaehlt jetzt die Seitenobjekte im PDF. 29 neue Tests, insgesamt 186. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ffbca01bdc
commit
b9d6041f3b
@@ -174,6 +174,49 @@ export const anhang = sqliteTable(
|
||||
(t) => [index('anhang_bezug_idx').on(t.bezugTyp, t.bezugId), index('anhang_benutzer_idx').on(t.benutzerId)],
|
||||
);
|
||||
|
||||
export const checklisteLauf = sqliteTable(
|
||||
'checkliste_lauf',
|
||||
{
|
||||
id: text('id').primaryKey(),
|
||||
benutzerId: text('benutzer_id')
|
||||
.notNull()
|
||||
.references(() => benutzer.id, { onDelete: 'cascade' }),
|
||||
checklisteId: text('checkliste_id').notNull(),
|
||||
titel: text('titel').notNull(),
|
||||
datum: text('datum').notNull(),
|
||||
ticket: text('ticket'),
|
||||
kunde: text('kunde'),
|
||||
bemerkung: text('bemerkung'),
|
||||
gestartetAm: text('gestartet_am').notNull(),
|
||||
abgeschlossenAm: text('abgeschlossen_am'),
|
||||
},
|
||||
(t) => [
|
||||
index('checkliste_lauf_benutzer_idx').on(t.benutzerId, t.datum),
|
||||
index('checkliste_lauf_vorlage_idx').on(t.checklisteId),
|
||||
],
|
||||
);
|
||||
|
||||
export const checklisteSchritt = sqliteTable(
|
||||
'checkliste_schritt',
|
||||
{
|
||||
id: text('id').primaryKey(),
|
||||
laufId: text('lauf_id')
|
||||
.notNull()
|
||||
.references(() => checklisteLauf.id, { onDelete: 'cascade' }),
|
||||
gruppeId: text('gruppe_id').notNull(),
|
||||
schrittId: text('schritt_id').notNull(),
|
||||
text: text('text').notNull(),
|
||||
reihenfolge: integer('reihenfolge').notNull(),
|
||||
erledigt: integer('erledigt').notNull().default(0),
|
||||
bemerkung: text('bemerkung'),
|
||||
erledigtAm: text('erledigt_am'),
|
||||
},
|
||||
(t) => [
|
||||
uniqueIndex('checkliste_schritt_idx').on(t.laufId, t.schrittId),
|
||||
index('checkliste_schritt_lauf_idx').on(t.laufId, t.reihenfolge),
|
||||
],
|
||||
);
|
||||
|
||||
export type Benutzer = typeof benutzer.$inferSelect;
|
||||
export type Sitzung = typeof sitzung.$inferSelect;
|
||||
export type Ausbildung = typeof ausbildung.$inferSelect;
|
||||
@@ -183,6 +226,8 @@ export type Karte = typeof karte.$inferSelect;
|
||||
export type KartenVerlauf = typeof kartenVerlauf.$inferSelect;
|
||||
export type AufgabeStatus = typeof aufgabeStatus.$inferSelect;
|
||||
export type Anhang = typeof anhang.$inferSelect;
|
||||
export type ChecklisteLauf = typeof checklisteLauf.$inferSelect;
|
||||
export type ChecklisteSchritt = typeof checklisteSchritt.$inferSelect;
|
||||
|
||||
/** Wird von der Schema-Abgleichprüfung im Test verwendet. */
|
||||
export const alleTabellen = {
|
||||
@@ -195,4 +240,6 @@ export const alleTabellen = {
|
||||
kartenVerlauf,
|
||||
aufgabeStatus,
|
||||
anhang,
|
||||
checklisteLauf,
|
||||
checklisteSchritt,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user