Task: Prepare haih-cms templates and routes
Prepare haih-cms templates and routes
Implement the core page templates, navigation, and routing in haih-cms required to replace the Ruby-based website.
Goal
Prepare a working public layer for the new version of the website where all migrated content has proper representation and stable routes.
What to do
- Implement templates for the main page types identified during the inventory.
- Set up routes for sections, lists, material cards, and service pages.
- Restore main navigation, hierarchy, breadcrumbs, and internal linking.
- Ensure consistent behavior for titles, metadata, images, and related materials.
- Handle empty states, missing entities, and 404s.
- Verify responsiveness and basic accessibility for key templates.
- Coordinate routes with the URL preservation and redirection task.
Result
A set of working haih-cms templates and routes sufficient to display all core public content.
Definition of Done
- All key page types open successfully in the new implementation.
- Navigation and links between materials work properly.
- URLs are generated predictably and match the migration map.
- Error and missing routes are handled correctly.
- Pages are ready for further SEO and content testing.
Ворклоги
Assets Proxy Middleware for Legacy Assets
A new middleware has been added to serve static files of the legacy site at the /assets/ path in the new implementation.
Original Problem
Historically, the Rails Asset Pipeline resolved asset links not directly by the physical file location, but through its own search mechanism and manifest. As a result, actual files can be located in various subdirectories, while HTML and CSS continue to reference them via simplified paths.
In practice, at least the following storage options were discovered:
shared/assets/— main assets;shared/assets/stylesheets/— CSS and related files;shared/assets/stylesheets/fonts/— fonts.
At the same time, client links may look like /assets/filename.css or relative url(font.woff2) without specifying the actual subdirectory. In the old Rails application, this was hidden by the Asset Pipeline logic.
Implemented Solution
The middleware server/middleware/assetsProxy.ts has been added, which intercepts requests to /assets/ and sequentially searches for the requested file in several known legacy directories.
Search order:
shared/assets/shared/assets/stylesheets/shared/assets/stylesheets/fonts/
The first matching file found is served to the client. Thus, the new system reproduces the necessary part of the Rails Asset Pipeline behavior without migrating the pipeline itself.
Security
The middleware provides basic limitations against directory traversal outside the assets directory:
- paths with
..are blocked; - colons in the path are blocked;
- after normalization, it is checked that the resolved path remains inside
shared/assets/.
Significance for Migration
This solution allows legacy pages and styles to be displayed correctly during the transition period without manually rewriting a large number of historical asset links. At the same time, the compatibility logic is isolated in one place and does not leak into the core data model or routing of haih-cms.
Further Verification
- check correct MIME types for CSS, JS, fonts, and images;
- check cache headers;
- check behavior when file names overlap in multiple directories;
- ensure the middleware does not allow reading files outside the allowed tree;
- as assets are normalized, decide whether the proxy is needed as a permanent layer or only for migration compatibility.
Adjusting the Public Layer Architecture
After deciding to unify the content data around Concept, the rendering task is also simplified: there is no longer a need to automatically reproduce a separate template for each legacy entity type. The universal Concept renderer should become the baseline, and specialized views should only be added when there is a real user need.
This reduces the amount of code that needs to be maintained and allows AI-generated/AI-updated content to be published through a common mechanism.
Progress: Public layer of the new version built
The new site is already effectively running on top of the new architecture and universal rendering. During the migration, it became clear how costly the old model was: various legacy entities had their own views and, in many cases, separate CSS.
Full restoration of the visual styling for all internal pages was intentionally skipped. Doing so would have meant extra work to reproduce old specialized templates, which would then have had to be reworked anyway during a design refresh.
At the current stage, functionally correct and consistent content display is sufficient. The next visual iteration should be built on the new common model rather than mimicking the legacy structure.