Saltar al contenido principal

Database schema

PocketBase collections for plantitas.

Collections

admin_groups

FieldTypeRequiredNotes
nametextyesunique
descriptiontextno

Rules: Users see only their own group; admins see all. Only admins can create/update/delete.

users (auth collection — extended)

FieldTypeRequiredNotes
usernametextyesbuilt-in
emailemailnobuilt-in
passwordpasswordyesbuilt-in
first_nametextno
last_nametextno
phonetextnoguardado en E.164 (+5492236193597)
is_adminboolnotrue grants backoffice access
group_idrelation → admin_groupsnose vincula después de crear la cuenta; cascade delete

Rules: Users see only themselves; admins see all. Users can update own record.

places

FieldTypeRequiredNotes
nametextyes
descriptiontextno
addresstextyesdisplay_name de Nominatim
latitude / longitudenumbernogeocodificado con Nominatim
typeselectnohouse, hotel, shop, warehouse, event_venue
referent_nametextnopersona de contacto del lugar
opening_daysselect (multi)nomon..sun
opening_from / opening_totextnohora HH:MM
climatejsonnoperfil climático de Open-Meteo (promedios 5 años)
group_idrelation → admin_groupsyescascade delete

Rules: Users see only places in their group; admins see all. Only admins can create/update/delete.

sub_places

FieldTypeRequiredNotes
nametextyes
descriptiontextno
place_idrelation → placesyescascade delete

Rules: Users see only sub-places belonging to their group (traversed via place_id.group_id); admins see all. Only admins can create/update/delete.

plant_types

FieldTypeRequiredNotes
nametextyes
descriptiontextno
imagefilenosingle image, max 5MB, jpg/png/webp

Rules: Public read (no auth required). Only admins can create/update/delete.

plants

FieldTypeRequiredNotes
codenumbernosequential code, displayed as PLT-XXXXX in UI (auto-generation pending, generate client-side)
plant_type_idrelation → plant_typesyes
place_idrelation → placesyescurrent location
created_at_place_idrelation → placesnooriginal creation location, set once

Rules: Users see only plants in their group (via place_id.group_id); admins see all. Only admins can create/update/delete.

transfers

Historial de vida de cada planta: movimientos registrados solo por administradores. La ubicación física actual de la planta es plants.place_id, que se actualiza al registrar cada movimiento (client-side, hooks de PB deshabilitados).

FieldTypeRequiredNotes
plant_idrelation → plantsyescascade delete
transfer_typeselectyesacquire, transfer, loan, exchange
origin_place_idrelation → placesnonull en acquire (ingreso al inventario)
destination_place_idrelation → placesyes
origin_group_idrelation → admin_groupsnodenormalizado para historial; null en acquire
destination_group_idrelation → admin_groupsyesdenormalizado para historial
transferred_byrelation → usersyesquién ejecutó el movimiento
descriptiontextno
expected_return_datedatenosolo loan
returned_atdatenofecha de devolución del loan
statusselectnoactive, returned (solo loan; overdue derivable en UI)
exchange_pair_idtextnouuid compartido por las 2 piernas de un exchange

Reglas de consistencia:

  • acquire → origen null; el alta setea plants.created_at_place_id una sola vez.
  • loanexpected_return_date requerido, status: active; la devolución es un nuevo transfer de vuelta + returned_at en el préstamo.
  • exchange → siempre en pares con el mismo exchange_pair_id (planta A: X→Y, planta B: Y→X).

Rules: solo admin.

plant_identifiers

FieldTypeRequiredNotes
codetextyesunique, QR code value
plant_idrelation → plantsyesspecific plant, cascade delete
plant_type_idrelation → plant_typesyesdenormalized for public access
is_activeboolno

Rules: Public read. Only admins can create/update/delete.

Cascade delete chain

admin_groups ──cascade──→ places ──cascade──→ sub_places
└──cascade──→ users
plants ──cascade──→ transfers

Deleting a plant removes its transfers. A place does NOT cascade to its plants — plants can be relocated before the place is deleted.

Access rules (PocketBase filters)

CollectionRule
admin_groups@request.auth.group_id = id || @request.auth.is_admin = true
users@request.auth.is_admin = true || @request.auth.id = id
places@request.auth.group_id = group_id || @request.auth.is_admin = true
sub_places@request.auth.group_id = place_id.group_id || @request.auth.is_admin = true
plant_types"" (public)
plants@request.auth.group_id = place_id.group_id || @request.auth.is_admin = true
transfers@request.auth.is_admin = true
plant_identifiers"" (public)