Aller au contenu

Structure Git & Configuration Projet

Guide complet pour configurer un projet satellite DYNORS de A à Z.


Structure du repository

dynors-projects/
└── clients/
    └── mon-projet/
        ├── .git/
        ├── .gitignore
        ├── README.md
        ├── .gitlab-ci.yml          # Pipeline CI/CD (voir environnements-ci-cd.md)
        ├── sirrat.config.yml       # Config SIRRAT
        ├── docker-compose.*.yml    # Un par environnement
        ├── .env.example            # Template (commité)
        ├── .env.*                  # Valeurs réelles (gitignorés)
        ├── backend/
        │   ├── build.gradle.kts
        │   ├── gradle.properties
        │   ├── Dockerfile
        │   └── src/main/resources/
        │       ├── application.yml
        │       ├── application-local.yml
        │       ├── application-dev.yml
        │       ├── application-rmoa-dynors.yml
        │       ├── application-rmoa-client.yml
        │       └── application-prod.yml
        ├── frontend/
        │   ├── package.json
        │   ├── Dockerfile
        │   └── src/
        ├── scripts/
        │   ├── deploy-*.sh
        │   ├── backup-prod.sh
        │   └── rollback.sh
        └── docs/
            ├── architecture.md
            └── pv-recette-template.md

build.gradle.kts — dépendances DYNORS

repositories {
    maven {
        url = uri("https://gitlab.com/api/v4/projects/75907047/packages/maven")
        credentials(HttpHeaderCredentials::class) {
            name = "Private-Token"
            value = System.getenv("GITLAB_TOKEN") ?: findProperty("gitlabToken")?.toString() ?: ""
        }
        authentication { create<HttpHeaderAuthentication>("header") }
    }
}

dependencies {
    // BOM — gère les versions de tous les modules core
    implementation(platform("com.dynors:dynors-core-bom:1.0.2"))

    implementation("com.dynors:dynors-commons")          // SlyTransitFilter, InterAppCallService
    implementation("com.dynors:dynors-security")         // JWT, RBAC, TenantContext
    implementation("com.dynors:dynors-db")               // Multi-tenant DB
    implementation("com.dynors:dynors-interapp-client")  // Appels via SLY

    // Extensions (optionnel — versions explicites)
    // implementation("com.dynors:dynors-notify:1.0.0-SNAPSHOT")
    // implementation("com.dynors:dynors-invoicing-core:1.0.0-SNAPSHOT")
}

application.yml — configuration minimale

spring:
  application:
    name: mon-projet
  datasource:
    url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME}
    username: ${DB_USER}
    password: ${DB_PASSWORD}

dynors:
  interapp:
    source-app: mon-projet                    # code stable, minuscules
    gateway-url: ${SLY_BASE_URL:https://sly.dynors.com}
    return-base-url: ${SLY_BASE_URL:https://sly.dynors.com}/mon-projet
    sly-forward-secret: ${SLY_FORWARD_SECRET:}
    sly-signature-window-ms: 30000

management:
  endpoints:
    web:
      exposure:
        include: health,info

application-local.yml

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/monprojet_local
    username: dev
    password: dev123

dynors:
  interapp:
    gateway-url: http://localhost:8888   # SLY en local (docker-compose)
    sly-forward-secret:                  # vide en local — OK

logging:
  level:
    com.dynors: DEBUG

application-dev.yml

spring:
  datasource:
    url: jdbc:postgresql://${DB_HOST}:5432/${DB_NAME}

dynors:
  interapp:
    gateway-url: https://sly-dev.dynors.com
    sly-forward-secret: ${SLY_FORWARD_SECRET}

logging:
  level:
    com.dynors: DEBUG

application-prod.yml

spring:
  datasource:
    url: jdbc:postgresql://${DB_HOST}:5432/${DB_NAME}?ssl=true&sslmode=require

dynors:
  interapp:
    gateway-url: https://sly.dynors.com
    sly-forward-secret: ${SLY_FORWARD_SECRET}

logging:
  level:
    root: WARN
    com.dynors: INFO

Workflow Git complet (jour par jour)

# Jour 1–3 : développement local
git checkout -b feature/ma-feature
# ... coder ...
git commit -m "feat(module): description"
git push origin feature/ma-feature
# → Merge Request vers develop

# Jour 3–5 : merge et auto-deploy DEV
# MR approuvée → merge develop → pipeline auto → deploy DEV

# Jour 6 : créer release RMOA DYNORS
git checkout develop && git pull
git checkout -b release/v1.0.0-internal
git push origin release/v1.0.0-internal
# → pipeline GitLab → deploy RMOA DYNORS (manuel)

# Jour 7–11 : QA sur RMOA DYNORS
# Bugs → corriger sur release/v1.0.0-internal → re-deploy manuel

# Jour 12 : Porte #1 passée → release CLIENT
git checkout -b release/v1.0.0
git push origin release/v1.0.0
# → pipeline → deploy RMOA CLIENT (manuel)

# Jour 13–27 : validation client sur RMOA CLIENT

# Jour 28 : client signe PV dans SIRRAT

# Jour 29 : merge + tag + PROD
git checkout main && git merge release/v1.0.0
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin main --tags
# → pipeline tag → deploy PROD (manuel, après validation CTO)

Commandes Git essentielles (rappel)

# Branches
git branch -a                              # lister toutes les branches
git checkout -b feature/nom               # créer + switch
git push origin feature/nom              # pusher la branche
git push origin --delete feature/nom     # supprimer distante

# Tags
git tag -a v1.0.0 -m "Release v1.0.0"   # créer tag annoté
git push origin v1.0.0                   # pusher un tag
git push origin --tags                   # pusher tous les tags

# Synchronisation
git fetch origin                         # récupérer sans merger
git pull origin develop                  # pull + merge
git rebase develop                       # rebase (feature branch)

# Rollback
git reset --soft HEAD~1                  # annuler dernier commit (garder modifs)
git revert <sha>                         # annuler un commit (nouveau commit)
git stash && git stash pop               # mettre de côté / restaurer

sirrat.config.yml — référence complète

sirrat:
  version: "2.0"
  project:
    id: mon-projet-001                        # identifiant unique SIRRAT
    name: "Mon Projet"
    description: "Description courte"
    client: "Nom du client"
    scenario: on-premise                      # managed | on-premise | cloud-client | regie

  environments:
    local:
      enabled: true
      sirrat_integration: false

    dev:
      enabled: true
      url: https://dev-mon-projet.dynors.com
      sirrat_integration: true
      auto_deploy: true
      branch: develop
      notifications:
        slack: "#dev-mon-projet"
        email: "dev-team@dynors.com"

    rmoa-dynors:
      enabled: true
      url: https://rmoa-mon-projet.dynors.com
      sirrat_integration: true
      quality_gate: gate-1
      access: [qa-dynors, tech-lead]
      notifications:
        slack: "#qa-mon-projet"

    rmoa-client:
      enabled: true
      url: https://recette.mon-projet.client.sn
      sirrat_integration: true
      quality_gate: gate-2
      pv_recette:
        enabled: true
        signatories:
          - email: "moa@client.sn"
            role: "MOA Client"
          - email: "cto@dynors.com"
            role: "CTO DYNORS"
      notifications:
        slack: "#client-mon-projet"
        email: "moa@client.sn, pm@dynors.com"

    production:
      enabled: true
      url: https://mon-projet.client.sn
      sirrat_integration: true
      quality_gate: gate-3
      monitoring: [grafana, sentry]
      backup:
        enabled: true
        schedule: "0 2 * * *"
        retention_days: 30
      notifications:
        slack: "#prod-alerts"
        email: "oncall@dynors.com"

  quality_gates:
    gate-1:
      name: "Jugement des Tests"
      from: dev
      to: rmoa-dynors
      automatic_criteria:
        unit_tests: { threshold: 100, blocking: true }
        integration_tests: { threshold: 100, blocking: true }
        code_coverage: { threshold: 70, blocking: true }
        security_scan: { critical_max: 0, blocking: true }
      manual_criteria:
        functional_tests: { required: true, approvers: [qa-lead] }
      minimum_duration_days: 3

    gate-2:
      name: "Validation Interne"
      from: rmoa-dynors
      to: rmoa-client
      criteria:
        tech_lead_approval: { required: true }

    gate-3:
      name: "Sceau du CTO"
      from: rmoa-client
      to: production
      criteria:
        pv_recette: { signed: true, required: true }
        cto_approval: { required: true }
        backup: { recent: true, max_age_hours: 24 }

  karma:
    enabled: true

  integrations:
    gitlab:
      url: https://gitlab.com/dynors-projects/mon-projet
      token: ${GITLAB_TOKEN}
    slack:
      webhook: ${SLACK_WEBHOOK}
    sentry:
      dsn: ${SENTRY_DSN}