In ADR 21 we decided move the Fundraising Application PHP-based backend to an API. This task is an outline of the migration path.
There are 3 main points where the client-side code relies on the server-side code:
- I18N - We need to integrate the application messages (and other content) into the build process of the frontend code and deploy the built frontend code whenever the messages change. T285231: Compile i18n messages into Fundraising Application Frontend tracks how to do this and is the first and most important step to moving to the new architecture.
- "Application variables" - The server "renders" its template variables into an HTML data attribute where the client-side code picks it up. The section "Migrating application variables" outlines the different approaches of getting rid of those.
- Routing - Currently, the server side does all routing. We can gradually migrate the frontend to a SPA by using Vue Router with all pages (entry points) that don't have application variables. This allows for a gradual migration, page by page.
Migrating application variables
- HTML <head> content - Move to i18n or index.html template. The <title> attribute does not need to be dynamic, every other content item can also stay static
- Bucket selection:
- replace code in page_data_initializer with a class that can translate URL parameter into bucket names.
- Add the parameters to API requests so they get stored on the server.
- Make the "spenden_ttg" cookie client-accessible (remove HTTP-Only attribute).
- If we ever want to do the bucket selection without banners, we need to port the bucket configuration and selection logic into the frontend.
- Prefill banner parameters (payment) into donation form, skip payment page if they are correct. Can be done with client side code that takes the banner parameters from the URL. The banners must be adapted to send data via GET instead of POST. This means moving all URL parameters to hidden fields and then changing the method to GET (because the field values will drop all URL parameters). Open question for UX: How should the application behave when the banner sends invalid values (or malicious users put in invalid values in the URL)? See T262925: 🐛 Bug: Payment amount validation fails on donation form for an example
- Donation/Membership/Address change confirmation page - The application must use the access_token and donation id to request the donation data from the server (in case a user comes back to the confirmation page from a payment provider). To improve page load times (avoiding the API request trip), the application could cache the encrypted data in the session store (similar to the autofill feature). The fetched user data should also be used for pre-filling the "Add Address after donating anonymously" form.
- Address change form: We need to have an API endpoint that checks if the token for changing an address is still valid and displays the correct feedback/component on the page. We need to check with UX if we do this "synchronously" (showing a spinner while the API request is loading, then either displaying the form or an error message) or "asynchronously" (displaying the form immediately and when the check fails, do display a message and prevent the form from being sent).
- Address change confirmation page - Go to the confirmation page component if the address change was successful. Instead of deleting the store, keep the data in memory/session store until the user leaves the page.
- Insert Donor information on membership form - Copy donor information from donation store to membership store when transitioning from donation success page to membership page
- static page content - We compile the HTML content from fundraising-frontend-content (i18n/LOCALE/pages/web) is compiled into the bundle via html-loader and lazy-loaded with current locale. Some HTML pages (use of funds, supporters list) are obsolete because they are already componentized and get their contents from JSON (see next item).
- JSON content from i18n/LOCALE/data (e.g. FAQ, use of funds, supporters list) - compile into component via import "path/to/file.json". For small data files, compile in all files, for larger files (FAQ) use lazy loading based on locale setting.
- Check how the application behaves when the user hits "cancel" on the page of an external payment provider (MCP, PPL, SUB). Expected behavior: The user should go back to the address form (prefilled)