- Einladen per einmaligem 6-stelligem Code (7 Tage gültig), wahlweise als Mitglied oder Pflanzen-Sitter - Beitritt über Cloud Function joinHousehold (Transaktion, Admin-Rechte) - Security Rules: Sitter dürfen an Pflanzen nur Bestätigungs-Felder ändern; invites nur erstellen, nie lesen - Haushalts-Screen: Mitgliederliste mit Rollen, Einladen, Beitreten mit Wechsel-Warnung - UI-Gating: Sitter sehen keine Anlegen-/Bearbeiten-/Löschen-Aktionen - Bestätigungen speichern den Namen (lastWateredBy/lastFertilizedBy), Anzeige im Profil - Tests: Members-Map im Seed, neuer Sitter-Test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
87 lines
2.6 KiB
Dart
87 lines
2.6 KiB
Dart
import 'package:flutter/foundation.dart';
|
||
|
||
/// Eine Pflanze im Haushalt.
|
||
///
|
||
/// Das Modell ist bewusst haushaltszentriert gedacht: Sobald das
|
||
/// Firebase-Backend angebunden ist, leben Pflanzen unter
|
||
/// `households/{householdId}/plants/{plantId}`.
|
||
@immutable
|
||
class Plant {
|
||
const Plant({
|
||
required this.id,
|
||
required this.nickname,
|
||
required this.species,
|
||
required this.wateringIntervalDays,
|
||
required this.fertilizingIntervalDays,
|
||
this.locationId,
|
||
this.description = '',
|
||
this.careNotes = '',
|
||
this.photoUrl,
|
||
this.lastWatered,
|
||
this.lastFertilized,
|
||
this.lastWateredBy,
|
||
this.lastFertilizedBy,
|
||
});
|
||
|
||
final String id;
|
||
|
||
/// Vom Nutzer vergebener Name, z. B. "Omas Monstera".
|
||
final String nickname;
|
||
|
||
/// Pflanzenart (deutsch und/oder botanisch). Wird später von der
|
||
/// PlantNet-Erkennung befüllt, kann aber auch frei eingegeben werden.
|
||
final String species;
|
||
|
||
/// Referenz auf einen Stellplatz des Haushalts (optional).
|
||
final String? locationId;
|
||
|
||
/// Beschreibung und Pflegehinweise – von der KI erzeugt oder leer.
|
||
final String description;
|
||
final String careNotes;
|
||
|
||
/// Download-URL des Pflanzenfotos in Firebase Storage (optional).
|
||
final String? photoUrl;
|
||
|
||
final int wateringIntervalDays;
|
||
final int fertilizingIntervalDays;
|
||
|
||
/// `null` bedeutet: noch nie erledigt → Aufgabe ist sofort fällig.
|
||
final DateTime? lastWatered;
|
||
final DateTime? lastFertilized;
|
||
|
||
/// Wer zuletzt bestätigt hat (Anzeigename) – für den Haushalt sichtbar.
|
||
final String? lastWateredBy;
|
||
final String? lastFertilizedBy;
|
||
|
||
Plant copyWith({
|
||
String? nickname,
|
||
String? species,
|
||
String? Function()? locationId,
|
||
String? description,
|
||
String? careNotes,
|
||
String? photoUrl,
|
||
int? wateringIntervalDays,
|
||
int? fertilizingIntervalDays,
|
||
DateTime? lastWatered,
|
||
DateTime? lastFertilized,
|
||
String? lastWateredBy,
|
||
String? lastFertilizedBy,
|
||
}) {
|
||
return Plant(
|
||
id: id,
|
||
nickname: nickname ?? this.nickname,
|
||
species: species ?? this.species,
|
||
locationId: locationId != null ? locationId() : this.locationId,
|
||
description: description ?? this.description,
|
||
careNotes: careNotes ?? this.careNotes,
|
||
photoUrl: photoUrl ?? this.photoUrl,
|
||
wateringIntervalDays: wateringIntervalDays ?? this.wateringIntervalDays,
|
||
fertilizingIntervalDays:
|
||
fertilizingIntervalDays ?? this.fertilizingIntervalDays,
|
||
lastWatered: lastWatered ?? this.lastWatered,
|
||
lastFertilized: lastFertilized ?? this.lastFertilized,
|
||
lastWateredBy: lastWateredBy ?? this.lastWateredBy,
|
||
lastFertilizedBy: lastFertilizedBy ?? this.lastFertilizedBy,
|
||
);
|
||
}
|
||
}
|