Achievements
01
Git history places creation of this portfolio version on March 12, 2026, with initialization from Next.js. Git records successive code versions and makes it possible to retrieve the date and nature of initial changes. This release is not my first professional presence online: it is a reconstruction intended to replace earlier materials that no longer met my training and presentation objectives.
The project's original reason was academic. The qualification I was preparing required a portfolio, and its content was assessed against a precise rubric. Publishing an attractive page with my name and a few technologies was therefore insufficient. The website had to present my journey, compare skills, develop every skill, describe several achievements, connect content, and provide evidence. This requirement explains the scale the project gradually acquired.
Before this reconstruction, I already had a portfolio and a GitHub profile page. A GitHub profile page can display an introduction, links, and code repositories on the platform used to host projects. These materials provided an initial overview of my activity but did not match the qualification examiners' expectations. In particular, they lacked the required level of writing, structure, and relationships between skills, experience, and achievements.
The first audience consists of examiners who must verify that the portfolio meets qualification criteria. The second consists of recruiters seeking to understand my professional profile without browsing my complete code history. These audiences do not read in exactly the same way: examiners look for the required sections and depth, while recruiters need to identify my domain, level, achievements, and working approach quickly.
I am already employed, so the portfolio is not directly intended to obtain a job in the short term. It should instead make my professional abilities accessible and understandable. A visitor is not required to complete a specific commercial action after reading. The expected outcome is first a better understanding of what I can do, the problems I have solved, and the responsibilities I can take.
The intended image is that of a developer capable of understanding a business requirement, designing a solution, and maintaining it over time. A technology alone does not demonstrate this capability: writing “Odoo,” “Next.js,” or “PostgreSQL” does not explain how those tools were used. The portfolio therefore associates skills with situations, results, limitations, and development goals. It aims to show professional practice rather than an inventory of keywords.
This positioning is presented through my skills, current projects, and achievements. Articles about Odoo migration, business modules, and integrations show that I do more than configure an ERP. They explain how I analyze its code, adapt functions, automate processes, handle user feedback, and take ownership of structural changes. Together, they should make progress toward an experienced-developer role and a reference capable of supporting decisions around Odoo visible.
My professional project is not limited to Odoo. I want to build broader expertise in integrating ERPs with external systems through custom APIs for end customers. An API, or application programming interface, allows two software systems to exchange data and trigger operations according to defined rules. Projects around Business Intelligence, the B2B website, and synchronization demonstrate this expansion beyond the ERP core.
The project does not start from a ready-to-fill portfolio theme. I developed it to control structure, navigation, relationships between skills and achievements, and bilingual presentation. This custom approach does not mean reinventing every visual component: it means that architecture and content are adapted to the assessment requirement. Existing libraries and components remain appropriate when they provide a maintainable and accessible foundation.
Initial scope mainly presented my skills and journey in a concise form. This first release resembled a conventional professional portfolio: an introduction, several technical areas, and a timeline. It did not yet develop every skill in a complete article or describe achievements through objectives, risks, steps, participants, results, aftermath, and critical review as required by the rubric.
The current pages, sections, and writing volume were not all planned at the start. Their addition addresses the obligation to detail skills and achievements rather than a desire to multiply screens artificially. The project gradually added a comparative skill map, in-depth articles, circular navigation between evidence and expertise, an experience timeline, and content written more explicitly for readers outside the field.
Although training triggered this reconstruction, the portfolio should not become a frozen archive once the qualification is obtained. It will continue to present new responsibilities, projects, and learning. The blog is the main way for it to evolve regularly. This continuity turns a one-time academic obligation into a professional resource usable for several years.
I selected Next.js and React because I already knew the ecosystem and it provides a suitable framework for a website combining static pages, content, interactive components, and server logic. Next.js notably organizes routing, rendering, metadata, and resource optimization around React. Performance always depends on final implementation, but this foundation allows JavaScript to be limited to components that need it and pages to be structured for search engines.
TypeScript checks types and reduces certain inconsistencies before execution. Tailwind CSS provides composable styling classes. shadcn/ui provides accessible components whose code remains editable inside the project. GSAP handles animations requiring more precise control. Clean code means code that is readable, structured, and simple enough to change. Using these tools does not guarantee that quality automatically, but avoids rebuilding common mechanisms and lets work focus on portfolio-specific requirements.
I am responsible for the website's visual direction but do not claim to have created every idea without reference. I drew inspiration from portfolios I had already seen to observe hierarchy, navigation, project presentation, and animation use. The objective was not to reproduce a particular website, but to identify effective conventions and adapt them to my content, palette, and intended professional image.
The portfolio represents several full days of work, supplemented by writing, correction, and improvement periods performed as feedback arrived. I do not have a sufficiently precise time log to announce a reliable total. This duration remains open because every new experience, piece of evidence, or requirement can trigger a change. The project should therefore be assessed as a product maintained over time rather than a page completed in one session.
I used Codex during implementation, notably to help structure, rephrase, and expand written content. An assistance tool can accelerate exploration of a codebase or suggest an initial formulation, but it does not automatically know the reality of my experience. I remain responsible for reviewing text, correcting errors, providing facts, and deciding what is published. This transparency matters: the portfolio must represent my journey even when modern tools contribute to its production.
French is the website's primary language, while English broadens reach to recruiters and contacts who do not read French. Interface elements, metadata, and main pages therefore exist in both languages. Bilingual delivery should not create two contradictory portfolios: essential information must remain consistent and be updated together.
Technical articles were written in French before bilingual support was fully implemented. Their content therefore remains mainly in that language even when titles and descriptions are translated in the interface. MDX is a format combining Markdown's structured text with the ability to insert components. Translating every article in full would require significant editorial maintenance; the website discloses this limitation and allows the browser to provide translation when needed.
The blog is not included only to improve search visibility or fill a section. It allows me to document solutions to problems for which I had found no online answer, or none in a sufficiently clear form. Every article should save time for another developer facing the same context. This approach turns a difficulty encountered during a project into reusable knowledge and also demonstrates my ability to explain a technical solution.
The portfolio is published on the custom domain orhanmadiassani.com. A custom domain provides an address independent of the host's technical URL and can be retained even if infrastructure changes. It centralizes my professional presence and provides a stable address to share in a résumé, GitHub profile, or conversation with a recruiter.
A significant part of my work concerns Odoo and my employer's internal tools. I cannot freely publish data, figures, customer information, or code excerpts that reveal its operations. Evidence must therefore be anonymized, redacted, or replaced with approved screenshots. This limitation does not mean the achievement does not exist: it requires me to demonstrate my approach and added value without exposing information belonging to the company.
For the first launch, the minimum expected result was a website that presented me and my skills properly. It had to allow someone who did not know me to understand my field, journey, and main expertise. More advanced functions—blog, search, analytics, animations, or detailed navigation—could enrich this foundation, but did not replace the fundamental criterion: provide a faithful and understandable professional representation of my profile.
02
The objective is not merely to obtain a sufficient portfolio score. I intend to meet every criterion and achieve 100% of the scale. This ambition requires addressing both elements visible on every page—identity, photo, and navigation—and detailed articles, evidence, circular links, journey, contact, and spelling. Graphic quality cannot compensate for a missing section when points are awarded to explicitly verifiable elements.
The target period for completing assessment work is August 2026, although the exact date has not yet been confirmed. This uncertainty requires keeping a buffer and handling score-critical work first. An approximate deadline should not justify postponing verification: core content must be ready before the official date turns every correction into an emergency.
The absolute priority is to present every required point. Each skill must contain its definition, evidence, self-criticism, and development; each achievement must cover presentation, objectives, risks, steps, participants, results, aftermath, and critical review. This completeness matters more to assessment than a new animation or function absent from the rubric.
The mandatory core includes a presentation of my profile, human skills, technical skills, and achievements. These sections explain who I am, how I work, what I can implement, and the situations in which I demonstrated it. The journey and evidence complete this reading, but no technical enrichment can replace these four editorial pillars.
English translation and the blog provide professional value but could be postponed without making the portfolio non-compliant with the French rubric. Bilingual delivery broadens readership and the blog demonstrates my ability to share solutions; neither should delay a mandatory skill article or incomplete achievement. This distinction supports prioritization without abandoning the functions that will keep the website alive after examination.
The portfolio should not force an assessor to guess where information is located. The main menu, submenus, section titles, and links between skills and achievements must make every element easy to retrieve. The objective is not merely to possess content in code: it must be visible, understandable, and accessible through the journey expected by the rubric.
The website does not yet provide a public page directly linking every criterion to its location. Current structure and the internal checklist already support compliance tracking, but a mapping view could make final assessment verification easier. It should not turn the portfolio into a raw copy of the rubric; it would act as a control index proving that no requirement was forgotten.
I want to provide enough detail for examiners to understand context, decisions, and my added value even when they are unfamiliar with Odoo or the cited technologies. Every specialized concept should be defined and every important claim illustrated. Quantity is not an isolated objective, however: a paragraph should explain information, a cause-and-effect relationship, a result, or useful reflection.
Articles must be divided into paragraphs, subheadings, and highlighted phrases so readers can scan them first and then explore relevant points. Unnecessary details, repetition, and information unrelated to the skill or achievement should be removed. This structure balances opposing needs: providing substantial assessment material without turning every page into an unreadable block of text.
The technical objective is a minimum score of 95 out of 100 in categories measured by Lighthouse, notably performance, accessibility, best practices, and technical search optimization. Lighthouse runs automated checks on a page and reports selected loading, contrast, structure, or configuration problems. The score is not absolute proof of quality, but provides a reproducible threshold for detecting significant regressions.
Accessibility must also remain above 95 in audits. This notably requires coherent heading structure, usable navigation, understandable labels, sufficient contrast, and animations that do not block content. An automated score does not replace human checks with keyboard navigation or different settings, but the numerical target prevents accessibility from being treated as an optional end-of-project improvement.
I implement the necessary search foundations—metadata, sitemap, structured content, performance, and a custom domain—but do not set a precise ranking objective in a search engine. If the portfolio appears in relevant searches, that will be a benefit. The priority remains assessment compliance and a clear professional address rather than writing articles only to attract traffic.
The contact area was not only a possible portfolio requirement: I wanted to provide a direct way to reach me from the website. The form must validate information, send the message to a monitored address, and clearly report its outcome to the visitor. It supplements public contact details without requiring the person to open another service or manually copy an address.
Statistics should help me understand which pages are viewed and how visitors navigate the portfolio. Analytics covers audience measurements such as page views, entry pages, and selected interactions. The objective is not to collect the maximum amount of personal information, but to identify useful content, areas that remain hard to find, and journeys that could be improved. Loading must remain consent-gated where regulation requires it.
Bilingual delivery was not required by the training program. I added it to broaden portfolio reach among English-speaking recruiters or professionals. This feature must remain secondary to French completeness, but also demonstrates that the architecture can handle several languages and that core profile information is accessible beyond an exclusively French-speaking context.
For Odoo achievements, I prepare screenshots and excerpts myself by redacting confidential data, figures, and identifiers. I then show the intended material to people concerned by the project to obtain their approval. This process must provide concrete evidence without exposing customers, internal processes, or company-owned code. The objective is to demonstrate my work with authorization from the parties carrying the associated risk.
Codex helps me produce an initial structured draft from my answers more quickly. It must not decide what happened on my behalf or replace my judgment. I therefore review every text manually and change formulations that do not exactly match my experience. The objective is to save formatting time while retaining complete human responsibility for published meaning.
Skills, projects, objectives, and results can become outdated. I therefore plan to reread the website regularly and update content when a situation changes. This maintenance is not yet tied to an automated schedule: it relies on reviews and the addition of new experience. The blog and modular structure should support these changes without requiring a complete website rebuild.
03
The main assessment risk is not a spectacular technical outage, but missing content or failure to meet a requested element. A skill may be real yet earn no points if its definition, evidence, or development is absent. Reducing this risk requires criterion-by-criterion review, an updated checklist, and final verification of the rendered website—not merely data present in files.
The portfolio must let examiners locate criteria, but does not yet include a page explicitly linking them to their locations. Clear navigation reduces the problem without guaranteeing that a subtle requirement is not forgotten. The internal checklist currently provides this control. Before assessment, it must be compared with the version actually accessible online and, if necessary, supplemented by a visible index or verification document.
Multiplying sections can create an impression of completeness without demonstrating mastery. An anecdote without context, a skill without a result, or an undefined technical term would remain insufficient. The risk is particularly high for subjects I know well because I may wrongly assume that readers understand Odoo, an ORM, an API, or a migration. Every article must therefore answer “why,” “how,” “with what result,” and “with what reflection.”
Trying to avoid superficial presentation can produce text that is too long, repetitive, or filled with unnecessary definitions. Depth is not measured by paragraph count. Every subheading must add a distinct angle, details must support understanding, and repetition must be removed. Structure allows readers to scan a page but does not compensate for content that restates the same idea several times.
The main risk associated with company projects is failing to explain my contribution sufficiently after removing confidential information. A fully obscured screenshot or result without any scale may prove very little. I must find a balance: anonymize customers, figures, and internal data while retaining the problem, decisions, responsibilities, and observable effects. Approval by the people concerned then confirms that this balance creates no unwanted exposure.
I prepare evidence myself and can therefore make a redaction mistake or overlook a name in a background, URL, log, or metadata. Showing the material to the relevant people before publication adds a second check. Excerpts must also be reviewed in their final website form because a properly redacted file can be accompanied by a caption or text that indirectly reveals what the image hides.
Writing assistance may mistranscribe an oral answer, replace a term with a different concept, or remove a nuance incorrectly considered secondary. It can also produce a convincing explanation that does not match the facts. Generated text is therefore never a source. My answers, project files, approved evidence, and manual review remain the references that determine the published release.
I manually review and edit all assisted content to verify that it expresses what I mean. This step must check facts as well as attributed responsibility: text must not turn a team contribution into an individual achievement or present an intention as a result. The growing portfolio volume makes this review demanding; it should be performed section by section rather than in one session on the eve of assessment.
My level, Odoo versions, project state, planned training, or website functions may evolve. Content that is accurate in 2026 may become misleading several months later. I plan to identify these differences by rereading the portfolio and updating it with new experience. The absence of a fixed schedule still creates a risk of forgetting; dates and expressions such as “currently” require particular attention.
GSAP and transitions make the website livelier, but an effect added without purpose can slow the page, distract readers, or make content difficult to use. Animations must therefore remain simple, short, and limited to elements that genuinely benefit from staging. They must never hide required information or prevent a user requesting reduced motion from accessing content.
When the French version changes, its translation may retain an old responsibility, figure, or objective. Visitors then receive two different profiles depending on language. Every localized content addition must therefore change both releases, and tests must verify the presence of essential headings. French-only MDX articles must be clearly identified so that the editorial decision is not mistaken for broken translation.
The 95 threshold provides a target, but results vary according to page, simulated device, network, loaded content, and external services. A local audit with a warm cache may conceal a slower phone experience. Measurements must therefore be repeated on main pages, in preproduction, and after important changes. A high score does not remove the need to verify reading, keyboard navigation, and perception on an actual device.
The form depends on correct validation, the server action, Resend, and an available recipient address. A failure in any stage can leave the website appearing functional while losing a professional inquiry. The interface must report failure without claiming delivery. Logs and tests must provide enough information to diagnose non-delivery without exposing private message content.
Automated submissions can consume the Resend quota quickly, fill the inbox, and place unnecessary load on the server. In a significant case, they can make delivery unavailable to genuine visitors. The project uses several protections—a honeypot field, minimum delay, rate limiting, and reCAPTCHA when configured—but no layer is sufficient alone. Their behavior must remain verified and limits adapted to actual hosting conditions.
The General Data Protection Regulation, or GDPR, governs personal-data processing. Loading a measurement tool before consent, storing a choice ambiguously, or failing to provide an effective rejection would create legal and ethical risk. Analytics scripts must therefore remain disabled until the corresponding category is accepted, while necessary functions such as language or theme can operate independently.
Adding the blog, bilingual support, animations, analytics, and many articles has probably increased project duration. It has not yet made the scope unmanageable because the website remains a relatively focused JavaScript application. Risk would arise from continuing to add optional features before completing scored criteria. The priority rule must remain simple: compliance and content first, enhancements second.
The central achievement file eventually exceeded 790 KB and brought together all five case studies in both languages. Although behavior remained correct, this concentration slowed manipulation, complicated review, and increased conflict risk when only one article changed. I have since placed each achievement in its own module, moved shared types into a dedicated file, and retained a lightweight public index. The risk is therefore no longer one oversized file, but the need to preserve the same data contracts across several modules.
The website notably uses Vercel for hosting, Resend for email, and measurement services when consent allows. If one closed or remained unavailable, I could move the application or replace the affected service. The project remains a JavaScript application whose code and content are versioned. This portability reduces disappearance risk, but migration would still require reconfiguring the domain, environment variables, and dependent functions.
The absence of a confirmed assessment day complicates final-phase planning. Waiting for the exact date would risk discovering a missing section or unapproved piece of evidence too late. I must therefore work as though the earliest possible date were correct, finish mandatory content, then use remaining time for audits, review, and secondary functions.
A checklist may be marked compliant while a link is broken, a menu fails on mobile, or text appears in the wrong language. Final validation must therefore navigate the website like an examiner, from the homepage through evidence and circular links. The main risk of lost points will be controlled only when criteria are present in the published release, not merely declared complete in the repository.
04
I first listed what the portfolio had to contain: presentation, human and technical skills, achievements, journey, evidence, and contact. I then converted the assessment rubric into a tracking list in a Markdown file within the repository. Markdown is a lightweight text format that allows a checklist to live alongside the code. This method gives me a verifiable reference for what is complete, partial, or missing without relying on memory.
The first structural feature I developed was French and English localization. I understood from the outset that international recruiters might visit the website, so I avoided adding language support afterwards. Every application page lives under a [locale] URL segment, a locale being the code that identifies the language and regional conventions in use, such as fr or en. Because this structure preceded the homepage, skills, and achievements, no late migration of existing routes was necessary.
A Next.js proxy intercepts requests that do not yet contain a language and redirects them to the appropriate address. A proxy is a layer executed before a page is displayed. It first checks the NEXT_LOCALE cookie, which remembers an earlier choice, then the Accept-Language header sent by the browser, and uses French by default if no usable preference exists. The language switcher then replaces the first URL segment, preserves the rest of the path, and stores the preference for one year.
Interface copy is centralized in two JSON dictionaries, one per language. JSON is a structured key-value format. Components executed on the server load only the requested dictionary, while a limited React context passes interactive components only the labels they need. This choice avoids duplicating copy in every component and requires both dictionaries to be updated whenever a new key is created. The localized layout also emits the document's lang attribute on the server, before hydration, for screen readers and search engines.
The project uses the Next.js App Router, a system in which the folder tree defines routes and layouts. TypeScript runs in strict mode to identify more inconsistencies before execution. I favored Server Components, rendered on the server without unnecessary interactive JavaScript in the browser, and reserved Client Components for forms, menus, animations, theme changes, and other behaviors requiring state or user actions.
Before stabilizing the interface, I made several trials in Figma, an interface-design tool, to compare colors, typefaces, spacing, and block organization. I selected Roboto Flex for regular copy and Geist Mono for technical labels because the combination matched the professional, contemporary result I wanted. Next.js loads these fonts in an optimized way to limit visual shifts while the page starts.
Rather than redeveloping every button, field, or card separately, I used shadcn/ui and Base UI. A component library provides accessible, customizable interface building blocks without imposing the final design. Colors are defined through CSS variables in OKLCH, a color space that helps create consistent light and dark variations. Reusable components—buttons, cards, badges, fields, section headings, and reveal blocks—therefore keep behavior consistent across the website.
After the foundations, I built the homepage, then the skills pages, and finally the achievement pages. The homepage combines an introduction, concise presentation, journey, skills, projects, evidence, and a contact call to action. Listing pages provide the first reading level, while every skill or achievement has a detailed route. This progression let me validate the overall structure before inserting the largest articles.
The top bar uses fixed positioning so that it remains available while scrolling. It displays my photograph, first name, and last name on every page, together with short labels for the main sections. Skills and achievement submenus are generated from the same data as their pages, preventing an article from existing without being accessible. On mobile, these lists become accordions to remain usable on a narrow screen; language and light or dark theme controls remain available in both menu versions.
I defined ten records split between human and technical skills. Each one contains a shared score out of 100, a type, definition, anecdotes, self-assessment, development plan, and related achievements. The listing page turns the ten values into a radar chart: each axis represents one skill and distance from the center represents its relative level. This representation is not intended as a scientific measurement; it mainly makes each skill's place in relation to the others immediately understandable.
A detail page covers the professional definition, evidence and outcomes, my current level, the skill's importance, my advice, and my development goal. A progress bar repeats the radar value for consistent reading. Anecdotes can link to a specific achievement, and the bottom of the page lists every related achievement. Readers can therefore move from a claimed capability to the concrete situation demonstrating it.
Every achievement is stored with a name independent of school or company context, a summary, context, technologies, and mandatory sections: presentation, objectives, risks, steps, stakeholders, results, aftermath, and critical review. The detail page turns this data into numbered sections and interprets double asterisks as bold text. This mechanism allows key stakes, decisions, and outcomes to stand out without building a separate component for every project.
Every achievement lists its skills, and every skill lists its achievements. An automated test checks both directions: if a skill cites an achievement, that achievement must cite the skill in return, and vice versa. Circular navigation therefore does not depend on visual inspection alone. Pages then generate localized links from these relationships, allowing evidence to be followed in either direction.
The experience section presents the most recent periods first. Every entry provides an initial reading level—period, position or diploma, organization, and logo—then responsibilities, description, and related links. Institution and company logos can point to their websites. On large screens, a vertical line and markers materialize chronology; on mobile, content retains its order without relying on that visual effect.
The first animations concerned elements appearing on the main page. I wanted to add rhythm without distracting from content. GSAP, a JavaScript animation library, is imported through a central module that also registers ScrollTrigger, the extension that starts effects according to scroll position. Animations are scoped to their component through the useGSAP hook and use autoAlpha, which combines visibility and transparency to prevent content flashing before animation starts.
Lenis, a smooth-scrolling library, and page transitions were planned from the beginning. Lenis is synchronized with GSAP's animation loop so that scroll-driven effects stay aligned with the position actually displayed. On every route change, incoming content uses a small vertical move and fade. The code nevertheless detects the system prefers-reduced-motion setting and removes these movements for people who request a less animated interface.
Responsive means that layout adapts to screen width and device type. I used Tailwind CSS breakpoints to reorganize grids, menus, text sizes, and spacing on phones, tablets, and desktops. The theme is managed with next-themes and applies a light or dark class without duplicating components. The form, responsive behavior, theme switching, and language switching are among the journeys I treat as priorities during testing.
The six articles are written in MDX, a format that combines Markdown's simple syntax with the ability to insert React components. Long-form content remains in French, while title, description, date, and tags are translated in the dictionaries; the English release explicitly discloses this limitation. This organization lets me publish hard-to-find technical solutions while maintaining visual consistency with the rest of the portfolio.
The blog page does not search only titles. When building the index, code reads every MDX file, strips tags and formatting elements, then combines its text with the title, description, and tags. Search ignores case and accents, while topic filters and the query are reflected in the URL. A shared address can therefore reopen the same selection directly. Word count also provides a reading-time estimate based on 220 words per minute.
A shared component analyzes level-two and level-three headings on the page to create a table of contents. It calculates reading time, enables link copying, and suggests up to three articles sharing tags. These functions wrap the MDX content, so the author can focus on the article without rebuilding navigation or recommendations for every publication.
The contact form uses React Hook Form to manage fields and Zod to describe rules: name and message length, valid email address, mandatory reason, and a custom subject when “other” is selected. The same schema is executed again by a Server Action, a Next.js function running on the server. This double validation provides fast feedback without trusting data received by the server. Values are escaped before insertion into email to prevent a message from being interpreted as HTML code.
I wanted a service with a free tier and straightforward Next.js integration. Resend receives the validated name, address, reason, and message, then sends an email to my contact address with the visitor's address as reply-to. The interface explicitly distinguishes success from failure and allows another message to be sent. Keys, sender, and recipient remain in environment variables, which are configuration values kept outside public code.
A sprint here means a short work period devoted to a coherent feature set. I combined four controls: a honeypot, an invisible field that bots often fill; a three-second minimum delay between display and submission; a five-attempt-per-hour limit for each IP address; and reCAPTCHA v3, which assigns a behavior score when configured. The limit is now atomic and shared across serverless instances through Redis; the IP address is hashed before storage, and production rejects submissions when this durable protection is not configured.
I did not install an external consent platform: the component provides “accept all,” “reject all,” and detailed preference management. It distinguishes cookies necessary for operation—language and theme—from optional audience measurement. The choice is stored locally, and an event immediately informs the analytics component. Google Tag Manager or Google Analytics is inserted only after consent for that category, technically implementing the GDPR consent principle, the European regulation protecting personal data.
Metadata is translated and declares a canonical address, French and English alternatives, Open Graph previews, and indexing rules. A sitemap lists pages, articles, projects, skills, and achievements in both languages; robots.txt tells search engines which areas they may crawl. Schema.org structured data describes the person, website, and profile page. Security headers also restrict script sources, prevent the website from being embedded in an external iframe, and reduce browser permissions.
The homepage links directly to the CV, TOEIC certificate, and diplomas stored in the public directory. These documents open separately so an examiner can inspect them without losing position. Every public link is covered by a test. For professional achievements, however, I prepare anonymized screenshots and have them approved before publication so company data is not exposed.
Vitest and React Testing Library verify isolated functions and components: language rules, form, anti-spam, consent, search, navigation, and reciprocal links. Vitest browser mode uses Chromium to check real behavior and selected visual snapshots, including the form, cookie banner, and language switcher. Playwright runs end-to-end, or E2E, tests that navigate the built application like a visitor. This combination covers both logic that can be tested quickly and journeys in which several layers interact.
On every pull request or push to the main branch, the pipeline installs the exact locked dependencies with pnpm. It runs lint, which detects static-quality issues, unit tests, component tests in Chromium, and the production build. After a successful build, Playwright scenarios run and their report is retained for diagnosis. CI means continuous integration: the repository automatically verifies that a change can join the shared version. Continuous deployment is then handled by Vercel from the validated release.
Pages and features were not written in a single pass. After the first complete release, I added Odoo projects, skill and achievement records, then a visual redesign, evidence, article search, and related tests. Every stage can be reviewed in Git history, which records successive code revisions. This progression limits correction size and allows the result to be checked locally before publication.
I first listed what every section had to explain. I then used artificial intelligence to generate questions I would not have considered and to structure an initial draft from my answers. This assistance is not evidence and does not decide my experience: I manually review every passage, correct approximations from oral transcription, and remove any wording that does not match what I actually did.
The Markdown list is not a frozen document: I update it as articles, links, evidence, or depth evolve. Tests protect structural relationships, but cannot independently judge whether an anecdote is sufficiently clear or whether my critical assessment is sincere. Final validation therefore combines automated checks, spelling review, my own semantic review, and learning-coach feedback on alignment with examiner expectations.
The next step is not adding decorative animation. I need the content validated by my learning coach, to run thorough tests of every feature, and to stabilize the CI/CD pipeline before considering the website complete. This definition of done includes the form, responsive behavior, themes, languages, links, evidence, and articles. It distinguishes a page that “looks complete” from a controlled product ready to be presented to an examiner or recruiter.
05
I alone handle technical design, development, final visual design, writing, tests, deployment, and maintenance of the portfolio. This responsibility does not mean the project was completed without interaction: several people influence compliance, readability, or the publication of specific evidence. I nevertheless retain ownership of trade-offs and of the release ultimately published.
Their main role is to ensure that the portfolio meets the requirements of the qualification I am preparing. They do not develop the website or write articles on my behalf. They compare content and structure against the assessment rubric to identify what an examiner might consider missing, too superficial, or difficult to find. Their perspective therefore provides pedagogical validation in addition to my technical checks.
I presented progress to my learning coach approximately four or five times. These repeated discussions allow the project to be corrected while it is being built rather than waiting for final assessment. Every presentation acts as a checkpoint: I show the website's actual state, they provide observations, and I then decide how to convert them into content or interface changes.
Learning-coach feedback is not limited to ticking rubric criteria. It also concerns page structure, information order, and the amount of writing required for an examiner to understand my work. This dual reading matters: information may exist in code or on a page but remain ineffective if it appears too late, lacks explanation, or cannot be reached through the expected navigation.
The learning coach told me that the skills and achievements did not contain enough written explanation. A technology list or a few sentences cannot demonstrate expertise: context, decisions, interactions, outcomes, and lessons learned must be explained. This feedback initiated the detailed interview work for each achievement and the transformation of raw answers into structured articles. The objective is not to inflate pages artificially, but to make reasoning and added value verifiable.
My learning coach considered the “Journey” section too low on the page. I therefore moved it immediately after the presentation and before skills and achievements. This lets new readers understand the chronology of my education and experience before examining what I can do. Git history contains a commit dedicated to this reorganization, directly connecting the interaction to the implemented change.
Colleagues viewed the portfolio and some of my interface trials. Their knowledge of my professional context helps them assess whether the image conveyed is consistent with my work and whether the presentation remains credible. They do not act as technical decision-makers: their reactions provide additional information about perception, after which I select relevant corrections.
Relatives also browsed the website and viewed proposals created in Figma. An informal tester does not follow a written protocol with measurements: they use the interface freely and explain what they understand, appreciate, or consider improvable. Their feedback confirmed that the overall design was convincing and surfaced suggestions for interface improvement. I do not give these discussions a level of precision they did not have: they were qualitative observations, not a full usability study.
I showed colleagues and relatives my Figma trials, meaning visual representations used to test a graphical direction before or during implementation. They could therefore comment on hierarchy, components, and overall impression without having to interpret code. This step helps distinguish disagreement about appearance from a purely technical implementation problem.
I have not yet asked someone unfamiliar with both Odoo and my journey to read a complete skill or achievement page. This check is nevertheless necessary because an examiner or recruiter may not know the ERP. I therefore plan a reading test in which the person will reformulate the problem, my role, the result, and the main terms. Misunderstandings will identify concepts that remain insufficiently defined. I present this step as planned rather than already completed.
Examiners do not directly participate during development: the rubric and learning-coach feedback represent their expectations. Recruiters are a second target audience, notably through the English version, but no recruiter has yet participated in a formal test session. This distinction avoids presenting a design intention as an interaction that did not occur.
When advice conflicts or feedback does not fit the intended direction, I make the final decision. I first try to satisfy every item required for the qualification. Once that foundation is secured, I add features that I personally enjoy—bilingual support, blog, animation, theme, or search—when they also provide value to visitors. This rule lets me preserve personal identity without sacrificing an assessed criterion.
Screenshots, excerpts, or information from my employer's projects cannot be published on my decision alone. I show the CEO exactly what I intend to use, already anonymized where necessary. They can approve it, reject it, or request a change. This control protects customers, internal data, company-owned code, and the organization's image; it defines what I can prove publicly without undermining the reality of the work presented.
Artificial intelligence plays an important role in preparing text because interviewing, rewriting, and translating such a volume of content are time-consuming. I use it to produce questions, organize answers, and accelerate a first draft. My answers, code, Git history, and approved evidence nevertheless remain the sources. I review output to correct transcription errors and prevent plausible wording from replacing facts.
I do not delegate the complete design and implementation of essential portfolio features. If the tool independently decided the architecture, navigation, form, or content model, the project would no longer demonstrate my skills appropriately. Assistance can help me understand, verify, or accelerate a task, but I must be able to explain decisions, review code, run tests, and take responsibility for published behavior.
The general workflow follows four stages: I prepare a release, show it to the relevant person, collect feedback, then decide and implement. The learning coach contributes to compliance and structure, colleagues and relatives to interface perception, and the CEO to authorization of professional evidence. This distribution avoids asking someone to make a technical decision they are not responsible for while still incorporating the perspectives required before assessment and publication.
06
The portfolio is publicly available at orhanmadiassani.com rather than remaining a local demonstration. A custom domain provides a stable address that is easier to share on a résumé or with a recruiter than a technical hosting URL. The French release is available under /fr and the English release under /en; visitors can switch between them without returning to the homepage.
I consider that the website now lets someone who wants to understand my professional profile consult the main information: general presentation, professional and personal plans, journey, skills, achievements, articles, open-source projects, evidence, and contact methods. The result therefore does not depend on one spectacular page. It provides several reading levels, from the homepage summary to detailed articles.
The code contains ten compared skills, five achievements, 6 published articles, and the experiences in my journey across both interface languages. Relationships between skills and achievements can be navigated in both directions. The latest production build generated 109 pages or route variants, notably for languages and detail records. This volume shows that the result has become a small structured editorial application rather than a static résumé placed online.
After approximately four or five presentations, the learning coach considers that almost every expected element is present. They are asking me to continue writing because the remaining weakness no longer concerns primarily the existence of pages or features, but the depth of skill and achievement content. This validation remains coaching feedback rather than a jury's final score, so I do not present it as an already awarded certification.
Skills and achievements remain the areas preventing the portfolio from being considered editorially complete. Their structures, links, and sections exist, but every explanation must allow an external reader to understand context, my role, the outcome, and my perspective. Current work therefore involves adding fewer new features and replacing overly short wording with useful, factual demonstrations.
On July 16, 2026, I ran Lighthouse with Chrome's mobile profile on the 100 URLs in the public sitemap, in French and English. The averages are 94.3 out of 100 for performance, 99.8 for accessibility, 99.9 for best practices, and 100 for SEO. All 100 pages have a CLS of 0, meaning the measurement found no cumulative layout shift. Lighthouse is an automated audit tool integrated into Chrome developer tools; it provides a reproducible comparison point, not every visitor's exact experience.
98 of the 100 pages achieve at least 90 for performance, with a median of 96. Median FCP, which measures the first appearance of content, is 1.08 s; median LCP, which measures the main content's display, is 2.49 s; median TBT is 44 ms. The two exceptions are the French and English versions of the App Trajectoires de vie achievement: they score 57, with FCP of 8.63/8.72 s and LCP of 9.53/12.24 s. This result therefore gives concrete evidence both of the site's general strength and of the priority issue still to solve.
The four YouTube players loaded directly in this achievement explain most of the slowdown and also trigger a Cookies issue in Chrome. Replacing those iframes with a lightweight preview activated on click, then creating the player only after consent and interaction, should improve initial loading while limiting the loading of a third-party service. The audit also found around 25 KiB that could be saved on the decorative Fuji image, 25 KiB of unused JavaScript, and around 150 ms of render-blocking CSS; these are useful optimizations, but secondary to the videos.
The average reaches 99.8 out of 100; four pages remain at 96. On the French and English homepages, the achievement CTA uses white text on a #ff5444 background with a 3.18:1 contrast ratio instead of the required minimum of 4.5:1. On the French and English article listings, tag buttons are only about 22 px high instead of the required 24 px. These findings give concrete corrections to make; they do not remove the need for keyboard, screen-reader, and reduced-motion testing.
The best-practices category checks selected rules relating to browser errors, security, and correct Web API use. The two CAP2vie pages score 96 because of the YouTube players' cookie issue; every other page scores 100. SEO, or search engine optimization, is 100 across the whole sitemap: this confirms the quality of checks covered by Lighthouse without guaranteeing absolute security or a first-place search ranking.
The detailed report retains the four scores and FCP, LCP, TBT, and CLS metrics for each URL. It was obtained with one mobile lab measurement per page; device, network, cache, or an external service can vary the result. I must therefore rerun the full audit after replacing the YouTube players and after any important frontend change. This approach is more credible than an isolated score because it verifies production across every public route.
The General Data Protection Regulation governs the collection and use of personal data. This project required me to go further than on earlier work: distinguishing necessary functions from optional analytics, providing both acceptance and rejection, storing the choice, and loading measurement tooling according to the intended consent. The result is a more carefully designed consent architecture. I do not turn this learning into legal certification, however: the absence of compliance issues must continue to be checked with every change.
The analytics integration works and already provides data about website use. Analytics means measurements that observe, for example, viewed pages or movement between content. I have not provided sufficiently consolidated figures here to demonstrate audience size or conversion, so I limit the result to the verifiable fact that consented collection produces data. Its future value will be identifying pages that are actually read and those that remain difficult to discover.
Messages submitted during my tests successfully traveled through the form, server validation, and Resend to the recipient inbox. Resend is the service responsible for delivering email after data and anti-spam checks. This result proves the technical journey works. It is not yet a commercial result: no external visitor has contacted me through it so far.
My colleagues and relatives like the portfolio's visual result. This feedback confirms that the graphical direction creates the professional impression I wanted. It remains qualitative and informal: I did not collect ratings, run a usability protocol, or compare several variants across a sample. No recruiter or examiner has yet evaluated the website, which prevents me from concluding that the presentation already has measurable impact on those audiences.
The current suite covers 21 test files and checks languages, navigation, contact, anti-spam, consent, article search, evidence, and circular relationships. The Next.js build also passes TypeScript verification and generates the production release. This result reduces the risk that an editorial change silently breaks existing behavior. It does not remove the need to visually test responsive behavior, themes, and complete browser journeys.
The project made me work on topics I had explored less thoroughly before: consent, data protection, page semantics, motion preferences, keyboard navigation, metadata, and security policies. This progress goes beyond graphical integration. It taught me to treat a website as a product for real visitors, with responsibilities beginning before development and continuing after launch.
I learned how to turn an experience into a readable Web page: introduce context, separate stakes from steps, emphasize outcomes, and conclude with self-criticism. This organization differs from a raw report or technology list. It should support quick scanning through headings and bold text, followed by detailed reading when an examiner wants to verify reasoning.
The portfolio highlights my ability to produce a complete and coherent interface, but it also reveals an area I want to improve: creating more reusable code. A reusable component isolates a shared structure or behavior so it can be used in several places without duplication. This perspective is already a project result because it turns a general preference for clean code into a precise architectural objective.
The part that best reflects my level within this portfolio is the frontend: responsive design, components, animation, languages, themes, and accessibility. It is complemented on the server by Resend integration and form protection. Sanity, the content management system mentioned in my answer, belongs to the corporate website covered by another achievement rather than this portfolio's code. Together, these projects show my ability to connect a polished interface with external services without confusing their scopes.
I will consider the achievement fully successful when the visual result reaches the intended “top-notch” level, meaning a particularly polished and consistent design, and when no known compliance gap remains. This definition requires finishing the deeper skill and achievement content, review by a novice audience, learning-coach validation, evidence verification, and continued technical checks. Success is therefore not reduced to going live or to an isolated Lighthouse score.
07
The immediate next step is to review the rubric criterion by criterion and verify the result that is actually visible, not merely the presence of data in code. This check will cover identity and navigation on every page, article depth, circular links, journey, evidence, contact, spelling, and translations. I want to connect every requested item to a page and a precise element rather than assume the examiner will find it.
I am targeting August for completion of the version intended for assessment. This deadline does not mean the website will be permanently frozen: it establishes a reference release in which every known requirement has been checked. Optional features that I do not yet master sufficiently must not delay this completion.
Learning-coach feedback indicates that the main remaining work concerns content depth. I must therefore finish sections that remain too brief, define specialized concepts, and verify that every anecdote actually demonstrates a skill or outcome. This priority comes before adding effects or services because an additional feature would not compensate for an incomplete editorial criterion.
Before assessment, I plan another review with the learning coach and a reading session with someone unfamiliar with both Odoo and my journey. The first will check alignment with the qualification; the second must be able to restate the problem, my role, and the result without additional oral explanation. These validations address different risks: missing an official expectation and writing content understandable only to its author.
I will continue evolving the portfolio after assessment, notably because I enjoy designing new interfaces. The diploma is a delivery milestone rather than the end of the product. This continuity will allow the website to follow my actual level instead of permanently preserving a snapshot of my profile from August 2026.
I do not plan a rewrite on a fixed date. I will update content whenever my professional situation changes: a new responsibility, significant assignment, stronger skill, publishable achievement, certification, or position change. This event-driven maintenance avoids artificial edits while reducing the risk that a recruiter reads outdated information.
Odoo versions, article counts, my declared level, objectives, and expressions such as “currently” can quickly become inaccurate. With every change, I will need to locate this information in both French and English releases, update related relationships, and rerun tests. Bilingual delivery particularly requires avoiding an update in only one language.
I want to keep publishing technical articles, notably about Odoo. Topics will come from problems I actually encounter, solutions difficult to locate in documentation, or explanations likely to help another developer. The blog should keep the website alive while transforming experience into reusable knowledge rather than publishing on a schedule without meaningful content.
Over time, articles and open-source modules should allow the portfolio to produce more than a personal presentation. Open source means making code publicly accessible under the conditions of its license so others can study or reuse it. Documenting a solution, publishing a generic module release, and explaining its limitations are concrete ways to contribute to resources available online.
I will consult statistics to understand which categories of visitors reach the website, which pages they open, and how long they remain. The objective is not to identify a person by name. Aggregated data combines behavior across several visits to observe trends without claiming knowledge of every individual. It may reveal that an important achievement is rarely discovered or that visitors leave a page before its essential information.
The full audit shows an average of 99.8, but four pages score 96. I must correct the achievement CTA contrast on both homepages and give article-list tag controls a touch target of at least 24 px. Lighthouse provides the Accessibility category and reports these precise points; I will supplement it with keyboard navigation, focus, label, contrast, and reduced-motion checks. The objective is not only to gain a few points, but to remove a real barrier whenever it is identified.
The production audit establishes a baseline: 98 pages at least 90, a median LCP of 2.49 s, and two pages at 57 because of YouTube players. Chrome developer tools' Performance panel remains useful for recording page activity and understanding the cost of a script, animation, or render; Lighthouse then compares all four categories across the whole sitemap. After replacing the players and after a significant frontend change, I will rerun both checks to verify the gain and avoid regressions on another route.
Despite positive feedback and technical scores, I do not yet consider the interface to have fully reached the professional level I want. Future work will first concern consistency in hierarchy, spacing, components, and responsive detail rather than accumulating animation. A top-notch design must appear polished across every page, not only in the homepage hero.
I want to isolate shared structures used in pages, cards, metadata, narrative sections, and interactive states more effectively. A reusable component receives data and applies consistent behavior without copying the same structure. This evolution should reduce divergence between French and English pages, simplify design changes, and make tests more focused.
Each of the five case studies now has its own TypeScript module. One file contains shared types, while realisations.ts retains only imports, the ordered list, and the public lookup function. Content was compared before and after the split using a fingerprint calculated over all serialized data, and it remained identical. Each article can therefore be edited and reviewed independently without changing the imports used by pages and tests.
I have not yet decided which features will follow the assessed release. This is deliberate: I first want to understand, verify, and maintain the existing bilingual support, animation, blog, analytics, consent, contact, and tests correctly. A new feature will be relevant only if it addresses an identifiable need and I can take responsibility for its maintenance.
After stabilization, the portfolio can remain a testing ground for new interface choices, tools, or Web practices. A technical laboratory allows experimentation, but the public branch must remain stable: an idea will first be isolated and tested before replacing existing behavior. This separation allows continued learning without turning the professional showcase into an unstable demonstration.
I plan to rerun audits and consult updates published by relevant public bodies. Monitoring means following changes in rules, frameworks, and recommendations that may affect the website. For data protection, publications from the CNIL provide a French reference; changes in public accessibility frameworks must also be monitored. A regulatory update will need to become a concrete check in code or content.
After an update, I will verify internal links and documents, both languages, responsive behavior, themes, consent, analytics, and form delivery. Automated tests cover some of these areas, but a real trial remains necessary for external services and visual perception. If hosting or a service became unavailable for an extended period, the Next.js application could be redeployed to another platform from the repository and its documented environment variables.
In the long term, the website should remain a technical palette, meaning a space where several skills and technologies are demonstrated through concrete achievements. It should also present my profile accurately as my situation changes and allow me to participate in the developer community through articles and open-source projects. These three functions—experimenting, presenting, and contributing—give the project value beyond diploma assessment.
08
My main mistake was starting animation before stabilizing page content and structure. Animation quickly creates a sense of progress because its result is visible, but it depends on block size, order, and message. When those elements change later, the effect must be adjusted or removed. I therefore invested time in a finishing layer while the material it was meant to support remained insufficiently defined.
I should have written the main content, or at least established its volume and hierarchy, before finalizing visual choices. A card designed for three lines no longer works the same way when it receives several paragraphs; a detailed achievement page does not have the same needs as a short showcase. By reversing this order, I sometimes adapted text to design when the interface should have served assessed content.
The most efficient sequence would have been: first the rubric and mandatory content, then reusable components and navigation, followed by tests of main journeys, and finally animation and refinement. I sometimes handled an enjoyable feature before a scored need. This experience taught me that priority depends not on a task's technical appeal, but on its importance to the product objective.
The blog provides lasting value to the portfolio and developer community, but it was not essential to satisfy the first assessment criteria. Its MDX structure, search, tags, reading time, table of contents, and recommendations required substantial investment. Given the amount of free time available to me, some of this effort could have been postponed until skills and achievements were fully written.
Bilingual support, blog, animation, analytics, consent, contact, search, theme, evidence, and several test levels form an interesting but broad product for a personal-time project. The problem is not each feature individually; it is their accumulation before the mandatory foundation was closed. I should have defined a stricter assessed first release and then added enhancements in stages.
Yes, some effects were created while essential text remained incomplete. They are not necessarily poor and several remain subtle, but their development timing was wrong. Animation should reinforce an already clear hierarchy, signal a transition, or improve understanding. When it precedes content, it may hide a structural problem instead of solving it.
Achievement volume remains significant even after splitting the files. The problem is no longer finding an article inside a central file, but preserving human readability across several dozen points per case study. I therefore added responsive contents navigation, anchors, genuine numbered subheadings, limited line width, and links back to the contents. This solution improves consultation without hiding or removing the developments required by the assessment rubric.
Storing achievements in typed objects remains useful for producing consistent pages, verifiable links, and shared rendering. My mistake was allowing all five objects to grow in the same file until it exceeded 790 KB. Splitting by achievement addresses this debt without abandoning typing or duplicating access functions. I would make this separation earlier next time, as soon as editorial content represents most of a module's weight.
Several pages use cards to present a skill, achievement, article, piece of evidence, or project. I should have identified their shared elements earlier: header, badges, summary, metadata, action, and responsive behavior. A configurable card foundation would have reduced repetition while still allowing variants. Reuse does not mean making every card identical, but sharing what genuinely belongs to the same behavior.
The result is coherent and receives positive feedback, but I do not yet find it sufficiently mastered or professional. Some visual solutions remain close to common technical-portfolio conventions without creating a strong enough identity. My dissatisfaction does not justify rebuilding everything: it indicates a need to improve hierarchy, proportions, spacing, and cross-page consistency before adding more effects.
An integration test verifies that several real parts of a system work together, such as the form, server action, anti-spam protection, and delivery service. The project has unit, component, and end-to-end tests, but external dependencies are often simulated. Resend, reCAPTCHA, and rate limiting are replaced with mocks, meaning controlled test versions. Dedicated scenarios validating the boundaries between the deployed application and its services more faithfully are therefore still missing.
If starting again, I would define success criteria and main scenarios before or during initial features rather than after they accumulate. Early testing forces the expected interface to be clarified and makes regressions easier to attribute. Priority journeys would be language detection, navigation, theme switching, consent, contact, circular links, and responsive rendering.
Building the banner myself helped me understand categories, choice persistence, and conditional analytics loading. For long-term use, however, I am considering a specialized existing solution, often called a CMP, or Consent Management Platform. A maintained CMP can provide more complete handling of vendors, consent withdrawal, and regulatory evolution. Integrating one does not remove the need to understand its behavior or verify its configuration.
I should not claim that the portfolio is legally compliant merely because a cookie banner and privacy policy exist. GDPR also concerns processing necessity, supplied information, retention periods, processors, and data-subject rights. The current system shows genuine technical effort but still needs to be compared against an audit and official recommendations. This nuance replaces the previous overly absolute claim of “complete compliance.”
French and English files correctly centralize interface copy, but every change requires two coherent sets to be modified. A missing key, old translation, or differently written content can produce two contradictory profiles. Tests detect selected omissions, not semantic translation quality. As the website grows, short interface copy and editorial content will need to be separated more clearly, followed by a review method for both languages.
Artificial intelligence has already proposed text or code that looked correct at first glance but did not precisely match the project. I detected it by consulting code after the task, comparing the proposal to actual behavior, and running tests. A well-written result is therefore never validation. Human review remains necessary, particularly when the tool describes professional experience or changes a security mechanism.
The portfolio is functionally complete, published, tested, and already able to present my profile. I mainly remove three points because the design does not yet satisfy me and because skill and achievement content is still being consolidated. This rating describes a usable, serious product, but not yet the final professional release I want to defend.
I designed these elements early enough as components shared by every page and both languages. The header retains identity, navigation, theme, and language switching; the footer brings together secondary navigation, contact details, and legal information. Their placement in the common layout avoids duplication and guarantees their presence. I still find their structure clean and consistent with portfolio needs.
I would begin by writing and prioritizing content according to the rubric. I would then build reusable components from that actual content, notably cards and article sections. Finally, I would quickly write tests for priority features before moving to the blog, animation, and optional enhancements. This revised order responds directly to the time lost.
The main advice I would give another developer is to resist the temptation to start coding immediately. Designing means clarifying the audience, criteria, content, architecture, and delivery order. This time may appear to delay development, but it prevents rebuilding components, moving sections, or artificially adapting copy to an interface that has already been fixed.