Architecture
This page describes the skeleton the application stands on. It is written for two readers at once — a person deciding whether the product fits, and a coding agent that will change it. Both need the same thing: to know which layer owns what, before touching anything. Back to Fractera.
The architecture exists because of three elements. Everything else on this page belongs to one of them:
- The installer robot — the process that installs and starts the server on Ubuntu, connects authorization, the database, the starter template and the rest.
- The starter template — the mandatory architectural principles: reusable patterns of behaviour and the special instructions for artificial intelligence. This is the inner skeleton, the DNA of the project.
- The infrastructure shell — everything kept outside the application itself, with authorization and memory at its centre.
The Fractera installer robot
A server is not configured by hand. The installer takes a clean Ubuntu machine and leaves a working system behind it. It reports its progress step by step, so you can see where the installation is — and where it stopped, if it stopped.
- system packages, Node 22 and a process manager;
- seven processes: the application, authorization, the panel, the data layer, the map, channels, the knowledge graph;
- the application, authorization and panel built — plus a copy of the first good build, so there is always something to roll back to;
- a swap file if the machine has less than two gigabytes of memory: without it the installation dies halfway on a small server.
Installing by cloning the repository through an MCP server
The path for those who raise a server with a tool rather than by hand: an agent talks to the platform over the MCP protocol and installs the project itself.
More on this shortly.
Launching through the web interface
The main path. The control panel carries a project-launch section: eleven steps from an empty GitHub repository to the first change you have seen at your own address.
The steps are of two kinds, and the difference matters. Some are closed by the machine — the repository answered, the key was issued, the project was pushed; such a tick cannot be given out of politeness. The others you tick yourself: the panel has no eyes on your computer, and pretending it can see a folder you created would be a lie. Your own tick can be removed, and the step opens again.
Migrating from any other framework
A project that already works is not moved by rewriting its files. Its code is read as a description of what it does; from that description a queue of steps is born, and the skeleton comes first — addresses, tables, sign-in, permissions. An incompatible stack is therefore not an obstacle: what moves is the meaning of a capability, not its files.
Four questions are answered before the first route: what kind of application this is, whether there will be a sign-in, whether there will be role-based access, and which roles restrict what. The answer decides the whole layout — which layer a page lives in, what lock its door carries, what a guest sees. A mistake here relays the skeleton rather than fixing a page.
Data moves last, as a separate step under separate access. Defects of the original are named out loud along the way and are not repeated in the new one.
The starter template
You are reading this page from inside the starter template. It is not a set of ready-made pages but a set of mandatory principles and working examples: every class of thing in the project already has a specimen, and anything new is made by copying something that works. The shape therefore holds by construction, not by the discipline of whoever is writing.
Ready for high load
Load is survived not by the size of the server but by the fact that almost all the work is already done. Serving a finished page costs the same for ten visitors and for ten thousand.
Static page generation
Pages are generated ahead of time, not assembled per request. That is not a performance detail — it is the reason for three properties at once:
- the site stays cheap under load: a traffic spike costs nothing extra;
- a search engine receives finished markup instead of an empty page it has to wait for;
- navigation works with JavaScript switched off — the routing is server-side.
Only what depends on WHO is looking is built per request: an account, a work screen. Everything else is regenerated on a schedule, and refreshing one page does not rebuild the site.
Special architectural instructions
A coding agent starts every session with no memory of the last one. What survives is written down, inside the project, next to the code. This corpus is as much a part of the architecture as the ports are — it is what makes the second session no worse than the first.
| Document | What it is for |
|---|---|
| The project passport | What the product is, which roles, which languages, what the owner decided — in his words and dated. While an unanswered question stands in the passport, work does not start. |
| Development steps | The work as files: a step is opened before it is done and closed with a report. A session that dies loses nothing — the next one resumes from the files. |
| Testing | How a step is proven: two independent proofs from different planes. A green build is never one of them — its log looks identical whether the capability works or not. |
| Anti-patterns | Approaches that already cost time here, each with the mechanism of the failure. The agent appends to it the moment a dead end is understood. |
| The glossary | The words of the project. A term that means different things to two sessions is two different projects. |
Four development modes
A mode answers one question: where the task comes from. It is chosen in the project settings and can be changed at any time.
- Classic — the task arrives from you in words. No plan ahead, no accounting.
- Steps — a queue of numbered steps, each described before it is done. This is the default.
- Cases — work starts only from a confirmed product scenario, and every step names its own.
- Migration — the queue is born from reading a project that already works.
Products — the unit of work
One server carries several products: a landing page today, a scheduled watcher next week, the company brain after that. Each lives at its own pace and cannot quietly damage its neighbour — it has its own pages, its own logic, its own tables and its own scenarios.
A product is created in the control panel: you pick one of twenty-two structures — a landing page, a shop, delivery, a company brain and so on — and it answers the first questions for you. The product then passes four phases: intake, decomposition into steps, development, and a review of what was built.
Why not simply call it a project
Because a project is not a place. It has no address, no folder and no tables, so a scenario attached to it cannot be executed: the agent still has to guess where the work goes. A product has all three, and that is the whole difference. Its internal id means nothing and never changes — the paths hang off it, while the name and the address are yours to edit.
Not every product has a page
A product declares one of three surfaces, and the default always leans towards closed:
- Public — it has an address and visitors reach it;
- Private — it lives as a tab in your control panel, and the outside world has no way in;
- Headless — it has no screen at all: it works on a schedule and through communication channels, and you meet it in Telegram or in its report.
Design
Colour, type and spacing are not chosen per page. The scale lives in one place, the palette in another, and a hand-written heading fails a check before it ever reaches the site. The law behind it is short: nothing about how a page looks depends on who may open it. A storefront and an admin table are set the same way; access decides what a person sees, never how it is set.
The sections of design
The look is edited inside the project itself, in six sections. A change is visible on the next page load — no rebuild required.
- Fonts — which families set the headings and the body;
- Type scale — every size at once, by a single multiplier: the whole set grows or shrinks keeping its proportions;
- Shape — radii, borders, density;
- Colour — a palette of roles rather than values: light and dark are the same roles with different values, not two designs to keep in step by hand;
- Blocks — the catalogue of what pages are built from;
- Tools — service switches, such as the screen-width indicator.
Blocks
A page is a list of blocks, not a laid-out file. The catalogue is closed: a kind not declared in it does not exist for the application, and the build refuses. There are more than thirty kinds, and each has a specimen you can open and look at — a kind you cannot see anywhere is not "unused" but unverified.
A new block is created with the help of artificial intelligence, including from code samples, and is then standardised — it enters that same catalogue instead of staying as the markup of one page. From there it is reused across every project: drawn once, verified once, taken ready afterwards.
Types of block
The catalogue answers "what exists", and for choosing that is not enough. So blocks carry a type — by purpose rather than by construction: you pick the type first and the kind only inside it.
- hero · benefits and value · how it works · product demo · use cases;
- comparison · pricing · testimonials · showcase · trust;
- page material — headings, paragraphs, lists, tables, notes: half the catalogue is this one.
Four configuration files
A large part of the project changes by editing four files — with no rebuild and no artificial intelligence involved. The application reads them on every request, so a change is visible on the next page load.
| File | What is in it |
|---|---|
| Application | Name, description, address, logo and images, icons, author, social profiles, search, analytics, currency. |
| Platform | Which capabilities are on: the switches, the development mode, parallel routes. |
| Design | Fonts, scale, shape, colour. |
| Products | The registry of products, one dossier each. |
There is one exception, and it is worth knowing in advance: the language set and the access keys live in the environment file, and that one is baked in at build time. Saving a value there without rebuilding the project changes nothing.
Many languages
You enable the languages your market speaks and the rest wait. Enabling one later is a setting, not a rebuild of the way the site works. What matters more is what adding a language does NOT do:
- it does not turn any page dynamic: every language gets its own pages, generated ahead of time — ten languages means ten sets of finished pages, not one page assembled on the fly;
- it does not dilute search ranking: each page declares itself the original in its own language and names its translations, so a search engine sees one page in ten languages rather than ten near-duplicates competing with each other;
- it does not cost speed: serving a prerendered page is the same work regardless of how many languages exist beside it.
A single-language site is a case in its own right, not a stripped-down version: the language disappears from the addresses entirely, and the site stops advertising translations it does not have.
Found by search engines, readable by models
Two readers arrive at a modern site and they want different things. A search engine sends a person to a page. A model comes itself, reads, and retells. The product is built for both, and the two are not the same job.
The search engine gets finished markup: each page declares its own canonical address, translations name each other, and structured data, sitemaps and robots rules ship by default. Machine checks refuse a page that breaks any of it.
The model gets the same text without the markup: a map at `/llms.txt`, the whole corpus at `/llms-full.txt`, and a markdown version beside each page. That matters because page markup is half noise to a model — menus, footer, consent banner, scripts — and it spends its attention on all of it.
Until the semantic structure of your project is ready, it is worth closing it to indexing: the setting lives in the application settings, section "Search". Both forms of the page are built from the SAME content — there is no separate "version for AI" to drift out of step.
Role-based access out of the box
Roles are not built for a project — they are already there. Three of them decide access: a guest, a signed-in user, and the architect, meaning the owner of the server. The remaining twelve are a vocabulary for business: buyer, subscriber, manager, support, delivery, finance, editor, administrator.
It is enough to say which layer a page needs. The lock sits on the route layer rather than in the markup of each page, and the door to the data is no softer than the page above it: closing a page while leaving its door open is the most common way to build leaky access.
Parallel routing
A page can be made not of one tree but of several named areas drawn at the same time: header, footer, left and right panels, the centre with its own header and footer, a promo screen, breadcrumbs, notifications, a modal window. This is how a deep interface for a professional is assembled without turning the site into an application.
- an area has its own pages and its own addresses — it is a tree of its own, not a piece of markup;
- an area has its own error boundary: a failed area shows its own error while the rest of the page keeps working;
- an area is switched on and off, and a switched-off one is not drawn at all;
- there are three kinds of route: an ordinary page, a slide-out panel, and a modal window over the page — and the address stays real, so such a link can be sent to someone;
- search optimisation and prerendered pages are preserved, and changes apply without rebuilding the project.
More on this shortly.
The infrastructure shell
Everything that governs the project lives outside the project itself. What travels to your repository is the application; the control panel, authorization and the data stay on the server. The reason is not secrecy: editing the code must not be able to break the thing that governs the code. Breaking the shell by hand is possible — it is your server — and then the consequences are yours.
How it is wired
Several processes run side by side on your server. Four of them answer outward, and each has exactly one job. The boundary between them is a port rather than a folder — which is why a failure in one does not take the others with it.
| Port | Process | What it is for |
|---|---|---|
| 3000 | Your application | The pages visitors see. This is the one you work with every day. |
| 3001 | Authorization | Accounts, sessions, roles. Configured from the control panel, not edited by you. |
| 3002 | Control panel | The same: configured, not edited. |
| 3300 | Data layer | Rows, uploaded files, vectors — and the single door to everything else. Your application talks to it. |
Three more services run alongside, and none of them is a door of its own:
- the map — routes, distance matrices and address lookup, port 3400;
- channels — Telegram and whatever follows it, port 3500;
- the knowledge graph — the agentic RAG store, port 9621.
None of these ports is reachable from the internet: the firewall admits the web ports only, and everything public arrives through them. Your application reaches the three services through the data layer — /service/geo, /service/channels, /service/rag — with the same key that opens the data layer itself.
Each layer survives the others
Separate processes are not a diagram — they are what happens on a bad day. Any one of the four can stop without taking the rest down with it.
| If this stops | What still works |
|---|---|
| Your application | The panel, the data and the accounts are untouched; only the site is down. |
| Control panel | The site keeps serving visitors; only changes have to wait. |
| Data layer | Pages generated ahead of time still open — that is what static generation is for. |
| Authorization | Public pages are unaffected; only what sits behind a sign-in closes. |
Working with GitHub
The repository is yours. The project is pushed to it and pulled back with a button in the panel; the repository address and the access token live on the server rather than in the code, so they do not travel with the project and do not end up in anyone else’s hands along with it.
The way out
Leaving the platform is a legitimate scenario, not a breakage. The application is an ordinary project: remove its dependency on the panel and it runs anywhere. You lose what lives on the server — settings without a rebuild, the data layer and search by meaning, authorization in 82 languages, the deployment history with a rollback, the map and the channels. The code stays with you in full.
Your own domain and certificates
A project runs in one of two modes. At the start it is an IP address over an unprotected protocol — convenient for getting to know the project, and honest about the browser capabilities that are unavailable in it. The second mode is your own domain, HTTPS and strict role checking; you move to it as soon as you decide to develop the project in earnest.
Connecting a domain is described in the panel: a wizard of five steps and five records at your registrar — the domain itself, `www`, and three service names for sign-in, the panel and the data. The certificate is then issued automatically.
Security certificates
The certificate is issued and renewed without a human: renewal is handled by a system timer that wakes twice a day and renews whatever is due. The panel shows the expiry date and the names the certificate covers, and next to it stands a manual renewal button — for the case where waiting is not an option.
The automatic certificate
Free, from Let’s Encrypt. It is valid for 90 days and is renewed ahead of time rather than on the last day. What matters is what it actually attests: control over the domain, not your organisation. Such a certificate carries no company check — Let’s Encrypt does not issue organisation-validated certificates at all.
Your own certificate
Uploaded as a certificate-and-key pair and replaces the automatic one. It is needed when your company or an external regulator requires it: when the certificate must come from a particular authority, say, or carry an organisation check. The panel shows its expiry and covered names in the same way.
Authorization
Accounts, sessions and roles live in a separate service rather than inside the application. The sign-in interface is translated into 82 languages: a customer arrives from a country you did not choose and in a language you did not plan for.
Signing in by email
The default, and enough for a prototype: a person enters an address and receives a link by email — there is no password, so there is nothing to forget and nothing to steal. It is switched on with a mail-service key you paste into the panel.
Signing in with Google
Switched on with an id-and-secret pair from the Google console; the panel hands you the return address ready to copy. Beyond these two, more than eighty preconfigured sign-in providers are available: connecting any of them is a support request, not development work.
And the point of it all: signing in does not exist for its own sake. It returns a role — the very thing the route layers and the locks on the data doors stand on. The way in changes; what a person receives afterwards does not.
Memory
Memory is the heart of the project, and there is more than one of it. Four stores of different kinds sit behind one door and open with one key. For an artificial-intelligence agent this is the difference between finding by word and understanding what is meant: without such memory it starts from nothing every time.
The database
The rows of the application: users, orders, records, the build journal. A new table is declared in one place and appears the same way on your machine and on the server — there are no separate migrations to remember and run.
The object store
Files and what is known about them: images, video, documents, icon sets. A file is addressed by name rather than by number, so a link to it reads as human text and survives a move. Video is trimmed on the server, and the resulting duration is measured rather than assumed.
The vector store
Search by meaning rather than by matching words. It lives next to the rows it describes: one backup, one access contour, one meaning of deletion. Split them across services and one day a deleted record stays in the search.
The agentic RAG
A graph of connections: it stores not chunks of text but how entities relate to each other. It answers questions that have no single source of answer. Switched on with a toggle, and it deliberately has no interface of its own — you talk to it with questions, not with your eyes.
You can try the memory without programming anything: the Telegram bot answers by asking the knowledge graph — you write a question, it answers from the loaded documents, and if the base is empty it says honestly that it has nothing to answer from. A voice message it transcribes by itself.
Communication channels
One channel is built in deeply so far — Telegram. "Deeply" means a two-way link rather than the ability to send: incoming messages land in a shared inbox, files are accepted, voice is transcribed, and the answer comes from the project’s memory. One service reads the bot, and only one: Telegram hands each message to exactly one reader, and a second poller would silently eat half the conversation.
The next channel — email, a messenger, a widget on the site — is added by a developer as another entry in the same service rather than as a second service. Channels inside the application itself the architect builds without us: the platform is needed where a channel must be shared by the whole server.
The map
A map in the platform is not "show a pin on a tile". It is routes between addresses, distance matrices across dozens of points, address lookup by name, and visiting order: delivery, couriers, call-outs, site rounds — any process that has geography in it.
What makes it different is where it is computed: the mapping engines run on your own server rather than in someone else’s cloud. Two consequences follow — requests are not metered one by one, and your customers’ addresses do not travel to a third party to come back as a distance.
The control panel
The panel is deliberately shrinking: its sections move one by one into the project itself, next to the code. But part of the work will stay there for good — the part that must survive a breakage of the application. A broken application cannot repair itself from the inside.
Backups
A copy is taken in parts, chosen one at a time: the database with the vector memory · files and what is known about them · the knowledge graph · the application settings · the channels · the environment file. Six parts instead of one big button — because people restore one thing rather than everything, and bringing settings back without touching today’s orders is impossible otherwise.
Deployment and errors
The build journal keeps what was built, when, how long it took, how it ended and the whole output. A failed build does not leave the project in an undefined state: the last good one is restored and the site keeps working.
You can use all this by hand, but usually you do not need to: deployment and error triage are driven through the coding agent, and the panel stays as the safety net and the observation post — the place you come to when something has gone wrong.