GeoNature-citizen

GeoNature-citizen

Citizen science portal of the GeoNature suite for participatory biodiversity observation reporting, with 9 PRs (4 merged) and 34 commits over 2024–2025. Contributions focus on observation validation UX, taxonomic autocomplete, and Angular component upgrades.

🎯 Context and goals

  • Evolve production-grade naturalist applications across critical flows: import, synthesis, monitoring, taxonomy, and user management.
  • Stabilize backend/frontend interfaces through stronger API contracts, filtering/pagination, dynamic forms, and more consistent error handling.
  • Reduce manual business-side corrections by improving data model consistency, admin feedback, and UI flows.

🧩 Design

  • #project-citizen: Merged PRs: #430 reworked TaxHub retrieval to support large lists, reshape taxa/media payloads, and adapt the observation form to autocomplete and automatic preselection; #438 added site count to the home statistics endpoint and propagated the related translations; #436 completed the i18n layer, especially German translations, across authentication, observation, site, and configuration screens; #435 fixed backoffice redirection through Apache configuration. Open PRs: #466 adds an i18n proxy for development mode in webpack/server; #465 introduces a language switcher and frontend/server persistence service; #393 refactors observation and site details to safely render descriptions and nested JSON structures.

💻 Development

  • #project-citizen: #430 refactored TaxHub taxon adaptation so the form could consume a normalized payload with taxref, media, and attributes. Source: PR #430.

    • #project-citizen: #430 adapted the observation form so it can load the program taxonomy, distinguish between short and long lists, and auto-select the only available taxon. Source: PR #430.
      this.surveySpecies$ = this.programService
          .getProgramTaxonomyList(this.taxonomyListID)
          .pipe(
              tap((species) => {
                  this.taxa = species;
              }),
              switchMap((species) =>
                  this.programService.getAllProgramTaxonomyList().pipe(
                      map((listsTaxonomy) => {
                          this.taxaCount = listsTaxonomy
                              .filter((lt) => lt.id_liste === this.taxonomyListID)
                              .map((lt) => lt.nb_taxons)[0];
      
                          if (this.taxaCount >= this.taxonAutocompleteInputThreshold) {
                              this.inputAutoCompleteSetup();
                          } else if (this.taxaCount === 1) {
                              this.onTaxonSelected(species[0]);
                          }
                          return species;
                      })
                  )
              ),
              share()
          );
      

🏗️ Infrastructure and deployment

  • #project-citizen: #466 adds a translation proxy for local development; #465 adds a reusable language switcher in the topbar/server stack.

📈 Results

  • PR count: 7
  • Commit count: 34
  • Issue count: 3
  • Period: November 20, 2024 to June 17, 2025
🌐 View the project

Tech Stack

Frontend
Angular
RxJS
Backend
Flask
Python
DevOps
GitHub Actions
Bases de donnees (SGBD & SQL)
PostgreSQL