backend/model/
dto.rs

1//! DTOs of `PermaplanT`.
2#![allow(clippy::module_name_repetitions)] // There needs to be a difference between DTOs and entities otherwise imports will be messy.
3
4use chrono::{NaiveDate, NaiveDateTime};
5use postgis_diesel::types::{Point, Polygon};
6use serde::{Deserialize, Serialize};
7use typeshare::typeshare;
8use utoipa::{IntoParams, ToSchema};
9use uuid::Uuid;
10
11use self::layers::LayerDto;
12
13use super::r#enum::{
14    experience::Experience, include_archived_seeds::IncludeArchivedSeeds, life_cycle::LifeCycle,
15    membership::Membership, privacy_option::PrivacyOption, quality::Quality, quantity::Quantity,
16    salutation::Salutation, spatial_relation_type::SpatialRelationType,
17};
18
19pub mod actions;
20pub mod application_settings_impl;
21pub mod areas;
22pub mod areas_impl;
23pub mod base_layer_images;
24pub mod base_layer_images_impl;
25pub mod blossoms_impl;
26pub mod coordinates_impl;
27pub mod core;
28pub mod drawings;
29pub mod drawings_impl;
30pub mod guided_tours_impl;
31pub mod layer_impl;
32pub mod layers;
33pub mod map_collaborator_impl;
34pub mod map_impl;
35pub mod new_map_collaborator_impl;
36pub mod new_map_impl;
37pub mod new_seed_impl;
38pub mod page_impl;
39pub mod plantings;
40pub mod plantings_impl;
41pub mod plants_impl;
42pub mod seed_impl;
43pub mod timeline;
44pub mod update_map_geometry_impl;
45pub mod update_map_impl;
46pub mod users_impl;
47
48/// Contains configuration the frontend needs to run.
49#[typeshare]
50#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
51pub struct ConfigDto {
52    /// The base URL of the authorization server
53    pub issuer_uri: String,
54    /// The `client_id` the frontend should use to log in
55    pub client_id: String,
56    /// The version must be an exact match between frontend and backend.
57    pub version: String,
58}
59
60/// Represents seeds of a user.
61#[typeshare]
62#[derive(Serialize, Deserialize, ToSchema)]
63pub struct SeedDto {
64    /// The record id of the seed.
65    pub id: i32,
66    /// An additional name for the seed.
67    pub name: String,
68    /// The id of the plant this seed belongs to.
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub plant_id: Option<i32>,
71    /// When the seeds were harvested.
72    pub harvest_year: i16,
73    /// How many seeds there are.
74    pub quantity: Quantity,
75    /// When the seeds should be used by.
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub use_by: Option<NaiveDate>,
78    /// Where the seeds came from.
79    #[serde(skip_serializing_if = "Option::is_none")]
80    pub origin: Option<String>,
81    /// What the seeds taste like.
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub taste: Option<String>,
84    /// The yield of the seeds.
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub yield_: Option<String>,
87    /// How many generations the seeds have been grown.
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub generation: Option<i16>,
90    /// The quality of the seeds.
91    #[serde(skip_serializing_if = "Option::is_none")]
92    pub quality: Option<Quality>,
93    /// How much the seeds cost.
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub price: Option<i16>,
96    /// Notes about the seeds.
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub notes: Option<String>,
99    /// The id of the creator of the seed.
100    pub created_by: Uuid,
101    /// Timestamp indicating when the seed was archived.
102    /// Empty if the seed was not archived.
103    #[serde(skip_serializing_if = "Option::is_none")]
104    pub archived_at: Option<String>,
105}
106
107#[allow(clippy::missing_docs_in_private_items)] // TODO: See #97.
108#[typeshare]
109#[derive(Serialize, Deserialize, ToSchema)]
110pub struct NewSeedDto {
111    pub name: String,
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub plant_id: Option<i32>,
114    pub harvest_year: i16,
115    pub quantity: Quantity,
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub use_by: Option<NaiveDate>,
118    #[serde(skip_serializing_if = "Option::is_none")]
119    pub origin: Option<String>,
120    #[serde(skip_serializing_if = "Option::is_none")]
121    pub taste: Option<String>,
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub yield_: Option<String>,
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub generation: Option<i16>,
126    #[serde(skip_serializing_if = "Option::is_none")]
127    pub quality: Option<Quality>,
128    #[serde(skip_serializing_if = "Option::is_none")]
129    pub price: Option<i16>,
130    #[serde(skip_serializing_if = "Option::is_none")]
131    pub notes: Option<String>,
132}
133
134/// Data that is required when archiving a seed.
135#[typeshare]
136#[derive(Serialize, Deserialize, ToSchema)]
137pub struct ArchiveSeedDto {
138    /// Whether the seed should be archived.
139    pub archived: bool,
140}
141
142/// The essential identifying information of a plant.
143#[typeshare]
144#[derive(Debug, Serialize, PartialEq, Eq, Deserialize, ToSchema)]
145pub struct PlantsSummaryDto {
146    /// The plants database id.
147    pub id: i32,
148    /// Biological name of this plant (E.g. "Triticum aestivum", "Prunus cerasus")
149    pub unique_name: String,
150    /// A list of common english names (E.g. "Bread wheat", "Sour cherry")
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub common_name_en: Option<Vec<Option<String>>>,
153    /// A list of common german names (E.g. "Brotweizen", "Sauerkirsche")
154    #[serde(skip_serializing_if = "Option::is_none")]
155    pub common_name_de: Option<Vec<Option<String>>>,
156    /// How far a plant spreads (The 'width' of a plant) in cm
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub spread: Option<i32>,
159    /// Indicates life span of the plant.
160    pub life_cycle: Vec<LifeCycle>,
161    #[serde(skip_serializing_if = "Option::is_none")]
162    pub functions: Option<String>,
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub edible: Option<bool>,
165    pub edible_parts: Vec<Option<String>>,
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub warning: Option<String>,
168    pub sowing_outdoors: Vec<Option<i16>>,
169    pub harvest_time: Vec<Option<i16>>,
170}
171
172/// Query parameters for searching plants.
173#[typeshare]
174#[derive(Debug, Deserialize, IntoParams)]
175pub struct PlantsSearchParameters {
176    /// The system will check if this string occurs in the plants common name or unique name.
177    #[serde(skip_serializing_if = "Option::is_none")]
178    pub name: Option<String>,
179}
180
181/// Query parameters for searching spatial plant relations.
182#[typeshare]
183#[derive(Debug, Deserialize, IntoParams)]
184pub struct RelationSearchParameters {
185    /// The id of the plant to find relations for.
186    pub plant_id: i32,
187}
188
189/// Use to return spatial relations for the plant.
190#[typeshare]
191#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
192pub struct RelationsDto {
193    /// The id of the plant in the relation.
194    pub id: i32,
195    /// The type of relation.
196    pub relations: Vec<RelationDto>,
197}
198
199/// Use to return a spatial relation.
200#[typeshare]
201#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
202pub struct RelationDto {
203    /// The id of the plant in the relation.
204    pub id: i32,
205    /// The type of relation.
206    pub relation: SpatialRelationType,
207}
208
209/// Query parameters for searching seeds.
210#[typeshare]
211#[derive(Debug, Deserialize, IntoParams)]
212pub struct SeedSearchParameters {
213    /// Name of the seed to search for.
214    #[serde(skip_serializing_if = "Option::is_none")]
215    pub name: Option<String>,
216    /// The exact harvest year of the seed.
217    #[serde(skip_serializing_if = "Option::is_none")]
218    pub harvest_year: Option<i16>,
219    /// Whether archived, not archived or both kinds of seeds should be included.
220    /// If no value is provided, a default value of `NotArchived` is assumed.
221    #[serde(skip_serializing_if = "Option::is_none")]
222    pub archived: Option<IncludeArchivedSeeds>,
223}
224
225/// Query parameters paginating list endpoints.
226#[typeshare]
227#[derive(Debug, Deserialize, IntoParams)]
228pub struct PageParameters {
229    /// Number of results in per page.
230    #[serde(skip_serializing_if = "Option::is_none")]
231    pub per_page: Option<i32>,
232    /// Page number to be returned.
233    /// Note: pages start at one.
234    #[serde(skip_serializing_if = "Option::is_none")]
235    pub page: Option<i32>,
236}
237
238/// A page of results returned from a list endpoint.
239#[typeshare]
240#[derive(Debug, Serialize, PartialEq, Eq, Deserialize, ToSchema)]
241#[aliases(
242    PagePlantsSummaryDto = Page<PlantsSummaryDto>,
243    PageSeedDto = Page<SeedDto>,
244    PageMapDto = Page<MapDto>,
245    PageLayerDto = Page<LayerDto>
246)]
247pub struct Page<T> {
248    /// Resulting records.
249    pub results: Vec<T>,
250    /// Current page number.
251    pub page: i32,
252    /// Results per page.
253    pub per_page: i32,
254    /// Number of pages in total.
255    pub total_pages: i32,
256}
257
258/// The whole information of a map.
259#[typeshare]
260#[derive(Serialize, Deserialize, ToSchema)]
261pub struct MapDto {
262    /// The id of the map.
263    pub id: i32,
264    /// The name of the map.
265    pub name: String,
266    /// When the map was created.
267    pub created_at: NaiveDateTime,
268    /// When a map was last modified, e.g by modifying plantings.
269    pub modified_at: NaiveDateTime,
270    /// The id of the creator of the map.
271    pub created_by: Uuid,
272    /// By whom the map was last modified.
273    pub modified_by: Uuid,
274    /// The date the map is supposed to be deleted.
275    #[serde(skip_serializing_if = "Option::is_none")]
276    pub deletion_date: Option<NaiveDate>,
277    /// The date the last time the map view was opened by any user.
278    #[serde(skip_serializing_if = "Option::is_none")]
279    pub last_visit: Option<NaiveDate>,
280    /// A flag indicating if this map is marked for deletion.
281    pub is_inactive: bool,
282    /// The zoom factor of the map.
283    pub zoom_factor: i16,
284    /// The amount of honors the map received.
285    pub honors: i16,
286    /// The amount of visits the map had.
287    pub visits: i16,
288    /// The amount of plants harvested on the map.
289    pub harvested: i16,
290    /// An enum indicating if this map is private or not.
291    pub privacy: PrivacyOption,
292    /// The description of the map.
293    #[serde(skip_serializing_if = "Option::is_none")]
294    pub description: Option<String>,
295    /// The location of the map as a latitude/longitude point.
296    #[serde(skip_serializing_if = "Option::is_none")]
297    pub location: Option<Coordinates>,
298    /// The geometry of the map.
299    ///
300    /// E.g. `{"rings": [[{"x": 0.0,"y": 0.0},{"x": 1000.0,"y": 0.0},{"x": 1000.0,"y": 1000.0},{"x": 0.0,"y": 1000.0},{"x": 0.0,"y": 0.0}]],"srid": 4326}`
301    #[typeshare(serialized_as = "object")]
302    #[schema(value_type = Object)]
303    pub geometry: Polygon<Point>,
304}
305
306/// The information of a map necessary for its creation.
307#[typeshare]
308#[derive(Serialize, Deserialize, ToSchema)]
309pub struct NewMapDto {
310    /// The name of the map.
311    pub name: String,
312    /// The date the map is supposed to be deleted.
313    #[serde(skip_serializing_if = "Option::is_none")]
314    pub deletion_date: Option<NaiveDate>,
315    /// The date the last time the map view was opened by any user.
316    #[serde(skip_serializing_if = "Option::is_none")]
317    pub last_visit: Option<NaiveDate>,
318    /// A flag indicating if this map is marked for deletion.
319    pub is_inactive: bool,
320    /// The zoom factor of the map.
321    pub zoom_factor: i16,
322    /// The amount of honors the map received.
323    pub honors: i16,
324    /// The amount of visits the map had.
325    pub visits: i16,
326    /// The amount of plants harvested on the map.
327    pub harvested: i16,
328    /// An enum indicating if this map is private or not.
329    pub privacy: PrivacyOption,
330    /// The description of the map.
331    #[serde(skip_serializing_if = "Option::is_none")]
332    pub description: Option<String>,
333    /// The location of the map as a latitude/longitude point.
334    #[serde(skip_serializing_if = "Option::is_none")]
335    pub location: Option<Coordinates>,
336    /// The geometry of the map.
337    ///
338    /// E.g. `{"rings": [[{"x": 0.0,"y": 0.0},{"x": 1000.0,"y": 0.0},{"x": 1000.0,"y": 1000.0},{"x": 0.0,"y": 1000.0},{"x": 0.0,"y": 0.0}]],"srid": 4326}`
339    #[typeshare(serialized_as = "object")]
340    #[schema(value_type = Object)]
341    pub geometry: Polygon<Point>,
342}
343
344/// The information for updating a map.
345#[typeshare]
346#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
347pub struct UpdateMapDto {
348    /// The name of the map.
349    #[serde(skip_serializing_if = "Option::is_none")]
350    pub name: Option<String>,
351    /// An enum indicating if this map is private or not.
352    #[serde(skip_serializing_if = "Option::is_none")]
353    pub privacy: Option<PrivacyOption>,
354    /// The description of the map.
355    #[serde(skip_serializing_if = "Option::is_none")]
356    pub description: Option<String>,
357    /// The location of the map as a latitude/longitude point.
358    #[serde(skip_serializing_if = "Option::is_none")]
359    pub location: Option<Coordinates>,
360}
361
362/// Data for updating a maps geometry.
363#[typeshare]
364#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
365pub struct UpdateMapGeometryDto {
366    /// The geometry of the map.
367    ///
368    /// E.g. `{"rings": [[{"x": 0.0,"y": 0.0},{"x": 1000.0,"y": 0.0},{"x": 1000.0,"y": 1000.0},{"x": 0.0,"y": 1000.0},{"x": 0.0,"y": 0.0}]],"srid": 4326}`
369    #[typeshare(serialized_as = "object")]
370    #[schema(value_type = Object)]
371    pub geometry: Polygon<Point>,
372}
373
374/// Query parameters for searching maps.
375#[typeshare]
376#[derive(Debug, Deserialize, IntoParams)]
377pub struct MapSearchParameters {
378    /// Name of the map to search for.
379    #[serde(skip_serializing_if = "Option::is_none")]
380    pub name: Option<String>,
381    /// Whether or not the map is active.
382    #[serde(skip_serializing_if = "Option::is_none")]
383    pub is_inactive: Option<bool>,
384    /// The creator of the map.
385    #[serde(skip_serializing_if = "Option::is_none")]
386    pub created_by: Option<Uuid>,
387    /// The selected privacy of the map.
388    #[serde(skip_serializing_if = "Option::is_none")]
389    pub privacy: Option<PrivacyOption>,
390}
391
392/// Support struct for transmitting latitude/longitude coordinates.
393#[typeshare]
394#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
395pub struct Coordinates {
396    /// Latitude of the point.
397    pub latitude: f64,
398    /// Longitude of the point.
399    pub longitude: f64,
400}
401
402/// Query parameters for connecting to a map.
403#[typeshare]
404#[derive(Debug, Deserialize, IntoParams)]
405pub struct ConnectToMapQueryParams {
406    /// The id of the map to connect to.
407    pub map_id: i32,
408    /// The id of the user connecting to the map.
409    pub user_id: String,
410}
411
412/// Query parameters to configure the generation of the heatmap.
413#[typeshare]
414#[derive(Debug, Deserialize, IntoParams)]
415pub struct HeatMapQueryParams {
416    /// The id of the plant layer the planting will be planted on.
417    pub plant_layer_id: Uuid,
418    /// The id of the shade layer the planting will be planted on.
419    pub shade_layer_id: Uuid,
420    /// The id of the hydrology layer the planting will be planted on.
421    pub hydrology_layer_id: Uuid,
422    /// The id of the soil layer the planting will be planted on.
423    pub soil_layer_id: Uuid,
424    /// The id of the plant you want to plant.
425    pub plant_id: i32,
426    /// The date at which to generate the heatmap.
427    /// Will be set to the current date if `None`.
428    #[serde(skip_serializing_if = "Option::is_none")]
429    pub date: Option<NaiveDate>,
430}
431
432#[typeshare]
433#[derive(Serialize, Deserialize, ToSchema)]
434/// All of the application managed user data.
435pub struct UsersDto {
436    /// The preferred salutation of the user.
437    pub salutation: Salutation,
438    /// The title(s) of the user.
439    #[serde(skip_serializing_if = "Option::is_none")]
440    pub title: Option<String>,
441    /// The current country of the user.
442    pub country: String,
443    /// The phone number of the user.
444    #[serde(skip_serializing_if = "Option::is_none")]
445    pub phone: Option<String>,
446    /// The website of the user.
447    #[serde(skip_serializing_if = "Option::is_none")]
448    pub website: Option<String>,
449    /// The organization the user belongs to.
450    #[serde(skip_serializing_if = "Option::is_none")]
451    pub organization: Option<String>,
452    /// The experience level in permaculture of the user.
453    #[serde(skip_serializing_if = "Option::is_none")]
454    pub experience: Option<Experience>,
455    /// The membership type of the user.
456    #[serde(skip_serializing_if = "Option::is_none")]
457    pub membership: Option<Membership>,
458    /// A collection of years in which the user was a member.
459    #[serde(skip_serializing_if = "Option::is_none")]
460    pub member_years: Option<Vec<Option<i32>>>,
461    /// The date since when the user is a member.
462    #[serde(skip_serializing_if = "Option::is_none")]
463    pub member_since: Option<NaiveDate>,
464    /// The amount of permacoins the user earned in each year as a member.
465    #[serde(skip_serializing_if = "Option::is_none")]
466    pub permacoins: Option<Vec<Option<i32>>>,
467}
468
469#[typeshare]
470#[derive(Serialize, Deserialize, ToSchema)]
471/// Completion status of all Guided Tours.
472pub struct GuidedToursDto {
473    /// Whether or not the Map Editor Guided Tour was completed.
474    pub editor_tour_completed: bool,
475}
476
477#[typeshare]
478#[derive(Serialize, Deserialize, ToSchema)]
479/// The information for updating an users Guided Tour status.
480pub struct UpdateGuidedToursDto {
481    /// Whether or not the Map Editor Guided Tour was completed.
482    #[serde(skip_serializing_if = "Option::is_none")]
483    pub editor_tour_completed: Option<bool>,
484}
485
486#[typeshare]
487#[derive(Serialize, Deserialize, ToSchema)]
488/// Information on a specific Blossom gained by a user.
489pub struct GainedBlossomsDto {
490    /// The title of the Blossom.
491    pub blossom: String,
492    /// The number of times this Blossom was gained by this user.
493    pub times_gained: i32,
494    /// The date on which the user gained this Blossom.
495    pub gained_date: NaiveDate,
496}
497
498/// Application setting
499#[typeshare]
500#[derive(Serialize, Deserialize, ToSchema)]
501pub struct ApplicationSettingDto {
502    /// The id of the setting
503    pub id: i32,
504    /// The unique key of the setting
505    pub key: String,
506    /// The value of the setting
507    pub value: String,
508}
509
510#[typeshare]
511#[derive(Debug, Serialize, ToSchema)]
512#[serde(rename_all = "camelCase")]
513/// Information on user collaborating on a map.
514pub struct MapCollaboratorDto {
515    /// The id of the map.
516    pub map_id: i32,
517    /// The id of the collaborator.
518    pub user_id: Uuid,
519    /// The user name of the collaborator.
520    pub username: String,
521}
522
523#[typeshare]
524#[derive(Debug, Deserialize, ToSchema)]
525#[serde(rename_all = "camelCase")]
526/// The information of a map collaborator necessary for its creation.
527pub struct NewMapCollaboratorDto {
528    /// The id of the collaborator.
529    pub user_id: Uuid,
530}
531
532#[typeshare]
533#[derive(Debug, Serialize, Deserialize, ToSchema)]
534#[serde(rename_all = "camelCase")]
535pub struct DeleteMapCollaboratorDto {
536    /// The id of the collaborator.
537    pub user_id: Uuid,
538}
539
540#[typeshare]
541#[derive(Debug, Deserialize, IntoParams)]
542#[serde(rename_all = "camelCase")]
543/// Query params for searching map collaborators.
544pub struct MapCollaboratorSearchParameters {
545    /// The id of the map.
546    pub map_id: i32,
547}
548
549#[typeshare]
550#[derive(Debug, Deserialize, IntoParams)]
551#[serde(rename_all = "camelCase")]
552/// Query params for searching users.
553pub struct UserSearchParameters {
554    /// The name of the user to search for.
555    pub username: String,
556}