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