feat(graphql): expose more information on demarche descriptor

This commit is contained in:
Paul Chavard 2022-11-24 13:16:37 +01:00
parent ed1754e1fb
commit cdb3ce65cb
10 changed files with 181 additions and 249 deletions

View file

@ -50,7 +50,7 @@ class API::V2::StoredQuery
declarative
dateCreation
dateFermeture
publishedRevision @include(if: $includeRevision) {
activeRevision @include(if: $includeRevision) {
...RevisionFragment
}
groupeInstructeurs @include(if: $includeGroupeInstructeurs) {
@ -305,25 +305,47 @@ class API::V2::StoredQuery
datePublication
champDescriptors {
...ChampDescriptorFragment
champDescriptors {
...ChampDescriptorFragment
... on RepetitionChampDescriptor {
champDescriptors {
...ChampDescriptorFragment
}
}
}
annotationDescriptors {
...ChampDescriptorFragment
champDescriptors {
...ChampDescriptorFragment
... on RepetitionChampDescriptor {
champDescriptors {
...ChampDescriptorFragment
}
}
}
}
fragment ChampDescriptorFragment on ChampDescriptor {
__typename
id
type
label
description
required
options
... on DropDownListChampDescriptor {
options
otherOption
}
... on MultipleDropDownListChampDescriptor {
options
}
... on LinkedDropDownListChampDescriptor {
options
}
... on PieceJustificativeChampDescriptor {
fileTemplate {
...FileFragment
}
}
... on ExplicationChampDescriptor {
collapsibleExplanationEnabled
collapsibleExplanationText
}
}
fragment AvisFragment on Avis {

View file

@ -3,7 +3,7 @@
module Extensions
class Attachment < GraphQL::Schema::FieldExtension
attr_reader :attachment_assoc
attr_reader :attachment_assoc, :root
def apply
# Here we try to define the ActiveRecord association name:
@ -18,13 +18,14 @@ module Extensions
attachment = field.original_name.to_s.sub(/_url$/, "")
"#{attachment}_attachment"
end
@root = options&.dig(:root) || :object
end
# This method resolves (as it states) the field itself
# (it's the same as defining a method within a type)
def resolve(object:, **_rest)
Loaders::Association.for(
object.object.class,
object.public_send(root).class,
attachment_assoc => :blob
).load(object.object)
end

View file

@ -86,11 +86,6 @@ type AddressChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -146,11 +141,6 @@ type AnnuaireEducationChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -227,11 +217,6 @@ type CarteChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -279,11 +264,6 @@ interface ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -332,11 +312,6 @@ type CheckboxChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -397,11 +372,6 @@ type CiviliteChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -435,11 +405,6 @@ type CnafChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -497,11 +462,6 @@ type CommuneChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -609,11 +569,6 @@ type DateChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -665,11 +620,6 @@ type DatetimeChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -718,11 +668,6 @@ type DecimalNumberChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -1018,7 +963,7 @@ Ceci est une version abrégée du type `Demarche`, qui nexpose que les métad
Cela évite laccès récursif aux dossiers.
"""
type DemarcheDescriptor {
cadreJuridique: String
cadreJuridiqueUrl: String
"""
Date de la création.
@ -1049,30 +994,44 @@ type DemarcheDescriptor {
Pour une démarche déclarative, état cible des dossiers à valider automatiquement
"""
declarative: DossierDeclarativeState
deliberation: String
deliberation: File
demarcheUrl: String
"""
Description de la démarche.
"""
description: String!
dpoUrl: String
"""
Durée de conservation des dossiers en mois.
"""
dureeConservationDossiers: Int!
id: ID!
logo: File
notice: File
noticeUrl: String
"""
Numero de la démarche.
"""
number: Int!
opendata: Boolean!
revision: Revision!
service: Service
siteWebUrl: String
"""
État de la démarche.
"""
state: DemarcheState!
tags: [String!]!
"""
Titre de la démarche.
"""
title: String!
zones: [String!]!
}
enum DemarcheState {
@ -1123,11 +1082,6 @@ type DepartementChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -1161,11 +1115,6 @@ type DgfipChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -1541,11 +1490,6 @@ type DossierLinkChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -1989,11 +1933,6 @@ type DropDownListChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -2037,11 +1976,6 @@ type EmailChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -2122,11 +2056,6 @@ type ExplicationChampDescriptor implements ChampDescriptor {
collapsibleExplanationEnabled: Boolean
collapsibleExplanationText: String
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -2504,11 +2433,6 @@ type HeaderSectionChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -2552,11 +2476,6 @@ type IbanChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -2605,11 +2524,6 @@ type IntegerNumberChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -2659,11 +2573,6 @@ type LinkedDropDownListChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -2697,11 +2606,6 @@ type MesriChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -2759,11 +2663,6 @@ type MultipleDropDownListChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3005,11 +2904,6 @@ type NumberChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3119,11 +3013,6 @@ type PaysChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3184,11 +3073,6 @@ type PhoneChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3238,11 +3122,6 @@ type PieceJustificativeChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3281,11 +3160,6 @@ type PoleEmploiChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3374,11 +3248,6 @@ type RNAChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3432,11 +3301,6 @@ type RegionChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3486,11 +3350,6 @@ type RepetitionChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!]
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3575,11 +3434,6 @@ type SiretChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3628,11 +3482,6 @@ type TextChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3666,11 +3515,6 @@ type TextareaChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -3720,11 +3564,6 @@ type TitreIdentiteChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""
@ -4017,11 +3856,6 @@ type YesNoChampDescriptor implements ChampDescriptor {
"""
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
"""
Logique conditionnelle.
"""
condition: String
"""
Description du champ.
"""

View file

@ -14,7 +14,6 @@ module Types
field :label, String, "Libellé du champ.", null: false, method: :libelle
field :description, String, "Description du champ.", null: true
field :required, Boolean, "Est-ce que le champ est obligatoire ?", null: false, method: :mandatory?
field :condition, String, "Logique conditionnelle.", null: true
field :options, [String], "List des options dun champ avec selection.", null: true, deprecation_reason: 'Utilisez le champ `DropDownListChampDescriptor.options` à la place.'
field :champ_descriptors, [Types::ChampDescriptorType], "Description des champs dun bloc répétable.", null: true, deprecation_reason: 'Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.'
@ -97,10 +96,6 @@ module Types
end
end
def condition
Base64.urlsafe_encode64(type_de_champ.condition.to_json)
end
def champ_descriptors
if type_de_champ.block?
Loaders::Association.for(object.class, revision_types_de_champ: :type_de_champ).load(object)

View file

@ -25,11 +25,24 @@ Cela évite laccès récursif aux dossiers."
field :date_depublication, GraphQL::Types::ISO8601DateTime, "Date de la dépublication.", null: true
field :date_fermeture, GraphQL::Types::ISO8601DateTime, "Date de la fermeture.", null: true
field :duree_conservation_dossiers, Int, "Durée de conservation des dossiers en mois.", null: false
field :demarche_url, String, null: true
field :site_web_url, String, null: true
field :dpo_url, String, null: true
field :notice_url, String, null: true
field :cadre_juridique_url, String, null: true
field :opendata, Boolean, null: false
field :tags, [String], null: false
field :zones, [String], null: false
field :revision, Types::RevisionType, null: false
field :service, Types::ServiceType, null: true
field :cadre_juridique, String, null: true
field :deliberation, String, null: true
field :logo, Types::File, null: true, extensions: [{ Extensions::Attachment => { root: :procedure } }]
field :notice, Types::File, null: true, extensions: [{ Extensions::Attachment => { root: :procedure } }]
field :deliberation, Types::File, null: true, extensions: [{ Extensions::Attachment => { root: :procedure } }]
field :dossiers_count, Int, null: false, internal: true
@ -38,25 +51,51 @@ Cela évite laccès récursif aux dossiers."
end
def revision
object.is_a?(ProcedureRevision) ? object : object.active_revision
if object.is_a?(ProcedureRevision)
object
else
object.active_revision
end
end
def procedure
if object.is_a?(ProcedureRevision)
object.procedure
else
object
end
end
def dossiers_count
object.dossiers.count
end
def deliberation
Rails.application.routes.url_helpers.url_for(procedure.deliberation) if procedure.deliberation.attached?
procedure.dossiers.visible_by_administration.count
end
def state
procedure.aasm.current_state
end
def cadre_juridique
delegate :description, :opendata, :tags, to: :procedure
def demarche_url
procedure.lien_demarche
end
def dpo_url
procedure.lien_dpo
end
def notice_url
procedure.lien_notice
end
def cadre_juridique_url
procedure.cadre_juridique
end
def site_web_url
procedure.lien_site_web
end
def number
procedure.id
end
@ -65,10 +104,6 @@ Cela évite laccès récursif aux dossiers."
procedure.libelle
end
def description
procedure.description
end
def declarative
procedure.declarative_with_state
end
@ -93,15 +128,17 @@ Cela évite laccès récursif aux dossiers."
procedure.closed_at
end
def duree_conservation_dossiers
procedure.duree_conservation_dossiers_dans_ds
end
def zones
procedure.zones.map(&:current_label)
end
def self.authorized?(object, context)
procedure = object.is_a?(ProcedureRevision) ? object.procedure : object
procedure.opendata? || context.authorized_demarche?(procedure)
end
private
def procedure
revision.procedure
end
end
end

View file

@ -303,16 +303,18 @@ class SerializerService
}
fragment ChampDescriptorFragment on ChampDescriptor {
type
__typename
label
description
required
options
champDescriptors {
type
label
description
required
... on DropDownListChampDescriptor {
options
otherOption
}
... on MultipleDropDownListChampDescriptor {
options
}
... on LinkedDropDownListChampDescriptor {
options
}
}
@ -321,13 +323,28 @@ class SerializerService
number
title
description
tags
zones
datePublication
service { nom organisme typeOrganisme }
cadreJuridique
deliberation
demarcheUrl
dpoUrl
noticeUrl
siteWebUrl
cadreJuridiqueUrl
logo { ...FileFragment }
notice { ...FileFragment }
deliberation { ...FileFragment }
dossiersCount
revision {
champDescriptors { ...ChampDescriptorFragment }
champDescriptors {
...ChampDescriptorFragment
... on RepetitionChampDescriptor {
champDescriptors {
...ChampDescriptorFragment
}
}
}
}
}
GRAPHQL

View file

@ -67,7 +67,7 @@ describe API::V2::GraphqlController do
publishedRevision {
id
champDescriptors {
type
__typename
}
}
service {
@ -76,16 +76,26 @@ describe API::V2::GraphqlController do
organisme
}
champDescriptors {
__typename
id
type
label
description
required
champDescriptors {
id
type
... on RepetitionChampDescriptor {
champDescriptors {
__typename
id
}
}
... on DropDownListChampDescriptor {
options
}
... on MultipleDropDownListChampDescriptor {
options
}
... on LinkedDropDownListChampDescriptor {
options
}
options
}
dossiers {
nodes {
@ -157,9 +167,13 @@ describe API::V2::GraphqlController do
describe "query a demarche" do
let(:procedure) { create(:procedure, :published, :for_individual, :with_service, :with_all_champs, :with_all_annotations, administrateurs: [admin]) }
def format_type_champ(type_champ)
"#{type_champ.gsub('regions', 'region').gsub('departements', 'departement').gsub('communes', 'commune').camelcase}ChampDescriptor"
end
it "returns the demarche" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(demarche: {
expect(gql_data).to include(demarche: {
id: procedure.to_typed_id,
number: procedure.id,
title: procedure.libelle,
@ -174,15 +188,11 @@ describe API::V2::GraphqlController do
label: "défaut"
}
],
revisions: procedure.revisions.map { |revision| { id: revision.to_typed_id } },
revisions: procedure.revisions.map { { id: _1.to_typed_id } },
draftRevision: { id: procedure.draft_revision.to_typed_id },
publishedRevision: {
id: procedure.published_revision.to_typed_id,
champDescriptors: procedure.published_revision.types_de_champ_public.map do |tdc|
{
type: tdc.type_champ
}
end
champDescriptors: procedure.published_revision.types_de_champ_public.map { { __typename: format_type_champ(_1.type_champ) } }
},
service: {
nom: procedure.service.nom,
@ -193,15 +203,15 @@ describe API::V2::GraphqlController do
{
id: tdc.to_typed_id,
label: tdc.libelle,
type: tdc.type_champ,
__typename: format_type_champ(tdc.type_champ),
description: tdc.description,
required: tdc.mandatory?,
champDescriptors: tdc.repetition? ? procedure.active_revision.children_of(tdc.reload).map { |tdc| { id: tdc.to_typed_id, type: tdc.type_champ } } : nil,
champDescriptors: tdc.repetition? ? procedure.active_revision.children_of(tdc.reload).map { { id: _1.to_typed_id, __typename: format_type_champ(_1.type_champ) } } : nil,
options: tdc.drop_down_list? ? tdc.drop_down_list_options.reject(&:empty?) : nil
}
}.compact
end,
dossiers: {
nodes: dossiers.map { |dossier| { id: dossier.to_typed_id } }
nodes: dossiers.map { { id: _1.to_typed_id } }
}
})
end

View file

@ -79,6 +79,16 @@ describe API::V2::GraphqlController do
expect(gql_data[:demarche][:dossiers][:nodes].size).to eq(1)
}
end
context 'include Revision' do
let(:variables) { { demarcheNumber: procedure.id, includeRevision: true } }
it {
expect(gql_errors).to be_nil
expect(gql_data[:demarche][:id]).to eq(procedure.to_typed_id)
expect(gql_data[:demarche][:activeRevision]).not_to be_nil
}
end
end
context 'getGroupeInstructeur' do

View file

@ -5,9 +5,9 @@ FactoryBot.define do
labels { [{ designated_on: '1981-05-08', name: "Ministère de l'Education Populaire" }] }
end
after(:create) do |zone, evaluator|
after(:build) do |zone, evaluator|
evaluator.labels.each do |label|
zone.labels.create(designated_on: label[:designated_on], name: label[:name])
zone.labels.build(designated_on: label[:designated_on], name: label[:name])
end
end
end

View file

@ -1,6 +1,6 @@
describe DemarchesPubliquesExportService do
let(:procedure) { create(:procedure, :published, :with_service, :with_type_de_champ) }
let!(:dossier) { create(:dossier, procedure: procedure) }
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
let(:gzip_filename) { "demarches.json.gz" }
after { FileUtils.rm(gzip_filename) }
@ -16,19 +16,25 @@ describe DemarchesPubliquesExportService do
organisme: "organisme",
typeOrganisme: "association"
},
cadreJuridique: "un cadre juridique important",
cadreJuridiqueUrl: "un cadre juridique important",
demarcheUrl: nil,
dpoUrl: nil,
noticeUrl: nil,
siteWebUrl: "https://mon-site.gouv",
logo: nil,
notice: nil,
deliberation: nil,
datePublication: procedure.published_at.iso8601,
zones: ["Ministère de l'Education Populaire"],
tags: [],
dossiersCount: 1,
revision: {
champDescriptors: [
{
description: procedure.active_revision.types_de_champ_public.first.description,
label: procedure.active_revision.types_de_champ_public.first.libelle,
options: nil,
required: false,
type: "text",
champDescriptors: nil
__typename: "TextChampDescriptor"
}
]
}