[{"data":1,"prerenderedAt":688},["ShallowReactive",2],{"profile-en":3,"projects-en":85,"experiences-en":621},{"id":4,"about":5,"availability":8,"extension":9,"heroWords":10,"interests":16,"languages":19,"location":22,"meta":23,"name":24,"role":25,"skills":26,"stats":72,"stem":82,"tagline":83,"__hash__":84},"profile_en\u002Fen\u002Fprofile.yml",[6,7],"I'm a back-end-leaning full-stack developer with 6 years of professional experience in PHP (Symfony, CakePHP) and JavaScript \u002F TypeScript (Vue.js, Nuxt), and 15 years of writing code.","I build REST APIs, SaaS products and e-commerce sites, and I also take care of everything after the code — Docker, CI\u002FCD, server administration. With a Master's degree in IT project management, I'm equally comfortable scoping, estimating and planning work.","Open to a permanent role around Bordeaux","yml",[11,12,13,14,15],"REST APIs","SaaS products","online stores","back offices","CI\u002FCD pipelines",[17,18],"Chess and strategy games","Cybersecurity watch",[20,21],"French — native","English — professional","Bordeaux, France",{},"Jérémy Ounnas","Full-Stack Developer",[27,38,47,53,63],{"category":28,"items":29},"Back-end",[30,31,32,33,34,35,36,37],"PHP 8","Symfony","API Platform","CakePHP","Doctrine","PHPUnit","Nuxt (Nitro)","Prisma",{"category":39,"items":40},"Front-end",[41,42,43,44,45,46],"TypeScript","Vue.js","Nuxt","Tailwind CSS","HTML","CSS",{"category":48,"items":49},"Databases",[50,51,52],"MariaDB","MySQL","PostgreSQL",{"category":54,"items":55},"DevOps",[56,57,58,59,60,61,62],"Docker","Docker Compose","GitLab CI","Nginx","Dokploy","AWS","Linux",{"category":64,"items":65},"Ecosystem",[66,67,68,69,70,71],"WordPress","PrestaShop","React Native","PWA","n8n","Stripe",[73,76,79],{"value":74,"label":75},"6 yrs","of professional experience",{"value":77,"label":78},"30+","projects shipped to production",{"value":80,"label":81},"10+","clients supported","en\u002Fprofile","6 years building APIs, SaaS products and e-commerce sites for small businesses — code, infrastructure and client relationship included.","vtWaDYecj6i-rLShvWjJ9ep_D-rroH7fLP_OK5W3DrQ",[86,199,293,381,467,533],{"id":87,"title":88,"accent":89,"body":90,"client":88,"cover":161,"description":164,"extension":165,"gallery":166,"meta":189,"navigation":190,"order":191,"path":192,"repository":193,"role":194,"seo":195,"stack":196,"stem":197,"url":193,"__hash__":198},"projects_en\u002Fprojects\u002Fraise-my-cast.md","Raise My Cast","#e50914",{"type":91,"value":92,"toc":154},"minimark",[93,98,102,106,136,140],[94,95,97],"h2",{"id":96},"context","Context",[99,100,101],"p",{},"Raise My Cast rents out podcast recording studios. The client wanted customers to book a slot online and put their session together themselves: studio, lighting, sound and video.",[94,103,105],{"id":104},"what-i-built","What I built",[107,108,109,118,124,130],"ul",{},[110,111,112,113,117],"li",{},"A ",[114,115,116],"strong",{},"REST API with Symfony and API Platform"," for studios, time slots, add-ons and bookings.",[110,119,112,120,123],{},[114,121,122],{},"Nuxt front end"," that guides users through the booking and updates the price live as they pick add-ons.",[110,125,112,126,129],{},[114,127,128],{},"back office"," to manage availability and track bookings.",[110,131,132,135],{},[114,133,134],{},"Containerised hosting"," (Docker) with continuous deployment.",[94,137,139],{"id":138},"challenges","Challenges",[107,141,142,148],{},[110,143,144,147],{},[114,145,146],{},"Availability",": preventing double bookings and handling add-ons in limited supply.",[110,149,150,153],{},[114,151,152],{},"API \u002F front-end split",": a documented, typed API that other clients (mobile, partners) can reuse later.",{"title":155,"searchDepth":156,"depth":156,"links":157},"",2,[158,159,160],{"id":96,"depth":156,"text":97},{"id":104,"depth":156,"text":105},{"id":138,"depth":156,"text":139},{"src":162,"alt":163},"\u002Fprojects\u002Fraise-my-cast\u002Fdesktop-home.webp","Raise My Cast home page, podcast studio in Malta","Podcast studio booking platform with lighting, audio and video add-ons.","md",[167,171,175,179,183,186],{"src":168,"alt":169,"caption":170},"\u002Fprojects\u002Fraise-my-cast\u002Fdesktop-reservation.webp","Guests, audio\u002Fvideo setup and decor selection","The booking is built step by step: guests, setup, decor.",{"src":172,"alt":173,"caption":174},"\u002Fprojects\u002Fraise-my-cast\u002Fdesktop-creneaux.webp","Studio calendar and available time slots","Available slots, computed by the API from the chosen duration.",{"src":176,"alt":177,"caption":178},"\u002Fprojects\u002Fraise-my-cast\u002Fdesktop-paiement.webp","Order summary with total price, promo code and payment method","The summary: live pricing, promo code, card or crypto payment.",{"src":180,"alt":181,"device":182},"\u002Fprojects\u002Fraise-my-cast\u002Fmobile-home.webp","Home page on mobile","mobile",{"src":184,"alt":185,"device":182},"\u002Fprojects\u002Fraise-my-cast\u002Fmobile-reservation.webp","Session setup on mobile",{"src":187,"alt":188,"device":182},"\u002Fprojects\u002Fraise-my-cast\u002Fmobile-creneaux.webp","Date picker on mobile",{},true,1,"\u002Fprojects\u002Fraise-my-cast",null,"Freelance full-stack developer",{"title":88,"description":164},[31,32,43,41,50,56],"projects\u002Fraise-my-cast","7iXbBd_LJKRiRMXGTNHnTgnNoSpdlONytJ1Tfqye-aY",{"id":200,"title":201,"accent":202,"body":203,"client":260,"cover":261,"description":264,"extension":165,"gallery":265,"meta":283,"navigation":190,"order":156,"path":284,"repository":193,"role":285,"seo":286,"stack":287,"stem":290,"url":291,"__hash__":292},"projects_en\u002Fprojects\u002Fpdrxjob.md","Pdrxjob","#6c4cf0",{"type":91,"value":204,"toc":255},[205,207,210,212,239,241],[94,206,97],{"id":96},[99,208,209],{},"Paintless dent repair is a niche trade, with many independent technicians and short-notice jobs (hailstorms, garages, dealerships). Pdrxjob connects them with the businesses that need them.",[94,211,105],{"id":104},[107,213,214,220,230,236],{},[110,215,216,219],{},[114,217,218],{},"Job sharing"," between technicians and companies.",[110,221,112,222,225,226,229],{},[114,223,224],{},"recruitment module"," and ",[114,227,228],{},"work groups"," so several technicians can team up on a job.",[110,231,232,235],{},[114,233,234],{},"Factur-X e-invoicing",", ahead of the legal requirement.",[110,237,238],{},"Ongoing maintenance and new features as the community grew to around 500 registered technicians.",[94,240,139],{"id":138},[107,242,243,249],{},[110,244,245,248],{},[114,246,247],{},"Factur-X",": generating standard-compliant hybrid PDFs (PDF\u002FA-3 with embedded XML).",[110,250,251,254],{},[114,252,253],{},"Shipping changes without breaking things",": automated database migrations and PHPUnit tests in CI.",{"title":155,"searchDepth":156,"depth":156,"links":256},[257,258,259],{"id":96,"depth":156,"text":97},{"id":104,"depth":156,"text":105},{"id":138,"depth":156,"text":139},"Make It Créative",{"src":262,"alt":263},"\u002Fprojects\u002Fpdrxjob\u002Fdesktop-home.webp","Pdrxjob technician directory and subscription plans table","Matchmaking platform for paintless dent repair technicians, with around 500 registered technicians.",[266,270,274,277,280],{"src":267,"alt":268,"caption":269},"\u002Fprojects\u002Fpdrxjob\u002Fdesktop-sinistre.webp","Damage report form with vehicle photos","The damage report, sent to the repairers on the platform.",{"src":271,"alt":272,"caption":273},"\u002Fprojects\u002Fpdrxjob\u002Fdesktop-partenaires.webp","Pdrxjob partners page","The network partners.",{"src":275,"alt":276,"device":182},"\u002Fprojects\u002Fpdrxjob\u002Fmobile-home.webp","Directory on mobile",{"src":278,"alt":279,"device":182},"\u002Fprojects\u002Fpdrxjob\u002Fmobile-sinistre.webp","Damage report on mobile",{"src":281,"alt":282,"device":182},"\u002Fprojects\u002Fpdrxjob\u002Fmobile-apropos.webp","Concept page on mobile",{},"\u002Fprojects\u002Fpdrxjob","Web developer (work-study)",{"title":201,"description":264},[33,288,51,289,247,71],"PHP","JavaScript","projects\u002Fpdrxjob","https:\u002F\u002Fwww.pdrxjob.com","xnArJmp7HU42SzQNcLdfEeuU_QCqZqJZ3jd9x5q-OPQ",{"id":294,"title":295,"accent":296,"body":297,"client":260,"cover":351,"description":354,"extension":165,"gallery":355,"meta":372,"navigation":190,"order":373,"path":374,"repository":193,"role":375,"seo":376,"stack":377,"stem":378,"url":379,"__hash__":380},"projects_en\u002Fprojects\u002Fdaniel-nouvel-auto.md","Daniel Nouvel Auto","#ff1a1a",{"type":91,"value":298,"toc":346},[299,301,308,310,336,338],[94,300,97],{"id":96},[99,302,303,304,307],{},"A car dealer wanted to show their stock online and let buyers ",[114,305,306],{},"reserve a vehicle remotely"," by paying a deposit.",[94,309,105],{"id":104},[107,311,312,318,329],{},[110,313,112,314,317],{},[114,315,316],{},"catalogue"," with filters and detailed vehicle pages.",[110,319,320,321,324,325,328],{},"The ",[114,322,323],{},"pre-order flow",", through to ",[114,326,327],{},"Stripe deposit payment",".",[110,330,331,332,335],{},"An ",[114,333,334],{},"admin area"," to manage stock and track pre-orders.",[94,337,139],{"id":138},[107,339,340],{},[110,341,342,345],{},[114,343,344],{},"Reliable payments",": confirmation through Stripe webhooks, and each vehicle can only be reserved once.",{"title":155,"searchDepth":156,"depth":156,"links":347},[348,349,350],{"id":96,"depth":156,"text":97},{"id":104,"depth":156,"text":105},{"id":138,"depth":156,"text":139},{"src":352,"alt":353},"\u002Fprojects\u002Fdaniel-nouvel-auto\u002Fdesktop-home.webp","Daniel Nouvel Automobiles home page, with the vehicle search","Car catalogue with online pre-orders and Stripe deposits.",[356,360,364,366,369],{"src":357,"alt":358,"caption":359},"\u002Fprojects\u002Fdaniel-nouvel-auto\u002Fdesktop-catalogue.webp","Catalogue of new vehicles, shown as cards with discount and price","The catalogue, with discount, specs and financing on every card.",{"src":361,"alt":362,"caption":363},"\u002Fprojects\u002Fdaniel-nouvel-auto\u002Fdesktop-detail.webp","Opel Mokka page with photo gallery, equipment and price","The vehicle page, entry point to the pre-order flow.",{"src":365,"alt":181,"device":182},"\u002Fprojects\u002Fdaniel-nouvel-auto\u002Fmobile-home.webp",{"src":367,"alt":368,"device":182},"\u002Fprojects\u002Fdaniel-nouvel-auto\u002Fmobile-catalogue.webp","Catalogue on mobile",{"src":370,"alt":371,"device":182},"\u002Fprojects\u002Fdaniel-nouvel-auto\u002Fmobile-detail.webp","Vehicle page on mobile",{},3,"\u002Fprojects\u002Fdaniel-nouvel-auto","Freelance developer",{"title":295,"description":354},[33,288,71,50],"projects\u002Fdaniel-nouvel-auto","https:\u002F\u002Fwww.daniel-nouvel.com","L2B4SfPY-y5EPAqS3AoaoiyqlCUUcKi044qtx3LXDec",{"id":382,"title":383,"accent":384,"body":385,"client":260,"cover":432,"description":435,"extension":165,"gallery":436,"meta":458,"navigation":190,"order":459,"path":460,"repository":193,"role":285,"seo":461,"stack":462,"stem":465,"url":193,"__hash__":466},"projects_en\u002Fprojects\u002Fthankyoumax.md","ThankYouMax","#c9a24a",{"type":91,"value":386,"toc":427},[387,389,392,394,417,419],[94,388,97],{"id":96},[99,390,391],{},"ThankYouMax runs online prize draws. Participants buy tickets, and every ticket increases their odds of winning.",[94,393,105],{"id":104},[107,395,396,405,411],{},[110,397,398,399,225,402,328],{},"Participant ",[114,400,401],{},"sign-up",[114,403,404],{},"ticket purchase",[110,406,112,407,410],{},[114,408,409],{},"weighted draw algorithm"," that is fair and traceable.",[110,412,413,414,328],{},"A platform that kept up with growth to around ",[114,415,416],{},"2,000 sign-ups in 2023",[94,418,139],{"id":138},[107,420,421],{},[110,422,423,426],{},[114,424,425],{},"A fair, traceable draw",": a result that can be checked and justified.",{"title":155,"searchDepth":156,"depth":156,"links":428},[429,430,431],{"id":96,"depth":156,"text":97},{"id":104,"depth":156,"text":105},{"id":138,"depth":156,"text":139},{"src":433,"alt":434},"\u002Fprojects\u002Fthankyoumax\u002Fdesktop-home.webp","Featured prizes with each lottery progress bar","Online lottery with ticket-weighted draws, around 2,000 sign-ups in 2023.",[437,441,445,449,452,455],{"src":438,"alt":439,"caption":440},"\u002Fprojects\u002Fthankyoumax\u002Fdesktop-participer.webp","The three steps to take part","A three-step flow: sign up, bet on prizes, pay.",{"src":442,"alt":443,"caption":444},"\u002Fprojects\u002Fthankyoumax\u002Fdesktop-univers.webp","Prize categories mosaic: travel, Rolex, Chanel, cars","The prize categories.",{"src":446,"alt":447,"caption":448},"\u002Fprojects\u002Fthankyoumax\u002Fdesktop-associations.webp","Charities supported by the lottery","The supported charities, which receive 35% of the proceeds.",{"src":450,"alt":451,"device":182},"\u002Fprojects\u002Fthankyoumax\u002Fmobile-home.webp","Featured prizes on mobile",{"src":453,"alt":454,"device":182},"\u002Fprojects\u002Fthankyoumax\u002Fmobile-participer.webp","How to take part on mobile",{"src":456,"alt":457,"device":182},"\u002Fprojects\u002Fthankyoumax\u002Fmobile-associations.webp","Charities on mobile",{},4,"\u002Fprojects\u002Fthankyoumax",{"title":383,"description":435},[33,288,51,71,463,464],"PayGreen","Apple Pay","projects\u002Fthankyoumax","EPd6uY_9E-OwMnGwdWO94AYV4-pfC9pBFHRYFqWiYWg",{"id":468,"title":469,"accent":470,"body":471,"client":260,"cover":503,"description":506,"extension":165,"gallery":507,"meta":524,"navigation":190,"order":525,"path":526,"repository":193,"role":285,"seo":527,"stack":528,"stem":530,"url":531,"__hash__":532},"projects_en\u002Fprojects\u002Farmenak.md","Armenak","#a0785a",{"type":91,"value":472,"toc":499},[473,475,478,480],[94,474,97],{"id":96},[99,476,477],{},"A luxury shoe brand needed an online store that matched its high-end positioning.",[94,479,105],{"id":104},[107,481,482,488,494],{},[110,483,484,487],{},[114,485,486],{},"Custom PrestaShop modules"," for specific business needs.",[110,489,490,493],{},[114,491,492],{},"Bespoke theme elements"," that stay true to the brand identity.",[110,495,496,328],{},[114,497,498],{},"Shipping and payment integrations",{"title":155,"searchDepth":156,"depth":156,"links":500},[501,502],{"id":96,"depth":156,"text":97},{"id":104,"depth":156,"text":105},{"src":504,"alt":505},"\u002Fprojects\u002Farmenak\u002Fdesktop-home.webp","Armenak home page, with the men and women sections","Luxury footwear e-commerce on PrestaShop, with custom modules and theme.",[508,512,516,518,521],{"src":509,"alt":510,"caption":511},"\u002Fprojects\u002Farmenak\u002Fdesktop-liste.webp","Sneakers listing with filters and colour variants","The product listing, with faceted filters and colour variants.",{"src":513,"alt":514,"caption":515},"\u002Fprojects\u002Farmenak\u002Fdesktop-produit.webp","Product page with size picker and instalment payment","The product page: sizes, 4-instalment payment and reassurance.",{"src":517,"alt":181,"device":182},"\u002Fprojects\u002Farmenak\u002Fmobile-home.webp",{"src":519,"alt":520,"device":182},"\u002Fprojects\u002Farmenak\u002Fmobile-liste.webp","Product listing on mobile",{"src":522,"alt":523,"device":182},"\u002Fprojects\u002Farmenak\u002Fmobile-produit.webp","Product page on mobile",{},5,"\u002Fprojects\u002Farmenak",{"title":469,"description":506},[67,288,289,529],"Chronopost","projects\u002Farmenak","https:\u002F\u002Fwww.armenak.fr","m8jX2h9L3aJFh32rXVWu75I7r2jF2YyU7Gt1wRbeJE4",{"id":534,"title":535,"accent":536,"body":537,"client":588,"cover":589,"description":592,"extension":165,"gallery":593,"meta":612,"navigation":190,"order":613,"path":614,"repository":193,"role":615,"seo":616,"stack":617,"stem":619,"url":193,"__hash__":620},"projects_en\u002Fprojects\u002Fapplication-bien-etre.md","Wellness app","#3b8fd0",{"type":91,"value":538,"toc":584},[539,541,544,548,578],[94,540,97],{"id":96},[99,542,543],{},"This was a professional case project in the IT Project Management Master's: a cross-functional team had to deliver a wellness mobile app together with its back end.",[94,545,547],{"id":546},"my-role","My role",[107,549,550,559,566,572],{},[110,551,552,555,556,328],{},[114,553,554],{},"Technical lead",": architecture decisions and the ",[114,557,558],{},"technical specifications",[110,560,561,562,565],{},"Built the ",[114,563,564],{},"REST API and back office"," with Symfony.",[110,567,568,569,328],{},"Supported the team on the ",[114,570,571],{},"React Native mobile app",[110,573,574,575,328],{},"Set up the ",[114,576,577],{},"servers with Docker",[99,579,580],{},[581,582,583],"em",{},"The visuals shown are the app's Figma mockups.",{"title":155,"searchDepth":156,"depth":156,"links":585},[586,587],{"id":96,"depth":156,"text":97},{"id":546,"depth":156,"text":547},"Institut G4",{"src":590,"alt":591,"device":182},"\u002Fprojects\u002Fapplication-bien-etre\u002Fcover.webp","In-Spire app mockups: home, session player and stress meter","Symfony REST API and back office with a React Native mobile app. Master's project where I was tech lead.",[594,597,600,603,606,609],{"src":595,"alt":596,"device":182},"\u002Fprojects\u002Fapplication-bien-etre\u002Fmobile-bienvenue.webp","Onboarding welcome screen",{"src":598,"alt":599,"device":182},"\u002Fprojects\u002Fapplication-bien-etre\u002Fmobile-accueil.webp","Home with favourite sessions",{"src":601,"alt":602,"device":182},"\u002Fprojects\u002Fapplication-bien-etre\u002Fmobile-seance.webp","Breathing session player",{"src":604,"alt":605,"device":182},"\u002Fprojects\u002Fapplication-bien-etre\u002Fmobile-mesure.webp","Heart rate variability measurement with an oximeter",{"src":607,"alt":608,"device":182},"\u002Fprojects\u002Fapplication-bien-etre\u002Fmobile-stress.webp","Stress meter and result description",{"src":610,"alt":611,"device":182},"\u002Fprojects\u002Fapplication-bien-etre\u002Fmobile-respiration.webp","Breathing practice customisation",{},6,"\u002Fprojects\u002Fapplication-bien-etre","Tech lead",{"title":535,"description":592},[31,68,56,618],"REST API","projects\u002Fapplication-bien-etre","UxER2IchMNjAL26NSR2ULFBsata3RVxbZFJz69S1Vk0",[622,639,654,667,677],{"id":623,"title":624,"company":625,"end":193,"extension":9,"highlights":626,"location":633,"meta":634,"order":191,"start":635,"stem":636,"type":637,"__hash__":638},"experiences_en\u002Fen\u002Fexperiences\u002F01-freelance.yml","Freelance Web Developer","Self-employed",[627,628,629,630,631,632],"Designing, building and maintaining web applications for small businesses","Raise My Cast (Symfony, API Platform, Nuxt): podcast studio booking platform","Daniel Nouvel Auto (CakePHP): car catalogue with Stripe pre-orders and deposits","Business process automation with n8n","Hosting and server administration: MariaDB, Nginx, Docker, Dokploy","End-to-end client relationship: requirements, estimates, planning, delivery","Bordeaux",{},"Jan. 2024","en\u002Fexperiences\u002F01-freelance","work","lJ_e25y13TE7pitpaFDSKpRh1AflNa0-lBiVd89UNMs",{"id":640,"title":641,"company":260,"end":635,"extension":9,"highlights":642,"location":649,"meta":650,"order":156,"start":651,"stem":652,"type":637,"__hash__":653},"experiences_en\u002Fen\u002Fexperiences\u002F02-make-it-creative.yml","Web & Mobile Developer",[643,644,645,646,647,648],"Showcase sites, e-commerce, SaaS and PWAs in PHP (Symfony, CakePHP) and Vue.js","Pdrxjob: matchmaking platform (around 500 technicians), Factur-X e-invoicing","ThankYouMax: online lottery, around 2,000 sign-ups in 2023","Payment and shipping integrations: Stripe, PayGreen, PayPal, Chronopost","Automated database migrations and PHPUnit tests in CI\u002FCD (Buddy)","Introduced the Git Flow workflow and coding best practices to the team","Aubagne · Work-study",{},"Sept. 2020","en\u002Fexperiences\u002F02-make-it-creative","ydt6YorRHAWU1r91zoxlvx4RcuOUk5ONMyz41dxVUsg",{"id":655,"title":656,"company":588,"end":657,"extension":9,"highlights":658,"location":660,"meta":661,"order":662,"start":663,"stem":664,"type":665,"__hash__":666},"experiences_en\u002Fen\u002Fexperiences\u002F10-master.yml","MSc in IT Project Management","2024",[659],"Tech lead on a wellness app: Symfony API, React Native app, Docker","Marseille",{},10,"2022","en\u002Fexperiences\u002F10-master","education","AJsDXbDQRaSl4OAtu5Dvm4YKTe5i3ylNtZ4DHHr2Mqo",{"id":668,"title":669,"company":588,"end":663,"extension":9,"highlights":670,"location":660,"meta":672,"order":673,"start":674,"stem":675,"type":665,"__hash__":676},"experiences_en\u002Fen\u002Fexperiences\u002F11-licence.yml","Bachelor in Application Design & Development",[671],"Scrum Master on a nursing-home app: team of 12 people",{},11,"2020","en\u002Fexperiences\u002F11-licence","XlTZdmMfvNMbR5mlORpq7tPL0rEAnzLQ8r3_PMXcleM",{"id":678,"title":679,"company":680,"end":193,"extension":9,"highlights":681,"location":193,"meta":682,"order":683,"start":684,"stem":685,"type":686,"__hash__":687},"experiences_en\u002Fen\u002Fexperiences\u002F20-google-ai.yml","Google AI Professional Certificate","Google (Coursera)",[],{},20,"2026","en\u002Fexperiences\u002F20-google-ai","certification","-jPRUkLa3HNS2PCRRR4z9t15lNPWO5c_Er9__E4Ss9E",1792139140540]