diff --git a/404.html b/404.html index 4f5354e7..70dfa218 100644 --- a/404.html +++ b/404.html @@ -4,7 +4,7 @@ Page Not Found | TiBillet - + diff --git a/assets/js/927f7f94.572c57f2.js b/assets/js/927f7f94.572c57f2.js new file mode 100644 index 00000000..3e33db0b --- /dev/null +++ b/assets/js/927f7f94.572c57f2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation_v_2=self.webpackChunkdocumentation_v_2||[]).push([[1329],{6699:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>d,default:()=>a,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var s=t(6271),i=t(1621);const r={sidebar_position:1,slug:"development",title:"Development",keywords:["contribute","volunteer","open source","git","pull request","issue","help","code","development","programming","python","django","docker","poetry","testing","tdd"],tags:["contribute","open source","git","help","tdd","python","django","docker","poetry"],authors:"kaya"},d="Development",l={id:"contribute/dev",title:"Development",description:"So, you want to help with the development of TiBillet. Thank you! Open-source thrives thanks to people like you \ud83d\ude4f",source:"@site/docs/contribute/dev.md",sourceDirName:"contribute",slug:"/contribute/development",permalink:"/docs/contribute/development",draft:!1,unlisted:!1,editUrl:"https://github.com/TiBillet/documentation/tree/main/tibillet/docs/contribute/dev.md",tags:[{inline:!0,label:"contribute",permalink:"/docs/tags/contribute"},{inline:!0,label:"open source",permalink:"/docs/tags/open-source"},{inline:!0,label:"git",permalink:"/docs/tags/git"},{inline:!0,label:"help",permalink:"/docs/tags/help"},{inline:!0,label:"tdd",permalink:"/docs/tags/tdd"},{inline:!0,label:"python",permalink:"/docs/tags/python"},{inline:!0,label:"django",permalink:"/docs/tags/django"},{inline:!0,label:"docker",permalink:"/docs/tags/docker"},{inline:!0,label:"poetry",permalink:"/docs/tags/poetry"}],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1,slug:"development",title:"Development",keywords:["contribute","volunteer","open source","git","pull request","issue","help","code","development","programming","python","django","docker","poetry","testing","tdd"],tags:["contribute","open source","git","help","tdd","python","django","docker","poetry"],authors:"kaya"},sidebar:"tutorialSidebar",previous:{title:"Contribution guides",permalink:"/docs/category/contribution-guides"},next:{title:"API",permalink:"/docs/category/api"}},o={},c=[{value:"Understanding the workflow",id:"understanding-the-workflow",level:2},{value:"Tools and languages used",id:"tools-and-languages-used",level:2},{value:"Local install",id:"local-install",level:2},{value:"Traefik",id:"traefik",level:3},{value:"Key generation",id:"key-generation",level:3},{value:"Fedow, Lespass, LaBoutik",id:"fedow-lespass-laboutik",level:3},{value:"Fedow environment",id:"fedow-environment",level:4},{value:"Lespass environment",id:"lespass-environment",level:4},{value:"LaBoutik environment",id:"laboutik-environment",level:4},{value:"Tests setup",id:"tests-setup",level:3},{value:"Manual engine start",id:"manual-engine-start",level:3},{value:"Is it working?",id:"is-it-working",level:3},{value:"Lifecycle",id:"lifecycle",level:2},{value:"Updates",id:"updates",level:3},{value:"Testing",id:"testing",level:3},{value:"Backups",id:"backups",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"development",children:"Development"})}),"\n",(0,s.jsx)(n.p,{children:"So, you want to help with the development of TiBillet. Thank you! Open-source thrives thanks to people like you \ud83d\ude4f"}),"\n",(0,s.jsxs)(n.p,{children:["First, if you don't have a specific task in mind already, check out the open issues on the official ",(0,s.jsx)(n.a,{href:"https://github.com/TiBillet",children:"Github repositories"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"It's the easiest way to figure out what problem needs fixing or what feature is being requested."}),"\n",(0,s.jsxs)(n.admonition,{title:"Repositories",type:"note",children:[(0,s.jsx)(n.p,{children:"What you need is probably in the pinned repositories. If you are unsure of the role of Fedow, LaBoutik or Lespass, check out the basics on the three TiBillet engines."}),(0,s.jsxs)(n.p,{children:[(0,s.jsx)("mark",{children:"TODO: link to engines and their roles in the doc"})," (a very basic page in intro probably)"]})]}),"\n",(0,s.jsx)(n.h2,{id:"understanding-the-workflow",children:"Understanding the workflow"}),"\n",(0,s.jsxs)(n.p,{children:["When you work with ",(0,s.jsx)(n.em,{children:"Git forges"})," like Github, there are ways in which you can make your contributions easier to handle:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If you're not part of the core team, ",(0,s.jsx)(n.em,{children:"fork"})," the repository that interests you, work from there, and submit your changes through a ",(0,s.jsx)(n.em,{children:"pull request"}),"."]}),"\n",(0,s.jsx)(n.li,{children:"If you have an issue you want to work on, check that it doesn't already exists. If it does, join the discussion instead of doing your own thing!"}),"\n",(0,s.jsxs)(n.li,{children:["When you start working on an issue, ",(0,s.jsx)(n.strong,{children:"assign yourself"})," to let others know you're working on it."]}),"\n",(0,s.jsxs)(n.li,{children:["Last but not least: ",(0,s.jsx)(n.strong,{children:"don't create pull requests without running the tests"}),"! Happens to the best of us. Ideally, you should run them before committing, with the help of a ",(0,s.jsx)(n.em,{children:"git hook"})," for example."]}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{title:"Getting help",type:"note",children:(0,s.jsxs)(n.p,{children:["If you have any questions regarding Git, Github, or an aspect of development, join us on ",(0,s.jsx)(n.a,{href:"https://discord.gg/7FJvtYx",children:"Discord"})," or ",(0,s.jsx)(n.a,{href:"https://matrix.to/#/#tibillet:tiers-lieux.org",children:"Matrix"}),". These are mostly French-speaking spaces as the founders are from La Reunion, but we'll do our best to help (with a bit of ",(0,s.jsx)(n.em,{children:"un accent"})," \ud83c\udf77\ud83e\udd56)."]})}),"\n",(0,s.jsx)(n.h2,{id:"tools-and-languages-used",children:"Tools and languages used"}),"\n",(0,s.jsx)(n.p,{children:"TiBillet is:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://www.python.org/",children:"Python"})," software"]}),"\n",(0,s.jsxs)(n.li,{children:["developed with the help of the ",(0,s.jsx)(n.a,{href:"https://www.djangoproject.com/",children:"Django"})," framework"]}),"\n",(0,s.jsxs)(n.li,{children:["its dependencies are handled through ",(0,s.jsx)(n.a,{href:"https://python-poetry.org/",children:"Poetry"})]}),"\n",(0,s.jsxs)(n.li,{children:["it runs in ",(0,s.jsx)(n.a,{href:"https://www.docker.com/",children:"Docker"})," containers for production as well as development"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"If you don't feel at ease with the software stack, the best thing you can do is to go look for tutorials. Hopefully we'll compile a list of our own down here one of these days \ud83d\ude05"}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"In particular, basic knowledge of Git can help. It is relatively easy to make a complete mess of a project by not grasping the way versioning works. There are safeguards, but you might struggle a lot more than necessary! I remember how that feels \ud83d\ude11"})}),"\n",(0,s.jsx)(n.h2,{id:"local-install",children:"Local install"}),"\n",(0,s.jsx)(n.p,{children:"In order to develop and test things out, you're gonna need a (mostly) functional instance of TiBillet on your computer."}),"\n",(0,s.jsx)(n.p,{children:"Let's make sure you have the required tools at hand. You need:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Docker CLI and the ",(0,s.jsx)(n.code,{children:"docker-compose"})," extension"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"git"})}),"\n",(0,s.jsx)(n.li,{children:"a Github account with a registered SSH key for forge access"}),"\n",(0,s.jsx)(n.li,{children:"an IDE (there are open-source gift licenses of PyCharm available on request, but a regular IDE like VSCodium works reasonably well - that's what I'm using \ud83d\ude09)"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"We're gonna start by creating a folder that will hold the different repositories required, in your local repository or work folder if you have one for example. It will look like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"tibillet-dev\n\u251c\u2500\u2500 Fedow\n\u251c\u2500\u2500 LaBoutik\n\u251c\u2500\u2500 Lespass\n\u251c\u2500\u2500 Test-Driven-Development\n\u2514\u2500\u2500 Traefik\n"})}),"\n",(0,s.jsx)(n.h3,{id:"traefik",children:"Traefik"}),"\n",(0,s.jsx)(n.p,{children:"We are going to need an application proxy. TiBillet provides a basic configuration for a containerized Traefik + LetsEncrypt, so let's roll with it:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Traefik-reverse-proxy.git Traefik\n"})}),"\n",(0,s.jsx)(n.p,{children:"To start it:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cd Traefik\ndocker compose up -d\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Navigating to ",(0,s.jsx)(n.code,{children:"https://localhost"})," should now prompt you with a security warning about self-signed certificates (it's fine in this instance) and a ",(0,s.jsx)(n.code,{children:"404 page not found"}),". Good!"]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Remember to ",(0,s.jsx)(n.code,{children:"compose up"})," Traefik every time you start a dev session on this project."]})}),"\n",(0,s.jsx)(n.h3,{id:"key-generation",children:"Key generation"}),"\n",(0,s.jsx)("mark",{children:"TODO: Complicated and heavy for no reason."}),"\n",(0,s.jsx)(n.p,{children:"The legacy way of generating the necessary configuration keys is to pull the production Fedow docker image and run poetry inside of it."}),"\n",(0,s.jsx)(n.p,{children:"For each engine, we will need:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["one or two Fernet keys (for the ",(0,s.jsx)(n.code,{children:"FERNET_KEY"})," field and possibly, passwords)"]}),"\n",(0,s.jsxs)(n.li,{children:["a Django secret key (for the ",(0,s.jsx)(n.code,{children:"SECRET_KEY"})," field)"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"You can generate 30 of each in your terminal by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker run --rm tibillet/fedow poetry run python3 -c \"from cryptography.fernet import Fernet; print('\\n'.join([Fernet.generate_key().decode('utf-8') for i in range(0,30)]))\"\ndocker run --rm tibillet/fedow poetry run python3 -c \"from django.core.management.utils import get_random_secret_key; print('\\n'.join([get_random_secret_key() for i in range(0,30)]))\"\n"})}),"\n",(0,s.jsx)(n.p,{children:"The first line will take some time as it need to pull the entire Docker image. Keep the keys somewhere, we're gonna need them to setup the engines."}),"\n",(0,s.jsxs)(n.p,{children:["We're also going to need a Stripe test key for the ",(0,s.jsx)(n.code,{children:"STRIPE_KEY_TEST"})," field. Stripe is the payment solution that is currently taking care of the cashing in. You can obtain a key by creating a free account, then by going to Test mode -> API test key. Alternatively you can ask the team."]}),"\n",(0,s.jsx)(n.h3,{id:"fedow-lespass-laboutik",children:"Fedow, Lespass, LaBoutik"}),"\n",(0,s.jsx)(n.p,{children:"Start by cloning the repositories:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Fedow.git\ngit clone git@github.com:TiBillet/Lespass.git\ngit clone git@github.com:TiBillet/LaBoutik.git\n"})}),"\n",(0,s.jsx)(n.p,{children:"From here, we need to write a bit of configuration. It will be better streamlined in the future, so bear with us \ud83d\ude0b"}),"\n",(0,s.jsxs)(n.p,{children:["Each engine needs its own ",(0,s.jsx)(n.code,{children:".env"})," file, which you can base on the ",(0,s.jsx)(n.code,{children:"env_example"})," files you cloned."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["Each environment variable must be readable from the ",(0,s.jsx)(n.code,{children:".env"})," file. No line deletion! Some of them can however stay empty (nullable)."]})}),"\n",(0,s.jsx)(n.h4,{id:"fedow-environment",children:"Fedow environment"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp Fedow/env_example Fedow/.env\n"})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Name"}),(0,s.jsx)(n.th,{children:"Target environment"}),(0,s.jsx)(n.th,{children:"Nullable"}),(0,s.jsx)(n.th,{children:"Default value"}),(0,s.jsx)(n.th,{children:"Notes"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"SECRET_KEY"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"One of the previously generated Django secret key"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"FERNET_KEY"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"One of the previously generated Fernet key"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"STRIPE_KEY"})}),(0,s.jsx)(n.td,{children:"Production"}),(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Your Stripe API key"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DOMAIN"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"fedow.tibillet.localhost"})}),(0,s.jsx)(n.td,{children:"Change to you domain and subdomain for production mode"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"STRIPE_KEY_TEST"})}),(0,s.jsx)(n.td,{children:"Development, Testing"}),(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Your Stripe API test key"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"STRIPE_TEST"})}),(0,s.jsx)(n.td,{children:"Development, Testing"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"0"}),(0,s.jsxs)(n.td,{children:["Set to 1 if ",(0,s.jsx)(n.code,{children:"STRIPE_KEY_TEST"})," is filled"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"STRIPE_ENDPOINT_SECRET_TEST"})}),(0,s.jsx)(n.td,{children:"Development, Testing"}),(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"No idea"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DEBUG"})}),(0,s.jsx)(n.td,{children:"Development"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"0"}),(0,s.jsx)(n.td,{children:"Set to 1 for development"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TEST"})}),(0,s.jsx)(n.td,{children:"Testing"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"0"}),(0,s.jsx)(n.td,{children:"Set to 1 for testing"})]})]})]}),"\n",(0,s.jsx)(n.h4,{id:"lespass-environment",children:"Lespass environment"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp Lespass/env_example Lespass/.env\n"})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Name"}),(0,s.jsx)(n.th,{children:"Target environment"}),(0,s.jsx)(n.th,{children:"Nullable"}),(0,s.jsx)(n.th,{children:"Default value"}),(0,s.jsx)(n.th,{children:"Notes"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"SECRET_KEY"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"One of the previously generated Django secret key"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"FERNET_KEY"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"One of the previously generated Fernet key"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"STRIPE_KEY"})}),(0,s.jsx)(n.td,{children:"Production"}),(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Your Stripe API key"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DOMAIN"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"tibillet.localhost"})}),(0,s.jsx)(n.td,{children:"Change to your domain for production mode"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"SUB"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"lespass"})}),(0,s.jsx)(n.td,{children:"Instance subdomain, change for production mode as necessary"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"META"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"agenda"})}),(0,s.jsx)(n.td,{children:"Federated calendar subdomain, change for production mode as necessary"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"FEDOW_DOMAIN"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"fedow.tibillet.localhost"})}),(0,s.jsx)(n.td,{children:"Domain and subdomain of the Fedow engine"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"PUBLIC"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"TiBillet Coop."}),(0,s.jsx)(n.td,{children:"Main instance name"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TIME_ZONE"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"Europe/Paris"}),(0,s.jsx)(n.td,{children:"TZ time zone of the instance"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADMIN_EMAIL"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Admin email (for the first admin)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"POSTGRES_DB"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"lespass"}),(0,s.jsx)(n.td,{children:"Change for production mode if necessary"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"POSTGRES_USER"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"lespass_postgres"}),(0,s.jsx)(n.td,{children:"Change for production mode"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"POSTGRES_PASSWORD"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Strong password (one of the Fernet keys for example)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"EMAIL_HOST"}),", ",(0,s.jsx)(n.code,{children:"EMAIL_PORT"}),", ",(0,s.jsx)(n.code,{children:"EMAIL_HOST_USER"}),", ",(0,s.jsx)(n.code,{children:"EMAIL_HOST_PASSWORD"})]}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Email server, required to confirm user registrations for example"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"STRIPE_KEY_TEST"})}),(0,s.jsx)(n.td,{children:"Development, Testing"}),(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Your Stripe API test key"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"STRIPE_TEST"})}),(0,s.jsx)(n.td,{children:"Development, Testing"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"0"}),(0,s.jsxs)(n.td,{children:["Set to 1 if ",(0,s.jsx)(n.code,{children:"STRIPE_KEY_TEST"})," is filled"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DEBUG"})}),(0,s.jsx)(n.td,{children:"Development"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"0"}),(0,s.jsx)(n.td,{children:"Set to 1 for development"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TEST"})}),(0,s.jsx)(n.td,{children:"Testing"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"0"}),(0,s.jsx)(n.td,{children:"Set to 1 for testing"})]})]})]}),"\n",(0,s.jsx)(n.h4,{id:"laboutik-environment",children:"LaBoutik environment"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp LaBoutik/env_example LaBoutik/.env\n"})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Name"}),(0,s.jsx)(n.th,{children:"Target environment"}),(0,s.jsx)(n.th,{children:"Nullable"}),(0,s.jsx)(n.th,{children:"Default value"}),(0,s.jsx)(n.th,{children:"Notes"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"SECRET_KEY"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"One of the previously generated Django secret key"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"FERNET_KEY"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"One of the previously generated Fernet key"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DOMAIN"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"laboutik.tibillet.localhost"})}),(0,s.jsx)(n.td,{children:"Change to you domain and subdomain for production mode"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"FEDOW_URL"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"https://fedow.tibillet.localhost/",children:"https://fedow.tibillet.localhost/"})}),(0,s.jsx)(n.td,{children:"Fedow engine URL"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"LESPASS_TENANT_URL"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"https://lespass.tibillet.localhost/",children:"https://lespass.tibillet.localhost/"})}),(0,s.jsx)(n.td,{children:"Lespass instance URL"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TIME_ZONE"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"Europe/Paris"}),(0,s.jsx)(n.td,{children:"TZ time zone of the instance"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADMIN_EMAIL"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Admin email (for the first admin)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"MAIN_ASSET_NAME"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Name of your main cashless asset (Centiment, HeartBit\u2026 whatever you like)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"POSTGRES_DB"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"laboutik"}),(0,s.jsx)(n.td,{children:"Change for production mode if necessary"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"POSTGRES_USER"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"laboutik_user"}),(0,s.jsx)(n.td,{children:"Change for production mode"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"POSTGRES_PASSWORD"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Strong password (one of the Fernet keys for example)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"EMAIL_HOST"}),", ",(0,s.jsx)(n.code,{children:"EMAIL_PORT"}),", ",(0,s.jsx)(n.code,{children:"EMAIL_HOST_USER"}),", ",(0,s.jsx)(n.code,{children:"EMAIL_HOST_PASSWORD"})]}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Email server, required to confirm user registrations for example"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"BORG_PASSPHRASE"})}),(0,s.jsx)(n.td,{children:"All"}),(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Password used for data backup"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DEBUG"})}),(0,s.jsx)(n.td,{children:"Development"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"0"}),(0,s.jsx)(n.td,{children:"Set to 1 for development"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TEST"})}),(0,s.jsx)(n.td,{children:"Testing"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"0"}),(0,s.jsx)(n.td,{children:"Set to 1 for testing"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DEMO"})}),(0,s.jsx)(n.td,{children:"Development, Testing"}),(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:"0"}),(0,s.jsx)(n.td,{children:"Set to 1 for a register simulation"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"SENTRY_DNS"})}),(0,s.jsx)(n.td,{children:"Development, Testing"}),(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Sentry Debug pour le back-end"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"SENTRY_FRONT_DNS"}),", ",(0,s.jsx)(n.code,{children:"SENTRY_FRONT_ASSET"})]}),(0,s.jsx)(n.td,{children:"Development, Testing"}),(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Sentry Debug for front-end"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"DEMO_TAGID_CM"}),", ",(0,s.jsx)(n.code,{children:"DEMO_TAGID_CLIENT1"}),", ",(0,s.jsx)(n.code,{children:"DEMO_TAGID_CLIENT2"})]}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"No idea"})]})]})]}),"\n",(0,s.jsx)(n.p,{children:"The configuration should now be complete for the TiBillet engines."}),"\n",(0,s.jsx)(n.h3,{id:"tests-setup",children:"Tests setup"}),"\n",(0,s.jsx)(n.p,{children:"For\u2026 reasons, the entire dev environment is assembled through the tests. The setup of the testing repository might seem familiar:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Test-Driven-Development.git\ncp Test-Driven-Development/env_example Test-Driven-Development/.env\n"})}),"\n",(0,s.jsx)(n.p,{children:"There! Setup done \u263a\ufe0f Now we can start running the entire project from inside the test folder:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose up -d\n"})}),"\n",(0,s.jsx)(n.p,{children:"You can access the logs with:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose logs -f\n"})}),"\n",(0,s.jsx)(n.admonition,{title:"Careful!",type:"warning",children:(0,s.jsxs)(n.p,{children:["This particular ",(0,s.jsx)(n.code,{children:"docker-compose.yml"})," relies on the folder structure of its ",(0,s.jsx)(n.em,{children:"parent folder"})," shown in the beginning with the example name of ",(0,s.jsx)(n.code,{children:"tibillet-dev"}),". Counterintuitive, but hey: now you know!"]})}),"\n",(0,s.jsx)(n.h3,{id:"manual-engine-start",children:"Manual engine start"}),"\n",(0,s.jsxs)(n.p,{children:["The main difference between dev and prod containers is that running the ",(0,s.jsx)(n.code,{children:"docker compose"})," command will not start the individual Django apps. It's a level of granularity that helps with development, but it means you get to start them manually by entering the containers. Lucky you! \ud83c\udf40"]}),"\n",(0,s.jsx)(n.p,{children:"Were're gonna start them in a particular order:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Fedow"}),"\n",(0,s.jsx)(n.li,{children:"Lespass"}),"\n",(0,s.jsx)(n.li,{children:"LaBoutik (needs the other two to start)"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The tools we need are in the Django containers, named after the engines: ",(0,s.jsx)(n.code,{children:"fedow_django"}),", ",(0,s.jsx)(n.code,{children:"lespass_django"})," and ",(0,s.jsx)(n.code,{children:"laboutik_django"}),". To enter a container (Fedow example) :"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# starting bash shell in fedow_django container\ndocker exec -ti fedow_django bash\n"})}),"\n",(0,s.jsx)(n.p,{children:"From there we have a few options."}),"\n",(0,s.jsxs)(n.p,{children:["First is the ",(0,s.jsx)(n.code,{children:"flush.sh"})," script. It initializes testing data and starts the app right after. This is what we're gonna use at ",(0,s.jsx)(n.strong,{children:"first boot"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="fedow_django$"',children:"./flush.sh\n"})}),"\n",(0,s.jsxs)(n.p,{children:["We will also use it when we want to ",(0,s.jsx)(n.strong,{children:"reset"})," data, for example before starting the automated testing with relies on this predictible data."]}),"\n",(0,s.jsx)(n.p,{children:"For the rest of the container manipulations, we're going to need the Poetry shell, because we're gonna use Python commands."}),"\n",(0,s.jsx)(n.p,{children:"To start Poetry's virtual env from the container:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="fedow_django$"',children:" # we start the virtual env that handles the python dependencies\npoetry shell\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Django is handled through a script called ",(0,s.jsx)(n.code,{children:"manage.py"}),". Two commands are of interest to us here:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"rsp"})," (alias of ",(0,s.jsx)(n.code,{children:"./manage.py runserver 0.0.0.0:8000"}),") starts Django but doesn't wipe out the data. This will help keep data between sessions. GThis command is used in most cases, ",(0,s.jsx)(n.code,{children:"flush"})," is only used for testing or when something's gonz wrong."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["As an option, if you're encontering graphical issues (such as assets not loading), you can attempt ",(0,s.jsx)(n.code,{children:"./manage.py collectstatic"}),". Sometimes the graphical assets are not properly collected at first boot, in which case this can help."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Only thing left to do is to start the three engines in the order described earlier : Fedow, Lespass, then LaBoutik !"}),"\n",(0,s.jsxs)(n.admonition,{title:"Aliasing",type:"tip",children:[(0,s.jsx)(n.p,{children:"The docker command gets repetitive after a while. Why not create an alias, or even a little bash function that will shorten your labor and preserve your carpal tunnel? Here's mine:"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="~/.bashrc"',children:"function dockex {\n docker exec -ti $1 bash\n}\n"})}),(0,s.jsx)(n.p,{children:"There's probably even a way to add the poetry stuff to it, look it up!"})]}),"\n",(0,s.jsx)(n.h3,{id:"is-it-working",children:"Is it working?"}),"\n",(0,s.jsx)(n.p,{children:"If you have used the default domain configuration, you can now access:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["the federation engine Fedow at ",(0,s.jsx)(n.a,{href:"https://fedow.tibillet.localhost",children:"fedow.tibillet.localhost"})]}),"\n",(0,s.jsxs)(n.li,{children:["an instance of the ticketing engine Lespass at ",(0,s.jsx)(n.a,{href:"https://lespass.tibillet.localhost",children:"lespass.tibillet.localhost"})]}),"\n",(0,s.jsxs)(n.li,{children:["the currency register server LaBoutik at ",(0,s.jsx)(n.a,{href:"https://laboutik.tibillet.localhost",children:"laboutik.tibillet.localhost"})]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"If everything is working as expected, congratulations: you're ready to go \ud83d\udd27"}),"\n",(0,s.jsx)(n.p,{children:"If not, come talk to us, we'd love to help!"}),"\n",(0,s.jsxs)(n.admonition,{title:"Wrapping up",type:"note",children:[(0,s.jsxs)(n.p,{children:["Don't forget to ",(0,s.jsx)(n.code,{children:"docker compose down"})," both here and in Traefik when you're done. You computer needs a break sometimes."]}),(0,s.jsxs)(n.p,{children:["If you think you won't remember, remove the daemon option when you compose up (",(0,s.jsx)(n.code,{children:"-d"}),") and the command will run directly in the terminal, not as a background job. It's fine, you'll just need more tabs \ud83d\ude0b"]})]}),"\n",(0,s.jsx)(n.h2,{id:"lifecycle",children:"Lifecycle"}),"\n",(0,s.jsx)(n.h3,{id:"updates",children:"Updates"}),"\n",(0,s.jsx)(n.p,{children:"To stay up to date during development, pull the latest image:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose pull\ndocker compose up -d # start or restart the updated containers\n"})}),"\n",(0,s.jsx)(n.h3,{id:"testing",children:"Testing"}),"\n",(0,s.jsx)(n.p,{children:"You can run the Python tests through the same shell-ception required to do a manual start. Start by flushing the 3 Django apps to get fresh testing data, then run this inside your LaBoutik Django container:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="laboutik_django> poetry shell$"',children:"./manage.py test\n"})}),"\n",(0,s.jsx)("mark",{children:"TODO: end-to-end tests docs (they exist!)"}),"\n",(0,s.jsx)(n.h3,{id:"backups",children:"Backups"}),"\n",(0,s.jsxs)(n.p,{children:["Before causing any major change, backup any data that has value to your development. On your Fedow instance, you only need to save the ",(0,s.jsx)(n.code,{children:"database"})," folder regularly. The other engines can be backed up through the Borgbackup util, cron tasks and database dumps. More about this in the future."]}),"\n",(0,s.jsx)("mark",{children:"TODO: detailed backup explanation"})]})}function a(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},1621:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>l});var s=t(6663);const i={},r=s.createContext(i);function d(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/927f7f94.b5755322.js b/assets/js/927f7f94.b5755322.js deleted file mode 100644 index 6cf120b6..00000000 --- a/assets/js/927f7f94.b5755322.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocumentation_v_2=self.webpackChunkdocumentation_v_2||[]).push([[1329],{6699:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>a,toc:()=>d});var i=t(6271),o=t(1621);const s={sidebar_position:1,slug:"development",title:"Development",keywords:["contribute","volunteer","open source","git","pull request","issue","help","code","development","programming","python","django","docker","poetry","testing","tdd"],tags:["contribute","open source","git","help","tdd","python","django","docker","poetry"],authors:"kaya"},r="Development",a={id:"contribute/dev",title:"Development",description:"So, you want to help with the development of TiBillet. Thank you! Open-source thrives thanks to people like you \ud83d\ude4f",source:"@site/docs/contribute/dev.md",sourceDirName:"contribute",slug:"/contribute/development",permalink:"/docs/contribute/development",draft:!1,unlisted:!1,editUrl:"https://github.com/TiBillet/documentation/tree/main/tibillet/docs/contribute/dev.md",tags:[{inline:!0,label:"contribute",permalink:"/docs/tags/contribute"},{inline:!0,label:"open source",permalink:"/docs/tags/open-source"},{inline:!0,label:"git",permalink:"/docs/tags/git"},{inline:!0,label:"help",permalink:"/docs/tags/help"},{inline:!0,label:"tdd",permalink:"/docs/tags/tdd"},{inline:!0,label:"python",permalink:"/docs/tags/python"},{inline:!0,label:"django",permalink:"/docs/tags/django"},{inline:!0,label:"docker",permalink:"/docs/tags/docker"},{inline:!0,label:"poetry",permalink:"/docs/tags/poetry"}],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1,slug:"development",title:"Development",keywords:["contribute","volunteer","open source","git","pull request","issue","help","code","development","programming","python","django","docker","poetry","testing","tdd"],tags:["contribute","open source","git","help","tdd","python","django","docker","poetry"],authors:"kaya"},sidebar:"tutorialSidebar",previous:{title:"Contribution guides",permalink:"/docs/category/contribution-guides"},next:{title:"API",permalink:"/docs/category/api"}},l={},d=[{value:"Understanding the workflow",id:"understanding-the-workflow",level:2},{value:"Tools and languages used",id:"tools-and-languages-used",level:2},{value:"Local install",id:"local-install",level:2},{value:"Traefik",id:"traefik",level:3},{value:"Key generation",id:"key-generation",level:3},{value:"Fedow, Lespass, Laboutik",id:"fedow-lespass-laboutik",level:3},{value:"Tests setup",id:"tests-setup",level:3},{value:"Manual engine start",id:"manual-engine-start",level:3},{value:"Is it working?",id:"is-it-working",level:3},{value:"Lifecycle",id:"lifecycle",level:2},{value:"Updates",id:"updates",level:3},{value:"Testing",id:"testing",level:3},{value:"Backups",id:"backups",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"development",children:"Development"})}),"\n",(0,i.jsx)(n.p,{children:"So, you want to help with the development of TiBillet. Thank you! Open-source thrives thanks to people like you \ud83d\ude4f"}),"\n",(0,i.jsxs)(n.p,{children:["First, if you don't have a specific task in mind already, check out the open issues on the official ",(0,i.jsx)(n.a,{href:"https://github.com/TiBillet",children:"Github repositories"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"It's the easiest way to figure out what problem needs fixing or what feature is being requested."}),"\n",(0,i.jsxs)(n.admonition,{title:"Repositories",type:"note",children:[(0,i.jsx)(n.p,{children:"What you need is probably in the pinned repositories. If you are unsure of the role of Fedow, Laboutik or Lespass, check out the basics on the three TiBillet engines."}),(0,i.jsxs)(n.p,{children:[(0,i.jsx)("mark",{children:"TODO: link to engines and their roles in the doc"})," (a very basic page in intro probably)"]})]}),"\n",(0,i.jsx)(n.h2,{id:"understanding-the-workflow",children:"Understanding the workflow"}),"\n",(0,i.jsxs)(n.p,{children:["When you work with ",(0,i.jsx)(n.em,{children:"Git forges"})," like Github, there are ways in which you can make your contributions easier to handle:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["If you're not part of the core team, ",(0,i.jsx)(n.em,{children:"fork"})," the repository that interests you, work from there, and submit your changes through a ",(0,i.jsx)(n.em,{children:"pull request"}),"."]}),"\n",(0,i.jsx)(n.li,{children:"If you have an issue you want to work on, check that it doesn't already exists. If it does, join the discussion instead of doing your own thing!"}),"\n",(0,i.jsxs)(n.li,{children:["When you start working on an issue, ",(0,i.jsx)(n.strong,{children:"assign yourself"})," to let others know you're working on it."]}),"\n",(0,i.jsxs)(n.li,{children:["Last but not least: ",(0,i.jsx)(n.strong,{children:"don't create pull requests without running the tests"}),"! Happens to the best of us. Ideally, you should run them before committing, with the help of a ",(0,i.jsx)(n.em,{children:"git hook"})," for example."]}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{title:"Getting help",type:"note",children:(0,i.jsxs)(n.p,{children:["If you have any questions regarding Git, Github, or an aspect of development, join us on ",(0,i.jsx)(n.a,{href:"https://discord.gg/7FJvtYx",children:"Discord"})," or ",(0,i.jsx)(n.a,{href:"https://matrix.to/#/#tibillet:tiers-lieux.org",children:"Matrix"}),". These are mostly French-speaking spaces as the founders are from La Reunion, but we'll do our best to help (with a bit of ",(0,i.jsx)(n.em,{children:"un accent"})," \ud83c\udf77\ud83e\udd56)."]})}),"\n",(0,i.jsx)(n.h2,{id:"tools-and-languages-used",children:"Tools and languages used"}),"\n",(0,i.jsx)(n.p,{children:"TiBillet is:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://www.python.org/",children:"Python"})," software"]}),"\n",(0,i.jsxs)(n.li,{children:["developed with the help of the ",(0,i.jsx)(n.a,{href:"https://www.djangoproject.com/",children:"Django"})," framework"]}),"\n",(0,i.jsxs)(n.li,{children:["its dependencies are handled through ",(0,i.jsx)(n.a,{href:"https://python-poetry.org/",children:"Poetry"})]}),"\n",(0,i.jsxs)(n.li,{children:["it runs in ",(0,i.jsx)(n.a,{href:"https://www.docker.com/",children:"Docker"})," containers for production as well as development"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"If you don't feel at ease with the software stack, the best thing you can do is to go look for tutorials. Hopefully we'll compile a list of our own down here one of these days \ud83d\ude05"}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"In particular, basic knowledge of Git can help. It is relatively easy to make a complete mess of a project by not grasping the way versioning works. There are safeguards, but you might struggle a lot more than necessary! I remember how that feels \ud83d\ude11"})}),"\n",(0,i.jsx)(n.h2,{id:"local-install",children:"Local install"}),"\n",(0,i.jsx)(n.p,{children:"In order to develop and test things out, you're gonna need a (mostly) functional instance of TiBillet on your computer."}),"\n",(0,i.jsx)(n.p,{children:"Let's make sure you have the required tools at hand. You need:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Docker CLI and the ",(0,i.jsx)(n.code,{children:"docker-compose"})," extension"]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"git"})}),"\n",(0,i.jsx)(n.li,{children:"a Github account with a registered SSH key for forge access"}),"\n",(0,i.jsx)(n.li,{children:"an IDE (there are open-source gift licenses of PyCharm available on request, but a regular IDE like VSCodium works reasonably well - that's what I'm using \ud83d\ude09)"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"We're gonna start by creating a folder that will hold the different repositories required, in your local repository or work folder if you have one for example. It will look like this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"tibillet-dev\n\u251c\u2500\u2500 Fedow\n\u251c\u2500\u2500 LaBoutik\n\u251c\u2500\u2500 Lespass\n\u251c\u2500\u2500 Test-Driven-Development\n\u2514\u2500\u2500 Traefik\n"})}),"\n",(0,i.jsx)(n.h3,{id:"traefik",children:"Traefik"}),"\n",(0,i.jsx)(n.p,{children:"We are going to need an application proxy. TiBillet provides a basic configuration for a containerized Traefik + LetsEncrypt, so let's roll with it:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Traefik-reverse-proxy.git Traefik\n"})}),"\n",(0,i.jsx)(n.p,{children:"To start it:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cd Traefik\ndocker compose up -d\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Navigating to ",(0,i.jsx)(n.code,{children:"https://localhost"})," should now prompt you with a security warning about self-signed certificates (it's fine in this instance) and a ",(0,i.jsx)(n.code,{children:"404 page not found"}),". Good!"]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["Remember to ",(0,i.jsx)(n.code,{children:"compose up"})," Traefik every time you start a dev session on this project."]})}),"\n",(0,i.jsx)(n.h3,{id:"key-generation",children:"Key generation"}),"\n",(0,i.jsx)("mark",{children:"TODO: Complicated and heavy for no reason."}),"\n",(0,i.jsx)(n.p,{children:"The legacy way of generating the necessary configuration keys is to pull the production Fedow docker image and run poetry inside of it."}),"\n",(0,i.jsx)(n.p,{children:"For each engine, we will need:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"one or two Fernet keys"}),"\n",(0,i.jsx)(n.li,{children:"a Django secret key"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"You can generate 30 of each in your terminal by running:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker run --rm tibillet/fedow poetry run python3 -c \"from cryptography.fernet import Fernet; print('\\n'.join([Fernet.generate_key().decode('utf-8') for i in range(0,30)]))\"\ndocker run --rm tibillet/fedow poetry run python3 -c \"from django.core.management.utils import get_random_secret_key; print('\\n'.join([get_random_secret_key() for i in range(0,30)]))\"\n"})}),"\n",(0,i.jsx)(n.p,{children:"The first line will take some time as it need to pull the entire Docker image. Keep the keys somewhere, we're gonna need them to setup the engines."}),"\n",(0,i.jsx)(n.h3,{id:"fedow-lespass-laboutik",children:"Fedow, Lespass, Laboutik"}),"\n",(0,i.jsx)(n.p,{children:"Start by cloning the repositories:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Fedow.git\ngit clone git@github.com:TiBillet/Lespass.git\ngit clone git@github.com:TiBillet/LaBoutik.git\n"})}),"\n",(0,i.jsx)(n.p,{children:"From here, we need to write a bit of configuration. It will be better streamlined in the future, so bear with us \ud83d\ude0b"}),"\n",(0,i.jsxs)(n.p,{children:["Each engine needs its own ",(0,i.jsx)(n.code,{children:".env"})," file, which you can base on the ",(0,i.jsx)(n.code,{children:"env_example"})," files you cloned."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp Fedow/env_example Fedow/.env\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Fedow/.env"',children:"SECRET_KEY='' # add a Django secret key here\nFERNET_KEY='' # same with one of the Fernet key you previously generated\nDOMAIN='fedow.tibillet.localhost' # default local domain, referenced in docker-compose.yml\n\n### FOR TEST AND DEBUG ###\n\nDEBUG=1\nTEST=1\n\nSTRIPE_TEST=1\nSTRIPE_KEY_TEST='' # ask the core team! for obvious reasons, we don't freely distribute Stripe keys \ud83d\ude09\nSTRIPE_ENDPOINT_SECRET_TEST='' # not required in development\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can follow the same process for Lespass, even if the environment setup is different."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp Lespass/env_example Lespass/.env\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Lespass/.env"',children:"DJANGO_SECRET='' # Django secret key, different from the Fedow env\nFERNET_KEY='' # same with a different Fernet\n\nDEBUG=1\nTEST=1\n\nSTRIPE_TEST=1\nSTRIPE_KEY_TEST='' # same as in Fedow env\n\n# Database\nPOSTGRES_HOST='lespass_postgres' # referenced in docker-compose.yml\nPOSTGRES_USER='lespass_postgres_user'\nPOSTGRES_PASSWORD='' # you can add a second Fernet key here (or another strong password)\nPOSTGRES_DB='lespass'\n\nTIME_ZONE='Europe/Paris' # TZ timezone identifier\nPUBLIC='TiBillet Coop.' # instance name\n\nFEDOW_DOMAIN='fedow.tibillet.localhost' # federation engine domain\n\nDOMAIN='tibillet.localhost' # for the wildcard: without subdomain ! ex : tibillet.coop, not lespass.tibillet.coop\nSUB='demo' # instance referenced in docker-compose.yml as demo.tibillet.localhost\nMETA='agenda' # the federated agenda for all events on all tenants. the default setup is accessible as agenda.tibillet.coop\nADMIN_EMAIL='' # required but will not be used in dev to send email\n\n# not required in dev\nEMAIL_HOST=''\nEMAIL_PORT=''\nEMAIL_HOST_USER=''\nEMAIL_HOST_PASSWORD=''\n\n# change only if needed\nCELERY_BROKER='redis://redis:6379/0'\nCELERY_BACKEND='redis://redis:6379/0'\n"})}),"\n",(0,i.jsx)(n.p,{children:"Lastly, we configure Laboutik in the same way:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp Laboutik/env_example Laboutik/.env\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Laboutik/.env"',children:"DJANGO_SECRET='' # yet another unique Django secret key\nFERNET_KEY='' # unique Fernet key\n\nDEBUG=1\nTEST=1\nDEMO=1\n\nPOSTGRES_USER='laboutik_user'\nPOSTGRES_PASSWORD='' # again, you can use a unique Fernet for this or a strong password of your choice\nPOSTGRES_DB='laboutik'\n\nDOMAIN='cashless.tibillet.localhost' # default, referenced in docker-compose.yml\n\n# laboutik requires Fedow and a Lespass instance (tenant)\nFEDOW_URL='https://fedow.tibillet.localhost/'\nLESPASS_TENANT_URL='https://demo.tibillet.localhost/'\n\n# name of your cashless asset (virtual currency)\nMAIN_ASSET_NAME='TestCoin'\n\n# admin email, required but not in use in dev, use the same as for lespass\nADMIN_EMAIL=''\n\n# still not required in dev\nEMAIL_HOST=\"\"\nEMAIL_PORT=\"\"\nEMAIL_HOST_USER=\"\"\nEMAIL_HOST_PASSWORD=\"\"\n\nTIME_ZONE='Europe/Paris'\nLANGUAGE_CODE='fr'\n\n\n########## FOR SAVE CRON TASK ##########\n\n# can be empty if you don't backup\nBORG_PASSPHRASE=\"\"\n\n########## FOR TEST AND DEBUG ONLY ##########\n\n# Sentry Debug for django backend\nSENTRY_DNS=\"\"\n# Sentry Debug for js frontend\nSENTRY_FRONT_DNS=\"\"\nSENTRY_FRONT_ASSET=\"\"\n\n###!!!!!! Don't push to production with debug, test or demo !!!!!!###\n\nDEMO_TAGID_CM=''\nDEMO_TAGID_CLIENT1=''\nDEMO_TAGID_CLIENT2=''\n"})}),"\n",(0,i.jsx)(n.p,{children:"The configuration should now be complete for the TiBillet engines."}),"\n",(0,i.jsx)(n.h3,{id:"tests-setup",children:"Tests setup"}),"\n",(0,i.jsx)(n.p,{children:"For\u2026 reasons, the entire dev environment is assembled through the tests. The setup of the testing repository might seem familiar:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Test-Driven-Development.git\ncp Test-Driven-Development/env_example Test-Driven-Development/.env\n"})}),"\n",(0,i.jsx)(n.p,{children:"There! Setup done \u263a\ufe0f Now we can start running the entire project from inside the test folder:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose up -d\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can access the logs with:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose logs -f\n"})}),"\n",(0,i.jsx)(n.admonition,{title:"Careful!",type:"warning",children:(0,i.jsxs)(n.p,{children:["This particular ",(0,i.jsx)(n.code,{children:"docker-compose.yml"})," relies on the folder structure of its ",(0,i.jsx)(n.em,{children:"parent folder"})," shown in the beginning with the example name of ",(0,i.jsx)(n.code,{children:"tibillet-dev"}),". Counterintuitive, but hey: now you know!"]})}),"\n",(0,i.jsx)(n.h3,{id:"manual-engine-start",children:"Manual engine start"}),"\n",(0,i.jsxs)(n.p,{children:["The main difference between dev and prod containers is that running the ",(0,i.jsx)(n.code,{children:"docker compose"})," command will not start the individual Django apps. It's a level of granularity that helps with development, but it means you get to start them manually by entering the containers. Lucky you! \ud83c\udf40"]}),"\n",(0,i.jsx)(n.p,{children:"Let's do a bit of a shell-ception: we're going to enter a bash shell inside a Docker container, then from there enter the Poetry virtual environment. For example with Fedow:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker exec -ti fedow_django bash # entering the container\npoetry shell # entering the virtual environment\n"})}),"\n",(0,i.jsx)(n.p,{children:"From there we have a few options."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="poetry env$"',children:"./flush.sh # will start the Django app from scratch with test data\nrsp # alias to 'python manage.py runserver 0.0.0.0:8000' if you want to keep your data\n./manage.py collectstatic # sometimes static assets do not get collected properly in the first startup, which makes it look like a website from the 90s. if that happens, run this\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The django containers are by default named after the engines: ",(0,i.jsx)(n.code,{children:"fedow_django"}),", ",(0,i.jsx)(n.code,{children:"lespass_django"}),", ",(0,i.jsx)(n.code,{children:"laboutik_django"}),". Manually start them all!"]}),"\n",(0,i.jsxs)(n.admonition,{title:"Aliasing",type:"tip",children:[(0,i.jsx)(n.p,{children:"The docker command gets repetitive after a while. Why not create an alias, or even a little bash function that will shorten your labor and preserve your carpal tunnel? Here's mine:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="~/.bashrc"',children:"function dockex {\n docker exec -ti $1 bash\n}\n"})}),(0,i.jsx)(n.p,{children:"There's probably even a way to add the poetry stuff to it, look it up!"})]}),"\n",(0,i.jsx)(n.h3,{id:"is-it-working",children:"Is it working?"}),"\n",(0,i.jsx)(n.p,{children:"If you have used the default domain configuration, you can now access:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["the federation engine Fedow at ",(0,i.jsx)(n.a,{href:"https://fedow.tibillet.localhost",children:"fedow.tibillet.localhost"})]}),"\n",(0,i.jsxs)(n.li,{children:["an instance of the ticketing engine Lespass at ",(0,i.jsx)(n.a,{href:"https://demo.tibillet.localhost",children:"demo.tibillet.localhost"})]}),"\n",(0,i.jsxs)(n.li,{children:["the currency register server Laboutik at ",(0,i.jsx)(n.a,{href:"https://cashless.tibillet.localhost",children:"cashless.tibillet.localhost"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"If everything is working as expected, congratulations: you're ready to go \ud83d\udd27"}),"\n",(0,i.jsx)(n.p,{children:"If not, come talk to us, we'd love to help!"}),"\n",(0,i.jsxs)(n.admonition,{title:"Wrapping up",type:"note",children:[(0,i.jsxs)(n.p,{children:["Don't forget to ",(0,i.jsx)(n.code,{children:"docker compose down"})," both here and in Traefik when you're done. You computer needs a break sometimes."]}),(0,i.jsxs)(n.p,{children:["If you think you won't remember, remove the daemon option when you compose up (",(0,i.jsx)(n.code,{children:"-d"}),") and the command will run directly in the terminal, not as a background job. It's fine, you'll just need more tabs \ud83d\ude0b"]})]}),"\n",(0,i.jsx)(n.h2,{id:"lifecycle",children:"Lifecycle"}),"\n",(0,i.jsx)(n.h3,{id:"updates",children:"Updates"}),"\n",(0,i.jsx)(n.p,{children:"To stay up to date during development, pull the latest image:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose pull\ndocker compose up -d # start or restart the updated containers\n"})}),"\n",(0,i.jsx)(n.h3,{id:"testing",children:"Testing"}),"\n",(0,i.jsx)(n.p,{children:"You can run the Python tests through the same shell-ception required to do a manual start. Start by flushing the 3 Django apps to get fresh testing data, then run this inside your Laboutik Django container:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="laboutik_django> poetry shell$"',children:"./manage.py test\n"})}),"\n",(0,i.jsx)("mark",{children:"TODO: end-to-end tests docs (they exist!)"}),"\n",(0,i.jsx)(n.h3,{id:"backups",children:"Backups"}),"\n",(0,i.jsxs)(n.p,{children:["Before causing any major change, backup any data that has value to your development. On your Fedow instance, you only need to save the ",(0,i.jsx)(n.code,{children:"database"})," folder regularly. The other engines can be backed up through the Borgbackup util, cron tasks and database dumps. More about this in the future."]}),"\n",(0,i.jsx)("mark",{children:"TODO: detailed backup explanation"})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},1621:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(6663);const o={},s=i.createContext(o);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.5a52da23.js b/assets/js/runtime~main.5cad4ef9.js similarity index 98% rename from assets/js/runtime~main.5a52da23.js rename to assets/js/runtime~main.5cad4ef9.js index b748667c..a1347605 100644 --- a/assets/js/runtime~main.5a52da23.js +++ b/assets/js/runtime~main.5cad4ef9.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,c,d,f,b={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var c=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(c.exports,c,c.exports,r),c.loaded=!0,c.exports}r.m=b,r.c=t,e=[],r.O=(a,c,d,f)=>{if(!c){var b=1/0;for(i=0;i=f)&&Object.keys(r.O).every((e=>r.O[e](c[o])))?c.splice(o--,1):(t=!1,f0&&e[i-1][2]>f;i--)e[i]=e[i-1];e[i]=[c,d,f]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var f=Object.create(null);r.r(f);var b={};a=a||[null,c({}),c([]),c(c)];for(var t=2&d&&e;"object"==typeof t&&!~a.indexOf(t);t=c(t))Object.getOwnPropertyNames(t).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(f,b),f},r.d=(e,a)=>{for(var c in a)r.o(a,c)&&!r.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,c)=>(r.f[c](e,a),a)),[])),r.u=e=>"assets/js/"+({26:"8daeed5c",382:"c02dc41d",418:"bcf52ae3",472:"27da2698",726:"e568d197",795:"3da2692a",853:"2e4a270e",889:"f353014f",966:"baa2bd41",1005:"a78153fe",1127:"ce2cc516",1235:"a7456010",1302:"0392a4a7",1329:"927f7f94",1377:"f45aee62",1938:"11632215",2045:"726c8938",2074:"7f42cc60",2098:"f64e22e3",2240:"b221afeb",2256:"11b43341",2365:"731a8187",2404:"cbabd45f",2560:"659fa473",2561:"c0ac7b9c",2634:"c4f5d8e4",3189:"54bc6b6f",3387:"9cd72b32",3452:"a168b62a",3579:"c7bb5360",3648:"495e69cb",4078:"79300ddd",4171:"9812aca5",4222:"6da2f242",4279:"df203c0f",4280:"2c5a8c25",4285:"6a4065f0",4384:"2c890d29",4507:"f5245bec",4568:"fa75baf9",4634:"65f38bd9",4713:"7e0acfec",4787:"3720c009",4825:"8c76d684",4910:"cc3b42c3",5004:"c046ee4b",5072:"9a4c38d3",5418:"1623311b",5606:"d26ec100",5741:"d159361a",5742:"aba21aa0",5808:"527523d7",5875:"0efb64b9",6011:"941310dd",6061:"1f391b9e",6142:"3fd7c400",6203:"d527cc20",6317:"fd4196ca",6330:"2c241401",6370:"d8254e36",6557:"512b8e12",6590:"285ac952",6604:"57b2c8d2",6969:"14eb3368",7077:"ff005427",7098:"a7bd4aaa",7293:"1eec3456",7415:"f306de51",7527:"9b32cf81",7537:"52efbe89",7679:"3dd44a97",7967:"7ec4066a",7972:"74b3184d",8019:"3ddc391e",8059:"d083fab2",8180:"0492922a",8194:"c7170f78",8198:"86b2e310",8255:"0a1333cb",8328:"fc924a68",8401:"17896441",8433:"c1e0fb1f",8440:"da7a2e8a",8503:"2e7de751",8657:"2d9a2f91",8678:"321184fb",8703:"3f20655a",8908:"b4e94af8",9045:"d2d25e00",9048:"a94703ab",9393:"36c171c8",9397:"f293808f",9425:"fc5b8a36",9498:"07b63270",9647:"5e95c892",9672:"e0d6de2a",9720:"4ee12e50",9863:"02c41862"}[e]||e)+"."+{26:"8263115c",171:"a22cb800",382:"eec6fcc6",418:"5f4eec61",472:"4913ccd1",726:"8947fce3",795:"a9deb8b0",853:"91bae2a1",889:"92480494",966:"cd2d661b",1005:"3bc165b4",1127:"1fcc7e7e",1235:"64267856",1302:"3554099d",1329:"b5755322",1377:"dfb850f1",1938:"eb99e6cc",2045:"51e16626",2074:"4c7e5c04",2098:"ebcc2a25",2240:"301c4959",2256:"75e124a8",2365:"a16feeb6",2404:"5f45b750",2560:"cd4b34ca",2561:"46275bf4",2634:"3c944a99",3189:"ae20eac3",3387:"a27a35ba",3452:"2ab33bad",3579:"497a3a92",3648:"f03ea2d5",4078:"f2ee0a2b",4171:"b830047d",4222:"c428a413",4279:"2617a656",4280:"97c3f97d",4285:"556966c4",4384:"c8c76acc",4507:"857dfe7f",4568:"b0b347cf",4634:"d93b831d",4713:"14f7009d",4787:"447543d1",4825:"0061c074",4910:"a30d51b4",5004:"3ef8f170",5072:"f45215b4",5418:"ab10cdce",5460:"43ac4a6a",5606:"e2f3a975",5741:"239003cb",5742:"eaf0e070",5808:"abe92e3f",5875:"666710af",6011:"0f7ddde9",6061:"483bbb2c",6142:"e22af835",6203:"6933d636",6317:"3c54c8ad",6330:"f7fc610b",6370:"760b3b29",6557:"f7cf953b",6590:"b5c30dba",6604:"4de051d0",6969:"41145fce",7077:"47187b21",7098:"c0b26ad9",7293:"ad8391de",7415:"f1897ea3",7527:"c57955f2",7537:"f0c8abce",7679:"fff9ecae",7967:"2c28bd7f",7972:"0d7f05cc",8019:"b94301b5",8059:"85d37cd0",8180:"52cc15aa",8194:"f43f44b8",8198:"5f4c2c8f",8255:"73fecff8",8328:"273adc88",8401:"01f28df4",8433:"c19fac77",8440:"59d3bf63",8503:"222deeec",8657:"1f1666d5",8678:"98a89015",8703:"8cff32d8",8908:"f73764ac",9045:"2b346e6c",9048:"5f10afe8",9393:"d72e1908",9397:"0455253e",9425:"89207e86",9498:"ea700919",9647:"73b378c9",9672:"f2a1005e",9720:"f2e6c69a",9863:"813c5c2e"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},f="documentation-v-2:",r.l=(e,a,c,b)=>{if(d[e])d[e].push(a);else{var t,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var f=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),f&&f.forEach((e=>e(c))),a)return a(c)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={11632215:"1938",17896441:"8401","8daeed5c":"26",c02dc41d:"382",bcf52ae3:"418","27da2698":"472",e568d197:"726","3da2692a":"795","2e4a270e":"853",f353014f:"889",baa2bd41:"966",a78153fe:"1005",ce2cc516:"1127",a7456010:"1235","0392a4a7":"1302","927f7f94":"1329",f45aee62:"1377","726c8938":"2045","7f42cc60":"2074",f64e22e3:"2098",b221afeb:"2240","11b43341":"2256","731a8187":"2365",cbabd45f:"2404","659fa473":"2560",c0ac7b9c:"2561",c4f5d8e4:"2634","54bc6b6f":"3189","9cd72b32":"3387",a168b62a:"3452",c7bb5360:"3579","495e69cb":"3648","79300ddd":"4078","9812aca5":"4171","6da2f242":"4222",df203c0f:"4279","2c5a8c25":"4280","6a4065f0":"4285","2c890d29":"4384",f5245bec:"4507",fa75baf9:"4568","65f38bd9":"4634","7e0acfec":"4713","3720c009":"4787","8c76d684":"4825",cc3b42c3:"4910",c046ee4b:"5004","9a4c38d3":"5072","1623311b":"5418",d26ec100:"5606",d159361a:"5741",aba21aa0:"5742","527523d7":"5808","0efb64b9":"5875","941310dd":"6011","1f391b9e":"6061","3fd7c400":"6142",d527cc20:"6203",fd4196ca:"6317","2c241401":"6330",d8254e36:"6370","512b8e12":"6557","285ac952":"6590","57b2c8d2":"6604","14eb3368":"6969",ff005427:"7077",a7bd4aaa:"7098","1eec3456":"7293",f306de51:"7415","9b32cf81":"7527","52efbe89":"7537","3dd44a97":"7679","7ec4066a":"7967","74b3184d":"7972","3ddc391e":"8019",d083fab2:"8059","0492922a":"8180",c7170f78:"8194","86b2e310":"8198","0a1333cb":"8255",fc924a68:"8328",c1e0fb1f:"8433",da7a2e8a:"8440","2e7de751":"8503","2d9a2f91":"8657","321184fb":"8678","3f20655a":"8703",b4e94af8:"8908",d2d25e00:"9045",a94703ab:"9048","36c171c8":"9393",f293808f:"9397",fc5b8a36:"9425","07b63270":"9498","5e95c892":"9647",e0d6de2a:"9672","4ee12e50":"9720","02c41862":"9863"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,c)=>{var d=r.o(e,a)?e[a]:void 0;if(0!==d)if(d)c.push(d[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var f=new Promise(((c,f)=>d=e[a]=[c,f]));c.push(d[2]=f);var b=r.p+r.u(a),t=new Error;r.l(b,(c=>{if(r.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var f=c&&("load"===c.type?"missing":c.type),b=c&&c.target&&c.target.src;t.message="Loading chunk "+a+" failed.\n("+f+": "+b+")",t.name="ChunkLoadError",t.type=f,t.request=b,d[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,c)=>{var d,f,b=c[0],t=c[1],o=c[2],n=0;if(b.some((a=>0!==e[a]))){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(a&&a(c);n{"use strict";var e,a,c,d,f,b={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var c=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(c.exports,c,c.exports,r),c.loaded=!0,c.exports}r.m=b,r.c=t,e=[],r.O=(a,c,d,f)=>{if(!c){var b=1/0;for(i=0;i=f)&&Object.keys(r.O).every((e=>r.O[e](c[o])))?c.splice(o--,1):(t=!1,f0&&e[i-1][2]>f;i--)e[i]=e[i-1];e[i]=[c,d,f]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var f=Object.create(null);r.r(f);var b={};a=a||[null,c({}),c([]),c(c)];for(var t=2&d&&e;"object"==typeof t&&!~a.indexOf(t);t=c(t))Object.getOwnPropertyNames(t).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(f,b),f},r.d=(e,a)=>{for(var c in a)r.o(a,c)&&!r.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,c)=>(r.f[c](e,a),a)),[])),r.u=e=>"assets/js/"+({26:"8daeed5c",382:"c02dc41d",418:"bcf52ae3",472:"27da2698",726:"e568d197",795:"3da2692a",853:"2e4a270e",889:"f353014f",966:"baa2bd41",1005:"a78153fe",1127:"ce2cc516",1235:"a7456010",1302:"0392a4a7",1329:"927f7f94",1377:"f45aee62",1938:"11632215",2045:"726c8938",2074:"7f42cc60",2098:"f64e22e3",2240:"b221afeb",2256:"11b43341",2365:"731a8187",2404:"cbabd45f",2560:"659fa473",2561:"c0ac7b9c",2634:"c4f5d8e4",3189:"54bc6b6f",3387:"9cd72b32",3452:"a168b62a",3579:"c7bb5360",3648:"495e69cb",4078:"79300ddd",4171:"9812aca5",4222:"6da2f242",4279:"df203c0f",4280:"2c5a8c25",4285:"6a4065f0",4384:"2c890d29",4507:"f5245bec",4568:"fa75baf9",4634:"65f38bd9",4713:"7e0acfec",4787:"3720c009",4825:"8c76d684",4910:"cc3b42c3",5004:"c046ee4b",5072:"9a4c38d3",5418:"1623311b",5606:"d26ec100",5741:"d159361a",5742:"aba21aa0",5808:"527523d7",5875:"0efb64b9",6011:"941310dd",6061:"1f391b9e",6142:"3fd7c400",6203:"d527cc20",6317:"fd4196ca",6330:"2c241401",6370:"d8254e36",6557:"512b8e12",6590:"285ac952",6604:"57b2c8d2",6969:"14eb3368",7077:"ff005427",7098:"a7bd4aaa",7293:"1eec3456",7415:"f306de51",7527:"9b32cf81",7537:"52efbe89",7679:"3dd44a97",7967:"7ec4066a",7972:"74b3184d",8019:"3ddc391e",8059:"d083fab2",8180:"0492922a",8194:"c7170f78",8198:"86b2e310",8255:"0a1333cb",8328:"fc924a68",8401:"17896441",8433:"c1e0fb1f",8440:"da7a2e8a",8503:"2e7de751",8657:"2d9a2f91",8678:"321184fb",8703:"3f20655a",8908:"b4e94af8",9045:"d2d25e00",9048:"a94703ab",9393:"36c171c8",9397:"f293808f",9425:"fc5b8a36",9498:"07b63270",9647:"5e95c892",9672:"e0d6de2a",9720:"4ee12e50",9863:"02c41862"}[e]||e)+"."+{26:"8263115c",171:"a22cb800",382:"eec6fcc6",418:"5f4eec61",472:"4913ccd1",726:"8947fce3",795:"a9deb8b0",853:"91bae2a1",889:"92480494",966:"cd2d661b",1005:"3bc165b4",1127:"1fcc7e7e",1235:"64267856",1302:"3554099d",1329:"572c57f2",1377:"dfb850f1",1938:"eb99e6cc",2045:"51e16626",2074:"4c7e5c04",2098:"ebcc2a25",2240:"301c4959",2256:"75e124a8",2365:"a16feeb6",2404:"5f45b750",2560:"cd4b34ca",2561:"46275bf4",2634:"3c944a99",3189:"ae20eac3",3387:"a27a35ba",3452:"2ab33bad",3579:"497a3a92",3648:"f03ea2d5",4078:"f2ee0a2b",4171:"b830047d",4222:"c428a413",4279:"2617a656",4280:"97c3f97d",4285:"556966c4",4384:"c8c76acc",4507:"857dfe7f",4568:"b0b347cf",4634:"d93b831d",4713:"14f7009d",4787:"447543d1",4825:"0061c074",4910:"a30d51b4",5004:"3ef8f170",5072:"f45215b4",5418:"ab10cdce",5460:"43ac4a6a",5606:"e2f3a975",5741:"239003cb",5742:"eaf0e070",5808:"abe92e3f",5875:"666710af",6011:"0f7ddde9",6061:"483bbb2c",6142:"e22af835",6203:"6933d636",6317:"3c54c8ad",6330:"f7fc610b",6370:"760b3b29",6557:"f7cf953b",6590:"b5c30dba",6604:"4de051d0",6969:"41145fce",7077:"47187b21",7098:"c0b26ad9",7293:"ad8391de",7415:"f1897ea3",7527:"c57955f2",7537:"f0c8abce",7679:"fff9ecae",7967:"2c28bd7f",7972:"0d7f05cc",8019:"b94301b5",8059:"85d37cd0",8180:"52cc15aa",8194:"f43f44b8",8198:"5f4c2c8f",8255:"73fecff8",8328:"273adc88",8401:"01f28df4",8433:"c19fac77",8440:"59d3bf63",8503:"222deeec",8657:"1f1666d5",8678:"98a89015",8703:"8cff32d8",8908:"f73764ac",9045:"2b346e6c",9048:"5f10afe8",9393:"d72e1908",9397:"0455253e",9425:"89207e86",9498:"ea700919",9647:"73b378c9",9672:"f2a1005e",9720:"f2e6c69a",9863:"813c5c2e"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},f="documentation-v-2:",r.l=(e,a,c,b)=>{if(d[e])d[e].push(a);else{var t,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var f=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),f&&f.forEach((e=>e(c))),a)return a(c)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={11632215:"1938",17896441:"8401","8daeed5c":"26",c02dc41d:"382",bcf52ae3:"418","27da2698":"472",e568d197:"726","3da2692a":"795","2e4a270e":"853",f353014f:"889",baa2bd41:"966",a78153fe:"1005",ce2cc516:"1127",a7456010:"1235","0392a4a7":"1302","927f7f94":"1329",f45aee62:"1377","726c8938":"2045","7f42cc60":"2074",f64e22e3:"2098",b221afeb:"2240","11b43341":"2256","731a8187":"2365",cbabd45f:"2404","659fa473":"2560",c0ac7b9c:"2561",c4f5d8e4:"2634","54bc6b6f":"3189","9cd72b32":"3387",a168b62a:"3452",c7bb5360:"3579","495e69cb":"3648","79300ddd":"4078","9812aca5":"4171","6da2f242":"4222",df203c0f:"4279","2c5a8c25":"4280","6a4065f0":"4285","2c890d29":"4384",f5245bec:"4507",fa75baf9:"4568","65f38bd9":"4634","7e0acfec":"4713","3720c009":"4787","8c76d684":"4825",cc3b42c3:"4910",c046ee4b:"5004","9a4c38d3":"5072","1623311b":"5418",d26ec100:"5606",d159361a:"5741",aba21aa0:"5742","527523d7":"5808","0efb64b9":"5875","941310dd":"6011","1f391b9e":"6061","3fd7c400":"6142",d527cc20:"6203",fd4196ca:"6317","2c241401":"6330",d8254e36:"6370","512b8e12":"6557","285ac952":"6590","57b2c8d2":"6604","14eb3368":"6969",ff005427:"7077",a7bd4aaa:"7098","1eec3456":"7293",f306de51:"7415","9b32cf81":"7527","52efbe89":"7537","3dd44a97":"7679","7ec4066a":"7967","74b3184d":"7972","3ddc391e":"8019",d083fab2:"8059","0492922a":"8180",c7170f78:"8194","86b2e310":"8198","0a1333cb":"8255",fc924a68:"8328",c1e0fb1f:"8433",da7a2e8a:"8440","2e7de751":"8503","2d9a2f91":"8657","321184fb":"8678","3f20655a":"8703",b4e94af8:"8908",d2d25e00:"9045",a94703ab:"9048","36c171c8":"9393",f293808f:"9397",fc5b8a36:"9425","07b63270":"9498","5e95c892":"9647",e0d6de2a:"9672","4ee12e50":"9720","02c41862":"9863"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,c)=>{var d=r.o(e,a)?e[a]:void 0;if(0!==d)if(d)c.push(d[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var f=new Promise(((c,f)=>d=e[a]=[c,f]));c.push(d[2]=f);var b=r.p+r.u(a),t=new Error;r.l(b,(c=>{if(r.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var f=c&&("load"===c.type?"missing":c.type),b=c&&c.target&&c.target.src;t.message="Loading chunk "+a+" failed.\n("+f+": "+b+")",t.name="ChunkLoadError",t.type=f,t.request=b,d[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,c)=>{var d,f,b=c[0],t=c[1],o=c[2],n=0;if(b.some((a=>0!==e[a]))){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(a&&a(c);n Conditions générales de vente et d'utilisation | TiBillet - + diff --git a/docs/Tips/facebook/index.html b/docs/Tips/facebook/index.html index c2c52d70..4e714dd8 100644 --- a/docs/Tips/facebook/index.html +++ b/docs/Tips/facebook/index.html @@ -4,7 +4,7 @@ Social media posting | TiBillet - + diff --git a/docs/Utilisateur/Billetterie/admin_add_new_event/index.html b/docs/Utilisateur/Billetterie/admin_add_new_event/index.html index 12c0512e..b05e2a63 100644 --- a/docs/Utilisateur/Billetterie/admin_add_new_event/index.html +++ b/docs/Utilisateur/Billetterie/admin_add_new_event/index.html @@ -4,7 +4,7 @@ Create a new event from A to Z | TiBillet - + diff --git a/docs/Utilisateur/Billetterie/admin_add_new_free_event/index.html b/docs/Utilisateur/Billetterie/admin_add_new_free_event/index.html index 1ad00aed..23ac5584 100644 --- a/docs/Utilisateur/Billetterie/admin_add_new_free_event/index.html +++ b/docs/Utilisateur/Billetterie/admin_add_new_free_event/index.html @@ -4,7 +4,7 @@ Create a free event | TiBillet - + diff --git a/docs/Utilisateur/Billetterie/iframe/index.html b/docs/Utilisateur/Billetterie/iframe/index.html index ea23a1fe..fb86172f 100644 --- a/docs/Utilisateur/Billetterie/iframe/index.html +++ b/docs/Utilisateur/Billetterie/iframe/index.html @@ -4,7 +4,7 @@ Integration | TiBillet - + diff --git a/docs/Utilisateur/Billetterie/rss/index.html b/docs/Utilisateur/Billetterie/rss/index.html index 2fcbeff1..4fb9637a 100644 --- a/docs/Utilisateur/Billetterie/rss/index.html +++ b/docs/Utilisateur/Billetterie/rss/index.html @@ -4,7 +4,7 @@ RSS Feed | TiBillet - + diff --git a/docs/Utilisateur/Billetterie/webhook/index.html b/docs/Utilisateur/Billetterie/webhook/index.html index 81fae80d..be66956c 100644 --- a/docs/Utilisateur/Billetterie/webhook/index.html +++ b/docs/Utilisateur/Billetterie/webhook/index.html @@ -4,7 +4,7 @@ Webhook | TiBillet - + diff --git a/docs/Utilisateur/Cashless/admin_add_article/index.html b/docs/Utilisateur/Cashless/admin_add_article/index.html index 96b7275e..eacdac6c 100644 --- a/docs/Utilisateur/Cashless/admin_add_article/index.html +++ b/docs/Utilisateur/Cashless/admin_add_article/index.html @@ -4,7 +4,7 @@ Articles | TiBillet - + diff --git a/docs/Utilisateur/Cashless/admin_add_categorie/index.html b/docs/Utilisateur/Cashless/admin_add_categorie/index.html index 65fe41e6..2abc1175 100644 --- a/docs/Utilisateur/Cashless/admin_add_categorie/index.html +++ b/docs/Utilisateur/Cashless/admin_add_categorie/index.html @@ -4,7 +4,7 @@ Article categories | TiBillet - + diff --git a/docs/Utilisateur/Cashless/admin_add_pos/index.html b/docs/Utilisateur/Cashless/admin_add_pos/index.html index f248bc9e..c6743f4c 100644 --- a/docs/Utilisateur/Cashless/admin_add_pos/index.html +++ b/docs/Utilisateur/Cashless/admin_add_pos/index.html @@ -4,7 +4,7 @@ Points of sale | TiBillet - + diff --git a/docs/Utilisateur/Cashless/admin_add_primary/index.html b/docs/Utilisateur/Cashless/admin_add_primary/index.html index d48386bc..70e963c8 100644 --- a/docs/Utilisateur/Cashless/admin_add_primary/index.html +++ b/docs/Utilisateur/Cashless/admin_add_primary/index.html @@ -4,7 +4,7 @@ Primary Cards | TiBillet - + diff --git a/docs/Utilisateur/Cashless/admin_supp/index.html b/docs/Utilisateur/Cashless/admin_supp/index.html index 5e2ae090..5041674c 100644 --- a/docs/Utilisateur/Cashless/admin_supp/index.html +++ b/docs/Utilisateur/Cashless/admin_supp/index.html @@ -4,7 +4,7 @@ Removing Orders | TiBillet - + diff --git a/docs/Utilisateur/Cashless/android/index.html b/docs/Utilisateur/Cashless/android/index.html index f36227c5..5db08dbd 100644 --- a/docs/Utilisateur/Cashless/android/index.html +++ b/docs/Utilisateur/Cashless/android/index.html @@ -4,7 +4,7 @@ Android application | TiBillet - + diff --git a/docs/Utilisateur/Cashless/badge/index.html b/docs/Utilisateur/Cashless/badge/index.html index 4342d9b7..a9205831 100644 --- a/docs/Utilisateur/Cashless/badge/index.html +++ b/docs/Utilisateur/Cashless/badge/index.html @@ -4,7 +4,7 @@ Time clock machine | TiBillet - + diff --git a/docs/Utilisateur/Cashless/cashback/index.html b/docs/Utilisateur/Cashless/cashback/index.html index af76edf3..2bcc0372 100644 --- a/docs/Utilisateur/Cashless/cashback/index.html +++ b/docs/Utilisateur/Cashless/cashback/index.html @@ -4,7 +4,7 @@ Cashback | TiBillet - + diff --git a/docs/Utilisateur/Cashless/fidelity/index.html b/docs/Utilisateur/Cashless/fidelity/index.html index c673b619..b6724f1e 100644 --- a/docs/Utilisateur/Cashless/fidelity/index.html +++ b/docs/Utilisateur/Cashless/fidelity/index.html @@ -4,7 +4,7 @@ Loyalty points | TiBillet - + diff --git a/docs/Utilisateur/Cashless/impression_preparation/index.html b/docs/Utilisateur/Cashless/impression_preparation/index.html index 18b74c28..e705a09b 100644 --- a/docs/Utilisateur/Cashless/impression_preparation/index.html +++ b/docs/Utilisateur/Cashless/impression_preparation/index.html @@ -4,7 +4,7 @@ Printing orders | TiBillet - + diff --git a/docs/api/apikey/index.html b/docs/api/apikey/index.html index 16e6d529..7851d8e4 100644 --- a/docs/api/apikey/index.html +++ b/docs/api/apikey/index.html @@ -4,7 +4,7 @@ API Keys | TiBillet - + diff --git a/docs/api/events/index.html b/docs/api/events/index.html index a91e319d..c7849564 100644 --- a/docs/api/events/index.html +++ b/docs/api/events/index.html @@ -4,7 +4,7 @@ Évènements | TiBillet - + diff --git a/docs/api/intro/index.html b/docs/api/intro/index.html index 54b440af..5f9774ec 100644 --- a/docs/api/intro/index.html +++ b/docs/api/intro/index.html @@ -4,7 +4,7 @@ Introduction | TiBillet - + diff --git a/docs/api/products/index.html b/docs/api/products/index.html index ef3a76fe..23bc51b8 100644 --- a/docs/api/products/index.html +++ b/docs/api/products/index.html @@ -4,7 +4,7 @@ Produits | TiBillet - + diff --git a/docs/api/reservations/index.html b/docs/api/reservations/index.html index 3a8edd6b..06682a16 100644 --- a/docs/api/reservations/index.html +++ b/docs/api/reservations/index.html @@ -4,7 +4,7 @@ Réservations et billets | TiBillet - + diff --git a/docs/api/tenants/index.html b/docs/api/tenants/index.html index 0beb5a61..69b82c9f 100644 --- a/docs/api/tenants/index.html +++ b/docs/api/tenants/index.html @@ -4,7 +4,7 @@ Tenants | TiBillet - + diff --git a/docs/category/api/index.html b/docs/category/api/index.html index 2edb5c74..96bc0eec 100644 --- a/docs/category/api/index.html +++ b/docs/category/api/index.html @@ -4,7 +4,7 @@ API | TiBillet - + diff --git a/docs/category/billetterie/index.html b/docs/category/billetterie/index.html index 5f651b80..a5dde73e 100644 --- a/docs/category/billetterie/index.html +++ b/docs/category/billetterie/index.html @@ -4,7 +4,7 @@ Ticketing | TiBillet - + diff --git a/docs/category/cashless/index.html b/docs/category/cashless/index.html index 1b74871e..3975ce1f 100644 --- a/docs/category/cashless/index.html +++ b/docs/category/cashless/index.html @@ -4,7 +4,7 @@ Cashless | TiBillet - + diff --git a/docs/category/contribution-guides/index.html b/docs/category/contribution-guides/index.html index 25a4c1e4..9181e748 100644 --- a/docs/category/contribution-guides/index.html +++ b/docs/category/contribution-guides/index.html @@ -4,7 +4,7 @@ Contribution guides | TiBillet - + diff --git a/docs/category/diy/index.html b/docs/category/diy/index.html index 505fe1ed..343b810e 100644 --- a/docs/category/diy/index.html +++ b/docs/category/diy/index.html @@ -4,7 +4,7 @@ DIY | TiBillet - + diff --git a/docs/category/documentation-utilisateur/index.html b/docs/category/documentation-utilisateur/index.html index e9ac73c0..7f151329 100644 --- a/docs/category/documentation-utilisateur/index.html +++ b/docs/category/documentation-utilisateur/index.html @@ -4,7 +4,7 @@ User documentation | TiBillet - + diff --git "a/docs/category/pr\303\251sentation/index.html" "b/docs/category/pr\303\251sentation/index.html" index 5e47fb6e..2833150d 100644 --- "a/docs/category/pr\303\251sentation/index.html" +++ "b/docs/category/pr\303\251sentation/index.html" @@ -4,7 +4,7 @@ Presentation | TiBillet - + diff --git a/docs/category/trucs-et-astuces/index.html b/docs/category/trucs-et-astuces/index.html index 4ab403bc..07d0f895 100644 --- a/docs/category/trucs-et-astuces/index.html +++ b/docs/category/trucs-et-astuces/index.html @@ -4,7 +4,7 @@ Tips and tricks | TiBillet - + diff --git a/docs/contribute/development/index.html b/docs/contribute/development/index.html index 24a6d673..78be4b2f 100644 --- a/docs/contribute/development/index.html +++ b/docs/contribute/development/index.html @@ -4,7 +4,7 @@ Development | TiBillet - + @@ -12,7 +12,7 @@

So, you want to help with the development of TiBillet. Thank you! Open-source thrives thanks to people like you 🙏

First, if you don't have a specific task in mind already, check out the open issues on the official Github repositories.

It's the easiest way to figure out what problem needs fixing or what feature is being requested.

-
Repositories

What you need is probably in the pinned repositories. If you are unsure of the role of Fedow, Laboutik or Lespass, check out the basics on the three TiBillet engines.

TODO: link to engines and their roles in the doc (a very basic page in intro probably)

+
Repositories

What you need is probably in the pinned repositories. If you are unsure of the role of Fedow, LaBoutik or Lespass, check out the basics on the three TiBillet engines.

TODO: link to engines and their roles in the doc (a very basic page in intro probably)

Understanding the workflow

When you work with Git forges like Github, there are ways in which you can make your contributions easier to handle:

    @@ -55,25 +55,28 @@

    Key generatio

    The legacy way of generating the necessary configuration keys is to pull the production Fedow docker image and run poetry inside of it.

    For each engine, we will need:

      -
    • one or two Fernet keys
    • -
    • a Django secret key
    • +
    • one or two Fernet keys (for the FERNET_KEY field and possibly, passwords)
    • +
    • a Django secret key (for the SECRET_KEY field)

    You can generate 30 of each in your terminal by running:

    docker run --rm tibillet/fedow poetry run python3 -c "from cryptography.fernet import Fernet; print('\n'.join([Fernet.generate_key().decode('utf-8') for i in range(0,30)]))"
    docker run --rm tibillet/fedow poetry run python3 -c "from django.core.management.utils import get_random_secret_key; print('\n'.join([get_random_secret_key() for i in range(0,30)]))"

    The first line will take some time as it need to pull the entire Docker image. Keep the keys somewhere, we're gonna need them to setup the engines.

    -

    Fedow, Lespass, Laboutik

    +

    We're also going to need a Stripe test key for the STRIPE_KEY_TEST field. Stripe is the payment solution that is currently taking care of the cashing in. You can obtain a key by creating a free account, then by going to Test mode -> API test key. Alternatively you can ask the team.

    +

    Fedow, Lespass, LaBoutik

    Start by cloning the repositories:

    tibillet-dev$
    git clone git@github.com:TiBillet/Fedow.git
    git clone git@github.com:TiBillet/Lespass.git
    git clone git@github.com:TiBillet/LaBoutik.git

    From here, we need to write a bit of configuration. It will be better streamlined in the future, so bear with us 😋

    Each engine needs its own .env file, which you can base on the env_example files you cloned.

    +
    warning

    Each environment variable must be readable from the .env file. No line deletion! Some of them can however stay empty (nullable).

    +

    Fedow environment

    tibillet-dev$
    cp Fedow/env_example Fedow/.env
    -
    Fedow/.env
    SECRET_KEY='' # add a Django secret key here
    FERNET_KEY='' # same with one of the Fernet key you previously generated
    DOMAIN='fedow.tibillet.localhost' # default local domain, referenced in docker-compose.yml

    ### FOR TEST AND DEBUG ###

    DEBUG=1
    TEST=1

    STRIPE_TEST=1
    STRIPE_KEY_TEST='' # ask the core team! for obvious reasons, we don't freely distribute Stripe keys 😉
    STRIPE_ENDPOINT_SECRET_TEST='' # not required in development
    -

    You can follow the same process for Lespass, even if the environment setup is different.

    +
    NameTarget environmentNullableDefault valueNotes
    SECRET_KEYAllNoOne of the previously generated Django secret key
    FERNET_KEYAllNoOne of the previously generated Fernet key
    STRIPE_KEYProductionYesYour Stripe API key
    DOMAINAllNofedow.tibillet.localhostChange to you domain and subdomain for production mode
    STRIPE_KEY_TESTDevelopment, TestingYesYour Stripe API test key
    STRIPE_TESTDevelopment, TestingNo0Set to 1 if STRIPE_KEY_TEST is filled
    STRIPE_ENDPOINT_SECRET_TESTDevelopment, TestingYesNo idea
    DEBUGDevelopmentNo0Set to 1 for development
    TESTTestingNo0Set to 1 for testing
    +

    Lespass environment

    tibillet-dev$
    cp Lespass/env_example Lespass/.env
    -
    Lespass/.env
    DJANGO_SECRET='' # Django secret key, different from the Fedow env
    FERNET_KEY='' # same with a different Fernet

    DEBUG=1
    TEST=1

    STRIPE_TEST=1
    STRIPE_KEY_TEST='' # same as in Fedow env

    # Database
    POSTGRES_HOST='lespass_postgres' # referenced in docker-compose.yml
    POSTGRES_USER='lespass_postgres_user'
    POSTGRES_PASSWORD='' # you can add a second Fernet key here (or another strong password)
    POSTGRES_DB='lespass'

    TIME_ZONE='Europe/Paris' # TZ timezone identifier
    PUBLIC='TiBillet Coop.' # instance name

    FEDOW_DOMAIN='fedow.tibillet.localhost' # federation engine domain

    DOMAIN='tibillet.localhost' # for the wildcard: without subdomain ! ex : tibillet.coop, not lespass.tibillet.coop
    SUB='demo' # instance referenced in docker-compose.yml as demo.tibillet.localhost
    META='agenda' # the federated agenda for all events on all tenants. the default setup is accessible as agenda.tibillet.coop
    ADMIN_EMAIL='' # required but will not be used in dev to send email

    # not required in dev
    EMAIL_HOST=''
    EMAIL_PORT=''
    EMAIL_HOST_USER=''
    EMAIL_HOST_PASSWORD=''

    # change only if needed
    CELERY_BROKER='redis://redis:6379/0'
    CELERY_BACKEND='redis://redis:6379/0'
    -

    Lastly, we configure Laboutik in the same way:

    -
    tibillet-dev$
    cp Laboutik/env_example Laboutik/.env
    -
    Laboutik/.env
    DJANGO_SECRET='' # yet another unique Django secret key
    FERNET_KEY='' # unique Fernet key

    DEBUG=1
    TEST=1
    DEMO=1

    POSTGRES_USER='laboutik_user'
    POSTGRES_PASSWORD='' # again, you can use a unique Fernet for this or a strong password of your choice
    POSTGRES_DB='laboutik'

    DOMAIN='cashless.tibillet.localhost' # default, referenced in docker-compose.yml

    # laboutik requires Fedow and a Lespass instance (tenant)
    FEDOW_URL='https://fedow.tibillet.localhost/'
    LESPASS_TENANT_URL='https://demo.tibillet.localhost/'

    # name of your cashless asset (virtual currency)
    MAIN_ASSET_NAME='TestCoin'

    # admin email, required but not in use in dev, use the same as for lespass
    ADMIN_EMAIL=''

    # still not required in dev
    EMAIL_HOST=""
    EMAIL_PORT=""
    EMAIL_HOST_USER=""
    EMAIL_HOST_PASSWORD=""

    TIME_ZONE='Europe/Paris'
    LANGUAGE_CODE='fr'


    ########## FOR SAVE CRON TASK ##########

    # can be empty if you don't backup
    BORG_PASSPHRASE=""

    ########## FOR TEST AND DEBUG ONLY ##########

    # Sentry Debug for django backend
    SENTRY_DNS=""
    # Sentry Debug for js frontend
    SENTRY_FRONT_DNS=""
    SENTRY_FRONT_ASSET=""

    ###!!!!!! Don't push to production with debug, test or demo !!!!!!###

    DEMO_TAGID_CM=''
    DEMO_TAGID_CLIENT1=''
    DEMO_TAGID_CLIENT2=''
    +
    NameTarget environmentNullableDefault valueNotes
    SECRET_KEYAllNoOne of the previously generated Django secret key
    FERNET_KEYAllNoOne of the previously generated Fernet key
    STRIPE_KEYProductionYesYour Stripe API key
    DOMAINAllNotibillet.localhostChange to your domain for production mode
    SUBAllNolespassInstance subdomain, change for production mode as necessary
    METAAllNoagendaFederated calendar subdomain, change for production mode as necessary
    FEDOW_DOMAINAllNofedow.tibillet.localhostDomain and subdomain of the Fedow engine
    PUBLICAllNoTiBillet Coop.Main instance name
    TIME_ZONEAllNoEurope/ParisTZ time zone of the instance
    ADMIN_EMAILAllNoAdmin email (for the first admin)
    POSTGRES_DBAllNolespassChange for production mode if necessary
    POSTGRES_USERAllNolespass_postgresChange for production mode
    POSTGRES_PASSWORDAllNoStrong password (one of the Fernet keys for example)
    EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORDAllYesEmail server, required to confirm user registrations for example
    STRIPE_KEY_TESTDevelopment, TestingYesYour Stripe API test key
    STRIPE_TESTDevelopment, TestingNo0Set to 1 if STRIPE_KEY_TEST is filled
    DEBUGDevelopmentNo0Set to 1 for development
    TESTTestingNo0Set to 1 for testing
    +

    LaBoutik environment

    +
    tibillet-dev$
    cp LaBoutik/env_example LaBoutik/.env
    +
    NameTarget environmentNullableDefault valueNotes
    SECRET_KEYAllNoOne of the previously generated Django secret key
    FERNET_KEYAllNoOne of the previously generated Fernet key
    DOMAINAllNolaboutik.tibillet.localhostChange to you domain and subdomain for production mode
    FEDOW_URLAllNohttps://fedow.tibillet.localhost/Fedow engine URL
    LESPASS_TENANT_URLAllNohttps://lespass.tibillet.localhost/Lespass instance URL
    TIME_ZONEAllNoEurope/ParisTZ time zone of the instance
    ADMIN_EMAILAllNoAdmin email (for the first admin)
    MAIN_ASSET_NAMEAllNoName of your main cashless asset (Centiment, HeartBit… whatever you like)
    POSTGRES_DBAllNolaboutikChange for production mode if necessary
    POSTGRES_USERAllNolaboutik_userChange for production mode
    POSTGRES_PASSWORDAllNoStrong password (one of the Fernet keys for example)
    EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORDAllYesEmail server, required to confirm user registrations for example
    BORG_PASSPHRASEAllYesPassword used for data backup
    DEBUGDevelopmentNo0Set to 1 for development
    TESTTestingNo0Set to 1 for testing
    DEMODevelopment, TestingNo0Set to 1 for a register simulation
    SENTRY_DNSDevelopment, TestingYesSentry Debug pour le back-end
    SENTRY_FRONT_DNS, SENTRY_FRONT_ASSETDevelopment, TestingYesSentry Debug for front-end
    DEMO_TAGID_CM, DEMO_TAGID_CLIENT1, DEMO_TAGID_CLIENT2YesNo idea

    The configuration should now be complete for the TiBillet engines.

    Tests setup

    For… reasons, the entire dev environment is assembled through the tests. The setup of the testing repository might seem familiar:

    @@ -85,18 +88,38 @@

    Tests setup
    Careful!

    This particular docker-compose.yml relies on the folder structure of its parent folder shown in the beginning with the example name of tibillet-dev. Counterintuitive, but hey: now you know!

    Manual engine start

    The main difference between dev and prod containers is that running the docker compose command will not start the individual Django apps. It's a level of granularity that helps with development, but it means you get to start them manually by entering the containers. Lucky you! 🍀

    -

    Let's do a bit of a shell-ception: we're going to enter a bash shell inside a Docker container, then from there enter the Poetry virtual environment. For example with Fedow:

    -
    docker exec -ti fedow_django bash # entering the container
    poetry shell # entering the virtual environment
    +

    Were're gonna start them in a particular order:

    +
      +
    1. Fedow
    2. +
    3. Lespass
    4. +
    5. LaBoutik (needs the other two to start)
    6. +
    +

    The tools we need are in the Django containers, named after the engines: fedow_django, lespass_django and laboutik_django. To enter a container (Fedow example) :

    +
    # starting bash shell in fedow_django container
    docker exec -ti fedow_django bash

    From there we have a few options.

    -
    poetry env$
    ./flush.sh # will start the Django app from scratch with test data
    rsp # alias to 'python manage.py runserver 0.0.0.0:8000' if you want to keep your data
    ./manage.py collectstatic # sometimes static assets do not get collected properly in the first startup, which makes it look like a website from the 90s. if that happens, run this
    -

    The django containers are by default named after the engines: fedow_django, lespass_django, laboutik_django. Manually start them all!

    +

    First is the flush.sh script. It initializes testing data and starts the app right after. This is what we're gonna use at first boot:

    +
    fedow_django$
    ./flush.sh
    +

    We will also use it when we want to reset data, for example before starting the automated testing with relies on this predictible data.

    +

    For the rest of the container manipulations, we're going to need the Poetry shell, because we're gonna use Python commands.

    +

    To start Poetry's virtual env from the container:

    +
    fedow_django$
     # we start the virtual env that handles the python dependencies
    poetry shell
    +

    Django is handled through a script called manage.py. Two commands are of interest to us here:

    +
      +
    • +

      rsp (alias of ./manage.py runserver 0.0.0.0:8000) starts Django but doesn't wipe out the data. This will help keep data between sessions. GThis command is used in most cases, flush is only used for testing or when something's gonz wrong.

      +
    • +
    • +

      As an option, if you're encontering graphical issues (such as assets not loading), you can attempt ./manage.py collectstatic. Sometimes the graphical assets are not properly collected at first boot, in which case this can help.

      +
    • +
    +

    Only thing left to do is to start the three engines in the order described earlier : Fedow, Lespass, then LaBoutik !

    Aliasing

    The docker command gets repetitive after a while. Why not create an alias, or even a little bash function that will shorten your labor and preserve your carpal tunnel? Here's mine:

    ~/.bashrc
    function dockex {
    docker exec -ti $1 bash
    }

    There's probably even a way to add the poetry stuff to it, look it up!

    Is it working?

    If you have used the default domain configuration, you can now access:

    If everything is working as expected, congratulations: you're ready to go 🔧

    If not, come talk to us, we'd love to help!

    @@ -106,11 +129,11 @@

    Updates
    Test-Driven-Development$
    docker compose pull
    docker compose up -d # start or restart the updated containers

    Testing

    -

    You can run the Python tests through the same shell-ception required to do a manual start. Start by flushing the 3 Django apps to get fresh testing data, then run this inside your Laboutik Django container:

    +

    You can run the Python tests through the same shell-ception required to do a manual start. Start by flushing the 3 Django apps to get fresh testing data, then run this inside your LaBoutik Django container:

    laboutik_django> poetry shell$
    ./manage.py test
    TODO: end-to-end tests docs (they exist!)

    Backups

    Before causing any major change, backup any data that has value to your development. On your Fedow instance, you only need to save the database folder regularly. The other engines can be backed up through the Borgbackup util, cron tasks and database dumps. More about this in the future.

    -TODO: detailed backup explanation +TODO: detailed backup explanation \ No newline at end of file diff --git a/docs/install/docker_install/index.html b/docs/install/docker_install/index.html index ee05b61b..72229ed5 100644 --- a/docs/install/docker_install/index.html +++ b/docs/install/docker_install/index.html @@ -4,7 +4,7 @@ Self hosted TiBillet instances | TiBillet - + diff --git a/docs/install/raspberry/index.html b/docs/install/raspberry/index.html index 9eeded13..bd8d3116 100644 --- a/docs/install/raspberry/index.html +++ b/docs/install/raspberry/index.html @@ -4,7 +4,7 @@ Raspberry Box - Hardware | TiBillet - + diff --git a/docs/install/raspberry_soft/index.html b/docs/install/raspberry_soft/index.html index 09d97e53..e10d43ec 100644 --- a/docs/install/raspberry_soft/index.html +++ b/docs/install/raspberry_soft/index.html @@ -4,7 +4,7 @@ Raspberry Box - Software | TiBillet - + diff --git a/docs/presentation/demonstration/index.html b/docs/presentation/demonstration/index.html index 631a1d31..13e4b455 100644 --- a/docs/presentation/demonstration/index.html +++ b/docs/presentation/demonstration/index.html @@ -4,7 +4,7 @@ Demonstration | TiBillet - + diff --git a/docs/presentation/introduction/index.html b/docs/presentation/introduction/index.html index 29944405..084ed6e5 100644 --- a/docs/presentation/introduction/index.html +++ b/docs/presentation/introduction/index.html @@ -4,7 +4,7 @@ Introduction | TiBillet - + diff --git a/docs/presentation/logos/index.html b/docs/presentation/logos/index.html index 7bc6d906..31cbd72b 100644 --- a/docs/presentation/logos/index.html +++ b/docs/presentation/logos/index.html @@ -4,7 +4,7 @@ Logos | TiBillet - + diff --git a/docs/presentation/philosophie/index.html b/docs/presentation/philosophie/index.html index 5aa74178..cd242b0d 100644 --- a/docs/presentation/philosophie/index.html +++ b/docs/presentation/philosophie/index.html @@ -4,7 +4,7 @@ Philosophy | TiBillet - + diff --git a/docs/presentation/tarifs/index.html b/docs/presentation/tarifs/index.html index 10cf72f0..fb268e54 100644 --- a/docs/presentation/tarifs/index.html +++ b/docs/presentation/tarifs/index.html @@ -4,7 +4,7 @@ Prices, conditions and licenses | TiBillet - + diff --git a/docs/presentation/usages/index.html b/docs/presentation/usages/index.html index 0ad6d47d..a8a834be 100644 --- a/docs/presentation/usages/index.html +++ b/docs/presentation/usages/index.html @@ -4,7 +4,7 @@ Uses | TiBillet - + diff --git a/docs/tags/access-card/index.html b/docs/tags/access-card/index.html index 7c1dd18b..b1d994d8 100644 --- a/docs/tags/access-card/index.html +++ b/docs/tags/access-card/index.html @@ -4,7 +4,7 @@ One doc tagged with "access card" | TiBillet - + diff --git a/docs/tags/associations/index.html b/docs/tags/associations/index.html index be61c678..d10978a5 100644 --- a/docs/tags/associations/index.html +++ b/docs/tags/associations/index.html @@ -4,7 +4,7 @@ One doc tagged with "associations" | TiBillet - + diff --git a/docs/tags/badge-inter-lieux/index.html b/docs/tags/badge-inter-lieux/index.html index 21a7354b..a61290b5 100644 --- a/docs/tags/badge-inter-lieux/index.html +++ b/docs/tags/badge-inter-lieux/index.html @@ -4,7 +4,7 @@ One doc tagged with "badge inter-lieux" | TiBillet - + diff --git a/docs/tags/billetterie/index.html b/docs/tags/billetterie/index.html index 74ca19d6..03ec1894 100644 --- a/docs/tags/billetterie/index.html +++ b/docs/tags/billetterie/index.html @@ -4,7 +4,7 @@ 4 docs tagged with "billetterie" | TiBillet - + diff --git a/docs/tags/caisse-enregistreuse/index.html b/docs/tags/caisse-enregistreuse/index.html index 179bbf80..590a3206 100644 --- a/docs/tags/caisse-enregistreuse/index.html +++ b/docs/tags/caisse-enregistreuse/index.html @@ -4,7 +4,7 @@ 2 docs tagged with "caisse enregistreuse" | TiBillet - + diff --git a/docs/tags/card/index.html b/docs/tags/card/index.html index 24b5d175..6e7e3555 100644 --- a/docs/tags/card/index.html +++ b/docs/tags/card/index.html @@ -4,7 +4,7 @@ One doc tagged with "card" | TiBillet - + diff --git a/docs/tags/cash-register/index.html b/docs/tags/cash-register/index.html index ce7a6604..ee562ca1 100644 --- a/docs/tags/cash-register/index.html +++ b/docs/tags/cash-register/index.html @@ -4,7 +4,7 @@ One doc tagged with "cash register" | TiBillet - + diff --git a/docs/tags/cashback/index.html b/docs/tags/cashback/index.html index d3047cdf..99d288b4 100644 --- a/docs/tags/cashback/index.html +++ b/docs/tags/cashback/index.html @@ -4,7 +4,7 @@ One doc tagged with "cashback" | TiBillet - + diff --git a/docs/tags/cashless/index.html b/docs/tags/cashless/index.html index 6a89a5c7..18ce0363 100644 --- a/docs/tags/cashless/index.html +++ b/docs/tags/cashless/index.html @@ -4,7 +4,7 @@ 4 docs tagged with "cashless" | TiBillet - + diff --git a/docs/tags/catering/index.html b/docs/tags/catering/index.html index 82b928b9..cc7f2899 100644 --- a/docs/tags/catering/index.html +++ b/docs/tags/catering/index.html @@ -4,7 +4,7 @@ 2 docs tagged with "catering" | TiBillet - + diff --git a/docs/tags/contribute/index.html b/docs/tags/contribute/index.html index aa0f598a..44b8108e 100644 --- a/docs/tags/contribute/index.html +++ b/docs/tags/contribute/index.html @@ -4,7 +4,7 @@ One doc tagged with "contribute" | TiBillet - + diff --git a/docs/tags/cooperative/index.html b/docs/tags/cooperative/index.html index ca119f8f..92c875d4 100644 --- a/docs/tags/cooperative/index.html +++ b/docs/tags/cooperative/index.html @@ -4,7 +4,7 @@ One doc tagged with "coopérative" | TiBillet - + diff --git a/docs/tags/dematerialized-payment/index.html b/docs/tags/dematerialized-payment/index.html index efc51fce..5dde72c9 100644 --- a/docs/tags/dematerialized-payment/index.html +++ b/docs/tags/dematerialized-payment/index.html @@ -4,7 +4,7 @@ One doc tagged with "dematerialized payment" | TiBillet - + diff --git a/docs/tags/demonstration/index.html b/docs/tags/demonstration/index.html index c7fef2fc..ea0af932 100644 --- a/docs/tags/demonstration/index.html +++ b/docs/tags/demonstration/index.html @@ -4,7 +4,7 @@ One doc tagged with "démonstration" | TiBillet - + diff --git a/docs/tags/django/index.html b/docs/tags/django/index.html index 8a1bb4b5..b0aff92d 100644 --- a/docs/tags/django/index.html +++ b/docs/tags/django/index.html @@ -4,7 +4,7 @@ One doc tagged with "django" | TiBillet - + diff --git a/docs/tags/docker/index.html b/docs/tags/docker/index.html index 6f46348e..0e1ef179 100644 --- a/docs/tags/docker/index.html +++ b/docs/tags/docker/index.html @@ -4,7 +4,7 @@ One doc tagged with "docker" | TiBillet - + diff --git a/docs/tags/dokos/index.html b/docs/tags/dokos/index.html index 6a841999..1a1f4459 100644 --- a/docs/tags/dokos/index.html +++ b/docs/tags/dokos/index.html @@ -4,7 +4,7 @@ One doc tagged with "dokos" | TiBillet - + diff --git a/docs/tags/events/index.html b/docs/tags/events/index.html index f8846796..5d044cd5 100644 --- a/docs/tags/events/index.html +++ b/docs/tags/events/index.html @@ -4,7 +4,7 @@ One doc tagged with "events" | TiBillet - + diff --git a/docs/tags/federated/index.html b/docs/tags/federated/index.html index a31ec142..f4f8f1f5 100644 --- a/docs/tags/federated/index.html +++ b/docs/tags/federated/index.html @@ -4,7 +4,7 @@ One doc tagged with "federated" | TiBillet - + diff --git a/docs/tags/festival/index.html b/docs/tags/festival/index.html index 9a362bbb..06d3e553 100644 --- a/docs/tags/festival/index.html +++ b/docs/tags/festival/index.html @@ -4,7 +4,7 @@ One doc tagged with "festival" | TiBillet - + diff --git a/docs/tags/fidelite/index.html b/docs/tags/fidelite/index.html index 7c13b21a..21fa00da 100644 --- a/docs/tags/fidelite/index.html +++ b/docs/tags/fidelite/index.html @@ -4,7 +4,7 @@ One doc tagged with "fidélité" | TiBillet - + diff --git a/docs/tags/fidelity/index.html b/docs/tags/fidelity/index.html index 3365aba8..c33d749b 100644 --- a/docs/tags/fidelity/index.html +++ b/docs/tags/fidelity/index.html @@ -4,7 +4,7 @@ One doc tagged with "fidelity" | TiBillet - + diff --git a/docs/tags/free-software/index.html b/docs/tags/free-software/index.html index 54a9f801..011ab603 100644 --- a/docs/tags/free-software/index.html +++ b/docs/tags/free-software/index.html @@ -4,7 +4,7 @@ One doc tagged with "free software" | TiBillet - + diff --git a/docs/tags/git/index.html b/docs/tags/git/index.html index 9be5977f..204f661e 100644 --- a/docs/tags/git/index.html +++ b/docs/tags/git/index.html @@ -4,7 +4,7 @@ One doc tagged with "git" | TiBillet - + diff --git a/docs/tags/help/index.html b/docs/tags/help/index.html index 55aac2c3..71abd9f3 100644 --- a/docs/tags/help/index.html +++ b/docs/tags/help/index.html @@ -4,7 +4,7 @@ One doc tagged with "help" | TiBillet - + diff --git a/docs/tags/index.html b/docs/tags/index.html index 5f9a5ddf..d54c291e 100644 --- a/docs/tags/index.html +++ b/docs/tags/index.html @@ -4,7 +4,7 @@ Tags | TiBillet - + diff --git a/docs/tags/local-currencies/index.html b/docs/tags/local-currencies/index.html index d7a23ff4..149614d6 100644 --- a/docs/tags/local-currencies/index.html +++ b/docs/tags/local-currencies/index.html @@ -4,7 +4,7 @@ One doc tagged with "local currencies" | TiBillet - + diff --git a/docs/tags/logiciel-libre/index.html b/docs/tags/logiciel-libre/index.html index 1add568f..85c47370 100644 --- a/docs/tags/logiciel-libre/index.html +++ b/docs/tags/logiciel-libre/index.html @@ -4,7 +4,7 @@ One doc tagged with "logiciel libre" | TiBillet - + diff --git a/docs/tags/loyalty/index.html b/docs/tags/loyalty/index.html index 11368cc9..15df444f 100644 --- a/docs/tags/loyalty/index.html +++ b/docs/tags/loyalty/index.html @@ -4,7 +4,7 @@ One doc tagged with "loyalty" | TiBillet - + diff --git a/docs/tags/monnaie-locale/index.html b/docs/tags/monnaie-locale/index.html index 71532233..34bd3ec6 100644 --- a/docs/tags/monnaie-locale/index.html +++ b/docs/tags/monnaie-locale/index.html @@ -4,7 +4,7 @@ One doc tagged with "monnaie locale" | TiBillet - + diff --git a/docs/tags/monnaies-locales/index.html b/docs/tags/monnaies-locales/index.html index d9a560d5..630b60c3 100644 --- a/docs/tags/monnaies-locales/index.html +++ b/docs/tags/monnaies-locales/index.html @@ -4,7 +4,7 @@ One doc tagged with "monnaies locales" | TiBillet - + diff --git a/docs/tags/monnaies-temps/index.html b/docs/tags/monnaies-temps/index.html index d4752315..aa17352f 100644 --- a/docs/tags/monnaies-temps/index.html +++ b/docs/tags/monnaies-temps/index.html @@ -4,7 +4,7 @@ One doc tagged with "monnaies temps" | TiBillet - + diff --git a/docs/tags/open-source/index.html b/docs/tags/open-source/index.html index 6242f01e..60be6556 100644 --- a/docs/tags/open-source/index.html +++ b/docs/tags/open-source/index.html @@ -4,7 +4,7 @@ 2 docs tagged with "open source" | TiBillet - + diff --git a/docs/tags/order-taking/index.html b/docs/tags/order-taking/index.html index 5e97a4a7..3fef7309 100644 --- a/docs/tags/order-taking/index.html +++ b/docs/tags/order-taking/index.html @@ -4,7 +4,7 @@ One doc tagged with "order taking" | TiBillet - + diff --git a/docs/tags/paiement-dematerialise/index.html b/docs/tags/paiement-dematerialise/index.html index 9c1621d0..5c52a66c 100644 --- a/docs/tags/paiement-dematerialise/index.html +++ b/docs/tags/paiement-dematerialise/index.html @@ -4,7 +4,7 @@ One doc tagged with "paiement dématérialisé" | TiBillet - + diff --git a/docs/tags/poetry/index.html b/docs/tags/poetry/index.html index 67036570..0b49af53 100644 --- a/docs/tags/poetry/index.html +++ b/docs/tags/poetry/index.html @@ -4,7 +4,7 @@ One doc tagged with "poetry" | TiBillet - + diff --git a/docs/tags/prise-de-commandes/index.html b/docs/tags/prise-de-commandes/index.html index 5a8b45f8..4da4f850 100644 --- a/docs/tags/prise-de-commandes/index.html +++ b/docs/tags/prise-de-commandes/index.html @@ -4,7 +4,7 @@ One doc tagged with "prise de commandes" | TiBillet - + diff --git a/docs/tags/python/index.html b/docs/tags/python/index.html index 07b6fdf5..a8c0959f 100644 --- a/docs/tags/python/index.html +++ b/docs/tags/python/index.html @@ -4,7 +4,7 @@ One doc tagged with "python" | TiBillet - + diff --git a/docs/tags/stripe/index.html b/docs/tags/stripe/index.html index 8c946742..2ceb5d74 100644 --- a/docs/tags/stripe/index.html +++ b/docs/tags/stripe/index.html @@ -4,7 +4,7 @@ One doc tagged with "stripe" | TiBillet - + diff --git a/docs/tags/tdd/index.html b/docs/tags/tdd/index.html index 82122019..1cae44f7 100644 --- a/docs/tags/tdd/index.html +++ b/docs/tags/tdd/index.html @@ -4,7 +4,7 @@ One doc tagged with "tdd" | TiBillet - + diff --git a/docs/tags/ticketing/index.html b/docs/tags/ticketing/index.html index 7316edb0..ebe33361 100644 --- a/docs/tags/ticketing/index.html +++ b/docs/tags/ticketing/index.html @@ -4,7 +4,7 @@ 4 docs tagged with "ticketing" | TiBillet - + diff --git a/docs/tags/tiers-lieux/index.html b/docs/tags/tiers-lieux/index.html index 96e49285..c527a3c2 100644 --- a/docs/tags/tiers-lieux/index.html +++ b/docs/tags/tiers-lieux/index.html @@ -4,7 +4,7 @@ One doc tagged with "tiers-lieux" | TiBillet - + diff --git a/docs/tags/time-currencies/index.html b/docs/tags/time-currencies/index.html index 11c0f6c9..ad27aa4a 100644 --- a/docs/tags/time-currencies/index.html +++ b/docs/tags/time-currencies/index.html @@ -4,7 +4,7 @@ One doc tagged with "time currencies" | TiBillet - + diff --git a/docs/tags/venue/index.html b/docs/tags/venue/index.html index 259f285b..97f9cf48 100644 --- a/docs/tags/venue/index.html +++ b/docs/tags/venue/index.html @@ -4,7 +4,7 @@ 2 docs tagged with "venue" | TiBillet - + diff --git a/fr/404.html b/fr/404.html index 693382c6..2a561810 100644 --- a/fr/404.html +++ b/fr/404.html @@ -4,7 +4,7 @@ Page introuvable | TiBillet - + diff --git a/fr/assets/js/c0af11f0.28fafb3a.js b/fr/assets/js/c0af11f0.d7c80e2f.js similarity index 52% rename from fr/assets/js/c0af11f0.28fafb3a.js rename to fr/assets/js/c0af11f0.d7c80e2f.js index 6eccf00b..05c1f39e 100644 --- a/fr/assets/js/c0af11f0.28fafb3a.js +++ b/fr/assets/js/c0af11f0.d7c80e2f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocumentation_v_2=self.webpackChunkdocumentation_v_2||[]).push([[639],{2540:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>o,contentTitle:()=>t,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=n(6271),d=n(1621);const i={sidebar_position:1,slug:"development",title:"D\xe9veloppement",keywords:["contribuer","b\xe9n\xe9volat","open source","git","pull request","issue","soutien","code","d\xe9veloppement","programmation","python","django","docker","poetry","tests","tdd"],tags:["contribuer","open source","git","soutien","tdd","python","django","docker","poetry"],authors:"kaya"},t="D\xe9veloppement",l={id:"contribute/dev",title:"D\xe9veloppement",description:"Vous voulez aider au d\xe9veloppement de TiBillet? Merci! C'est gr\xe2ce aux gens comme vous que l'open-source fonctionne \ud83d\ude4f",source:"@site/i18n/fr/docusaurus-plugin-content-docs/current/contribute/dev.md",sourceDirName:"contribute",slug:"/contribute/development",permalink:"/fr/docs/contribute/development",draft:!1,unlisted:!1,editUrl:"https://github.com/TiBillet/documentation/tree/main/tibillet/docs/contribute/dev.md",tags:[{inline:!0,label:"contribuer",permalink:"/fr/docs/tags/contribuer"},{inline:!0,label:"open source",permalink:"/fr/docs/tags/open-source"},{inline:!0,label:"git",permalink:"/fr/docs/tags/git"},{inline:!0,label:"soutien",permalink:"/fr/docs/tags/soutien"},{inline:!0,label:"tdd",permalink:"/fr/docs/tags/tdd"},{inline:!0,label:"python",permalink:"/fr/docs/tags/python"},{inline:!0,label:"django",permalink:"/fr/docs/tags/django"},{inline:!0,label:"docker",permalink:"/fr/docs/tags/docker"},{inline:!0,label:"poetry",permalink:"/fr/docs/tags/poetry"}],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1,slug:"development",title:"D\xe9veloppement",keywords:["contribuer","b\xe9n\xe9volat","open source","git","pull request","issue","soutien","code","d\xe9veloppement","programmation","python","django","docker","poetry","tests","tdd"],tags:["contribuer","open source","git","soutien","tdd","python","django","docker","poetry"],authors:"kaya"},sidebar:"tutorialSidebar",previous:{title:"Contribution guides",permalink:"/fr/docs/category/contribution-guides"},next:{title:"API",permalink:"/fr/docs/category/api"}},o={},c=[{value:"M\xe9thodes de travail",id:"m\xe9thodes-de-travail",level:2},{value:"Outils et langages utilis\xe9s",id:"outils-et-langages-utilis\xe9s",level:2},{value:"Installation locale",id:"installation-locale",level:2},{value:"Traefik",id:"traefik",level:3},{value:"G\xe9n\xe9ration des cl\xe9s",id:"g\xe9n\xe9ration-des-cl\xe9s",level:3},{value:"Fedow, Lespass, LaBoutik",id:"fedow-lespass-laboutik",level:3},{value:"Environnement Fedow",id:"environnement-fedow",level:4},{value:"Environnement Lespass",id:"environnement-lespass",level:4},{value:"Environnement LaBoutik",id:"environnement-laboutik",level:4},{value:"Mise en place des tests",id:"mise-en-place-des-tests",level:3},{value:"D\xe9marrage des moteurs",id:"d\xe9marrage-des-moteurs",level:3},{value:"\xc7a tourne ?",id:"\xe7a-tourne-",level:3},{value:"Cycle de vie",id:"cycle-de-vie",level:2},{value:"Mises \xe0 jour",id:"mises-\xe0-jour",level:3},{value:"Tests",id:"tests",level:3},{value:"Sauvegardes",id:"sauvegardes",level:3}];function a(e){const s={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"d\xe9veloppement",children:"D\xe9veloppement"})}),"\n",(0,r.jsx)(s.p,{children:"Vous voulez aider au d\xe9veloppement de TiBillet? Merci! C'est gr\xe2ce aux gens comme vous que l'open-source fonctionne \ud83d\ude4f"}),"\n",(0,r.jsxs)(s.p,{children:["Premi\xe8rement, si vous n'avez pas une t\xe2che pr\xe9cise en t\xeate, allez voir les tickets ouverts sur les ",(0,r.jsx)(s.a,{href:"https://github.com/orgs/TiBillet/projects?query=is%3Aopen",children:"d\xe9p\xf4ts Github"})," officiels."]}),"\n",(0,r.jsx)(s.p,{children:"C'est le moyen le plus simple de comprendre quels sont les probl\xe8mes \xe0 r\xe9soudre et quelles fonctionnalit\xe9s sont demand\xe9es."}),"\n",(0,r.jsxs)(s.admonition,{title:"Les d\xe9p\xf4ts",type:"note",children:[(0,r.jsx)(s.p,{children:'Les d\xe9p\xf4ts \xe9pingl\xe9s ("Pinned") sur la page de l\'organisation devraient suffire. Si vous avez des doutes sur les r\xf4les respectifs de Fedow, LaBoutik ou Lespass, r\xe9visez les bases sur les trois moteurs de TiBillet.'}),(0,r.jsxs)(s.p,{children:[(0,r.jsx)("mark",{children:"TODO: lien doc vers les moteurs et leur r\xf4le"})," (une page dans pr\xe9sentation probablement)"]})]}),"\n",(0,r.jsx)(s.h2,{id:"m\xe9thodes-de-travail",children:"M\xe9thodes de travail"}),"\n",(0,r.jsxs)(s.p,{children:["Quand on travaille avec des ",(0,r.jsx)(s.em,{children:"forges Git"})," comme Github, il y a des fa\xe7ons d'aider qui rendent votre contribution plus facile \xe0 prendre en compte :"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Si vous ne faites pas partie de l'organisation (avec les acc\xe8s au d\xe9p\xf4t), faites un ",(0,r.jsx)(s.em,{children:"fork"})," (d\xe9doublement) du d\xe9p\xf4t qui vous int\xe9resse, travaillez \xe0 partir de celui-ci et soumettez vous modifications par le biais d'une ",(0,r.jsx)(s.em,{children:"pull request"})," (demande de fusion)."]}),"\n",(0,r.jsx)(s.li,{children:"Si vous avez un ticket sur lequel vous souhaitez travailler, v\xe9rifiez s'il n'existe pas d\xe9j\xe0. Si c'est le cas, rejoignez la discussion plut\xf4t que de faire la m\xeame chose en parall\xe8le!"}),"\n",(0,r.jsxs)(s.li,{children:["Quand vous d\xe9marrez le travail sur un ticket, ",(0,r.jsx)(s.strong,{children:"assignez-vous"})," dessus pour informer les autres qu'un chantier est en cours."]}),"\n",(0,r.jsxs)(s.li,{children:["Enfin, un point important: ",(0,r.jsx)(s.strong,{children:"ne cr\xe9ez pas de demandes de fusion sans avoir fait tourner les tests"})," ! \xc7a arrive aux meilleur\u22c5es d'entre nous. Id\xe9alement, vous devriez les faire tourner avant chaque ",(0,r.jsx)(s.em,{children:"commit"}),", avec l'aide d'un ",(0,r.jsx)(s.em,{children:"git hook"})," (d\xe9clencheur automatique) par exemple."]}),"\n"]}),"\n",(0,r.jsx)(s.admonition,{title:"Trouver de l'aide",type:"note",children:(0,r.jsxs)(s.p,{children:["Si vous avez des questions sur Git, Github, ou un aspect du d\xe9veloppement, rejoignez-nous sur le serveur ",(0,r.jsx)(s.a,{href:"https://discord.gg/7FJvtYx",children:"Discord"})," ou ",(0,r.jsx)(s.a,{href:"https://matrix.to/#/#tibillet:tiers-lieux.org",children:"Matrix"}),". Nous ferons de notre mieux pour aider !"]})}),"\n",(0,r.jsx)(s.h2,{id:"outils-et-langages-utilis\xe9s",children:"Outils et langages utilis\xe9s"}),"\n",(0,r.jsx)(s.p,{children:"TiBillet, c'est :"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["une suite d'applications ",(0,r.jsx)(s.a,{href:"https://www.python.org/",children:"Python"}),","]}),"\n",(0,r.jsxs)(s.li,{children:["d\xe9velopp\xe9es avec l'aide du framework ",(0,r.jsx)(s.a,{href:"https://www.djangoproject.com/",children:"Django"}),","]}),"\n",(0,r.jsxs)(s.li,{children:["ses d\xe9pendances sont g\xe9r\xe9es avec ",(0,r.jsx)(s.a,{href:"https://python-poetry.org/",children:"Poetry"}),","]}),"\n",(0,r.jsxs)(s.li,{children:["le tout tournant dans des conteneurs ",(0,r.jsx)(s.a,{href:"https://www.docker.com/",children:"Docker"})," en production comme en d\xe9veloppement."]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Si vous ne vous sentez pas \xe0 l'aise avec la pile logicielle, la meilleure chose \xe0 faire est d'aller chercher des tutoriels. Avec un peu de chance on compilera notre propre liste de ressources ici un de ces jours \ud83d\ude05"}),"\n",(0,r.jsx)(s.admonition,{title:"Attention",type:"warning",children:(0,r.jsx)(s.p,{children:"En particulier, des connaissances de bases avec Git feront une diff\xe9rence. C'est assez facile de semer le chaos dans un d\xe9p\xf4t quand on ne comprend pas comment le versionnage marche. Il y a des s\xe9curit\xe9s en place, mais vous pourriez avoir beaucoup plus de difficult\xe9s que n\xe9cessaire! Je dis \xe7a par exp\xe9rience \ud83d\ude11"})}),"\n",(0,r.jsx)(s.h2,{id:"installation-locale",children:"Installation locale"}),"\n",(0,r.jsx)(s.p,{children:"Pour coder et tester votre code, vous allez avoir besoin d'une instance (\xe0 peu pr\xe8s) fonctionnelle de TiBillet sur votre ordinateur."}),"\n",(0,r.jsx)(s.p,{children:"V\xe9rifions que vous avez l'outillage requis sous la main. Vous avez besoin de :"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Docker CLI et l'extension ",(0,r.jsx)(s.code,{children:"docker-compose"}),","]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"git"}),","]}),"\n",(0,r.jsx)(s.li,{children:"un compte Github avec une cl\xe9 SSH enregistr\xe9e (pour un acc\xe8s authentifi\xe9 \xe0 la forge),"}),"\n",(0,r.jsx)(s.li,{children:"un IDE (environnement de d\xe9veloppement). Des coupons pour PyCharm sot disponibles sur demande, mais un IDE g\xe9n\xe9raliste comme VSCodium fonctionne assez bien - c'est ce que j'utilise \ud83d\ude09."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"On va commencer en cr\xe9ant un dossier qui contiendra les diff\xe9rents d\xe9p\xf4ts requis \xe0 sa racine, dans votre dossier de travail par exemple. \xc7a ressemblera \xe0 :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"tibillet-dev\n\u251c\u2500\u2500 Fedow\n\u251c\u2500\u2500 LaBoutik\n\u251c\u2500\u2500 Lespass\n\u251c\u2500\u2500 Test-Driven-Development\n\u2514\u2500\u2500 Traefik\n"})}),"\n",(0,r.jsx)(s.h3,{id:"traefik",children:"Traefik"}),"\n",(0,r.jsxs)(s.p,{children:["On va avoir besoin d'un ",(0,r.jsx)(s.em,{children:"proxy d'application"})," (un outil qui va aider \xe0 rediriger le trafic des conteneurs vers des adresses locales). TiBillet fournit une configuration de base pour un conteneur Trafik + LetsEncrypt (certificats SSL), partons donc l\xe0-dessus :"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Traefik-reverse-proxy.git Traefik\n"})}),"\n",(0,r.jsx)(s.p,{children:"Pour le d\xe9marrer :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cd Traefik\ndocker compose up -d\n"})}),"\n",(0,r.jsxs)(s.p,{children:["Consulter le navigateur \xe0 l'adresse ",(0,r.jsx)(s.a,{href:"https://localhost",children:(0,r.jsx)(s.code,{children:"https://localhost"})})," devrait vous donner un avertissement de s\xe9curit\xe9 sur les certificats auto-sign\xe9s (pas un probl\xe8me dans ce cas pr\xe9cis) et une ",(0,r.jsx)(s.code,{children:"404 page not found"}),". Parfait !"]}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsxs)(s.p,{children:["Rappelez-vous de ",(0,r.jsx)(s.code,{children:"compose up"})," Traefik chaque fois que vous d\xe9marrez une session de travail sur TiBillet."]})}),"\n",(0,r.jsx)(s.h3,{id:"g\xe9n\xe9ration-des-cl\xe9s",children:"G\xe9n\xe9ration des cl\xe9s"}),"\n",(0,r.jsx)("mark",{children:"TODO: \xe0 simplifier ? lourd et compliqu\xe9 pour aucune raison valable"}),"\n",(0,r.jsxs)(s.p,{children:["Pour g\xe9n\xe9rer les cl\xe9s n\xe9cessaires \xe0 la configuration des moteurs, \xe0 l'heure actuelle, on ",(0,r.jsx)(s.em,{children:"pull"})," l'image Docker de la version production de Fedow, puis on lance quelques commandes dans l'environnement de Poetry."]}),"\n",(0,r.jsx)(s.p,{children:"Pour chaque moteur, on aura besoin :"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["d'une ou deux cl\xe9s Fernet (pour le champ ",(0,r.jsx)(s.code,{children:"FERNET_KEY"})," et possiblement des mots de passe),"]}),"\n",(0,r.jsxs)(s.li,{children:["d'une cl\xe9 secr\xe8te Django (pour le champ ",(0,r.jsx)(s.code,{children:"SECRET_KEY"}),")."]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Vous pouvez g\xe9n\xe9rer 30 cl\xe9s uniques de chaque type en lan\xe7ant les commandes :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"docker run --rm tibillet/fedow poetry run python3 -c \"from cryptography.fernet import Fernet; print('\\n'.join([Fernet.generate_key().decode('utf-8') for i in range(0,30)]))\"\ndocker run --rm tibillet/fedow poetry run python3 -c \"from django.core.management.utils import get_random_secret_key; print('\\n'.join([get_random_secret_key() for i in range(0,30)]))\"\n"})}),"\n",(0,r.jsx)(s.p,{children:"La premi\xe8re commande prendra quelques minutes, vu qu'elle t\xe9l\xe9charge une image Docker. Gardez les cl\xe9s quelque part, on s'en servira au moment de la mise en place des moteurs."}),"\n",(0,r.jsxs)(s.p,{children:["On aura \xe9galement besoin d'une cl\xe9 de test Stripe pour le champ ",(0,r.jsx)(s.code,{children:"STRIPE_KEY_TEST"}),". Stripe est actuellement la solution de paiement qui se charge de la conversion cash en cashless. Une cl\xe9 de test peut \xeatre obtenue en se cr\xe9ant un compte gratuit, puis and allant dans le Mode test -> Cl\xe9 API de test. Alternativement, demandez \xe0 l'\xe9quipe."]}),"\n",(0,r.jsx)(s.h3,{id:"fedow-lespass-laboutik",children:"Fedow, Lespass, LaBoutik"}),"\n",(0,r.jsx)(s.p,{children:"D\xe9marrons en clonant les d\xe9p\xf4ts des diff\xe9rents moteurs :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Fedow.git\ngit clone git@github.com:TiBillet/Lespass.git\ngit clone git@github.com:TiBillet/LaBoutik.git\n"})}),"\n",(0,r.jsx)(s.p,{children:"\xc0 partir de l\xe0, on a besoin d'\xe9crire un peu de configuration. \xc7a sera plus simple \xe0 l'avenir, prenez patience \ud83d\ude0b"}),"\n",(0,r.jsxs)(s.p,{children:["Chaque moteur a besoin de son propre fichier ",(0,r.jsx)(s.code,{children:".env"}),", que vous pouvez baser sur les fichiers ",(0,r.jsx)(s.code,{children:"env_example"})," qu'on vient de cloner."]}),"\n",(0,r.jsx)(s.admonition,{title:"Attention",type:"warning",children:(0,r.jsxs)(s.p,{children:["Toute variable d'environnement, doit \xeatre trouvable dans le fichier ",(0,r.jsx)(s.code,{children:".env"}),". Pas de suppression de variable ! Elle peut par contre suivant les cas rester vide (nullable)."]})}),"\n",(0,r.jsx)(s.h4,{id:"environnement-fedow",children:"Environnement Fedow"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp Fedow/env_example Fedow/.env\n"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Nom"}),(0,r.jsx)(s.th,{children:"Environnement cible"}),(0,r.jsx)(s.th,{children:"Nullable"}),(0,r.jsx)(s.th,{children:"Valeur par d\xe9faut"}),(0,r.jsx)(s.th,{children:"Notes"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SECRET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s secr\xe8tes Django g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FERNET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s Fernet g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_KEY"})}),(0,r.jsx)(s.td,{children:"Production"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Cl\xe9 API de votre compte Stripe"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DOMAIN"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"fedow.tibillet.localhost"})}),(0,r.jsx)(s.td,{children:"\xc0 adapter \xe0 votre nom de domaine et sous-domaine en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_KEY_TEST"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Cl\xe9 API de test de votre compte Stripe"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_TEST"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsxs)(s.td,{children:["Passer \xe0 1 si ",(0,r.jsx)(s.code,{children:"STRIPE_KEY_TEST"})," est rempli"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_ENDPOINT_SECRET_TEST"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Aucune id\xe9e"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DEBUG"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour le d\xe9veloppement"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"TEST"})}),(0,r.jsx)(s.td,{children:"Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour les tests"})]})]})]}),"\n",(0,r.jsx)(s.h4,{id:"environnement-lespass",children:"Environnement Lespass"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp Lespass/env_example Lespass/.env\n"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Nom"}),(0,r.jsx)(s.th,{children:"Environnement cible"}),(0,r.jsx)(s.th,{children:"Nullable"}),(0,r.jsx)(s.th,{children:"Valeur par d\xe9faut"}),(0,r.jsx)(s.th,{children:"Notes"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SECRET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s secr\xe8tes Django g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FERNET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s Fernet g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_KEY"})}),(0,r.jsx)(s.td,{children:"Production"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Cl\xe9 API de votre compte Stripe"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DOMAIN"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"tibillet.localhost"})}),(0,r.jsx)(s.td,{children:"\xc0 adapter \xe0 votre nom de domaine en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SUB"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"lespass"})}),(0,r.jsx)(s.td,{children:"Sous-domaine de l'instance, \xe0 adapter en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"META"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"agenda"})}),(0,r.jsx)(s.td,{children:"Sous-domaine de l'agenda f\xe9d\xe9r\xe9, \xe0 adapter en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FEDOW_DOMAIN"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"agenda"})}),(0,r.jsx)(s.td,{children:"Sous-domaine de l'agenda f\xe9d\xe9r\xe9, \xe0 adapter en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"PUBLIC"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"TiBillet Coop."}),(0,r.jsx)(s.td,{children:"Nom de l'instance principale"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"TIME_ZONE"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"Europe/Paris"}),(0,r.jsx)(s.td,{children:"Plage horaire TZ de l'instance"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"ADMIN_EMAIL"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Email administrateur (pour le\u22c5a premier\u22c5e admin)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_DB"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"lespass"}),(0,r.jsx)(s.td,{children:"\xc0 changer en production si n\xe9cessaire"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_USER"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"lespass_postgres"}),(0,r.jsx)(s.td,{children:"\xc0 changer en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_PASSWORD"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Mot de passe fort (une des cl\xe9s Fernets par exemple)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"EMAIL_HOST"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_PORT"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_HOST_USER"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_HOST_PASSWORD"})]}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Serveur d'email, requis pour confirmer des abonn\xe9\u22c5es par exemple"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_KEY_TEST"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Cl\xe9 API de test de votre compte Stripe"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_TEST"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsxs)(s.td,{children:["Passer \xe0 1 si ",(0,r.jsx)(s.code,{children:"STRIPE_KEY_TEST"})," est rempli"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DEBUG"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour le d\xe9veloppement"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"TEST"})}),(0,r.jsx)(s.td,{children:"Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour les tests"})]})]})]}),"\n",(0,r.jsx)(s.h4,{id:"environnement-laboutik",children:"Environnement LaBoutik"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp LaBoutik/env_example LaBoutik/.env\n"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Nom"}),(0,r.jsx)(s.th,{children:"Environnement cible"}),(0,r.jsx)(s.th,{children:"Nullable"}),(0,r.jsx)(s.th,{children:"Valeur par d\xe9faut"}),(0,r.jsx)(s.th,{children:"Notes"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SECRET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s secr\xe8tes Django g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FERNET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s Fernet g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DOMAIN"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"laboutik.tibillet.localhost"})}),(0,r.jsx)(s.td,{children:"\xc0 adapter \xe0 votre nom de domaine et sous-domaine en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FEDOW_URL"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"https://fedow.tibillet.localhost/",children:"https://fedow.tibillet.localhost/"})}),(0,r.jsx)(s.td,{children:"URL du moteur Fedow"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"LESPASS_TENANT_URL"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"https://lespass.tibillet.localhost/",children:"https://lespass.tibillet.localhost/"})}),(0,r.jsx)(s.td,{children:"URL de l'instance Lespass"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"TIME_ZONE"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"Europe/Paris"}),(0,r.jsx)(s.td,{children:"Plage horaire TZ de l'instance"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"ADMIN_EMAIL"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Email administrateur (pour le\u22c5a premier\u22c5e admin)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"MAIN_ASSET_NAME"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Le nom de votre unit\xe9 de valeur cashless (Pi\xe9cette, CoeurDor\u2026 comme vous voulez)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_DB"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"laboutik"}),(0,r.jsx)(s.td,{children:"\xc0 changer en production si n\xe9cessaire"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_USER"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"laboutik_user"}),(0,r.jsx)(s.td,{children:"\xc0 changer en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_PASSWORD"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Mot de passe fort (une des cl\xe9s Fernets par exemple)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"EMAIL_HOST"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_PORT"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_HOST_USER"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_HOST_PASSWORD"})]}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Serveur d'email, requis pour confirmer des abonn\xe9\u22c5es par exemple"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"BORG_PASSPHRASE"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Mot de passe utilis\xe9 pour la sauvegarde des donn\xe9es"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DEBUG"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour le d\xe9veloppement"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"TEST"})}),(0,r.jsx)(s.td,{children:"Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour les tests"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DEMO"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour une simulation de terminal de caisse"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SENTRY_DNS"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Sentry Debug pour le back-end"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"SENTRY_FRONT_DNS"}),", ",(0,r.jsx)(s.code,{children:"SENTRY_FRONT_ASSET"})]}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Sentry Debug pour le front-end"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"DEMO_TAGID_CM"}),", ",(0,r.jsx)(s.code,{children:"DEMO_TAGID_CLIENT1"}),", ",(0,r.jsx)(s.code,{children:"DEMO_TAGID_CLIENT2"})]}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Aucune id\xe9e"})]})]})]}),"\n",(0,r.jsx)(s.p,{children:"La configuration devrait \xeatre maintenant compl\xe8te pour les trois moteurs."}),"\n",(0,r.jsx)(s.h3,{id:"mise-en-place-des-tests",children:"Mise en place des tests"}),"\n",(0,r.jsx)(s.p,{children:"Pour une raison\u2026 une raison, l'image Docker de dev est assembl\xe9e \xe0 partir des tests. L'installation est similaire au moteurs :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Test-Driven-Development.git\ncp Test-Driven-Development/env_example Test-Driven-Development/.env\n"})}),"\n",(0,r.jsx)(s.p,{children:"C'est fait \u263a\ufe0f On peut maintenant conteneuriser l'application enti\xe8re depuis le dossier des tests :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose up -d\n"})}),"\n",(0,r.jsx)(s.p,{children:"Vous pouvez acc\xe9der en prime aux logs avec la commande :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose logs -f\n"})}),"\n",(0,r.jsx)(s.admonition,{title:"Attention",type:"warning",children:(0,r.jsxs)(s.p,{children:["Ce ",(0,r.jsx)(s.code,{children:"docker-compose.yml"})," en particulier s'appuie sur la structure d\xe9crite au d\xe9but de l'installation, donc sur la structure du dossier ",(0,r.jsx)(s.em,{children:"parent"})," aux tests, appel\xe9 pour l'exemple ",(0,r.jsx)(s.code,{children:"tibillet-dev"}),". Contre-intuitif, mais maintenant vous savez \ud83d\ude09"]})}),"\n",(0,r.jsx)(s.h3,{id:"d\xe9marrage-des-moteurs",children:"D\xe9marrage des moteurs"}),"\n",(0,r.jsxs)(s.p,{children:["La principale diff\xe9rence entre les conteneurs de dev et de prod, c'est qu'en dev la commande ",(0,r.jsx)(s.code,{children:"docker compose"})," ne d\xe9marre pas les applications Django individuelles. C'est un niveau de contr\xf4le fin qui est utile pour le d\xe9veloppement, mais \xe7a veut dire que vous avez besoin de les lancer manuellement."]}),"\n",(0,r.jsx)(s.p,{children:"On va les lancer de pr\xe9f\xe9rence dans l'ordre :"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsx)(s.li,{children:"Fedow"}),"\n",(0,r.jsx)(s.li,{children:"Lespass"}),"\n",(0,r.jsx)(s.li,{children:"LaBoutik (qui a besoin des deux autres pour fonctionner)"}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["Les outils dont on a besoin sont dans les conteneurs, nomm\xe9s d'apr\xe8s leur moteur : ",(0,r.jsx)(s.code,{children:"fedow_django"}),", ",(0,r.jsx)(s.code,{children:"lespass_django"})," et enfin ",(0,r.jsx)(s.code,{children:"laboutik_django"}),". Pour rentrer dans un conteneur (exemple avec Fedow) :"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"# on d\xe9marre un environnement bash dans le conteneur fedow_django\ndocker exec -ti fedow_django bash\n"})}),"\n",(0,r.jsx)(s.p,{children:"\xc0 partir de l\xe0, on a quelques options."}),"\n",(0,r.jsxs)(s.p,{children:["La premi\xe8re, c'est le script ",(0,r.jsx)(s.code,{children:"flush.sh"}),". Il initialise les donn\xe9es de test et d\xe9marre Django dans la foul\xe9e. C'est cette commande qu'on va utiliser au ",(0,r.jsx)(s.strong,{children:"premier d\xe9marrage"})," de notre application :"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="fedow_django$"',children:"./flush.sh\n"})}),"\n",(0,r.jsxs)(s.p,{children:["On l'utilisera aussi quand on veut ",(0,r.jsx)(s.strong,{children:"r\xe9initialiser"})," les donn\xe9es, par exemple avant de lancer les tests automatis\xe9s qui ont besoin de ces donn\xe9es pr\xe9visibles."]}),"\n",(0,r.jsx)(s.p,{children:"Pour le reste des manipulation dans le conteneur, on a besoin de rentrer dans l'environnement de Poetry, car on va lancer du Python."}),"\n",(0,r.jsx)(s.p,{children:"Pour lancer l'environnement virtuel de Poetry depuis le conteneur :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="fedow_django$"',children:" # on d\xe9marre l'environnement virtuel qui prend en charge les d\xe9pendances python\npoetry shell\n"})}),"\n",(0,r.jsxs)(s.p,{children:["Bien, \xe7a va nous simplifier le d\xe9veloppement Django, qui se g\xe8re habituellement avec un script appel\xe9 ",(0,r.jsx)(s.code,{children:"manage.py"}),". Deux commandes nous int\xe9ressent \xe0 l'heure actuelle :"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"rsp"})," (alias de ",(0,r.jsx)(s.code,{children:"./manage.py runserver 0.0.0.0:8000"}),") d\xe9marre Django sans r\xe9initialiser les donn\xe9es. \xc7a nous servira quand on veut garder des donn\xe9es entre deux d\xe9marrages. G\xe9n\xe9ralement, si on a pas besoin de lancer les tests, c'est cette commande qu'on utilise plut\xf4t que ",(0,r.jsx)(s.code,{children:"flush"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Optionnellement, si on a des bugs graphiques, on peut tenter ",(0,r.jsx)(s.code,{children:"./manage.py collectstatic"}),". Parfois, les ressources graphiques ne sont pas correctement copi\xe9es au premier d\xe9marrage, et \xe7a peut r\xe9gler le probl\xe8me."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Plus qu'\xe0 d\xe9marrer les trois moteurs de TiBillet dans l'ordre indiqu\xe9 pr\xe9c\xe9demment : Fedow, Lespass, puis LaBoutik !"}),"\n",(0,r.jsxs)(s.admonition,{title:"Cr\xe9ation d'alias",type:"tip",children:[(0,r.jsx)(s.p,{children:"La commande Docker devient vite r\xe9p\xe9titive. Pourquoi ne pas cr\xe9er un alias, ou m\xeame une petite fonction bash pour gagner du temps et soulager son canal carpien par la m\xeame occasion ? Voil\xe0 ma fonction :"}),(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="~/.bashrc"',children:"function dockex {\n docker exec -ti $1 bash\n}\n"})}),(0,r.jsx)(s.p,{children:"Il suffit d'ouvrir un nouveau terminal pour que la fonction s'ajoute \xe0 l'environnement. Il y a m\xeame sans doule moyen d'ajouter poetry \xe0 tout \xe7a si vous cherchez un peu !"})]}),"\n",(0,r.jsx)(s.h3,{id:"\xe7a-tourne-",children:"\xc7a tourne ?"}),"\n",(0,r.jsx)(s.p,{children:"Si vous avez utilis\xe9 la configuration des sous-domaines par d\xe9faut, vous avez maintenant acc\xe8s :"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["au moteur de f\xe9d\xe9ration Fedow sur ",(0,r.jsx)(s.a,{href:"https://fedow.tibillet.localhost",children:"fedow.tibillet.localhost"}),","]}),"\n",(0,r.jsxs)(s.li,{children:["\xe0 une instance du moteur de billetterie Lespass sur ",(0,r.jsx)(s.a,{href:"https://lespass.tibillet.localhost",children:"lespass.tibillet.localhost"}),","]}),"\n",(0,r.jsxs)(s.li,{children:["au serveur de caisse LaBoutik sur ",(0,r.jsx)(s.a,{href:"https://laboutik.tibillet.localhost",children:"laboutik.tibillet.localhost"})]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Si tout marche comme pr\xe9vu, f\xe9licitations : vous \xeates pr\xeat\u22c5es \xe0 vous lancer \ud83d\udd27"}),"\n",(0,r.jsx)(s.p,{children:"Sinon, venez nous en parler, on est l\xe0 pour aider !"}),"\n",(0,r.jsxs)(s.admonition,{title:"Pour conclure",type:"note",children:[(0,r.jsxs)(s.p,{children:["N'oubliez pas de ",(0,r.jsx)(s.code,{children:"docker compose down"})," \xe0 la fois dans les tests et dans Trafik quand vous avez fini votre session de travail. Votre ordinateur aussi a besoin de faire des pauses !"]}),(0,r.jsxs)(s.p,{children:["Si vous avez peur de ne pas vous en souvenir, enlevez l'option ",(0,r.jsx)(s.code,{children:"-d"})," \xe0 ",(0,r.jsx)(s.code,{children:"compose up"})," et la commande se lancera directement dans le terminal, pas en t\xe2che de fond. C'est pas grave, vous aurez juste besoin de plus d'onglets \ud83d\ude0b"]})]}),"\n",(0,r.jsx)(s.h2,{id:"cycle-de-vie",children:"Cycle de vie"}),"\n",(0,r.jsx)(s.h3,{id:"mises-\xe0-jour",children:"Mises \xe0 jour"}),"\n",(0,r.jsx)(s.p,{children:"Pour rester \xe0 jour durant le d\xe9veloppement, t\xe9l\xe9charger l'image la plus r\xe9cente :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose pull\ndocker compose up -d # d\xe9marrer ou red\xe9marrer les conteneurs\n"})}),"\n",(0,r.jsx)(s.h3,{id:"tests",children:"Tests"}),"\n",(0,r.jsx)(s.p,{children:"Vous pouvez lancer les tests Python de la m\xeame fa\xe7on que pour un d\xe9marrage manuel. Commencez par r\xe9initialiser les trois app Django pour obtenir les donn\xe9es testables, puis lancez cette commande depuis votre conteneur Django LaBoutik :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="laboutik_django> poetry shell$"',children:"./manage.py test\n"})}),"\n",(0,r.jsx)("mark",{children:"TODO: docs des tests end-to-end (ils existent !)"}),"\n",(0,r.jsx)(s.h3,{id:"sauvegardes",children:"Sauvegardes"}),"\n",(0,r.jsxs)(s.p,{children:["Avant de vous attaquer \xe0 un changement majeur, sauvegardez toute donn\xe9e qui a de la valeur pour votre d\xe9veloppement. Sur votre instance Fedow, par exemple, il suffit de sauvegarder le dossier ",(0,r.jsx)(s.code,{children:"database"})," r\xe9guli\xe8rement. Les autres moteurs peuvent \xeatre sauvegard\xe9s par l'utilitaire Borgbackup, des t\xe2ches cron et des dump de bases de donn\xe9es. Plus sur ce sujet \xe0 l'avenir."]}),"\n",(0,r.jsx)("mark",{children:"TODO: explications d\xe9taill\xe9es"})]})}function u(e={}){const{wrapper:s}={...(0,d.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},1621:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>l});var r=n(6663);const d={},i=r.createContext(d);function t(e){const s=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:t(e.components),r.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocumentation_v_2=self.webpackChunkdocumentation_v_2||[]).push([[639],{2540:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>o,contentTitle:()=>t,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=n(6271),d=n(1621);const i={sidebar_position:1,slug:"development",title:"D\xe9veloppement",keywords:["contribuer","b\xe9n\xe9volat","open source","git","pull request","issue","soutien","code","d\xe9veloppement","programmation","python","django","docker","poetry","tests","tdd"],tags:["contribuer","open source","git","soutien","tdd","python","django","docker","poetry"],authors:"kaya"},t="D\xe9veloppement",l={id:"contribute/dev",title:"D\xe9veloppement",description:"Vous voulez aider au d\xe9veloppement de TiBillet? Merci! C'est gr\xe2ce aux gens comme vous que l'open-source fonctionne \ud83d\ude4f",source:"@site/i18n/fr/docusaurus-plugin-content-docs/current/contribute/dev.md",sourceDirName:"contribute",slug:"/contribute/development",permalink:"/fr/docs/contribute/development",draft:!1,unlisted:!1,editUrl:"https://github.com/TiBillet/documentation/tree/main/tibillet/docs/contribute/dev.md",tags:[{inline:!0,label:"contribuer",permalink:"/fr/docs/tags/contribuer"},{inline:!0,label:"open source",permalink:"/fr/docs/tags/open-source"},{inline:!0,label:"git",permalink:"/fr/docs/tags/git"},{inline:!0,label:"soutien",permalink:"/fr/docs/tags/soutien"},{inline:!0,label:"tdd",permalink:"/fr/docs/tags/tdd"},{inline:!0,label:"python",permalink:"/fr/docs/tags/python"},{inline:!0,label:"django",permalink:"/fr/docs/tags/django"},{inline:!0,label:"docker",permalink:"/fr/docs/tags/docker"},{inline:!0,label:"poetry",permalink:"/fr/docs/tags/poetry"}],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1,slug:"development",title:"D\xe9veloppement",keywords:["contribuer","b\xe9n\xe9volat","open source","git","pull request","issue","soutien","code","d\xe9veloppement","programmation","python","django","docker","poetry","tests","tdd"],tags:["contribuer","open source","git","soutien","tdd","python","django","docker","poetry"],authors:"kaya"},sidebar:"tutorialSidebar",previous:{title:"Contribution guides",permalink:"/fr/docs/category/contribution-guides"},next:{title:"API",permalink:"/fr/docs/category/api"}},o={},c=[{value:"M\xe9thodes de travail",id:"m\xe9thodes-de-travail",level:2},{value:"Outils et langages utilis\xe9s",id:"outils-et-langages-utilis\xe9s",level:2},{value:"Installation locale",id:"installation-locale",level:2},{value:"Traefik",id:"traefik",level:3},{value:"G\xe9n\xe9ration des cl\xe9s",id:"g\xe9n\xe9ration-des-cl\xe9s",level:3},{value:"Fedow, Lespass, LaBoutik",id:"fedow-lespass-laboutik",level:3},{value:"Environnement Fedow",id:"environnement-fedow",level:4},{value:"Environnement Lespass",id:"environnement-lespass",level:4},{value:"Environnement LaBoutik",id:"environnement-laboutik",level:4},{value:"Mise en place des tests",id:"mise-en-place-des-tests",level:3},{value:"D\xe9marrage des moteurs",id:"d\xe9marrage-des-moteurs",level:3},{value:"\xc7a tourne ?",id:"\xe7a-tourne-",level:3},{value:"Cycle de vie",id:"cycle-de-vie",level:2},{value:"Mises \xe0 jour",id:"mises-\xe0-jour",level:3},{value:"Tests",id:"tests",level:3},{value:"Sauvegardes",id:"sauvegardes",level:3}];function a(e){const s={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"d\xe9veloppement",children:"D\xe9veloppement"})}),"\n",(0,r.jsx)(s.p,{children:"Vous voulez aider au d\xe9veloppement de TiBillet? Merci! C'est gr\xe2ce aux gens comme vous que l'open-source fonctionne \ud83d\ude4f"}),"\n",(0,r.jsxs)(s.p,{children:["Premi\xe8rement, si vous n'avez pas une t\xe2che pr\xe9cise en t\xeate, allez voir les tickets ouverts sur les ",(0,r.jsx)(s.a,{href:"https://github.com/orgs/TiBillet/projects?query=is%3Aopen",children:"d\xe9p\xf4ts Github"})," officiels."]}),"\n",(0,r.jsx)(s.p,{children:"C'est le moyen le plus simple de comprendre quels sont les probl\xe8mes \xe0 r\xe9soudre et quelles fonctionnalit\xe9s sont demand\xe9es."}),"\n",(0,r.jsxs)(s.admonition,{title:"Les d\xe9p\xf4ts",type:"note",children:[(0,r.jsx)(s.p,{children:'Les d\xe9p\xf4ts \xe9pingl\xe9s ("Pinned") sur la page de l\'organisation devraient suffire. Si vous avez des doutes sur les r\xf4les respectifs de Fedow, LaBoutik ou Lespass, r\xe9visez les bases sur les trois moteurs de TiBillet.'}),(0,r.jsxs)(s.p,{children:[(0,r.jsx)("mark",{children:"TODO: lien doc vers les moteurs et leur r\xf4le"})," (une page dans pr\xe9sentation probablement)"]})]}),"\n",(0,r.jsx)(s.h2,{id:"m\xe9thodes-de-travail",children:"M\xe9thodes de travail"}),"\n",(0,r.jsxs)(s.p,{children:["Quand on travaille avec des ",(0,r.jsx)(s.em,{children:"forges Git"})," comme Github, il y a des fa\xe7ons d'aider qui rendent votre contribution plus facile \xe0 prendre en compte :"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Si vous ne faites pas partie de l'organisation (avec les acc\xe8s au d\xe9p\xf4t), faites un ",(0,r.jsx)(s.em,{children:"fork"})," (d\xe9doublement) du d\xe9p\xf4t qui vous int\xe9resse, travaillez \xe0 partir de celui-ci et soumettez vous modifications par le biais d'une ",(0,r.jsx)(s.em,{children:"pull request"})," (demande de fusion)."]}),"\n",(0,r.jsx)(s.li,{children:"Si vous avez un ticket sur lequel vous souhaitez travailler, v\xe9rifiez s'il n'existe pas d\xe9j\xe0. Si c'est le cas, rejoignez la discussion plut\xf4t que de faire la m\xeame chose en parall\xe8le!"}),"\n",(0,r.jsxs)(s.li,{children:["Quand vous d\xe9marrez le travail sur un ticket, ",(0,r.jsx)(s.strong,{children:"assignez-vous"})," dessus pour informer les autres qu'un chantier est en cours."]}),"\n",(0,r.jsxs)(s.li,{children:["Enfin, un point important: ",(0,r.jsx)(s.strong,{children:"ne cr\xe9ez pas de demandes de fusion sans avoir fait tourner les tests"})," ! \xc7a arrive aux meilleur\u22c5es d'entre nous. Id\xe9alement, vous devriez les faire tourner avant chaque ",(0,r.jsx)(s.em,{children:"commit"}),", avec l'aide d'un ",(0,r.jsx)(s.em,{children:"git hook"})," (d\xe9clencheur automatique) par exemple."]}),"\n"]}),"\n",(0,r.jsx)(s.admonition,{title:"Trouver de l'aide",type:"note",children:(0,r.jsxs)(s.p,{children:["Si vous avez des questions sur Git, Github, ou un aspect du d\xe9veloppement, rejoignez-nous sur le serveur ",(0,r.jsx)(s.a,{href:"https://discord.gg/7FJvtYx",children:"Discord"})," ou ",(0,r.jsx)(s.a,{href:"https://matrix.to/#/#tibillet:tiers-lieux.org",children:"Matrix"}),". Nous ferons de notre mieux pour aider !"]})}),"\n",(0,r.jsx)(s.h2,{id:"outils-et-langages-utilis\xe9s",children:"Outils et langages utilis\xe9s"}),"\n",(0,r.jsx)(s.p,{children:"TiBillet, c'est :"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["une suite d'applications ",(0,r.jsx)(s.a,{href:"https://www.python.org/",children:"Python"}),","]}),"\n",(0,r.jsxs)(s.li,{children:["d\xe9velopp\xe9es avec l'aide du framework ",(0,r.jsx)(s.a,{href:"https://www.djangoproject.com/",children:"Django"}),","]}),"\n",(0,r.jsxs)(s.li,{children:["ses d\xe9pendances sont g\xe9r\xe9es avec ",(0,r.jsx)(s.a,{href:"https://python-poetry.org/",children:"Poetry"}),","]}),"\n",(0,r.jsxs)(s.li,{children:["le tout tournant dans des conteneurs ",(0,r.jsx)(s.a,{href:"https://www.docker.com/",children:"Docker"})," en production comme en d\xe9veloppement."]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Si vous ne vous sentez pas \xe0 l'aise avec la pile logicielle, la meilleure chose \xe0 faire est d'aller chercher des tutoriels. Avec un peu de chance on compilera notre propre liste de ressources ici un de ces jours \ud83d\ude05"}),"\n",(0,r.jsx)(s.admonition,{title:"Attention",type:"warning",children:(0,r.jsx)(s.p,{children:"En particulier, des connaissances de bases avec Git feront une diff\xe9rence. C'est assez facile de semer le chaos dans un d\xe9p\xf4t quand on ne comprend pas comment le versionnage marche. Il y a des s\xe9curit\xe9s en place, mais vous pourriez avoir beaucoup plus de difficult\xe9s que n\xe9cessaire! Je dis \xe7a par exp\xe9rience \ud83d\ude11"})}),"\n",(0,r.jsx)(s.h2,{id:"installation-locale",children:"Installation locale"}),"\n",(0,r.jsx)(s.p,{children:"Pour coder et tester votre code, vous allez avoir besoin d'une instance (\xe0 peu pr\xe8s) fonctionnelle de TiBillet sur votre ordinateur."}),"\n",(0,r.jsx)(s.p,{children:"V\xe9rifions que vous avez l'outillage requis sous la main. Vous avez besoin de :"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Docker CLI et l'extension ",(0,r.jsx)(s.code,{children:"docker-compose"}),","]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"git"}),","]}),"\n",(0,r.jsx)(s.li,{children:"un compte Github avec une cl\xe9 SSH enregistr\xe9e (pour un acc\xe8s authentifi\xe9 \xe0 la forge),"}),"\n",(0,r.jsx)(s.li,{children:"un IDE (environnement de d\xe9veloppement). Des coupons pour PyCharm sot disponibles sur demande, mais un IDE g\xe9n\xe9raliste comme VSCodium fonctionne assez bien - c'est ce que j'utilise \ud83d\ude09."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"On va commencer en cr\xe9ant un dossier qui contiendra les diff\xe9rents d\xe9p\xf4ts requis \xe0 sa racine, dans votre dossier de travail par exemple. \xc7a ressemblera \xe0 :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"tibillet-dev\n\u251c\u2500\u2500 Fedow\n\u251c\u2500\u2500 LaBoutik\n\u251c\u2500\u2500 Lespass\n\u251c\u2500\u2500 Test-Driven-Development\n\u2514\u2500\u2500 Traefik\n"})}),"\n",(0,r.jsx)(s.h3,{id:"traefik",children:"Traefik"}),"\n",(0,r.jsxs)(s.p,{children:["On va avoir besoin d'un ",(0,r.jsx)(s.em,{children:"proxy d'application"})," (un outil qui va aider \xe0 rediriger le trafic des conteneurs vers des adresses locales). TiBillet fournit une configuration de base pour un conteneur Trafik + LetsEncrypt (certificats SSL), partons donc l\xe0-dessus :"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Traefik-reverse-proxy.git Traefik\n"})}),"\n",(0,r.jsx)(s.p,{children:"Pour le d\xe9marrer :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cd Traefik\ndocker compose up -d\n"})}),"\n",(0,r.jsxs)(s.p,{children:["Consulter le navigateur \xe0 l'adresse ",(0,r.jsx)(s.a,{href:"https://localhost",children:(0,r.jsx)(s.code,{children:"https://localhost"})})," devrait vous donner un avertissement de s\xe9curit\xe9 sur les certificats auto-sign\xe9s (pas un probl\xe8me dans ce cas pr\xe9cis) et une ",(0,r.jsx)(s.code,{children:"404 page not found"}),". Parfait !"]}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsxs)(s.p,{children:["Rappelez-vous de ",(0,r.jsx)(s.code,{children:"compose up"})," Traefik chaque fois que vous d\xe9marrez une session de travail sur TiBillet."]})}),"\n",(0,r.jsx)(s.h3,{id:"g\xe9n\xe9ration-des-cl\xe9s",children:"G\xe9n\xe9ration des cl\xe9s"}),"\n",(0,r.jsx)("mark",{children:"TODO: \xe0 simplifier ? lourd et compliqu\xe9 pour aucune raison valable"}),"\n",(0,r.jsxs)(s.p,{children:["Pour g\xe9n\xe9rer les cl\xe9s n\xe9cessaires \xe0 la configuration des moteurs, \xe0 l'heure actuelle, on ",(0,r.jsx)(s.em,{children:"pull"})," l'image Docker de la version production de Fedow, puis on lance quelques commandes dans l'environnement de Poetry."]}),"\n",(0,r.jsx)(s.p,{children:"Pour chaque moteur, on aura besoin :"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["d'une ou deux cl\xe9s Fernet (pour le champ ",(0,r.jsx)(s.code,{children:"FERNET_KEY"})," et possiblement des mots de passe),"]}),"\n",(0,r.jsxs)(s.li,{children:["d'une cl\xe9 secr\xe8te Django (pour le champ ",(0,r.jsx)(s.code,{children:"SECRET_KEY"}),")."]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Vous pouvez g\xe9n\xe9rer 30 cl\xe9s uniques de chaque type en lan\xe7ant les commandes :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"docker run --rm tibillet/fedow poetry run python3 -c \"from cryptography.fernet import Fernet; print('\\n'.join([Fernet.generate_key().decode('utf-8') for i in range(0,30)]))\"\ndocker run --rm tibillet/fedow poetry run python3 -c \"from django.core.management.utils import get_random_secret_key; print('\\n'.join([get_random_secret_key() for i in range(0,30)]))\"\n"})}),"\n",(0,r.jsx)(s.p,{children:"La premi\xe8re commande prendra quelques minutes, vu qu'elle t\xe9l\xe9charge une image Docker. Gardez les cl\xe9s quelque part, on s'en servira au moment de la mise en place des moteurs."}),"\n",(0,r.jsxs)(s.p,{children:["On aura \xe9galement besoin d'une cl\xe9 de test Stripe pour le champ ",(0,r.jsx)(s.code,{children:"STRIPE_KEY_TEST"}),". Stripe est actuellement la solution de paiement qui se charge de la conversion cash en cashless. Une cl\xe9 de test peut \xeatre obtenue en se cr\xe9ant un compte gratuit, puis and allant dans le Mode test -> Cl\xe9 API de test. Alternativement, demandez \xe0 l'\xe9quipe."]}),"\n",(0,r.jsx)(s.h3,{id:"fedow-lespass-laboutik",children:"Fedow, Lespass, LaBoutik"}),"\n",(0,r.jsx)(s.p,{children:"D\xe9marrons en clonant les d\xe9p\xf4ts des diff\xe9rents moteurs :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Fedow.git\ngit clone git@github.com:TiBillet/Lespass.git\ngit clone git@github.com:TiBillet/LaBoutik.git\n"})}),"\n",(0,r.jsx)(s.p,{children:"\xc0 partir de l\xe0, on a besoin d'\xe9crire un peu de configuration. \xc7a sera plus simple \xe0 l'avenir, prenez patience \ud83d\ude0b"}),"\n",(0,r.jsxs)(s.p,{children:["Chaque moteur a besoin de son propre fichier ",(0,r.jsx)(s.code,{children:".env"}),", que vous pouvez baser sur les fichiers ",(0,r.jsx)(s.code,{children:"env_example"})," qu'on vient de cloner."]}),"\n",(0,r.jsx)(s.admonition,{title:"Attention",type:"warning",children:(0,r.jsxs)(s.p,{children:["Toute variable d'environnement, doit \xeatre trouvable dans le fichier ",(0,r.jsx)(s.code,{children:".env"}),". Pas de suppression de variable ! Elle peut par contre suivant les cas rester vide (nullable)."]})}),"\n",(0,r.jsx)(s.h4,{id:"environnement-fedow",children:"Environnement Fedow"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp Fedow/env_example Fedow/.env\n"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Nom"}),(0,r.jsx)(s.th,{children:"Environnement cible"}),(0,r.jsx)(s.th,{children:"Nullable"}),(0,r.jsx)(s.th,{children:"Valeur par d\xe9faut"}),(0,r.jsx)(s.th,{children:"Notes"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SECRET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s secr\xe8tes Django g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FERNET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s Fernet g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_KEY"})}),(0,r.jsx)(s.td,{children:"Production"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Cl\xe9 API de votre compte Stripe"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DOMAIN"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"fedow.tibillet.localhost"})}),(0,r.jsx)(s.td,{children:"\xc0 adapter \xe0 votre nom de domaine et sous-domaine en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_KEY_TEST"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Cl\xe9 API de test de votre compte Stripe"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_TEST"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsxs)(s.td,{children:["Passer \xe0 1 si ",(0,r.jsx)(s.code,{children:"STRIPE_KEY_TEST"})," est rempli"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_ENDPOINT_SECRET_TEST"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Aucune id\xe9e"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DEBUG"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour le d\xe9veloppement"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"TEST"})}),(0,r.jsx)(s.td,{children:"Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour les tests"})]})]})]}),"\n",(0,r.jsx)(s.h4,{id:"environnement-lespass",children:"Environnement Lespass"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp Lespass/env_example Lespass/.env\n"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Nom"}),(0,r.jsx)(s.th,{children:"Environnement cible"}),(0,r.jsx)(s.th,{children:"Nullable"}),(0,r.jsx)(s.th,{children:"Valeur par d\xe9faut"}),(0,r.jsx)(s.th,{children:"Notes"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SECRET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s secr\xe8tes Django g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FERNET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s Fernet g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_KEY"})}),(0,r.jsx)(s.td,{children:"Production"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Cl\xe9 API de votre compte Stripe"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DOMAIN"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"tibillet.localhost"})}),(0,r.jsx)(s.td,{children:"\xc0 adapter \xe0 votre nom de domaine en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SUB"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"lespass"})}),(0,r.jsx)(s.td,{children:"Sous-domaine de l'instance, \xe0 adapter en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"META"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"agenda"})}),(0,r.jsx)(s.td,{children:"Sous-domaine de l'agenda f\xe9d\xe9r\xe9, \xe0 adapter en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FEDOW_DOMAIN"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"fedow.tibillet.localhost"})}),(0,r.jsx)(s.td,{children:"Domaine et sous-domaine du moteur Fedow"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"PUBLIC"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"TiBillet Coop."}),(0,r.jsx)(s.td,{children:"Nom de l'instance principale"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"TIME_ZONE"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"Europe/Paris"}),(0,r.jsx)(s.td,{children:"Plage horaire TZ de l'instance"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"ADMIN_EMAIL"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Email administrateur (pour le\u22c5a premier\u22c5e admin)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_DB"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"lespass"}),(0,r.jsx)(s.td,{children:"\xc0 changer en production si n\xe9cessaire"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_USER"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"lespass_postgres"}),(0,r.jsx)(s.td,{children:"\xc0 changer en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_PASSWORD"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Mot de passe fort (une des cl\xe9s Fernets par exemple)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"EMAIL_HOST"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_PORT"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_HOST_USER"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_HOST_PASSWORD"})]}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Serveur d'email, requis pour confirmer des abonn\xe9\u22c5es par exemple"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_KEY_TEST"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Cl\xe9 API de test de votre compte Stripe"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"STRIPE_TEST"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsxs)(s.td,{children:["Passer \xe0 1 si ",(0,r.jsx)(s.code,{children:"STRIPE_KEY_TEST"})," est rempli"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DEBUG"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour le d\xe9veloppement"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"TEST"})}),(0,r.jsx)(s.td,{children:"Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour les tests"})]})]})]}),"\n",(0,r.jsx)(s.h4,{id:"environnement-laboutik",children:"Environnement LaBoutik"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"cp LaBoutik/env_example LaBoutik/.env\n"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Nom"}),(0,r.jsx)(s.th,{children:"Environnement cible"}),(0,r.jsx)(s.th,{children:"Nullable"}),(0,r.jsx)(s.th,{children:"Valeur par d\xe9faut"}),(0,r.jsx)(s.th,{children:"Notes"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SECRET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s secr\xe8tes Django g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FERNET_KEY"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Une des cl\xe9s Fernet g\xe9n\xe9r\xe9es pr\xe9c\xe9demment"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DOMAIN"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"laboutik.tibillet.localhost"})}),(0,r.jsx)(s.td,{children:"\xc0 adapter \xe0 votre nom de domaine et sous-domaine en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FEDOW_URL"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"https://fedow.tibillet.localhost/",children:"https://fedow.tibillet.localhost/"})}),(0,r.jsx)(s.td,{children:"URL du moteur Fedow"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"LESPASS_TENANT_URL"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"https://lespass.tibillet.localhost/",children:"https://lespass.tibillet.localhost/"})}),(0,r.jsx)(s.td,{children:"URL de l'instance Lespass"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"TIME_ZONE"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"Europe/Paris"}),(0,r.jsx)(s.td,{children:"Plage horaire TZ de l'instance"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"ADMIN_EMAIL"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Email administrateur (pour le\u22c5a premier\u22c5e admin)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"MAIN_ASSET_NAME"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Le nom de votre unit\xe9 de valeur cashless (Pi\xe9cette, CoeurDor\u2026 comme vous voulez)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_DB"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"laboutik"}),(0,r.jsx)(s.td,{children:"\xc0 changer en production si n\xe9cessaire"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_USER"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"laboutik_user"}),(0,r.jsx)(s.td,{children:"\xc0 changer en production"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POSTGRES_PASSWORD"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Mot de passe fort (une des cl\xe9s Fernets par exemple)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"EMAIL_HOST"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_PORT"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_HOST_USER"}),", ",(0,r.jsx)(s.code,{children:"EMAIL_HOST_PASSWORD"})]}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Serveur d'email, requis pour confirmer des abonn\xe9\u22c5es par exemple"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"BORG_PASSPHRASE"})}),(0,r.jsx)(s.td,{children:"Tous"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Mot de passe utilis\xe9 pour la sauvegarde des donn\xe9es"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DEBUG"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour le d\xe9veloppement"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"TEST"})}),(0,r.jsx)(s.td,{children:"Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour les tests"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DEMO"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Non"}),(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"Passer \xe0 1 pour une simulation de terminal de caisse"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SENTRY_DNS"})}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Sentry Debug pour le back-end"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"SENTRY_FRONT_DNS"}),", ",(0,r.jsx)(s.code,{children:"SENTRY_FRONT_ASSET"})]}),(0,r.jsx)(s.td,{children:"D\xe9veloppement, Tests"}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Sentry Debug pour le front-end"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"DEMO_TAGID_CM"}),", ",(0,r.jsx)(s.code,{children:"DEMO_TAGID_CLIENT1"}),", ",(0,r.jsx)(s.code,{children:"DEMO_TAGID_CLIENT2"})]}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Oui"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Aucune id\xe9e"})]})]})]}),"\n",(0,r.jsx)(s.p,{children:"La configuration devrait \xeatre maintenant compl\xe8te pour les trois moteurs."}),"\n",(0,r.jsx)(s.h3,{id:"mise-en-place-des-tests",children:"Mise en place des tests"}),"\n",(0,r.jsx)(s.p,{children:"Pour une raison\u2026 une raison, l'image Docker de dev est assembl\xe9e \xe0 partir des tests. L'installation est similaire au moteurs :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="tibillet-dev$"',children:"git clone git@github.com:TiBillet/Test-Driven-Development.git\ncp Test-Driven-Development/env_example Test-Driven-Development/.env\n"})}),"\n",(0,r.jsx)(s.p,{children:"C'est fait \u263a\ufe0f On peut maintenant conteneuriser l'application enti\xe8re depuis le dossier des tests :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose up -d\n"})}),"\n",(0,r.jsx)(s.p,{children:"Vous pouvez acc\xe9der en prime aux logs avec la commande :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose logs -f\n"})}),"\n",(0,r.jsx)(s.admonition,{title:"Attention",type:"warning",children:(0,r.jsxs)(s.p,{children:["Ce ",(0,r.jsx)(s.code,{children:"docker-compose.yml"})," en particulier s'appuie sur la structure d\xe9crite au d\xe9but de l'installation, donc sur la structure du dossier ",(0,r.jsx)(s.em,{children:"parent"})," aux tests, appel\xe9 pour l'exemple ",(0,r.jsx)(s.code,{children:"tibillet-dev"}),". Contre-intuitif, mais maintenant vous savez \ud83d\ude09"]})}),"\n",(0,r.jsx)(s.h3,{id:"d\xe9marrage-des-moteurs",children:"D\xe9marrage des moteurs"}),"\n",(0,r.jsxs)(s.p,{children:["La principale diff\xe9rence entre les conteneurs de dev et de prod, c'est qu'en dev la commande ",(0,r.jsx)(s.code,{children:"docker compose"})," ne d\xe9marre pas les applications Django individuelles. C'est un niveau de contr\xf4le fin qui est utile pour le d\xe9veloppement, mais \xe7a veut dire que vous avez besoin de les lancer manuellement."]}),"\n",(0,r.jsx)(s.p,{children:"On va les lancer de pr\xe9f\xe9rence dans l'ordre :"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsx)(s.li,{children:"Fedow"}),"\n",(0,r.jsx)(s.li,{children:"Lespass"}),"\n",(0,r.jsx)(s.li,{children:"LaBoutik (qui a besoin des deux autres pour fonctionner)"}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["Les outils dont on a besoin sont dans les conteneurs, nomm\xe9s d'apr\xe8s leur moteur : ",(0,r.jsx)(s.code,{children:"fedow_django"}),", ",(0,r.jsx)(s.code,{children:"lespass_django"})," et enfin ",(0,r.jsx)(s.code,{children:"laboutik_django"}),". Pour rentrer dans un conteneur (exemple avec Fedow) :"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"# on d\xe9marre un environnement bash dans le conteneur fedow_django\ndocker exec -ti fedow_django bash\n"})}),"\n",(0,r.jsx)(s.p,{children:"\xc0 partir de l\xe0, on a quelques options."}),"\n",(0,r.jsxs)(s.p,{children:["La premi\xe8re, c'est le script ",(0,r.jsx)(s.code,{children:"flush.sh"}),". Il initialise les donn\xe9es de test et d\xe9marre Django dans la foul\xe9e. C'est cette commande qu'on va utiliser au ",(0,r.jsx)(s.strong,{children:"premier d\xe9marrage"})," de notre application :"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="fedow_django$"',children:"./flush.sh\n"})}),"\n",(0,r.jsxs)(s.p,{children:["On l'utilisera aussi quand on veut ",(0,r.jsx)(s.strong,{children:"r\xe9initialiser"})," les donn\xe9es, par exemple avant de lancer les tests automatis\xe9s qui ont besoin de ces donn\xe9es pr\xe9visibles."]}),"\n",(0,r.jsx)(s.p,{children:"Pour le reste des manipulation dans le conteneur, on a besoin de rentrer dans l'environnement de Poetry, car on va lancer du Python."}),"\n",(0,r.jsx)(s.p,{children:"Pour lancer l'environnement virtuel de Poetry depuis le conteneur :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="fedow_django$"',children:" # on d\xe9marre l'environnement virtuel qui prend en charge les d\xe9pendances python\npoetry shell\n"})}),"\n",(0,r.jsxs)(s.p,{children:["Django se g\xe8re avec un script appel\xe9 ",(0,r.jsx)(s.code,{children:"manage.py"}),". Deux commandes nous int\xe9ressent \xe0 l'heure actuelle :"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"rsp"})," (alias de ",(0,r.jsx)(s.code,{children:"./manage.py runserver 0.0.0.0:8000"}),") d\xe9marre Django sans r\xe9initialiser les donn\xe9es. \xc7a nous servira quand on veut garder des donn\xe9es entre deux d\xe9marrages. G\xe9n\xe9ralement, si on a pas besoin de lancer les tests, c'est cette commande qu'on utilise plut\xf4t que ",(0,r.jsx)(s.code,{children:"flush"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Optionnellement, si on a des bugs graphiques, on peut tenter ",(0,r.jsx)(s.code,{children:"./manage.py collectstatic"}),". Parfois, les ressources graphiques ne sont pas correctement copi\xe9es au premier d\xe9marrage, et \xe7a peut r\xe9gler le probl\xe8me."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Plus qu'\xe0 d\xe9marrer les trois moteurs de TiBillet dans l'ordre indiqu\xe9 pr\xe9c\xe9demment : Fedow, Lespass, puis LaBoutik !"}),"\n",(0,r.jsxs)(s.admonition,{title:"Cr\xe9ation d'alias",type:"tip",children:[(0,r.jsx)(s.p,{children:"La commande Docker devient vite r\xe9p\xe9titive. Pourquoi ne pas cr\xe9er un alias, ou m\xeame une petite fonction bash pour gagner du temps et soulager son canal carpien par la m\xeame occasion ? Voil\xe0 ma fonction :"}),(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="~/.bashrc"',children:"function dockex {\n docker exec -ti $1 bash\n}\n"})}),(0,r.jsx)(s.p,{children:"Il suffit d'ouvrir un nouveau terminal pour que la fonction s'ajoute \xe0 l'environnement. Il y a m\xeame sans doule moyen d'ajouter poetry \xe0 tout \xe7a si vous cherchez un peu !"})]}),"\n",(0,r.jsx)(s.h3,{id:"\xe7a-tourne-",children:"\xc7a tourne ?"}),"\n",(0,r.jsx)(s.p,{children:"Si vous avez utilis\xe9 la configuration des sous-domaines par d\xe9faut, vous avez maintenant acc\xe8s :"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["au moteur de f\xe9d\xe9ration Fedow sur ",(0,r.jsx)(s.a,{href:"https://fedow.tibillet.localhost",children:"fedow.tibillet.localhost"}),","]}),"\n",(0,r.jsxs)(s.li,{children:["\xe0 une instance du moteur de billetterie Lespass sur ",(0,r.jsx)(s.a,{href:"https://lespass.tibillet.localhost",children:"lespass.tibillet.localhost"}),","]}),"\n",(0,r.jsxs)(s.li,{children:["au serveur de caisse LaBoutik sur ",(0,r.jsx)(s.a,{href:"https://laboutik.tibillet.localhost",children:"laboutik.tibillet.localhost"})]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Si tout marche comme pr\xe9vu, f\xe9licitations : vous \xeates pr\xeat\u22c5es \xe0 vous lancer \ud83d\udd27"}),"\n",(0,r.jsx)(s.p,{children:"Sinon, venez nous en parler, on est l\xe0 pour aider !"}),"\n",(0,r.jsxs)(s.admonition,{title:"Pour conclure",type:"note",children:[(0,r.jsxs)(s.p,{children:["N'oubliez pas de ",(0,r.jsx)(s.code,{children:"docker compose down"})," \xe0 la fois dans les tests et dans Trafik quand vous avez fini votre session de travail. Votre ordinateur aussi a besoin de faire des pauses !"]}),(0,r.jsxs)(s.p,{children:["Si vous avez peur de ne pas vous en souvenir, enlevez l'option ",(0,r.jsx)(s.code,{children:"-d"})," \xe0 ",(0,r.jsx)(s.code,{children:"compose up"})," et la commande se lancera directement dans le terminal, pas en t\xe2che de fond. C'est pas grave, vous aurez juste besoin de plus d'onglets \ud83d\ude0b"]})]}),"\n",(0,r.jsx)(s.h2,{id:"cycle-de-vie",children:"Cycle de vie"}),"\n",(0,r.jsx)(s.h3,{id:"mises-\xe0-jour",children:"Mises \xe0 jour"}),"\n",(0,r.jsx)(s.p,{children:"Pour rester \xe0 jour durant le d\xe9veloppement, t\xe9l\xe9charger l'image la plus r\xe9cente :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="Test-Driven-Development$"',children:"docker compose pull\ndocker compose up -d # d\xe9marrer ou red\xe9marrer les conteneurs\n"})}),"\n",(0,r.jsx)(s.h3,{id:"tests",children:"Tests"}),"\n",(0,r.jsx)(s.p,{children:"Vous pouvez lancer les tests Python de la m\xeame fa\xe7on que pour un d\xe9marrage manuel. Commencez par r\xe9initialiser les trois app Django pour obtenir les donn\xe9es testables, puis lancez cette commande depuis votre conteneur Django LaBoutik :"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",metastring:'title="laboutik_django> poetry shell$"',children:"./manage.py test\n"})}),"\n",(0,r.jsx)("mark",{children:"TODO: docs des tests end-to-end (ils existent !)"}),"\n",(0,r.jsx)(s.h3,{id:"sauvegardes",children:"Sauvegardes"}),"\n",(0,r.jsxs)(s.p,{children:["Avant de vous attaquer \xe0 un changement majeur, sauvegardez toute donn\xe9e qui a de la valeur pour votre d\xe9veloppement. Sur votre instance Fedow, par exemple, il suffit de sauvegarder le dossier ",(0,r.jsx)(s.code,{children:"database"})," r\xe9guli\xe8rement. Les autres moteurs peuvent \xeatre sauvegard\xe9s par l'utilitaire Borgbackup, des t\xe2ches cron et des dump de bases de donn\xe9es. Plus sur ce sujet \xe0 l'avenir."]}),"\n",(0,r.jsx)("mark",{children:"TODO: explications d\xe9taill\xe9es"})]})}function u(e={}){const{wrapper:s}={...(0,d.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},1621:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>l});var r=n(6663);const d={},i=r.createContext(d);function t(e){const s=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:t(e.components),r.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/fr/assets/js/runtime~main.69eadfcd.js b/fr/assets/js/runtime~main.b66d18f5.js similarity index 99% rename from fr/assets/js/runtime~main.69eadfcd.js rename to fr/assets/js/runtime~main.b66d18f5.js index bab4f18f..77f54f71 100644 --- a/fr/assets/js/runtime~main.69eadfcd.js +++ b/fr/assets/js/runtime~main.b66d18f5.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,f,d,c,b={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var f=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(f.exports,f,f.exports,r),f.loaded=!0,f.exports}r.m=b,r.c=t,e=[],r.O=(a,f,d,c)=>{if(!f){var b=1/0;for(i=0;i=c)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(t=!1,c0&&e[i-1][2]>c;i--)e[i]=e[i-1];e[i]=[f,d,c]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var c=Object.create(null);r.r(c);var b={};a=a||[null,f({}),f([]),f(f)];for(var t=2&d&&e;"object"==typeof t&&!~a.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(c,b),c},r.d=(e,a)=>{for(var f in a)r.o(a,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:a[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,f)=>(r.f[f](e,a),a)),[])),r.u=e=>"assets/js/"+({114:"745e39fd",273:"deed564a",311:"6478c5d7",544:"a42a12d2",639:"c0af11f0",1108:"6929ad17",1178:"270a7541",1235:"a7456010",1339:"72c1897c",1394:"61ad30b6",1488:"03ad00ba",1579:"449f1965",1655:"00a627ec",1776:"df8088d9",2047:"583c92f6",2109:"65b5bc03",2145:"07d9d8ff",2216:"b85a8061",2340:"b24fcd7a",2387:"0c7e5857",2469:"1ed72f18",2527:"48065261",2598:"00afd901",2644:"68e5a7f1",2798:"91c19f46",2977:"3da3203d",3064:"55afe7bb",3111:"32a423af",3480:"474b1dc0",3628:"696d41fa",3808:"9292e017",4144:"027644ee",4279:"df203c0f",4300:"acef3f09",4359:"a10a0aa5",4411:"14c235f6",4484:"7b1d6ae7",4721:"22ad831a",4726:"2487d3c6",4787:"3720c009",4806:"8f0ce7bf",4831:"a4a43940",4859:"0f181b88",4878:"4b4b4e17",4967:"2ba7bea0",5053:"e462b8cb",5415:"bb6a9c94",5456:"5295d439",5478:"623e3017",5481:"8370a1d2",5525:"64a6eaa0",5605:"258bd27d",5612:"19463738",5742:"aba21aa0",5767:"0974cb83",5870:"1a90fa4c",6061:"1f391b9e",6244:"e9e8755a",6316:"07630c8f",6364:"21f279ec",6577:"ff3ce73e",6715:"b3d07ec0",6958:"c8fb810e",6969:"14eb3368",7091:"6b9c5894",7098:"a7bd4aaa",7403:"df2a2fef",7569:"34d64ec5",7583:"d9efc8e6",7672:"12acde98",7843:"1796c5bc",8017:"031b3c77",8310:"ba3701a6",8343:"63aafed8",8345:"070ddeb6",8383:"f268abb1",8401:"17896441",8555:"c8adef9d",8561:"a65a45c1",8697:"a691281d",8707:"a4153707",9048:"a94703ab",9131:"6bc29cb1",9503:"637d76cf",9579:"a727ba59",9647:"5e95c892",9751:"98ece4e3"}[e]||e)+"."+{114:"3dbfb23c",171:"a22cb800",273:"ea2000a8",311:"46b0e22f",544:"7cf877c8",639:"28fafb3a",1108:"55fff404",1178:"3bf120b5",1235:"64267856",1339:"2becdd67",1394:"2e3becde",1488:"ad911fe5",1579:"75e69521",1655:"e1638269",1776:"c43f2adc",2047:"b1c98bb8",2109:"e96332c7",2145:"293c9955",2216:"ad4aa707",2340:"88b7fab5",2387:"598bc512",2469:"91fb5ea6",2527:"3dc08754",2598:"2c73005f",2644:"8a7023c2",2798:"1a2d6e72",2977:"fcae564c",3064:"4aab4627",3111:"3ff0f6a7",3480:"6b2b5712",3628:"0ff1db3c",3808:"c1a676d2",4144:"36fc7bd1",4279:"2617a656",4300:"f97c03cc",4359:"614cfe7e",4411:"c1a7f582",4484:"c5fb8f56",4721:"bde37189",4726:"b31d6cf3",4787:"447543d1",4806:"81fc5dd6",4831:"6c1ced19",4859:"8ea0c308",4878:"c0e70402",4967:"92bc7c03",5053:"9027d428",5415:"035f574f",5456:"14778b33",5460:"43ac4a6a",5478:"ece3754f",5481:"42e0fa0e",5525:"af552e88",5605:"e28931b3",5612:"fd0336fe",5742:"eaf0e070",5767:"a483ff95",5870:"f80813b0",6061:"483bbb2c",6244:"4d1f8703",6316:"bd3bfa6e",6364:"92e76c1b",6577:"d70ba2c9",6715:"0326e80d",6958:"dbb03f8f",6969:"41145fce",7091:"16e5c4dd",7098:"c0b26ad9",7403:"fb66525e",7569:"ab69487d",7583:"5ef7b62a",7672:"6d04bf31",7843:"c0e22ac7",8017:"724c1b20",8310:"577bb476",8343:"432e8e9f",8345:"a64efe8c",8383:"61e49527",8401:"01f28df4",8555:"28ef7b66",8561:"96ac33f6",8697:"84bd8dda",8707:"a2a54788",9048:"5f10afe8",9131:"45188825",9503:"5b0b53c4",9579:"6f16b22a",9647:"73b378c9",9751:"9229bd21"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},c="documentation-v-2:",r.l=(e,a,f,b)=>{if(d[e])d[e].push(a);else{var t,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var c=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),c&&c.forEach((e=>e(f))),a)return a(f)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/fr/",r.gca=function(e){return e={17896441:"8401",19463738:"5612",48065261:"2527","745e39fd":"114",deed564a:"273","6478c5d7":"311",a42a12d2:"544",c0af11f0:"639","6929ad17":"1108","270a7541":"1178",a7456010:"1235","72c1897c":"1339","61ad30b6":"1394","03ad00ba":"1488","449f1965":"1579","00a627ec":"1655",df8088d9:"1776","583c92f6":"2047","65b5bc03":"2109","07d9d8ff":"2145",b85a8061:"2216",b24fcd7a:"2340","0c7e5857":"2387","1ed72f18":"2469","00afd901":"2598","68e5a7f1":"2644","91c19f46":"2798","3da3203d":"2977","55afe7bb":"3064","32a423af":"3111","474b1dc0":"3480","696d41fa":"3628","9292e017":"3808","027644ee":"4144",df203c0f:"4279",acef3f09:"4300",a10a0aa5:"4359","14c235f6":"4411","7b1d6ae7":"4484","22ad831a":"4721","2487d3c6":"4726","3720c009":"4787","8f0ce7bf":"4806",a4a43940:"4831","0f181b88":"4859","4b4b4e17":"4878","2ba7bea0":"4967",e462b8cb:"5053",bb6a9c94:"5415","5295d439":"5456","623e3017":"5478","8370a1d2":"5481","64a6eaa0":"5525","258bd27d":"5605",aba21aa0:"5742","0974cb83":"5767","1a90fa4c":"5870","1f391b9e":"6061",e9e8755a:"6244","07630c8f":"6316","21f279ec":"6364",ff3ce73e:"6577",b3d07ec0:"6715",c8fb810e:"6958","14eb3368":"6969","6b9c5894":"7091",a7bd4aaa:"7098",df2a2fef:"7403","34d64ec5":"7569",d9efc8e6:"7583","12acde98":"7672","1796c5bc":"7843","031b3c77":"8017",ba3701a6:"8310","63aafed8":"8343","070ddeb6":"8345",f268abb1:"8383",c8adef9d:"8555",a65a45c1:"8561",a691281d:"8697",a4153707:"8707",a94703ab:"9048","6bc29cb1":"9131","637d76cf":"9503",a727ba59:"9579","5e95c892":"9647","98ece4e3":"9751"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,f)=>{var d=r.o(e,a)?e[a]:void 0;if(0!==d)if(d)f.push(d[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var c=new Promise(((f,c)=>d=e[a]=[f,c]));f.push(d[2]=c);var b=r.p+r.u(a),t=new Error;r.l(b,(f=>{if(r.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var c=f&&("load"===f.type?"missing":f.type),b=f&&f.target&&f.target.src;t.message="Loading chunk "+a+" failed.\n("+c+": "+b+")",t.name="ChunkLoadError",t.type=c,t.request=b,d[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,f)=>{var d,c,b=f[0],t=f[1],o=f[2],n=0;if(b.some((a=>0!==e[a]))){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(a&&a(f);n{"use strict";var e,a,f,d,c,b={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var f=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(f.exports,f,f.exports,r),f.loaded=!0,f.exports}r.m=b,r.c=t,e=[],r.O=(a,f,d,c)=>{if(!f){var b=1/0;for(i=0;i=c)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(t=!1,c0&&e[i-1][2]>c;i--)e[i]=e[i-1];e[i]=[f,d,c]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var c=Object.create(null);r.r(c);var b={};a=a||[null,f({}),f([]),f(f)];for(var t=2&d&&e;"object"==typeof t&&!~a.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(c,b),c},r.d=(e,a)=>{for(var f in a)r.o(a,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:a[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,f)=>(r.f[f](e,a),a)),[])),r.u=e=>"assets/js/"+({114:"745e39fd",273:"deed564a",311:"6478c5d7",544:"a42a12d2",639:"c0af11f0",1108:"6929ad17",1178:"270a7541",1235:"a7456010",1339:"72c1897c",1394:"61ad30b6",1488:"03ad00ba",1579:"449f1965",1655:"00a627ec",1776:"df8088d9",2047:"583c92f6",2109:"65b5bc03",2145:"07d9d8ff",2216:"b85a8061",2340:"b24fcd7a",2387:"0c7e5857",2469:"1ed72f18",2527:"48065261",2598:"00afd901",2644:"68e5a7f1",2798:"91c19f46",2977:"3da3203d",3064:"55afe7bb",3111:"32a423af",3480:"474b1dc0",3628:"696d41fa",3808:"9292e017",4144:"027644ee",4279:"df203c0f",4300:"acef3f09",4359:"a10a0aa5",4411:"14c235f6",4484:"7b1d6ae7",4721:"22ad831a",4726:"2487d3c6",4787:"3720c009",4806:"8f0ce7bf",4831:"a4a43940",4859:"0f181b88",4878:"4b4b4e17",4967:"2ba7bea0",5053:"e462b8cb",5415:"bb6a9c94",5456:"5295d439",5478:"623e3017",5481:"8370a1d2",5525:"64a6eaa0",5605:"258bd27d",5612:"19463738",5742:"aba21aa0",5767:"0974cb83",5870:"1a90fa4c",6061:"1f391b9e",6244:"e9e8755a",6316:"07630c8f",6364:"21f279ec",6577:"ff3ce73e",6715:"b3d07ec0",6958:"c8fb810e",6969:"14eb3368",7091:"6b9c5894",7098:"a7bd4aaa",7403:"df2a2fef",7569:"34d64ec5",7583:"d9efc8e6",7672:"12acde98",7843:"1796c5bc",8017:"031b3c77",8310:"ba3701a6",8343:"63aafed8",8345:"070ddeb6",8383:"f268abb1",8401:"17896441",8555:"c8adef9d",8561:"a65a45c1",8697:"a691281d",8707:"a4153707",9048:"a94703ab",9131:"6bc29cb1",9503:"637d76cf",9579:"a727ba59",9647:"5e95c892",9751:"98ece4e3"}[e]||e)+"."+{114:"3dbfb23c",171:"a22cb800",273:"ea2000a8",311:"46b0e22f",544:"7cf877c8",639:"d7c80e2f",1108:"55fff404",1178:"3bf120b5",1235:"64267856",1339:"2becdd67",1394:"2e3becde",1488:"ad911fe5",1579:"75e69521",1655:"e1638269",1776:"c43f2adc",2047:"b1c98bb8",2109:"e96332c7",2145:"293c9955",2216:"ad4aa707",2340:"88b7fab5",2387:"598bc512",2469:"91fb5ea6",2527:"3dc08754",2598:"2c73005f",2644:"8a7023c2",2798:"1a2d6e72",2977:"fcae564c",3064:"4aab4627",3111:"3ff0f6a7",3480:"6b2b5712",3628:"0ff1db3c",3808:"c1a676d2",4144:"36fc7bd1",4279:"2617a656",4300:"f97c03cc",4359:"614cfe7e",4411:"c1a7f582",4484:"c5fb8f56",4721:"bde37189",4726:"b31d6cf3",4787:"447543d1",4806:"81fc5dd6",4831:"6c1ced19",4859:"8ea0c308",4878:"c0e70402",4967:"92bc7c03",5053:"9027d428",5415:"035f574f",5456:"14778b33",5460:"43ac4a6a",5478:"ece3754f",5481:"42e0fa0e",5525:"af552e88",5605:"e28931b3",5612:"fd0336fe",5742:"eaf0e070",5767:"a483ff95",5870:"f80813b0",6061:"483bbb2c",6244:"4d1f8703",6316:"bd3bfa6e",6364:"92e76c1b",6577:"d70ba2c9",6715:"0326e80d",6958:"dbb03f8f",6969:"41145fce",7091:"16e5c4dd",7098:"c0b26ad9",7403:"fb66525e",7569:"ab69487d",7583:"5ef7b62a",7672:"6d04bf31",7843:"c0e22ac7",8017:"724c1b20",8310:"577bb476",8343:"432e8e9f",8345:"a64efe8c",8383:"61e49527",8401:"01f28df4",8555:"28ef7b66",8561:"96ac33f6",8697:"84bd8dda",8707:"a2a54788",9048:"5f10afe8",9131:"45188825",9503:"5b0b53c4",9579:"6f16b22a",9647:"73b378c9",9751:"9229bd21"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},c="documentation-v-2:",r.l=(e,a,f,b)=>{if(d[e])d[e].push(a);else{var t,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var c=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),c&&c.forEach((e=>e(f))),a)return a(f)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/fr/",r.gca=function(e){return e={17896441:"8401",19463738:"5612",48065261:"2527","745e39fd":"114",deed564a:"273","6478c5d7":"311",a42a12d2:"544",c0af11f0:"639","6929ad17":"1108","270a7541":"1178",a7456010:"1235","72c1897c":"1339","61ad30b6":"1394","03ad00ba":"1488","449f1965":"1579","00a627ec":"1655",df8088d9:"1776","583c92f6":"2047","65b5bc03":"2109","07d9d8ff":"2145",b85a8061:"2216",b24fcd7a:"2340","0c7e5857":"2387","1ed72f18":"2469","00afd901":"2598","68e5a7f1":"2644","91c19f46":"2798","3da3203d":"2977","55afe7bb":"3064","32a423af":"3111","474b1dc0":"3480","696d41fa":"3628","9292e017":"3808","027644ee":"4144",df203c0f:"4279",acef3f09:"4300",a10a0aa5:"4359","14c235f6":"4411","7b1d6ae7":"4484","22ad831a":"4721","2487d3c6":"4726","3720c009":"4787","8f0ce7bf":"4806",a4a43940:"4831","0f181b88":"4859","4b4b4e17":"4878","2ba7bea0":"4967",e462b8cb:"5053",bb6a9c94:"5415","5295d439":"5456","623e3017":"5478","8370a1d2":"5481","64a6eaa0":"5525","258bd27d":"5605",aba21aa0:"5742","0974cb83":"5767","1a90fa4c":"5870","1f391b9e":"6061",e9e8755a:"6244","07630c8f":"6316","21f279ec":"6364",ff3ce73e:"6577",b3d07ec0:"6715",c8fb810e:"6958","14eb3368":"6969","6b9c5894":"7091",a7bd4aaa:"7098",df2a2fef:"7403","34d64ec5":"7569",d9efc8e6:"7583","12acde98":"7672","1796c5bc":"7843","031b3c77":"8017",ba3701a6:"8310","63aafed8":"8343","070ddeb6":"8345",f268abb1:"8383",c8adef9d:"8555",a65a45c1:"8561",a691281d:"8697",a4153707:"8707",a94703ab:"9048","6bc29cb1":"9131","637d76cf":"9503",a727ba59:"9579","5e95c892":"9647","98ece4e3":"9751"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,f)=>{var d=r.o(e,a)?e[a]:void 0;if(0!==d)if(d)f.push(d[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var c=new Promise(((f,c)=>d=e[a]=[f,c]));f.push(d[2]=c);var b=r.p+r.u(a),t=new Error;r.l(b,(f=>{if(r.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var c=f&&("load"===f.type?"missing":f.type),b=f&&f.target&&f.target.src;t.message="Loading chunk "+a+" failed.\n("+c+": "+b+")",t.name="ChunkLoadError",t.type=c,t.request=b,d[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,f)=>{var d,c,b=f[0],t=f[1],o=f[2],n=0;if(b.some((a=>0!==e[a]))){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(a&&a(f);n Conditions générales de vente et d'utilisation | TiBillet - + diff --git a/fr/docs/Tips/facebook/index.html b/fr/docs/Tips/facebook/index.html index 69f32c41..595a5cc7 100644 --- a/fr/docs/Tips/facebook/index.html +++ b/fr/docs/Tips/facebook/index.html @@ -4,7 +4,7 @@ Publication sur les réseaux sociaux | TiBillet - + diff --git a/fr/docs/Utilisateur/Billetterie/admin_add_new_event/index.html b/fr/docs/Utilisateur/Billetterie/admin_add_new_event/index.html index 44888480..2f8d76b4 100644 --- a/fr/docs/Utilisateur/Billetterie/admin_add_new_event/index.html +++ b/fr/docs/Utilisateur/Billetterie/admin_add_new_event/index.html @@ -4,7 +4,7 @@ Créer un nouvel évènement de A à Z | TiBillet - + diff --git a/fr/docs/Utilisateur/Billetterie/admin_add_new_free_event/index.html b/fr/docs/Utilisateur/Billetterie/admin_add_new_free_event/index.html index 8cb92f15..2bc4102d 100644 --- a/fr/docs/Utilisateur/Billetterie/admin_add_new_free_event/index.html +++ b/fr/docs/Utilisateur/Billetterie/admin_add_new_free_event/index.html @@ -4,7 +4,7 @@ Créer un évènement gratuit | TiBillet - + diff --git a/fr/docs/Utilisateur/Billetterie/iframe/index.html b/fr/docs/Utilisateur/Billetterie/iframe/index.html index 5833a27b..6874bf4c 100644 --- a/fr/docs/Utilisateur/Billetterie/iframe/index.html +++ b/fr/docs/Utilisateur/Billetterie/iframe/index.html @@ -4,7 +4,7 @@ Intégration | TiBillet - + diff --git a/fr/docs/Utilisateur/Billetterie/rss/index.html b/fr/docs/Utilisateur/Billetterie/rss/index.html index 52731fd0..0724fc82 100644 --- a/fr/docs/Utilisateur/Billetterie/rss/index.html +++ b/fr/docs/Utilisateur/Billetterie/rss/index.html @@ -4,7 +4,7 @@ Flux RSS | TiBillet - + diff --git a/fr/docs/Utilisateur/Billetterie/webhook/index.html b/fr/docs/Utilisateur/Billetterie/webhook/index.html index 5a6aae5e..830f61bb 100644 --- a/fr/docs/Utilisateur/Billetterie/webhook/index.html +++ b/fr/docs/Utilisateur/Billetterie/webhook/index.html @@ -4,7 +4,7 @@ Webhook | TiBillet - + diff --git a/fr/docs/Utilisateur/Cashless/admin_add_article/index.html b/fr/docs/Utilisateur/Cashless/admin_add_article/index.html index 115ca3ad..2d151d15 100644 --- a/fr/docs/Utilisateur/Cashless/admin_add_article/index.html +++ b/fr/docs/Utilisateur/Cashless/admin_add_article/index.html @@ -4,7 +4,7 @@ Articles | TiBillet - + diff --git a/fr/docs/Utilisateur/Cashless/admin_add_categorie/index.html b/fr/docs/Utilisateur/Cashless/admin_add_categorie/index.html index 06ebfd2a..2408b5fb 100644 --- a/fr/docs/Utilisateur/Cashless/admin_add_categorie/index.html +++ b/fr/docs/Utilisateur/Cashless/admin_add_categorie/index.html @@ -4,7 +4,7 @@ Catégories d'articles | TiBillet - + diff --git a/fr/docs/Utilisateur/Cashless/admin_add_pos/index.html b/fr/docs/Utilisateur/Cashless/admin_add_pos/index.html index 3c45cd89..1e5e1053 100644 --- a/fr/docs/Utilisateur/Cashless/admin_add_pos/index.html +++ b/fr/docs/Utilisateur/Cashless/admin_add_pos/index.html @@ -4,7 +4,7 @@ Points de vente | TiBillet - + diff --git a/fr/docs/Utilisateur/Cashless/admin_add_primary/index.html b/fr/docs/Utilisateur/Cashless/admin_add_primary/index.html index ee748d6d..43eb32b9 100644 --- a/fr/docs/Utilisateur/Cashless/admin_add_primary/index.html +++ b/fr/docs/Utilisateur/Cashless/admin_add_primary/index.html @@ -4,7 +4,7 @@ Cartes Primaires | TiBillet - + diff --git a/fr/docs/Utilisateur/Cashless/admin_supp/index.html b/fr/docs/Utilisateur/Cashless/admin_supp/index.html index c43e5799..8262ea11 100644 --- a/fr/docs/Utilisateur/Cashless/admin_supp/index.html +++ b/fr/docs/Utilisateur/Cashless/admin_supp/index.html @@ -4,7 +4,7 @@ Suppression des commandes | TiBillet - + diff --git a/fr/docs/Utilisateur/Cashless/android/index.html b/fr/docs/Utilisateur/Cashless/android/index.html index 84cf5b1c..40ff62c3 100644 --- a/fr/docs/Utilisateur/Cashless/android/index.html +++ b/fr/docs/Utilisateur/Cashless/android/index.html @@ -4,7 +4,7 @@ Application Android | TiBillet - + diff --git a/fr/docs/Utilisateur/Cashless/badge/index.html b/fr/docs/Utilisateur/Cashless/badge/index.html index 226d134e..92c6b594 100644 --- a/fr/docs/Utilisateur/Cashless/badge/index.html +++ b/fr/docs/Utilisateur/Cashless/badge/index.html @@ -4,7 +4,7 @@ Badgeuse | TiBillet - + diff --git a/fr/docs/Utilisateur/Cashless/cashback/index.html b/fr/docs/Utilisateur/Cashless/cashback/index.html index f9f2b6ce..eb19a00d 100644 --- a/fr/docs/Utilisateur/Cashless/cashback/index.html +++ b/fr/docs/Utilisateur/Cashless/cashback/index.html @@ -4,7 +4,7 @@ Cashback | TiBillet - + diff --git a/fr/docs/Utilisateur/Cashless/fedelity/index.html b/fr/docs/Utilisateur/Cashless/fedelity/index.html index 9446d816..a6bb93b1 100644 --- a/fr/docs/Utilisateur/Cashless/fedelity/index.html +++ b/fr/docs/Utilisateur/Cashless/fedelity/index.html @@ -4,7 +4,7 @@ Points de fidélités | TiBillet - + diff --git a/fr/docs/Utilisateur/Cashless/impression_preparation/index.html b/fr/docs/Utilisateur/Cashless/impression_preparation/index.html index 9a5132a8..dd2ebe66 100644 --- a/fr/docs/Utilisateur/Cashless/impression_preparation/index.html +++ b/fr/docs/Utilisateur/Cashless/impression_preparation/index.html @@ -4,7 +4,7 @@ Impression des commandes | TiBillet - + diff --git a/fr/docs/api/apikey/index.html b/fr/docs/api/apikey/index.html index 5f33d5b6..2c35b86c 100644 --- a/fr/docs/api/apikey/index.html +++ b/fr/docs/api/apikey/index.html @@ -4,7 +4,7 @@ API Keys | TiBillet - + diff --git a/fr/docs/api/events/index.html b/fr/docs/api/events/index.html index afb84690..8fccb385 100644 --- a/fr/docs/api/events/index.html +++ b/fr/docs/api/events/index.html @@ -4,7 +4,7 @@ Évènements | TiBillet - + diff --git a/fr/docs/api/intro/index.html b/fr/docs/api/intro/index.html index b24429fd..6c95ce32 100644 --- a/fr/docs/api/intro/index.html +++ b/fr/docs/api/intro/index.html @@ -4,7 +4,7 @@ Introduction | TiBillet - + diff --git a/fr/docs/api/products/index.html b/fr/docs/api/products/index.html index cb6ad609..c53266ae 100644 --- a/fr/docs/api/products/index.html +++ b/fr/docs/api/products/index.html @@ -4,7 +4,7 @@ Produits | TiBillet - + diff --git a/fr/docs/api/reservations/index.html b/fr/docs/api/reservations/index.html index 70a1c938..d93966dd 100644 --- a/fr/docs/api/reservations/index.html +++ b/fr/docs/api/reservations/index.html @@ -4,7 +4,7 @@ Réservations et billets | TiBillet - + diff --git a/fr/docs/api/tenants/index.html b/fr/docs/api/tenants/index.html index 4b6250cb..4adb3757 100644 --- a/fr/docs/api/tenants/index.html +++ b/fr/docs/api/tenants/index.html @@ -4,7 +4,7 @@ Tenants | TiBillet - + diff --git a/fr/docs/category/api/index.html b/fr/docs/category/api/index.html index e918b740..b9a2c7ea 100644 --- a/fr/docs/category/api/index.html +++ b/fr/docs/category/api/index.html @@ -4,7 +4,7 @@ API | TiBillet - + diff --git a/fr/docs/category/billetterie/index.html b/fr/docs/category/billetterie/index.html index 0dadc52c..68ae6fa2 100644 --- a/fr/docs/category/billetterie/index.html +++ b/fr/docs/category/billetterie/index.html @@ -4,7 +4,7 @@ Billetterie | TiBillet - + diff --git a/fr/docs/category/cashless/index.html b/fr/docs/category/cashless/index.html index 818f27a7..1d18df65 100644 --- a/fr/docs/category/cashless/index.html +++ b/fr/docs/category/cashless/index.html @@ -4,7 +4,7 @@ Cashless | TiBillet - + diff --git a/fr/docs/category/contribution-guides/index.html b/fr/docs/category/contribution-guides/index.html index e017de0c..5fceae27 100644 --- a/fr/docs/category/contribution-guides/index.html +++ b/fr/docs/category/contribution-guides/index.html @@ -4,7 +4,7 @@ Contribution guides | TiBillet - + diff --git a/fr/docs/category/diy/index.html b/fr/docs/category/diy/index.html index 6be5ca38..12bae492 100644 --- a/fr/docs/category/diy/index.html +++ b/fr/docs/category/diy/index.html @@ -4,7 +4,7 @@ DIY | TiBillet - + diff --git a/fr/docs/category/documentation-utilisateur/index.html b/fr/docs/category/documentation-utilisateur/index.html index 430324a8..32a157f8 100644 --- a/fr/docs/category/documentation-utilisateur/index.html +++ b/fr/docs/category/documentation-utilisateur/index.html @@ -4,7 +4,7 @@ Documentation utilisateur | TiBillet - + diff --git "a/fr/docs/category/pr\303\251sentation/index.html" "b/fr/docs/category/pr\303\251sentation/index.html" index 214dccf7..c500aac7 100644 --- "a/fr/docs/category/pr\303\251sentation/index.html" +++ "b/fr/docs/category/pr\303\251sentation/index.html" @@ -4,7 +4,7 @@ Présentation | TiBillet - + diff --git a/fr/docs/category/trucs-et-astuces/index.html b/fr/docs/category/trucs-et-astuces/index.html index f0a212e7..8ac682d6 100644 --- a/fr/docs/category/trucs-et-astuces/index.html +++ b/fr/docs/category/trucs-et-astuces/index.html @@ -4,7 +4,7 @@ Trucs et astuces | TiBillet - + diff --git a/fr/docs/contribute/development/index.html b/fr/docs/contribute/development/index.html index e94f852b..3f3b33cd 100644 --- a/fr/docs/contribute/development/index.html +++ b/fr/docs/contribute/development/index.html @@ -4,7 +4,7 @@ Développement | TiBillet - + @@ -73,7 +73,7 @@

    Environn
    NomEnvironnement cibleNullableValeur par défautNotes
    SECRET_KEYTousNonUne des clés secrètes Django générées précédemment
    FERNET_KEYTousNonUne des clés Fernet générées précédemment
    STRIPE_KEYProductionOuiClé API de votre compte Stripe
    DOMAINTousNonfedow.tibillet.localhostÀ adapter à votre nom de domaine et sous-domaine en production
    STRIPE_KEY_TESTDéveloppement, TestsOuiClé API de test de votre compte Stripe
    STRIPE_TESTDéveloppement, TestsNon0Passer à 1 si STRIPE_KEY_TEST est rempli
    STRIPE_ENDPOINT_SECRET_TESTDéveloppement, TestsOuiAucune idée
    DEBUGDéveloppementNon0Passer à 1 pour le développement
    TESTTestsNon0Passer à 1 pour les tests

    Environnement Lespass

    tibillet-dev$
    cp Lespass/env_example Lespass/.env
    -
    NomEnvironnement cibleNullableValeur par défautNotes
    SECRET_KEYTousNonUne des clés secrètes Django générées précédemment
    FERNET_KEYTousNonUne des clés Fernet générées précédemment
    STRIPE_KEYProductionOuiClé API de votre compte Stripe
    DOMAINTousNontibillet.localhostÀ adapter à votre nom de domaine en production
    SUBTousNonlespassSous-domaine de l'instance, à adapter en production
    METATousNonagendaSous-domaine de l'agenda fédéré, à adapter en production
    FEDOW_DOMAINTousNonagendaSous-domaine de l'agenda fédéré, à adapter en production
    PUBLICTousNonTiBillet Coop.Nom de l'instance principale
    TIME_ZONETousNonEurope/ParisPlage horaire TZ de l'instance
    ADMIN_EMAILTousNonEmail administrateur (pour le⋅a premier⋅e admin)
    POSTGRES_DBTousNonlespassÀ changer en production si nécessaire
    POSTGRES_USERTousNonlespass_postgresÀ changer en production
    POSTGRES_PASSWORDTousNonMot de passe fort (une des clés Fernets par exemple)
    EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORDTousOuiServeur d'email, requis pour confirmer des abonné⋅es par exemple
    STRIPE_KEY_TESTDéveloppement, TestsOuiClé API de test de votre compte Stripe
    STRIPE_TESTDéveloppement, TestsNon0Passer à 1 si STRIPE_KEY_TEST est rempli
    DEBUGDéveloppementNon0Passer à 1 pour le développement
    TESTTestsNon0Passer à 1 pour les tests
    +
    NomEnvironnement cibleNullableValeur par défautNotes
    SECRET_KEYTousNonUne des clés secrètes Django générées précédemment
    FERNET_KEYTousNonUne des clés Fernet générées précédemment
    STRIPE_KEYProductionOuiClé API de votre compte Stripe
    DOMAINTousNontibillet.localhostÀ adapter à votre nom de domaine en production
    SUBTousNonlespassSous-domaine de l'instance, à adapter en production
    METATousNonagendaSous-domaine de l'agenda fédéré, à adapter en production
    FEDOW_DOMAINTousNonfedow.tibillet.localhostDomaine et sous-domaine du moteur Fedow
    PUBLICTousNonTiBillet Coop.Nom de l'instance principale
    TIME_ZONETousNonEurope/ParisPlage horaire TZ de l'instance
    ADMIN_EMAILTousNonEmail administrateur (pour le⋅a premier⋅e admin)
    POSTGRES_DBTousNonlespassÀ changer en production si nécessaire
    POSTGRES_USERTousNonlespass_postgresÀ changer en production
    POSTGRES_PASSWORDTousNonMot de passe fort (une des clés Fernets par exemple)
    EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORDTousOuiServeur d'email, requis pour confirmer des abonné⋅es par exemple
    STRIPE_KEY_TESTDéveloppement, TestsOuiClé API de test de votre compte Stripe
    STRIPE_TESTDéveloppement, TestsNon0Passer à 1 si STRIPE_KEY_TEST est rempli
    DEBUGDéveloppementNon0Passer à 1 pour le développement
    TESTTestsNon0Passer à 1 pour les tests

    Environnement LaBoutik

    tibillet-dev$
    cp LaBoutik/env_example LaBoutik/.env
    NomEnvironnement cibleNullableValeur par défautNotes
    SECRET_KEYTousNonUne des clés secrètes Django générées précédemment
    FERNET_KEYTousNonUne des clés Fernet générées précédemment
    DOMAINTousNonlaboutik.tibillet.localhostÀ adapter à votre nom de domaine et sous-domaine en production
    FEDOW_URLTousNonhttps://fedow.tibillet.localhost/URL du moteur Fedow
    LESPASS_TENANT_URLTousNonhttps://lespass.tibillet.localhost/URL de l'instance Lespass
    TIME_ZONETousNonEurope/ParisPlage horaire TZ de l'instance
    ADMIN_EMAILTousNonEmail administrateur (pour le⋅a premier⋅e admin)
    MAIN_ASSET_NAMETousNonLe nom de votre unité de valeur cashless (Piécette, CoeurDor… comme vous voulez)
    POSTGRES_DBTousNonlaboutikÀ changer en production si nécessaire
    POSTGRES_USERTousNonlaboutik_userÀ changer en production
    POSTGRES_PASSWORDTousNonMot de passe fort (une des clés Fernets par exemple)
    EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORDTousOuiServeur d'email, requis pour confirmer des abonné⋅es par exemple
    BORG_PASSPHRASETousOuiMot de passe utilisé pour la sauvegarde des données
    DEBUGDéveloppementNon0Passer à 1 pour le développement
    TESTTestsNon0Passer à 1 pour les tests
    DEMODéveloppement, TestsNon0Passer à 1 pour une simulation de terminal de caisse
    SENTRY_DNSDéveloppement, TestsOuiSentry Debug pour le back-end
    SENTRY_FRONT_DNS, SENTRY_FRONT_ASSETDéveloppement, TestsOuiSentry Debug pour le front-end
    DEMO_TAGID_CM, DEMO_TAGID_CLIENT1, DEMO_TAGID_CLIENT2OuiAucune idée
    @@ -103,7 +103,7 @@

    Déma

    Pour le reste des manipulation dans le conteneur, on a besoin de rentrer dans l'environnement de Poetry, car on va lancer du Python.

    Pour lancer l'environnement virtuel de Poetry depuis le conteneur :

    fedow_django$
     # on démarre l'environnement virtuel qui prend en charge les dépendances python
    poetry shell
    -

    Bien, ça va nous simplifier le développement Django, qui se gère habituellement avec un script appelé manage.py. Deux commandes nous intéressent à l'heure actuelle :

    +

    Django se gère avec un script appelé manage.py. Deux commandes nous intéressent à l'heure actuelle :

    • rsp (alias de ./manage.py runserver 0.0.0.0:8000) démarre Django sans réinitialiser les données. Ça nous servira quand on veut garder des données entre deux démarrages. Généralement, si on a pas besoin de lancer les tests, c'est cette commande qu'on utilise plutôt que flush.

      @@ -112,7 +112,7 @@

      Déma

      Optionnellement, si on a des bugs graphiques, on peut tenter ./manage.py collectstatic. Parfois, les ressources graphiques ne sont pas correctement copiées au premier démarrage, et ça peut régler le problème.

    -

    Plus qu'à démarrer les trois moteurs de TiBillet dans l'ordre indiqué précédemment : Fedow, Lespass, puis LaBoutik !

    +

    Plus qu'à démarrer les trois moteurs de TiBillet dans l'ordre indiqué précédemment : Fedow, Lespass, puis LaBoutik !

    Création d'alias

    La commande Docker devient vite répétitive. Pourquoi ne pas créer un alias, ou même une petite fonction bash pour gagner du temps et soulager son canal carpien par la même occasion ? Voilà ma fonction :

    ~/.bashrc
    function dockex {
    docker exec -ti $1 bash
    }

    Il suffit d'ouvrir un nouveau terminal pour que la fonction s'ajoute à l'environnement. Il y a même sans doule moyen d'ajouter poetry à tout ça si vous cherchez un peu !

    Ça tourne ?

    Si vous avez utilisé la configuration des sous-domaines par défaut, vous avez maintenant accès :

    diff --git a/fr/docs/install/docker_install/index.html b/fr/docs/install/docker_install/index.html index 0fe15452..9a81a452 100644 --- a/fr/docs/install/docker_install/index.html +++ b/fr/docs/install/docker_install/index.html @@ -4,7 +4,7 @@ Self hosted TiBillet instances | TiBillet - + diff --git a/fr/docs/install/raspberry/index.html b/fr/docs/install/raspberry/index.html index 1fe9199c..e16a4f23 100644 --- a/fr/docs/install/raspberry/index.html +++ b/fr/docs/install/raspberry/index.html @@ -4,7 +4,7 @@ Raspberry Box - Hardware | TiBillet - + diff --git a/fr/docs/install/raspberry_soft/index.html b/fr/docs/install/raspberry_soft/index.html index 6e9d2794..7b20bf68 100644 --- a/fr/docs/install/raspberry_soft/index.html +++ b/fr/docs/install/raspberry_soft/index.html @@ -4,7 +4,7 @@ Raspberry Box - Software | TiBillet - + diff --git a/fr/docs/presentation/demonstration/index.html b/fr/docs/presentation/demonstration/index.html index d120e5a5..2a7bc8c5 100644 --- a/fr/docs/presentation/demonstration/index.html +++ b/fr/docs/presentation/demonstration/index.html @@ -4,7 +4,7 @@ Démonstration | TiBillet - + diff --git a/fr/docs/presentation/introduction/index.html b/fr/docs/presentation/introduction/index.html index 60f096d1..f906d626 100644 --- a/fr/docs/presentation/introduction/index.html +++ b/fr/docs/presentation/introduction/index.html @@ -4,7 +4,7 @@ Introduction | TiBillet - + diff --git a/fr/docs/presentation/logos/index.html b/fr/docs/presentation/logos/index.html index 45c2b7cf..ade8ad0c 100644 --- a/fr/docs/presentation/logos/index.html +++ b/fr/docs/presentation/logos/index.html @@ -4,7 +4,7 @@ Logos | TiBillet - + diff --git a/fr/docs/presentation/philosophie/index.html b/fr/docs/presentation/philosophie/index.html index 91eb52b5..8a3d3694 100644 --- a/fr/docs/presentation/philosophie/index.html +++ b/fr/docs/presentation/philosophie/index.html @@ -4,7 +4,7 @@ Philosophie | TiBillet - + diff --git a/fr/docs/presentation/tarifs/index.html b/fr/docs/presentation/tarifs/index.html index 21ee480e..0f525c0e 100644 --- a/fr/docs/presentation/tarifs/index.html +++ b/fr/docs/presentation/tarifs/index.html @@ -4,7 +4,7 @@ Tarifs, conditions et licences | TiBillet - + diff --git a/fr/docs/presentation/usages/index.html b/fr/docs/presentation/usages/index.html index 4f7d0825..ec39dd18 100644 --- a/fr/docs/presentation/usages/index.html +++ b/fr/docs/presentation/usages/index.html @@ -4,7 +4,7 @@ Usages | TiBillet - + diff --git a/fr/docs/tags/access-card/index.html b/fr/docs/tags/access-card/index.html index b914d1da..315bfa23 100644 --- a/fr/docs/tags/access-card/index.html +++ b/fr/docs/tags/access-card/index.html @@ -4,7 +4,7 @@ 2 documents tagués avec "access card" | TiBillet - + diff --git a/fr/docs/tags/badge-inter-lieux/index.html b/fr/docs/tags/badge-inter-lieux/index.html index 12ce7dd4..d7c5f8eb 100644 --- a/fr/docs/tags/badge-inter-lieux/index.html +++ b/fr/docs/tags/badge-inter-lieux/index.html @@ -4,7 +4,7 @@ 2 documents tagués avec "badge inter-lieux" | TiBillet - + diff --git a/fr/docs/tags/badge/index.html b/fr/docs/tags/badge/index.html index 92c3d6ca..95ad7a6f 100644 --- a/fr/docs/tags/badge/index.html +++ b/fr/docs/tags/badge/index.html @@ -4,7 +4,7 @@ Un document tagué avec "badge" | TiBillet - + diff --git a/fr/docs/tags/badgeuse/index.html b/fr/docs/tags/badgeuse/index.html index 9ab5dcf6..ee382284 100644 --- a/fr/docs/tags/badgeuse/index.html +++ b/fr/docs/tags/badgeuse/index.html @@ -4,7 +4,7 @@ Un document tagué avec "badgeuse" | TiBillet - + diff --git a/fr/docs/tags/billetterie/index.html b/fr/docs/tags/billetterie/index.html index 16976044..2daa5ecb 100644 --- a/fr/docs/tags/billetterie/index.html +++ b/fr/docs/tags/billetterie/index.html @@ -4,7 +4,7 @@ 5 documents tagués avec "billetterie" | TiBillet - + diff --git a/fr/docs/tags/caisse-enregistreuse/index.html b/fr/docs/tags/caisse-enregistreuse/index.html index b1613c23..e34d71f2 100644 --- a/fr/docs/tags/caisse-enregistreuse/index.html +++ b/fr/docs/tags/caisse-enregistreuse/index.html @@ -4,7 +4,7 @@ 2 documents tagués avec "caisse enregistreuse" | TiBillet - + diff --git a/fr/docs/tags/cashback/index.html b/fr/docs/tags/cashback/index.html index 7a3c09ac..12471765 100644 --- a/fr/docs/tags/cashback/index.html +++ b/fr/docs/tags/cashback/index.html @@ -4,7 +4,7 @@ 2 documents tagués avec "cashback" | TiBillet - + diff --git a/fr/docs/tags/cashless/index.html b/fr/docs/tags/cashless/index.html index d785a395..2000f64a 100644 --- a/fr/docs/tags/cashless/index.html +++ b/fr/docs/tags/cashless/index.html @@ -4,7 +4,7 @@ 5 documents tagués avec "cashless" | TiBillet - + diff --git a/fr/docs/tags/contribuer/index.html b/fr/docs/tags/contribuer/index.html index 1bdaa846..503076fe 100644 --- a/fr/docs/tags/contribuer/index.html +++ b/fr/docs/tags/contribuer/index.html @@ -4,7 +4,7 @@ Un document tagué avec "contribuer" | TiBillet - + diff --git a/fr/docs/tags/cooperative/index.html b/fr/docs/tags/cooperative/index.html index b43b0c69..9db33451 100644 --- a/fr/docs/tags/cooperative/index.html +++ b/fr/docs/tags/cooperative/index.html @@ -4,7 +4,7 @@ Un document tagué avec "coopérative" | TiBillet - + diff --git a/fr/docs/tags/demonstration/index.html b/fr/docs/tags/demonstration/index.html index 7a0b5d46..4f8cb781 100644 --- a/fr/docs/tags/demonstration/index.html +++ b/fr/docs/tags/demonstration/index.html @@ -4,7 +4,7 @@ Un document tagué avec "démonstration" | TiBillet - + diff --git a/fr/docs/tags/django/index.html b/fr/docs/tags/django/index.html index d6e7270e..61b9f26b 100644 --- a/fr/docs/tags/django/index.html +++ b/fr/docs/tags/django/index.html @@ -4,7 +4,7 @@ Un document tagué avec "django" | TiBillet - + diff --git a/fr/docs/tags/docker/index.html b/fr/docs/tags/docker/index.html index cf837c9b..3f943603 100644 --- a/fr/docs/tags/docker/index.html +++ b/fr/docs/tags/docker/index.html @@ -4,7 +4,7 @@ Un document tagué avec "docker" | TiBillet - + diff --git a/fr/docs/tags/dokos/index.html b/fr/docs/tags/dokos/index.html index 673c3038..6d399a07 100644 --- a/fr/docs/tags/dokos/index.html +++ b/fr/docs/tags/dokos/index.html @@ -4,7 +4,7 @@ 2 documents tagués avec "dokos" | TiBillet - + diff --git a/fr/docs/tags/festival/index.html b/fr/docs/tags/festival/index.html index dcbbcf49..9484da10 100644 --- a/fr/docs/tags/festival/index.html +++ b/fr/docs/tags/festival/index.html @@ -4,7 +4,7 @@ Un document tagué avec "festival" | TiBillet - + diff --git a/fr/docs/tags/fidelite/index.html b/fr/docs/tags/fidelite/index.html index bd84a617..0838fa4d 100644 --- a/fr/docs/tags/fidelite/index.html +++ b/fr/docs/tags/fidelite/index.html @@ -4,7 +4,7 @@ Un document tagué avec "fidélité" | TiBillet - + diff --git a/fr/docs/tags/fidelity/index.html b/fr/docs/tags/fidelity/index.html index d32cc4f7..7c6d4931 100644 --- a/fr/docs/tags/fidelity/index.html +++ b/fr/docs/tags/fidelity/index.html @@ -4,7 +4,7 @@ Un document tagué avec "fidelity" | TiBillet - + diff --git a/fr/docs/tags/git/index.html b/fr/docs/tags/git/index.html index 236163c7..5bdc00a2 100644 --- a/fr/docs/tags/git/index.html +++ b/fr/docs/tags/git/index.html @@ -4,7 +4,7 @@ Un document tagué avec "git" | TiBillet - + diff --git a/fr/docs/tags/index.html b/fr/docs/tags/index.html index a59ef7e1..81f69154 100644 --- a/fr/docs/tags/index.html +++ b/fr/docs/tags/index.html @@ -4,7 +4,7 @@ Tags | TiBillet - + diff --git a/fr/docs/tags/logiciel-libre/index.html b/fr/docs/tags/logiciel-libre/index.html index 01975ade..ae170cfd 100644 --- a/fr/docs/tags/logiciel-libre/index.html +++ b/fr/docs/tags/logiciel-libre/index.html @@ -4,7 +4,7 @@ Un document tagué avec "logiciel libre" | TiBillet - + diff --git a/fr/docs/tags/monnaie-locale/index.html b/fr/docs/tags/monnaie-locale/index.html index 2e8d962f..cb7a87e5 100644 --- a/fr/docs/tags/monnaie-locale/index.html +++ b/fr/docs/tags/monnaie-locale/index.html @@ -4,7 +4,7 @@ Un document tagué avec "monnaie locale" | TiBillet - + diff --git a/fr/docs/tags/monnaies-locales/index.html b/fr/docs/tags/monnaies-locales/index.html index 1544f27e..1c5618ab 100644 --- a/fr/docs/tags/monnaies-locales/index.html +++ b/fr/docs/tags/monnaies-locales/index.html @@ -4,7 +4,7 @@ Un document tagué avec "monnaies locales" | TiBillet - + diff --git a/fr/docs/tags/monnaies-temps/index.html b/fr/docs/tags/monnaies-temps/index.html index 37ccdfaa..651ab384 100644 --- a/fr/docs/tags/monnaies-temps/index.html +++ b/fr/docs/tags/monnaies-temps/index.html @@ -4,7 +4,7 @@ Un document tagué avec "monnaies temps" | TiBillet - + diff --git a/fr/docs/tags/open-source/index.html b/fr/docs/tags/open-source/index.html index 5801aa6b..bf21fe59 100644 --- a/fr/docs/tags/open-source/index.html +++ b/fr/docs/tags/open-source/index.html @@ -4,7 +4,7 @@ 2 documents tagués avec "open source" | TiBillet - + diff --git a/fr/docs/tags/paiement-dematerialise/index.html b/fr/docs/tags/paiement-dematerialise/index.html index 7bbeaac1..2c36f896 100644 --- a/fr/docs/tags/paiement-dematerialise/index.html +++ b/fr/docs/tags/paiement-dematerialise/index.html @@ -4,7 +4,7 @@ Un document tagué avec "paiement dématérialisé" | TiBillet - + diff --git a/fr/docs/tags/poetry/index.html b/fr/docs/tags/poetry/index.html index 8c12ffca..9645f33c 100644 --- a/fr/docs/tags/poetry/index.html +++ b/fr/docs/tags/poetry/index.html @@ -4,7 +4,7 @@ Un document tagué avec "poetry" | TiBillet - + diff --git a/fr/docs/tags/prise-de-commandes/index.html b/fr/docs/tags/prise-de-commandes/index.html index 132c31ed..d67531d9 100644 --- a/fr/docs/tags/prise-de-commandes/index.html +++ b/fr/docs/tags/prise-de-commandes/index.html @@ -4,7 +4,7 @@ Un document tagué avec "prise de commandes" | TiBillet - + diff --git a/fr/docs/tags/python/index.html b/fr/docs/tags/python/index.html index 75a923ec..bd40a45f 100644 --- a/fr/docs/tags/python/index.html +++ b/fr/docs/tags/python/index.html @@ -4,7 +4,7 @@ Un document tagué avec "python" | TiBillet - + diff --git a/fr/docs/tags/soutien/index.html b/fr/docs/tags/soutien/index.html index b97a6151..ac6d68c4 100644 --- a/fr/docs/tags/soutien/index.html +++ b/fr/docs/tags/soutien/index.html @@ -4,7 +4,7 @@ Un document tagué avec "soutien" | TiBillet - + diff --git a/fr/docs/tags/stripe/index.html b/fr/docs/tags/stripe/index.html index a57f02e3..6404066b 100644 --- a/fr/docs/tags/stripe/index.html +++ b/fr/docs/tags/stripe/index.html @@ -4,7 +4,7 @@ 2 documents tagués avec "stripe" | TiBillet - + diff --git a/fr/docs/tags/tdd/index.html b/fr/docs/tags/tdd/index.html index d80fc2a7..b2279330 100644 --- a/fr/docs/tags/tdd/index.html +++ b/fr/docs/tags/tdd/index.html @@ -4,7 +4,7 @@ Un document tagué avec "tdd" | TiBillet - + diff --git a/fr/docs/tags/ticketing/index.html b/fr/docs/tags/ticketing/index.html index 4f315c1a..3e33a0b4 100644 --- a/fr/docs/tags/ticketing/index.html +++ b/fr/docs/tags/ticketing/index.html @@ -4,7 +4,7 @@ 5 documents tagués avec "ticketing" | TiBillet - + diff --git a/fr/docs/tags/tiers-lieux/index.html b/fr/docs/tags/tiers-lieux/index.html index 873ae456..28ee8be0 100644 --- a/fr/docs/tags/tiers-lieux/index.html +++ b/fr/docs/tags/tiers-lieux/index.html @@ -4,7 +4,7 @@ Un document tagué avec "tiers-lieux" | TiBillet - + diff --git a/fr/index.html b/fr/index.html index 75c9f372..84d9e0ef 100644 --- a/fr/index.html +++ b/fr/index.html @@ -4,7 +4,7 @@ TiBillet | TiBillet - + diff --git a/fr/roadmap/index.html b/fr/roadmap/index.html index 3a26d3b0..5866a847 100644 --- a/fr/roadmap/index.html +++ b/fr/roadmap/index.html @@ -4,7 +4,7 @@ Fonctionnalités | TiBillet - + diff --git a/index.html b/index.html index 451e181d..4609252a 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ TiBillet | TiBillet - + diff --git a/roadmap/index.html b/roadmap/index.html index 0a2ea7ce..84c2eaa7 100644 --- a/roadmap/index.html +++ b/roadmap/index.html @@ -4,7 +4,7 @@ Fonctionnalités | TiBillet - +